From: Stephen Hurd <stephen.hurd@broadcom.com>
To: dev@dpdk.org
Subject: [dpdk-dev] [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
Date: Fri, 4 Mar 2016 13:05:24 -0800 [thread overview]
Message-ID: <1457125528-128877-4-git-send-email-stephen.hurd@broadcom.com> (raw)
In-Reply-To: <1457125528-128877-1-git-send-email-stephen.hurd@broadcom.com>
In-Reply-To: <1456978137-98097-1-git-send-email-stephen.hurd@broadcom.com>
New driver for Broadcom bnxt (NexXtreme C-series) devices.
Standards-compliant 10/25/50G support with 30MPPS full-duplex throughput
http://www.broadcom.com/press/release.php?id=s923886
Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
v3:
* Fix incorrect format specifier compilation error on i686
(PRIx64 instead of lx for uint64_t) on line 1337
drivers/net/bnxt/Makefile | 79 ++
drivers/net/bnxt/bnxt.h | 217 ++++
drivers/net/bnxt/bnxt_cpr.c | 138 +++
drivers/net/bnxt/bnxt_cpr.h | 117 ++
drivers/net/bnxt/bnxt_ethdev.c | 1381 ++++++++++++++++++++++
drivers/net/bnxt/bnxt_filter.c | 175 +++
drivers/net/bnxt/bnxt_filter.h | 74 ++
drivers/net/bnxt/bnxt_hwrm.c | 1554 ++++++++++++++++++++++++
drivers/net/bnxt/bnxt_hwrm.h | 105 ++
drivers/net/bnxt/bnxt_irq.c | 154 +++
drivers/net/bnxt/bnxt_irq.h | 51 +
drivers/net/bnxt/bnxt_ring.c | 306 +++++
drivers/net/bnxt/bnxt_ring.h | 104 ++
drivers/net/bnxt/bnxt_rxq.c | 383 ++++++
drivers/net/bnxt/bnxt_rxq.h | 75 ++
drivers/net/bnxt/bnxt_rxr.c | 369 ++++++
drivers/net/bnxt/bnxt_rxr.h | 73 ++
drivers/net/bnxt/bnxt_stats.c | 190 +++
drivers/net/bnxt/bnxt_stats.h | 44 +
drivers/net/bnxt/bnxt_txq.c | 164 +++
drivers/net/bnxt/bnxt_txq.h | 76 ++
drivers/net/bnxt/bnxt_txr.c | 326 +++++
drivers/net/bnxt/bnxt_txr.h | 71 ++
drivers/net/bnxt/bnxt_vnic.c | 285 +++++
drivers/net/bnxt/bnxt_vnic.h | 80 ++
drivers/net/bnxt/hsi_struct_def_dpdk.h | 1832 +++++++++++++++++++++++++++++
drivers/net/bnxt/rte_pmd_bnxt_version.map | 4 +
27 files changed, 8427 insertions(+)
create mode 100644 drivers/net/bnxt/Makefile
create mode 100644 drivers/net/bnxt/bnxt.h
create mode 100644 drivers/net/bnxt/bnxt_cpr.c
create mode 100644 drivers/net/bnxt/bnxt_cpr.h
create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
create mode 100644 drivers/net/bnxt/bnxt_filter.c
create mode 100644 drivers/net/bnxt/bnxt_filter.h
create mode 100644 drivers/net/bnxt/bnxt_hwrm.c
create mode 100644 drivers/net/bnxt/bnxt_hwrm.h
create mode 100644 drivers/net/bnxt/bnxt_irq.c
create mode 100644 drivers/net/bnxt/bnxt_irq.h
create mode 100644 drivers/net/bnxt/bnxt_ring.c
create mode 100644 drivers/net/bnxt/bnxt_ring.h
create mode 100644 drivers/net/bnxt/bnxt_rxq.c
create mode 100644 drivers/net/bnxt/bnxt_rxq.h
create mode 100644 drivers/net/bnxt/bnxt_rxr.c
create mode 100644 drivers/net/bnxt/bnxt_rxr.h
create mode 100644 drivers/net/bnxt/bnxt_stats.c
create mode 100644 drivers/net/bnxt/bnxt_stats.h
create mode 100644 drivers/net/bnxt/bnxt_txq.c
create mode 100644 drivers/net/bnxt/bnxt_txq.h
create mode 100644 drivers/net/bnxt/bnxt_txr.c
create mode 100644 drivers/net/bnxt/bnxt_txr.h
create mode 100644 drivers/net/bnxt/bnxt_vnic.c
create mode 100644 drivers/net/bnxt/bnxt_vnic.h
create mode 100644 drivers/net/bnxt/hsi_struct_def_dpdk.h
create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
new file mode 100644
index 0000000..74de642
--- /dev/null
+++ b/drivers/net/bnxt/Makefile
@@ -0,0 +1,79 @@
+# BSD LICENSE
+#
+# Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+# Copyright(c) 2014 6WIND S.A.
+# Copyright(c) 2015 Broadcom Corporation. All rights reserved.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# * Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# * Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+# * Neither the name of 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 $(RTE_SDK)/mk/rte.vars.mk
+
+#
+# library name
+#
+LIB = librte_pmd_bnxt.a
+
+LIBABIVER := 1
+
+CFLAGS += -O3
+CFLAGS += -DPORT_QSTATS_BROKEN
+CFLAGS += -DFUNC_QSTATS_BROKEN
+#CFLAGS += -DFPGA
+CFLAGS += $(WERROR_FLAGS)
+CFLAGS += -DCONFIG_B_SRIOV
+#CFLAGS += -DHSI_DEBUG
+
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_hwrm.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ring.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxr.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
+
+#
+# Export include files
+#
+SYMLINK-y-include +=
+
+# this lib depends upon:
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += lib/librte_mbuf
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += lib/librte_ether
+DEPDIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += lib/librte_malloc
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
new file mode 100644
index 0000000..1a708c8
--- /dev/null
+++ b/drivers/net/bnxt/bnxt.h
@@ -0,0 +1,217 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_H_
+#define _BNXT_H_
+
+#include <inttypes.h>
+#include <sys/queue.h>
+
+#include <rte_ethdev.h>
+#include <rte_memory.h>
+#include <rte_lcore.h>
+#include <rte_spinlock.h>
+
+/* TODO make bnxt.def_cp_ring a pointer to avoid this... */
+#include "bnxt_cpr.h"
+
+#define BNXT_VER_MAJ 1
+#define BNXT_VER_MIN 0
+#define BNXT_VER_UPD 1
+
+#define U64_TO_U32_LO(addr) ((uint32_t)(((uint64_t)(addr)) & 0xFFFFFFFF))
+#define U64_TO_U32_HI(addr) ((uint32_t)(((uint64_t)(addr)) >> 32))
+
+#define SET_BIT_IN_ARRAY(array, bitnum) \
+ (array[bitnum / (sizeof(array[0]) * 8)] |= \
+ (1 << (bitnum % (sizeof(array[0]) * 8))))
+
+#define B_MAX_MSIX_VEC 16
+
+#define BNXT_MAX_MTU 9000
+#define VLAN_TAG_SIZE 4
+
+#define NUM_ACTION_RECORD_REGIONS 5
+
+enum bnxt_hw_context {
+ HW_CONTEXT_NONE = 0,
+ HW_CONTEXT_IS_RSS = 1,
+ HW_CONTEXT_IS_COS = 2,
+ HW_CONTEXT_IS_LB = 3,
+};
+
+#define INVALID_STATS_CTX_ID -1
+
+#if defined(CONFIG_B_SRIOV)
+struct bnxt_vf_info {
+ uint16_t fw_fid;
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+ uint16_t max_rsscos_ctx;
+ uint16_t max_cp_rings;
+ uint16_t max_tx_rings;
+ uint16_t max_rx_rings;
+ uint16_t max_l2_ctx;
+ uint16_t max_vnics;
+ struct bnxt_pf_info *pf;
+};
+
+struct bnxt_pf_info {
+#define BNXT_FIRST_PF_FID 1
+#define BNXT_MAX_VFS(bp) (bp->pf.max_vfs)
+#define BNXT_FIRST_VF_FID 128
+#define BNXT_PF_RINGS_USED(bp) bnxt_get_num_queues(bp)
+#define BNXT_PF_RINGS_AVAIL(bp) (bp->pf.max_cp_rings - BNXT_PF_RINGS_USED(bp))
+ uint32_t fw_fid;
+ uint8_t port_id;
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+ uint16_t max_rsscos_ctx;
+ uint16_t max_cp_rings;
+ uint16_t max_tx_rings;
+ uint16_t max_rx_rings;
+ uint16_t max_l2_ctx;
+ uint16_t max_vnics;
+ uint16_t first_vf_id;
+ uint16_t active_vfs;
+ uint16_t max_vfs;
+ void *vf_req_buf;
+ phys_addr_t vf_req_buf_dma_addr;
+ uint32_t vf_req_fwd[8];
+ struct bnxt_vf_info *vf;
+};
+#endif
+
+/* Max wait time is 10 * 100ms = 1s */
+#define BNXT_LINK_WAIT_CNT 10
+#define BNXT_LINK_WAIT_INTERVAL 100
+struct bnxt_link_info {
+ uint8_t phy_flags;
+ uint8_t mac_type;
+ uint8_t phy_link_status;
+ uint8_t loop_back;
+ uint8_t link_up;
+ uint8_t duplex;
+ uint8_t pause;
+ uint8_t force_pause;
+ uint8_t auto_pause;
+ uint8_t auto_mode;
+#define PHY_VER_LEN 3
+ uint8_t phy_ver[PHY_VER_LEN];
+ uint16_t link_speed;
+ uint16_t support_speeds;
+ uint16_t auto_link_speed;
+ uint16_t auto_link_speed_mask;
+ uint32_t preemphasis;
+};
+
+#define BNXT_COS_QUEUE_COUNT 8
+struct bnxt_cos_queue_info {
+ uint8_t id;
+ uint8_t profile;
+};
+
+struct bnxt {
+ void *bar0;
+
+ struct rte_eth_dev *eth_dev;
+ struct rte_pci_device *pdev;
+
+ uint32_t flags;
+ #define BNXT_FLAG_DCB_ENABLED (1<<0)
+ #define BNXT_FLAG_VF (1<<1)
+ #define BNXT_FLAG_LRO (1<<2)
+ #define BNXT_FLAG_GRO (1<<3)
+ #define BNXT_FLAG_160B_TCAM (1<<16)
+
+#define BNXT_PF(bp) (!((bp)->flags & BNXT_FLAG_VF))
+#define BNXT_VF(bp) ((bp)->flags & BNXT_FLAG_VF)
+
+ unsigned rx_nr_rings;
+ unsigned rx_cp_nr_rings;
+ struct bnxt_rx_queue **rx_queues;
+
+ unsigned tx_nr_rings;
+ unsigned tx_cp_nr_rings;
+ struct bnxt_tx_queue **tx_queues;
+
+ /* Default completion ring */
+ struct bnxt_cp_ring_info def_cp_ring;
+
+#define MAX_NUM_RINGS 48 /* 340 for Cumulus */
+ struct bnxt_ring_grp_info grp_info[MAX_NUM_RINGS];
+ unsigned nr_vnics;
+ struct bnxt_vnic_info *vnic_info;
+
+ STAILQ_HEAD(, bnxt_vnic_info) free_vnic_list;
+
+ struct bnxt_filter_info *filter_info;
+
+ STAILQ_HEAD(, bnxt_filter_info) free_filter_list;
+
+ /* VNIC pointer for flow filter (VMDq) pools */
+#define MAX_FF_POOLS ETH_64_POOLS
+ STAILQ_HEAD(, bnxt_vnic_info) ff_pool[MAX_FF_POOLS];
+
+ unsigned int current_interval;
+
+ struct bnxt_irq *irq_tbl;
+
+#define MAX_NUM_MAC_ADDR 32
+ uint8_t mac_addr[ETHER_ADDR_LEN];
+
+#define NUM_REG_WINDOWS 16
+ uint32_t reg_window_base[NUM_REG_WINDOWS];
+ uint32_t msg_enable;
+
+ uint16_t hwrm_cmd_seq;
+ uint32_t hwrm_intr_seq_id;
+ void *hwrm_cmd_resp_addr;
+ phys_addr_t hwrm_cmd_resp_dma_addr;
+ rte_spinlock_t hwrm_lock;
+
+ uint16_t vxlan_port;
+ uint8_t vxlan_port_cnt;
+ uint16_t vxlan_fw_dst_port_id;
+
+ struct bnxt_link_info link_info;
+#define BNXT_LINK_SPEED_AUTO 0
+ struct bnxt_cos_queue_info cos_queue[BNXT_COS_QUEUE_COUNT];
+ uint16_t max_req_len;
+
+#ifdef CONFIG_B_SRIOV
+ int nr_vfs;
+ struct bnxt_pf_info pf;
+ struct bnxt_vf_info vf;
+#endif
+};
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
new file mode 100644
index 0000000..4a5e2e6
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -0,0 +1,138 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
+
+/*
+ * Async event handling
+ */
+void bnxt_handle_async_event(struct bnxt *bp __rte_unused,
+ struct cmpl_base *cmp)
+{
+ struct hwrm_async_event_cmpl *async_cmp =
+ (struct hwrm_async_event_cmpl *)cmp;
+
+ /* TODO: HWRM async events are not defined yet */
+ /* Needs to handle: link events, error events, etc. */
+ switch (async_cmp->event_id) {
+ case 0:
+ /* Assume LINK_CHANGE == 0 */
+ RTE_LOG(INFO, PMD, "Link change event\n");
+
+ /* Can just prompt the update_op routine to do a qcfg
+ instead of doing the actual qcfg */
+ break;
+ case 1:
+ break;
+ default:
+ RTE_LOG(ERR, PMD, "handle_async_event id = 0x%x\n",
+ async_cmp->event_id);
+ break;
+ }
+}
+
+void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
+{
+ struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
+ struct input *fwd_cmd;
+ uint16_t logical_vf_id, error_code;
+
+ /* Qualify the fwd request */
+ if (fwd_cmpl->source_id < bp->pf.first_vf_id) {
+ RTE_LOG(ERR, PMD,
+ "FWD req's source_id 0x%x > first_vf_id 0x%x\n",
+ fwd_cmpl->source_id, bp->pf.first_vf_id);
+ error_code = HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED;
+ goto reject;
+ } else if (fwd_cmpl->req_len_type >> HWRM_FWD_REQ_CMPL_REQ_LEN_SFT >
+ 128 - sizeof(struct input)) {
+ RTE_LOG(ERR, PMD,
+ "FWD req's cmd len 0x%x > 108 bytes allowed\n",
+ fwd_cmpl->req_len_type >> HWRM_FWD_REQ_CMPL_REQ_LEN_SFT);
+ error_code = HWRM_ERR_CODE_INVALID_PARAMS;
+ goto reject;
+ }
+
+ /* Locate VF's forwarded command */
+ logical_vf_id = fwd_cmpl->source_id - bp->pf.first_vf_id;
+ fwd_cmd = (struct input *)((uint8_t *)bp->pf.vf_req_buf +
+ (logical_vf_id * 128));
+
+ /* Provision the request */
+ switch (fwd_cmd->req_type) {
+ case HWRM_CFA_L2_FILTER_ALLOC:
+ case HWRM_CFA_L2_FILTER_FREE:
+ case HWRM_CFA_L2_FILTER_CFG:
+ case HWRM_CFA_L2_SET_RX_MASK:
+ break;
+ default:
+ error_code = HWRM_ERR_CODE_INVALID_PARAMS;
+ goto reject;
+ }
+
+ /* Forward */
+ fwd_cmd->target_id = fwd_cmpl->source_id;
+ bnxt_hwrm_exec_fwd_resp(bp, fwd_cmd);
+ return;
+
+reject:
+ /* TODO: Encap the reject error resp into the hwrm_err_iput? */
+ /* Use the error_code for the reject cmd */
+ RTE_LOG(ERR, PMD,
+ "Error 0x%x found in the forward request\n", error_code);
+}
+
+/* For the default completion ring only */
+void bnxt_free_def_cp_ring(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+ struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
+
+ bnxt_free_ring(ring);
+}
+
+/* For the default completion ring only */
+void bnxt_init_def_ring_struct(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+ struct bnxt_ring_struct *ring = &cpr->cp_ring_struct;
+
+ ring->bd = (void *)cpr->cp_desc_ring;
+ ring->bd_dma = cpr->cp_desc_mapping;
+ ring->ring_size = rte_align32pow2(DEFAULT_CP_RING_SIZE);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->vmem_size = 0;
+ ring->vmem = NULL;
+}
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
new file mode 100644
index 0000000..f1c3f81
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -0,0 +1,117 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_CPR_H_
+#define _BNXT_CPR_H_
+
+/* TODO make bnxt_cp_ring_info.cp_ring_struct a pointer to avoid this. */
+#include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
+
+#define CMP_VALID(cmp, raw_cons, ring) \
+ (!!(((struct cmpl_base *)(cmp))->info3_v & CMPL_BASE_V) == \
+ !((raw_cons) & ((ring)->ring_size)))
+
+#define CMP_TYPE(cmp) \
+ (((struct cmpl_base *)cmp)->type & CMPL_BASE_TYPE_MASK)
+
+#define ADV_RAW_CMP(idx, n) ((idx) + (n))
+#define NEXT_RAW_CMP(idx) ADV_RAW_CMP(idx, 1)
+#define RING_CMP(ring, idx) ((idx) & (ring)->ring_mask)
+#define NEXT_CMP(idx) RING_CMP(ADV_RAW_CMP(idx, 1))
+
+#define DB_CP_REARM_FLAGS (DB_KEY_CP | DB_IDX_VALID)
+#define DB_CP_FLAGS (DB_KEY_CP | DB_IDX_VALID | DB_IRQ_DIS)
+
+#define B_CP_DB_REARM(cpr, raw_cons) \
+ (*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+ RING_CMP(&cpr->cp_ring_struct, raw_cons)))
+
+#define B_CP_DIS_DB(cpr, raw_cons) \
+ (*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS | \
+ RING_CMP(&cpr->cp_ring_struct, raw_cons)))
+
+struct bnxt_cp_ring_info {
+ uint32_t cp_raw_cons;
+ void *cp_doorbell;
+
+ struct cmpl_base *cp_desc_ring;
+
+ phys_addr_t cp_desc_mapping;
+
+ struct ctx_hw_stats *hw_stats;
+ phys_addr_t hw_stats_map;
+ uint32_t hw_stats_ctx_id;
+
+ struct bnxt_ring_struct cp_ring_struct;
+};
+
+#define RX_CMP_L2_ERRORS \
+ (RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK | RX_PKT_CMPL_ERRORS_CRC_ERROR)
+
+#define RX_CMP_L4_CS_OK(rxcmp1) \
+ (((rxcmp1)->rx_cmp_flags2 & \
+ (RX_CMP_FLAGS2_L4_CS_CALC | RX_CMP_FLAGS2_T_L4_CS_CALC)) &&\
+ !((rxcmp1)->rx_cmp_cfa_code_errors_v2 & \
+ (RX_CMPL_ERRORS_L4_CS_ERROR | RX_CMPL_ERRORS_T_L4_CS_ERROR)))
+
+#define RX_CMP_ENCAP(rxcmp1) \
+ (((rxcmp1)->rx_cmp_flags2 & RX_CMP_FLAGS2_T_L4_CS_CALC) >> 3)
+
+#define B_TPA_START_AGG_ID(rx_tpa_start) \
+ (((rx_tpa_start)->rx_tpa_start_cmp_misc_v1 & \
+ RX_TPA_START_CMP_AGG_ID) >> RX_TPA_START_CMP_AGG_ID_SHIFT)
+
+#define B_TPA_END_AGG_ID(rx_tpa_end) \
+ ((rx_tpa_end)->rx_tpa_end_cmp_misc_v1 & \
+ (RX_TPA_END_CMP_AGG_ID) >> RX_TPA_END_CMP_AGG_ID_SHIFT)
+
+#define B_TPA_END_TPA_SEGS(rx_tpa_end) \
+ (((rx_tpa_end)->rx_tpa_end_cmp_misc_v1 & \
+ RX_TPA_END_CMP_TPA_SEGS) >> RX_TPA_END_CMP_TPA_SEGS_SHIFT)
+
+#define RX_TPA_END_CMP_FLAGS_PLACEMENT_ANY_GRO \
+ (RX_TPA_END_CMP_FLAGS_PLACEMENT_GRO_JUMBO & \
+ RX_TPA_END_CMP_FLAGS_PLACEMENT_GRO_HDS)
+
+#define B_TPA_END_GRO(rx_tpa_end) \
+ ((rx_tpa_end)->rx_tpa_end_cmp_len_flags_type & \
+ RX_TPA_END_CMP_FLAGS_PLACEMENT_ANY_GRO)
+
+struct bnxt;
+void bnxt_free_def_cp_ring(struct bnxt *bp);
+void bnxt_init_def_ring_struct(struct bnxt *bp);
+void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp);
+void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
new file mode 100644
index 0000000..dabaee7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -0,0 +1,1381 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+#include <stdbool.h>
+
+#include <rte_dev.h>
+#include <rte_ethdev.h>
+#include <rte_malloc.h>
+#include <rte_cycles.h>
+
+#include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_irq.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
+#include "bnxt_stats.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+#define STRIZE(x) #x
+#define STRIFY(x) STRIZE(x)
+#define DRV_MODULE_NAME "bnxt"
+#define DRV_MODULE_VERSION STRIFY(BNXT_VER_MAJ) "." STRIFY(BNXT_VER_MIN) \
+ "." STRIFY(BNXT_VER_UPD)
+
+static const char bnxt_version[] =
+ "Broadcom Cumulus driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION "\n";
+
+static struct rte_pci_id bnxt_pci_id_map[] = {
+#define RTE_PCI_DEV_ID_DECL_BNXT(vend, dev) {RTE_PCI_DEVICE(vend, dev)},
+#include "rte_pci_dev_ids.h"
+
+ {.device_id = 0},
+};
+
+#define BNXT_ETH_RSS_SUPPORT ( \
+ ETH_RSS_IPV4 | \
+ ETH_RSS_NONFRAG_IPV4_TCP | \
+ ETH_RSS_NONFRAG_IPV4_UDP | \
+ ETH_RSS_IPV6 | \
+ ETH_RSS_NONFRAG_IPV6_TCP | \
+ ETH_RSS_NONFRAG_IPV6_UDP)
+
+struct cfa_mcast_rec {
+ uint16_t action0_5[6];
+ uint32_t mc_grp_entry;
+};
+
+/***********************/
+
+/*
+ * High level utility functions
+ */
+
+static void bnxt_free_mem(struct bnxt *bp)
+{
+ bnxt_free_filter_mem(bp);
+ bnxt_free_vnic_attributes(bp);
+ bnxt_free_vnic_mem(bp);
+
+ bnxt_free_stats(bp);
+ bnxt_free_tx_rings(bp);
+ bnxt_free_rx_rings(bp);
+ bnxt_free_def_cp_ring(bp);
+}
+
+static int bnxt_alloc_mem(struct bnxt *bp)
+{
+ int rc;
+
+ /* Default completion ring */
+ bnxt_init_def_ring_struct(bp);
+ rc = bnxt_alloc_rings(bp, 0, NULL, NULL,
+ &bp->def_cp_ring, "def_cp_ring");
+ if (rc)
+ goto alloc_mem_err;
+
+ rc = bnxt_alloc_vnic_mem(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ rc = bnxt_alloc_vnic_attributes(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ rc = bnxt_alloc_filter_mem(bp);
+ if (rc)
+ goto alloc_mem_err;
+
+ return 0;
+
+alloc_mem_err:
+ bnxt_free_mem(bp);
+ return rc;
+}
+
+static int bnxt_init_chip(struct bnxt *bp)
+{
+ unsigned i, rss_idx, fw_idx;
+ int rc;
+
+ rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_alloc_hwrm_rings(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM ring alloc failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_alloc_all_hwrm_ring_grps(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM ring grp alloc failure: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_mq_rx_configure(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "MQ mode configure failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ /* bp->flags needs to be revisited for other stateless offload
+ features */
+ bp->flags &= ~(BNXT_FLAG_GRO | BNXT_FLAG_LRO);
+
+ /* VNIC configuration */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ rc = bnxt_hwrm_vnic_alloc(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
+ rc);
+ goto err_out;
+ }
+
+ rc = bnxt_hwrm_vnic_ctx_alloc(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "HWRM vnic ctx alloc failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM vnic cfg failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ rc = bnxt_set_hwrm_vnic_filters(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM vnic filter failure rc: %x\n",
+ rc);
+ goto err_out;
+ }
+ if (vnic->rss_table && vnic->hash_type) {
+ /* Fill the RSS hash & redirection table with
+ ring group ids for all VNICs */
+ for (rss_idx = 0, fw_idx = 0;
+ rss_idx < HW_HASH_INDEX_SIZE;
+ rss_idx++, fw_idx++) {
+ if (vnic->fw_grp_ids[fw_idx] ==
+ INVALID_HW_RING_ID)
+ fw_idx = 0;
+ vnic->rss_table[rss_idx] =
+ vnic->fw_grp_ids[fw_idx];
+ }
+ rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "HWRM vnic set RSS failure rc: %x\n",
+ rc);
+ goto err_out;
+ }
+ }
+ }
+ rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "HWRM cfa l2 rx mask failure rc: %x\n", rc);
+ goto err_out;
+ }
+
+ return 0;
+
+err_out:
+ bnxt_free_all_hwrm_resources(bp);
+
+ return rc;
+}
+
+static int bnxt_shutdown_nic(struct bnxt *bp)
+{
+ bnxt_free_all_hwrm_resources(bp);
+ bnxt_free_all_filters(bp);
+ bnxt_free_all_vnics(bp);
+ return 0;
+}
+
+static int bnxt_init_nic(struct bnxt *bp)
+{
+ int rc;
+
+ bnxt_init_ring_grps(bp);
+ bnxt_init_vnics(bp);
+ bnxt_init_filters(bp);
+
+ rc = bnxt_init_chip(bp);
+ if (rc)
+ return rc;
+
+ return 0;
+}
+
+/*
+ * Device configuration and status function
+ */
+
+static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_dev_info *dev_info)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint16_t max_vnics, i, j, vpool, vrxq;
+
+ /* MAC Specifics */
+ dev_info->max_mac_addrs = MAX_NUM_MAC_ADDR;
+ dev_info->max_hash_mac_addrs = 0;
+
+ /* PF/VF specifics */
+ if (BNXT_PF(bp)) {
+ dev_info->max_rx_queues = bp->pf.max_rx_rings;
+ dev_info->max_tx_queues = bp->pf.max_tx_rings;
+ dev_info->max_vfs = bp->pf.active_vfs;
+ dev_info->reta_size = bp->pf.max_rsscos_ctx;
+ max_vnics = bp->pf.max_vnics;
+ } else {
+ dev_info->max_rx_queues = bp->vf.max_rx_rings;
+ dev_info->max_tx_queues = bp->vf.max_tx_rings;
+ dev_info->reta_size = bp->vf.max_rsscos_ctx;
+ max_vnics = bp->vf.max_vnics;
+ }
+
+ /* Fast path specifics */
+ dev_info->min_rx_bufsize = 1;
+ dev_info->max_rx_pktlen = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN
+ + VLAN_TAG_SIZE;
+ dev_info->rx_offload_capa = 0;
+ dev_info->tx_offload_capa = DEV_TX_OFFLOAD_IPV4_CKSUM |
+ DEV_TX_OFFLOAD_TCP_CKSUM |
+ DEV_TX_OFFLOAD_UDP_CKSUM |
+ DEV_TX_OFFLOAD_TCP_TSO;
+
+ /* *INDENT-OFF* */
+ dev_info->default_rxconf = (struct rte_eth_rxconf) {
+ .rx_thresh = {
+ .pthresh = 8,
+ .hthresh = 8,
+ .wthresh = 0,
+ },
+ .rx_free_thresh = 32,
+ .rx_drop_en = 0,
+ };
+
+ dev_info->default_txconf = (struct rte_eth_txconf) {
+ .tx_thresh = {
+ .pthresh = 32,
+ .hthresh = 0,
+ .wthresh = 0,
+ },
+ .tx_free_thresh = 32,
+ .tx_rs_thresh = 32,
+ .txq_flags = ETH_TXQ_FLAGS_NOMULTSEGS |
+ ETH_TXQ_FLAGS_NOOFFLOADS,
+ };
+ /* *INDENT-ON* */
+
+ /*
+ * TODO: default_rxconf, default_txconf, rx_desc_lim, and tx_desc_lim
+ * need further investigation.
+ */
+
+ /* VMDq resources */
+ vpool = 64; /* ETH_64_POOLS */
+ vrxq = 128; /* ETH_VMDQ_DCB_NUM_QUEUES */
+ for (i = 0; i < 4; vpool >>= 1, i++) {
+ if (max_vnics > vpool) {
+ for (j = 0; j < 5; vrxq >>= 1, j++) {
+ if (dev_info->max_rx_queues > vrxq) {
+ if (vpool > vrxq)
+ vpool = vrxq;
+ goto found;
+ }
+ }
+ /* Not enough resources to support VMDq */
+ break;
+ }
+ }
+ /* Not enough resources to support VMDq */
+ vpool = 0;
+ vrxq = 0;
+found:
+ dev_info->max_vmdq_pools = vpool;
+ dev_info->vmdq_queue_num = vrxq;
+
+ dev_info->vmdq_pool_base = 0;
+ dev_info->vmdq_queue_base = 0;
+}
+
+/* Configure the device based on the configuration provided */
+static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ int rc = 0;
+
+ bp->rx_queues = (void *)eth_dev->data->rx_queues;
+ bp->tx_queues = (void *)eth_dev->data->tx_queues;
+
+ /* Inherit new configurations */
+ bp->rx_nr_rings = eth_dev->data->nb_rx_queues;
+ bp->tx_nr_rings = eth_dev->data->nb_tx_queues;
+ bp->rx_cp_nr_rings = bp->rx_nr_rings;
+ bp->tx_cp_nr_rings = bp->tx_nr_rings;
+
+ if (eth_dev->data->dev_conf.rxmode.jumbo_frame)
+ eth_dev->data->mtu =
+ eth_dev->data->dev_conf.rxmode.max_rx_pkt_len -
+ ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE;
+ bnxt_set_hwrm_link_config(bp, true);
+ return rc;
+}
+
+static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ int rc;
+
+ rc = bnxt_hwrm_func_reset(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc);
+ rc = -1;
+ goto error;
+ }
+ rc = bnxt_setup_int(bp);
+ if (rc)
+ goto error;
+
+ rc = bnxt_alloc_mem(bp);
+ if (rc)
+ goto error;
+
+ rc = bnxt_request_int(bp);
+ if (rc)
+ goto error;
+
+ rc = bnxt_init_nic(bp);
+ if (rc)
+ goto error;
+
+ bnxt_enable_int(bp);
+
+ return 0;
+
+error:
+ bnxt_shutdown_nic(bp);
+ bnxt_disable_int(bp);
+ bnxt_free_int(bp);
+ bnxt_free_tx_mbufs(bp);
+ bnxt_free_rx_mbufs(bp);
+ bnxt_free_mem(bp);
+ return rc;
+}
+
+/* Unload the driver, release the IRQ */
+static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+#ifdef FPGA_DEBUG
+ /* The FPGA needs about 10ms of settle time to DMA
+ the last few completions.
+ 100ms is the experimental value for reliability purposes */
+ rte_delay_ms(100);
+#endif
+
+ if (bp->eth_dev->data->dev_started) {
+ /* TBD: STOP HW queues DMA */
+ eth_dev->data->dev_link.link_status = 0;
+ }
+ bnxt_shutdown_nic(bp);
+ bnxt_disable_int(bp);
+ bnxt_free_int(bp);
+}
+
+static int bnxt_dev_set_link_up_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ eth_dev->data->dev_link.link_status = 1;
+ bnxt_set_hwrm_link_config(bp, true);
+ return 0;
+}
+
+static int bnxt_dev_set_link_down_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ eth_dev->data->dev_link.link_status = 0;
+ bnxt_set_hwrm_link_config(bp, false);
+ return 0;
+}
+
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ int rc;
+
+ bnxt_dev_stop_op(eth_dev);
+ bnxt_free_tx_mbufs(bp);
+ bnxt_free_rx_mbufs(bp);
+ bnxt_free_mem(bp);
+
+ if (BNXT_PF(bp)) {
+ /* Notify all VFs about the device going down */
+ /* PF to VF notification */
+
+ /* Clean up for VFs */
+ rc = bnxt_hwrm_func_vf_free(bp, bp->pf.active_vfs);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Failed to free VFs with rc = 0x%d!", rc);
+ bp->pf.active_vfs = 0;
+ }
+
+ /* Free all VF fwd cmd buffer */
+ rte_free(bp->pf.vf_req_buf);
+ }
+
+ rte_free(eth_dev->data->mac_addrs);
+ bnxt_free_hwrm_resources(bp);
+}
+
+#ifdef FPGA_DEBUG
+static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
+ int wait_to_complete __rte_unused)
+{
+ /* Hard code link status and attrib for now */
+ bnxt_dev_set_link_up_op(eth_dev);
+
+ eth_dev->data->dev_link.link_duplex = ETH_LINK_FULL_DUPLEX;
+ eth_dev->data->dev_link.link_speed = ETH_LINK_SPEED_10;
+ return 0;
+}
+#else
+static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
+ int wait_to_complete)
+{
+ int rc = 0;
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_link new;
+ unsigned cnt = BNXT_LINK_WAIT_CNT;
+
+ memset(&new, 0, sizeof(new));
+ do {
+ /* Retrieve link info from hardware */
+ rc = bnxt_get_hwrm_link_config(bp, &new);
+ if (rc) {
+ new.link_speed = ETH_LINK_SPEED_100;
+ new.link_duplex = ETH_LINK_FULL_DUPLEX;
+ RTE_LOG(ERR, PMD,
+ "Failed to retrieve link rc = 0x%d!", rc);
+ goto out;
+ }
+ if (!wait_to_complete)
+ break;
+
+ rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
+
+ } while (!new.link_status && cnt--);
+
+ /* Timed out or success */
+ if (new.link_status) {
+ /* Update only if success */
+ eth_dev->data->dev_link.link_duplex = new.link_duplex;
+ eth_dev->data->dev_link.link_speed = new.link_speed;
+ }
+ eth_dev->data->dev_link.link_status = new.link_status;
+out:
+ return rc;
+}
+#endif
+
+static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags |= BNXT_VNIC_INFO_PROMISC;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
+static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
+static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
+static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+
+ vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+ bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
+static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic;
+ int i;
+
+ if (!dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+ return -EINVAL;
+
+ if (reta_size != HW_HASH_INDEX_SIZE) {
+ RTE_LOG(ERR, PMD, "The configured hash table lookup size "
+ "(%d) must equal the size supported by the hardware "
+ "(%d)\n", reta_size, HW_HASH_INDEX_SIZE);
+ return -EINVAL;
+ }
+ /* Update the RSS VNIC(s) */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ memcpy(vnic->rss_table, reta_conf, reta_size);
+
+ bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ }
+ }
+ return 0;
+}
+
+static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_reta_entry64 *reta_conf,
+ uint16_t reta_size)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+
+ /* Retrieve from the default VNIC */
+ if (!vnic)
+ return -EINVAL;
+ if (!vnic->rss_table)
+ return -EINVAL;
+
+ if (reta_size != HW_HASH_INDEX_SIZE) {
+ RTE_LOG(ERR, PMD, "The configured hash table lookup size "
+ "(%d) must equal the size supported by the hardware "
+ "(%d)\n", reta_size, HW_HASH_INDEX_SIZE);
+ return -EINVAL;
+ }
+ /* EW - need to revisit here copying from u64 to u16 */
+ memcpy(reta_conf, vnic->rss_table, reta_size);
+
+ return 0;
+}
+
+static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_vnic_info *vnic;
+ uint16_t hash_type = 0;
+ int i;
+
+ /* If RSS enablement were different than dev_configure,
+ then return -EINVAL */
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG) {
+ if (!rss_conf->rss_hf)
+ return -EINVAL;
+ } else {
+ if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT)
+ return -EINVAL;
+ }
+ switch (rss_conf->rss_hf) {
+ case ETH_RSS_IPV4:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+ break;
+ case ETH_RSS_NONFRAG_IPV4_TCP:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+ break;
+ case ETH_RSS_IPV6:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ break;
+ case ETH_RSS_NONFRAG_IPV6_TCP:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+ break;
+ case ETH_RSS_IP:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ break;
+ case ETH_RSS_NONFRAG_IPV4_UDP:
+ case ETH_RSS_NONFRAG_IPV6_UDP:
+ case ETH_RSS_UDP:
+ break;
+ default:
+ hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+ break;
+ }
+ /* Update the RSS VNIC(s) */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ vnic->hash_type = hash_type;
+
+ /* Use the supplied key if the key length is
+ acceptable and the rss_key is not NULL */
+ if (rss_conf->rss_key &&
+ rss_conf->rss_key_len <= HW_HASH_KEY_SIZE)
+ memcpy(vnic->rss_hash_key, rss_conf->rss_key,
+ rss_conf->rss_key_len);
+
+ bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+ }
+ }
+ return 0;
+}
+
+static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_rss_conf *rss_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+ int len;
+
+ /* RSS configuration is the same for all VNICs */
+ if (vnic && vnic->rss_hash_key) {
+ if (rss_conf->rss_key) {
+ len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
+ rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
+ memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
+ }
+ switch (vnic->hash_type) {
+ case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4:
+ rss_conf->rss_hf = ETH_RSS_IPV4;
+ break;
+ case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4:
+ rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV4_TCP;
+ break;
+ case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6:
+ rss_conf->rss_hf = ETH_RSS_IPV6;
+ break;
+ case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6:
+ rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV6_TCP;
+ break;
+ case (HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6):
+ rss_conf->rss_hf = ETH_RSS_IP;
+ break;
+ default:
+ rss_conf->rss_hf = 0;
+ break;
+ }
+ } else {
+ rss_conf->rss_hf = 0;
+ }
+ return 0;
+}
+
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+ struct rte_eth_dev_info dev_info;
+ uint32_t max_dev_mtu;
+
+ bnxt_dev_info_get_op(eth_dev, &dev_info);
+ max_dev_mtu = dev_info.max_rx_pktlen -
+ ETHER_HDR_LEN - ETHER_CRC_LEN - VLAN_TAG_SIZE;
+
+ if (new_mtu < ETHER_MIN_MTU || new_mtu > max_dev_mtu) {
+ RTE_LOG(ERR, PMD, "MTU requested must be within (%d, %d)\n",
+ ETHER_MIN_MTU, max_dev_mtu);
+ return -EINVAL;
+ }
+ if (new_mtu > ETHER_MTU) {
+ eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+ eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+ new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE;
+ } else {
+ eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+ }
+ eth_dev->data->mtu = new_mtu;
+
+ /* TODO: If the device is active:
+ - Close NIC
+ - Free all ring/buffer resources as according to the new MTU
+ - Open NIC
+
+ Else
+
+ If the queues have already been setup:
+ - Re-allocate all ring/buffer resources as according to the new MTU
+ */
+ return 0;
+}
+
+static void bnxt_mac_addr_remove_op(struct rte_eth_dev *eth_dev,
+ uint32_t index)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ uint64_t pool_mask = eth_dev->data->mac_pool_sel[index];
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter, *temp_filter;
+ int i;
+
+ /* Loop through all VNICs from the specified filter flow pools to
+ remove the corresponding MAC addr filter */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ if (!(pool_mask & (1 << i)))
+ continue;
+
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+ if (filter->mac_index == index) {
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_filter(bp, filter);
+ filter->mac_index = INVALID_MAC_INDEX;
+ memset(&filter->l2_addr, 0,
+ ETHER_ADDR_LEN);
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+ }
+ filter = temp_filter;
+ }
+ }
+ }
+}
+
+static void bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
+ struct ether_addr *mac_addr,
+ uint32_t index, uint32_t pool)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_vnic_info *vnic = STAILQ_FIRST(&bp->ff_pool[pool]);
+ struct bnxt_filter_info *filter;
+
+ if (!vnic) {
+ RTE_LOG(ERR, PMD, "VNIC not found for pool %d!\n", pool);
+ return;
+ }
+ /* Attach requested MAC address to the new l2_filter */
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ if (filter->mac_index == index) {
+ RTE_LOG(ERR, PMD,
+ "MAC addr already existed for pool %d\n", pool);
+ return;
+ }
+ }
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
+ return;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+ filter->mac_index = index;
+ memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
+ bnxt_hwrm_set_filter(bp, vnic, filter);
+}
+
+static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
+{
+ struct bnxt_filter_info *filter, *temp_filter, *new_filter;
+ struct bnxt_vnic_info *vnic;
+ unsigned i;
+ int rc = 0;
+
+ /* Cycle through all VNICs */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ /* For each VNIC and each associated filter(s)
+ if VLAN exists && VLAN matches vlan_id
+ remove the MAC+VLAN filter
+ add a new MAC only filter
+ else
+ VLAN filter doesn't exist, just skip and continue
+ */
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+
+ if (filter->enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN &&
+ filter->l2_ovlan == vlan_id) {
+ /* Must delete the filter */
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_filter(bp, filter);
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+
+ /* Need to examine to see if the MAC
+ filter already existed or not before
+ allocating a new one */
+
+ new_filter = bnxt_alloc_filter(bp);
+ if (!new_filter) {
+ RTE_LOG(ERR, PMD,
+ "MAC/VLAN filter alloc failed\n");
+ rc = -ENOMEM;
+ goto exit;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter,
+ new_filter, next);
+ /* Inherit MAC from the previous
+ filter */
+ new_filter->mac_index =
+ filter->mac_index;
+ memcpy(new_filter->l2_addr,
+ filter->l2_addr, ETHER_ADDR_LEN);
+ /* MAC only filter */
+ rc = bnxt_hwrm_set_filter(bp, vnic,
+ new_filter);
+ if (rc)
+ goto exit;
+ }
+ filter = temp_filter;
+ }
+ }
+ }
+exit:
+ return rc;
+}
+
+static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
+{
+ struct bnxt_filter_info *filter, *temp_filter, *new_filter;
+ struct bnxt_vnic_info *vnic;
+ unsigned i;
+ int rc = 0;
+
+ /* Cycle through all VNICs */
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ /* For each VNIC and each associated filter(s)
+ if VLAN exists:
+ if VLAN matches vlan_id
+ VLAN filter already exists, just skip and continue
+ else
+ add a new MAC+VLAN filter
+ else
+ Remove the old MAC only filter
+ Add a new MAC+VLAN filter
+ */
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+
+ if (filter->enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN) {
+ if (filter->l2_ovlan == vlan_id)
+ goto cont;
+ } else {
+ /* Must delete the MAC filter */
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ bnxt_hwrm_clear_filter(bp, filter);
+ filter->l2_ovlan = 0;
+ STAILQ_INSERT_TAIL(
+ &bp->free_filter_list,
+ filter, next);
+ }
+ new_filter = bnxt_alloc_filter(bp);
+ if (!new_filter) {
+ RTE_LOG(ERR, PMD,
+ "MAC/VLAN filter alloc failed\n");
+ rc = -ENOMEM;
+ goto exit;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, new_filter,
+ next);
+ /* Inherit MAC from the previous filter */
+ new_filter->mac_index = filter->mac_index;
+ memcpy(new_filter->l2_addr, filter->l2_addr,
+ ETHER_ADDR_LEN);
+ /* MAC + VLAN ID filter */
+ new_filter->l2_ovlan = vlan_id;
+ new_filter->l2_ovlan_mask = 0xF000;
+ new_filter->enables |=
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
+ rc = bnxt_hwrm_set_filter(bp, vnic, new_filter);
+ if (rc)
+ goto exit;
+cont:
+ filter = temp_filter;
+ }
+ }
+ }
+exit:
+ return rc;
+}
+
+static int bnxt_vlan_filter_set_op(struct rte_eth_dev *eth_dev,
+ uint16_t vlan_id, int on)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ /* These operations apply to ALL existing MAC/VLAN filters */
+ if (on)
+ return bnxt_add_vlan_filter(bp, vlan_id);
+ else
+ return bnxt_del_vlan_filter(bp, vlan_id);
+}
+
+static void bnxt_vlan_strip_queue_set_op(struct rte_eth_dev *eth_dev,
+ uint16_t rx_queue_id, int on)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_rx_queue *rxq = eth_dev->data->rx_queues[rx_queue_id];
+ struct bnxt_vnic_info *vnic;
+ int rc = 0;
+
+ /* VLAN strip at the VNIC level is supported */
+ if (!rxq) {
+ RTE_LOG(ERR, PMD, "Rx queue with id %d not defined!",
+ rx_queue_id);
+ return;
+ }
+ if (rxq->vnic) {
+ RTE_LOG(ERR, PMD, "Rx queue with id %d does not have a VNIC!",
+ rx_queue_id);
+ return;
+ }
+ vnic = rxq->vnic;
+ if ((on && vnic->vlan_strip) ||
+ (!on && vnic->vlan_strip)) {
+ RTE_LOG(INFO, PMD,
+ "Rx queue with id %d already has VLAN strip set to %d",
+ rx_queue_id, on);
+ goto done;
+ }
+ vnic->vlan_strip = on ? true : false;
+ rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "HWRM vnic cfg failure rc: %x\n", rc);
+ return;
+ }
+
+ /* TODO: If there are other rx queues that belong to the same VNIC,
+ we have the following options:
+
+ 1. Accept the change and silently force the same VLAN strip
+ setting to all associated rx queues [current implementation]
+ 2. Migrate any rx queues that are hanging on the same VNIC to
+ a new VNIC
+ 3. Reject the request if there are other rx queues using the
+ same VNIC
+ */
+done:
+ RTE_LOG(ERR, PMD, "Rx queue with id %d has VLAN strip set to %d!",
+ rx_queue_id, on);
+}
+
+static int bnxt_flow_ctrl_get_op(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf __rte_unused)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+ struct rte_eth_link link_info;
+ int rc;
+
+ rc = bnxt_get_hwrm_link_config(bp, &link_info);
+ if (rc)
+ return rc;
+
+ memset(fc_conf, 0, sizeof(*fc_conf));
+ fc_conf->high_water = 0;
+ fc_conf->low_water = 0;
+ fc_conf->pause_time = 0;
+ fc_conf->send_xon = 0;
+ fc_conf->mac_ctrl_frame_fwd = 0;
+ if (bp->link_info.auto_pause)
+ fc_conf->autoneg = 1;
+ switch (bp->link_info.pause) {
+ case 0:
+ fc_conf->mode = RTE_FC_NONE;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX:
+ fc_conf->mode = RTE_FC_TX_PAUSE;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:
+ fc_conf->mode = RTE_FC_RX_PAUSE;
+ break;
+ case (HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX |
+ HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX):
+ fc_conf->mode = RTE_FC_FULL;
+ break;
+ }
+ return 0;
+}
+
+static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
+ struct rte_eth_fc_conf *fc_conf)
+{
+ struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+ switch (fc_conf->mode) {
+ case RTE_FC_NONE:
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause = 0;
+ break;
+ case RTE_FC_RX_PAUSE:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
+ }
+ break;
+ case RTE_FC_TX_PAUSE:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;
+ }
+ break;
+ case RTE_FC_FULL:
+ if (fc_conf->autoneg) {
+ bp->link_info.auto_pause =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;
+ bp->link_info.force_pause = 0;
+ } else {
+ bp->link_info.auto_pause = 0;
+ bp->link_info.force_pause =
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX |
+ HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;
+ }
+ break;
+ }
+ return bnxt_set_hwrm_link_config(bp, true);
+}
+
+/*
+ * Initialization
+ */
+
+static struct eth_dev_ops bnxt_dev_ops = {
+ .dev_infos_get = bnxt_dev_info_get_op,
+ .dev_configure = bnxt_dev_configure_op,
+ .dev_start = bnxt_dev_start_op,
+ .dev_stop = bnxt_dev_stop_op,
+ .dev_set_link_up = bnxt_dev_set_link_up_op,
+ .dev_set_link_down = bnxt_dev_set_link_down_op,
+ .dev_close = bnxt_dev_close_op,
+ .stats_get = bnxt_stats_get_op,
+ .stats_reset = bnxt_stats_reset_op,
+ .rx_queue_setup = bnxt_rx_queue_setup_op,
+ .rx_queue_release = bnxt_rx_queue_release_op,
+ .tx_queue_setup = bnxt_tx_queue_setup_op,
+ .tx_queue_release = bnxt_tx_queue_release_op,
+ .reta_update = bnxt_reta_update_op,
+ .reta_query = bnxt_reta_query_op,
+ .rss_hash_update = bnxt_rss_hash_update_op,
+ .rss_hash_conf_get = bnxt_rss_hash_conf_get_op,
+ .link_update = bnxt_link_update_op,
+ .promiscuous_enable = bnxt_promiscuous_enable_op,
+ .promiscuous_disable = bnxt_promiscuous_disable_op,
+ .allmulticast_enable = bnxt_allmulticast_enable_op,
+ .allmulticast_disable = bnxt_allmulticast_disable_op,
+ .mtu_set = bnxt_mtu_set_op,
+ .mac_addr_add = bnxt_mac_addr_add_op,
+ .mac_addr_remove = bnxt_mac_addr_remove_op,
+ .vlan_filter_set = bnxt_vlan_filter_set_op,
+ .vlan_strip_queue_set = bnxt_vlan_strip_queue_set_op,
+ .flow_ctrl_get = bnxt_flow_ctrl_get_op,
+ .flow_ctrl_set = bnxt_flow_ctrl_set_op,
+};
+
+static bool bnxt_vf_pciid(uint16_t id)
+{
+ if (id == BROADCOM_DEV_ID_57304_VF ||
+ id == BROADCOM_DEV_ID_57406_VF)
+ return true;
+ return false;
+}
+
+static int bnxt_init_board(struct rte_eth_dev *eth_dev)
+{
+ int rc;
+ struct bnxt *bp = eth_dev->data->dev_private;
+
+ /* enable device (incl. PCI PM wakeup), and bus-mastering */
+ if (!eth_dev->pci_dev->mem_resource[0].addr) {
+ RTE_LOG(ERR, PMD,
+ "Cannot find PCI device base address, aborting\n");
+ rc = -ENODEV;
+ goto init_err_disable;
+ }
+
+ bp->eth_dev = eth_dev;
+ bp->pdev = eth_dev->pci_dev;
+
+ bp->bar0 = (void *)eth_dev->pci_dev->mem_resource[0].addr;
+ if (!bp->bar0) {
+ RTE_LOG(ERR, PMD, "Cannot map device registers, aborting\n");
+ rc = -ENOMEM;
+ goto init_err_release;
+ }
+ return 0;
+
+init_err_release:
+ if (bp->bar0)
+ bp->bar0 = NULL;
+
+init_err_disable:
+
+ return rc;
+}
+
+static int
+bnxt_dev_init(struct rte_eth_dev *eth_dev)
+{
+ static int version_printed;
+ struct bnxt *bp;
+ int rc;
+
+ if (version_printed++ == 0)
+ RTE_LOG(INFO, PMD, "%s", bnxt_version);
+
+ if (eth_dev->pci_dev->addr.function >= 2 &&
+ eth_dev->pci_dev->addr.function < 4) {
+ RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
+ eth_dev->pci_dev->addr.function);
+ return -ENOMEM;
+ }
+
+ rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
+ bp = eth_dev->data->dev_private;
+
+ if (bnxt_vf_pciid(eth_dev->pci_dev->id.device_id))
+ bp->flags |= BNXT_FLAG_VF;
+
+ rc = bnxt_init_board(eth_dev);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Board initialization failed rc: %x\n", rc);
+ goto error;
+ }
+ eth_dev->dev_ops = &bnxt_dev_ops;
+ eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
+ eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
+
+ rc = bnxt_alloc_hwrm_resources(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "hwrm resource allocation failure rc: %x\n", rc);
+ goto error;
+ }
+ rc = bnxt_hwrm_ver_get(bp);
+ if (rc)
+ goto error;
+ bnxt_hwrm_queue_qportcfg(bp);
+
+ /* Get the MAX capabilities for this function */
+ rc = bnxt_hwrm_func_qcaps(bp);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
+ goto error_free;
+ }
+ eth_dev->data->mac_addrs = rte_zmalloc("bnxt_mac_addr_tbl",
+ ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR, 0);
+ if (eth_dev->data->mac_addrs == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc %u bytes needed to store MAC addr tbl",
+ ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR);
+ rc = -ENOMEM;
+ goto error_free;
+ }
+ /* Copy the permanent MAC from the qcap response address now. */
+ if (BNXT_PF(bp))
+ memcpy(bp->mac_addr, bp->pf.mac_addr, sizeof(bp->mac_addr));
+ else
+ memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
+ memcpy(ð_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+ bp->def_cp_ring.cp_ring_struct.ring_size =
+ rte_align32pow2(MAX_CP_DESC_CNT);
+
+ /* SR-IOV specifics */
+ if (eth_dev->pci_dev->max_vfs) {
+ if (BNXT_PF(bp)) {
+ uint16_t buf_size = bp->pf.max_vfs * 128;
+
+ if (eth_dev->pci_dev->max_vfs > bp->pf.max_vfs) {
+ RTE_LOG(ERR, PMD,
+ "Max VF request (%d) exceeded support (%d)",
+ eth_dev->pci_dev->max_vfs, bp->pf.max_vfs);
+ rc = -EINVAL;
+ bp->pf.active_vfs = 0;
+ goto error_free;
+ }
+ /* Allocate VFs */
+ bp->pf.active_vfs = eth_dev->pci_dev->max_vfs;
+ rc = bnxt_hwrm_func_vf_alloc(bp, bp->pf.active_vfs);
+ if (rc) {
+ RTE_LOG(ERR, PMD, "Failed to alloc VFs");
+ rc = -ENOMEM;
+ bp->pf.active_vfs = 0;
+ goto error_free;
+ }
+
+ /* Register VF forwarding command buffer */
+ bp->pf.vf_req_buf = rte_zmalloc("bnxt_vf_req_buf",
+ buf_size, 0);
+ if (bp->pf.vf_req_buf == NULL) {
+ RTE_LOG(ERR, PMD,
+ "Failed to alloc %u bytes needed for VF req buf",
+ buf_size);
+ rc = -ENOMEM;
+ goto error_free;
+ }
+ bp->pf.vf_req_buf_dma_addr =
+ rte_malloc_virt2phy(bp->pf.vf_req_buf);
+
+ rc = bnxt_hwrm_func_pfvfbufs_register(bp,
+ bp->pf.vf_req_buf_dma_addr,
+ buf_size);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Failed to register VF req buf");
+ rc = -EBUSY;
+ goto error_free;
+ }
+
+ SET_BIT_IN_ARRAY(bp->pf.vf_req_fwd,
+ HWRM_CFA_L2_FILTER_ALLOC);
+ SET_BIT_IN_ARRAY(bp->pf.vf_req_fwd,
+ HWRM_CFA_L2_FILTER_FREE);
+ SET_BIT_IN_ARRAY(bp->pf.vf_req_fwd,
+ HWRM_CFA_L2_FILTER_CFG);
+ SET_BIT_IN_ARRAY(bp->pf.vf_req_fwd,
+ HWRM_CFA_L2_SET_RX_MASK);
+ }
+ }
+ rc = bnxt_hwrm_func_driver_register(bp, 0,
+ bp->pf.vf_req_fwd);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Failed to register driver");
+ rc = -EBUSY;
+ goto error_free;
+ }
+
+ RTE_LOG(INFO, PMD, DRV_MODULE_NAME " found at mem %" PRIx64 ", node addr %pM\n",
+ eth_dev->pci_dev->mem_resource[0].phys_addr,
+ eth_dev->pci_dev->mem_resource[0].addr);
+
+ return 0;
+
+error_free:
+ bnxt_dev_close_op(eth_dev);
+error:
+ return rc;
+}
+
+static int
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
+ struct bnxt *bp;
+
+ bp = eth_dev->data->dev_private;
+ return bnxt_hwrm_func_driver_unregister(bp, 0);
+}
+
+static struct eth_driver bnxt_rte_pmd = {
+ .pci_drv = {
+ .name = "rte_" DRV_MODULE_NAME "_pmd",
+ .id_table = bnxt_pci_id_map,
+ .drv_flags = RTE_PCI_DRV_NEED_MAPPING,
+ },
+ .eth_dev_init = bnxt_dev_init,
+ .eth_dev_uninit = bnxt_dev_uninit,
+ .dev_private_size = sizeof(struct bnxt),
+};
+
+static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused)
+{
+ RTE_LOG(INFO, PMD, "bnxt_rte_pmd_init() called for %s\n", name);
+ rte_eth_driver_register(&bnxt_rte_pmd);
+ return 0;
+}
+
+static struct rte_driver bnxt_pmd_drv = {
+ .name = "eth_bnxt",
+ .type = PMD_PDEV,
+ .init = bnxt_rte_pmd_init,
+};
+
+PMD_REGISTER_DRIVER(bnxt_pmd_drv);
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
new file mode 100644
index 0000000..430b70d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -0,0 +1,175 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <sys/queue.h>
+
+#include <rte_log.h>
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Filter Functions
+ */
+
+struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+
+ /* Find the 1st unused filter from the free_filter_list pool*/
+ filter = STAILQ_FIRST(&bp->free_filter_list);
+ if (!filter) {
+ RTE_LOG(ERR, PMD, "No more free filter resources\n");
+ return NULL;
+ }
+ STAILQ_REMOVE_HEAD(&bp->free_filter_list, next);
+
+ /* Default to L2 MAC Addr filter */
+ filter->flags = HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX;
+ filter->enables = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;
+ memcpy(filter->l2_addr, bp->eth_dev->data->mac_addrs->addr_bytes,
+ ETHER_ADDR_LEN);
+ memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+ return filter;
+}
+
+void bnxt_init_filters(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+ int i, max_filters;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_filters = pf->max_l2_ctx;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_filters = vf->max_l2_ctx;
+ }
+ STAILQ_INIT(&bp->free_filter_list);
+ for (i = 0; i < max_filters; i++) {
+ filter = &bp->filter_info[i];
+ filter->fw_l2_filter_id = -1;
+ STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
+ }
+}
+
+void bnxt_free_all_filters(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter, *temp_filter;
+ int i;
+
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ STAILQ_FOREACH(vnic, &bp->ff_pool[i], next) {
+ filter = STAILQ_FIRST(&vnic->filter);
+ while (filter) {
+ temp_filter = STAILQ_NEXT(filter, next);
+ STAILQ_REMOVE(&vnic->filter, filter,
+ bnxt_filter_info, next);
+ STAILQ_INSERT_TAIL(&bp->free_filter_list,
+ filter, next);
+ filter = temp_filter;
+ }
+ STAILQ_INIT(&vnic->filter);
+ }
+ }
+}
+
+void bnxt_free_filter_mem(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter;
+ uint16_t max_filters, i;
+ int rc = 0;
+
+ /* Ensure that all filters are freed */
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_filters = pf->max_l2_ctx;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_filters = vf->max_l2_ctx;
+ }
+ for (i = 0; i < max_filters; i++) {
+ filter = &bp->filter_info[i];
+ if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
+ RTE_LOG(ERR, PMD, "HWRM filter is not freed??\n");
+ /* Call HWRM to try to free filter again */
+ rc = bnxt_hwrm_clear_filter(bp, filter);
+ if (rc)
+ RTE_LOG(ERR, PMD,
+ "HWRM filter cannot be freed rc = %d\n",
+ rc);
+ }
+ filter->fw_l2_filter_id = -1;
+ }
+ STAILQ_INIT(&bp->free_filter_list);
+
+ rte_free(bp->filter_info);
+ bp->filter_info = NULL;
+}
+
+int bnxt_alloc_filter_mem(struct bnxt *bp)
+{
+ struct bnxt_filter_info *filter_mem;
+ uint16_t max_filters;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_filters = pf->max_l2_ctx;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_filters = vf->max_l2_ctx;
+ }
+ /* Allocate memory for VNIC pool and filter pool */
+ filter_mem = rte_zmalloc("bnxt_filter_info",
+ max_filters * sizeof(struct bnxt_filter_info),
+ 0);
+ if (filter_mem == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for %d filters",
+ max_filters);
+ return -ENOMEM;
+ }
+ bp->filter_info = filter_mem;
+ return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
new file mode 100644
index 0000000..0da504a
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -0,0 +1,74 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_FILTER_H_
+#define _BNXT_FILTER_H_
+
+#include <rte_ether.h>
+
+struct bnxt;
+struct bnxt_filter_info {
+ STAILQ_ENTRY(bnxt_filter_info) next;
+ uint64_t fw_l2_filter_id;
+#define INVALID_MAC_INDEX ((uint16_t)-1)
+ uint16_t mac_index;
+
+ /* Filter Characteristics */
+ uint32_t flags;
+ uint32_t enables;
+ uint8_t l2_addr[ETHER_ADDR_LEN];
+ uint8_t l2_addr_mask[ETHER_ADDR_LEN];
+ uint16_t l2_ovlan;
+ uint16_t l2_ovlan_mask;
+ uint16_t l2_ivlan;
+ uint16_t l2_ivlan_mask;
+ uint8_t t_l2_addr[ETHER_ADDR_LEN];
+ uint8_t t_l2_addr_mask[ETHER_ADDR_LEN];
+ uint16_t t_l2_ovlan;
+ uint16_t t_l2_ovlan_mask;
+ uint16_t t_l2_ivlan;
+ uint16_t t_l2_ivlan_mask;
+ uint8_t tunnel_type;
+ uint16_t mirror_vnic_id;
+ uint32_t vni;
+ uint8_t pri_hint;
+ uint64_t l2_filter_id_hint;
+};
+
+struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+void bnxt_init_filters(struct bnxt *bp);
+void bnxt_free_all_filters(struct bnxt *bp);
+void bnxt_free_filter_mem(struct bnxt *bp);
+int bnxt_alloc_filter_mem(struct bnxt *bp);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
new file mode 100644
index 0000000..68ce671
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -0,0 +1,1554 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <rte_byteorder.h>
+#include <rte_common.h>
+#include <rte_cycles.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_txq.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+#define HWRM_RING_ALLOC_TX 0x1
+#define HWRM_RING_ALLOC_RX 0x2
+#define HWRM_RING_ALLOC_AGG 0x4
+#define HWRM_RING_ALLOC_CMPL 0x8
+
+#define HWRM_RESP_LENGTH 4096
+
+#ifdef FPGA
+#define HWRM_CMD_TIMEOUT 200000
+#else
+#define HWRM_CMD_TIMEOUT 2000
+#endif
+#define HWRM_RESP_ERR_CODE_MASK 0xffff
+
+/*
+ * HWRM Functions (sent to HWRM)
+ * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message()
+ * fails (ie: a timeout), and a positive non-zero HWRM error code if the HWRM
+ * command was failed by the ChiMP.
+ */
+
+static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
+{
+ unsigned i;
+ int intr_process;
+ struct input *req = msg;
+ struct output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t *data = msg;
+ uint8_t *bar;
+ uint8_t *valid;
+
+ rte_spinlock_lock(&bp->hwrm_lock);
+ intr_process = (req->cmpl_ring == INVALID_HW_RING_ID) ? 0 : 1;
+
+ /* Write request msg to hwrm channel */
+ for (i = 0; i < msg_len; i += 4) {
+ bar = (uint8_t *)bp->bar0 + i;
+ *(volatile uint32_t *)bar = *data;
+ data++;
+ }
+
+ for (; i < bp->max_req_len; i += 4) {
+ bar = (uint8_t *)bp->bar0 + i;
+ *(volatile uint32_t *)bar = 0;
+ }
+
+ /* currently supports only one outstanding message */
+ if (intr_process)
+ bp->hwrm_intr_seq_id = req->seq_id;
+
+ /* Ring channel doorbell */
+ bar = (uint8_t *)bp->bar0 + 0x100;
+ *(volatile uint32_t *)bar = 1;
+
+ rte_rmb();
+
+ if (intr_process) {
+ i = 0;
+ /* Wait until hwrm response cmpl interrupt is processed */
+ while (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID &&
+ i++ < HWRM_CMD_TIMEOUT) {
+ rte_delay_us(600);
+ }
+
+ if (bp->hwrm_intr_seq_id != HWRM_SEQ_ID_INVALID) {
+ RTE_LOG(ERR, PMD, "Resp cmpl intr err msg:%x\n",
+ req->req_type);
+ goto err_ret;
+ }
+ } else {
+ /* Poll for the valid bit */
+ for (i = 0; i < HWRM_CMD_TIMEOUT; i++) {
+ /* Sanity check on the resp->resp_len */
+ if (resp->resp_len && resp->resp_len <=
+ HWRM_RESP_LENGTH) {
+ /* Last byte of resp contains the valid key */
+ valid = (uint8_t *)resp + resp->resp_len - 1;
+ if (*valid == HWRM_RESP_VALID_KEY)
+ break;
+ }
+ rte_delay_us(600);
+ }
+
+ if (i >= HWRM_CMD_TIMEOUT) {
+ RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+ req->req_type);
+ goto err_ret;
+ }
+ }
+ rte_spinlock_unlock(&bp->hwrm_lock);
+ return 0;
+
+err_ret:
+ rte_spinlock_unlock(&bp->hwrm_lock);
+ return -1;
+}
+
+#define HWRM_PREP(req, type, cr, resp) \
+ memset(bp->hwrm_cmd_resp_addr, 0, HWRM_RESP_LENGTH); \
+ req.req_type = rte_cpu_to_le_16(HWRM_##type); \
+ req.cmpl_ring = rte_cpu_to_le_16(cr); \
+ req.seq_id = rte_cpu_to_le_16(bp->hwrm_cmd_seq++); \
+ req.target_id = rte_cpu_to_le_16(0xffff); \
+ req.resp_addr = rte_cpu_to_le_64(bp->hwrm_cmd_resp_dma_addr)
+
+#define HWRM_CHECK_RESULT \
+ { \
+ if (rc) { \
+ RTE_LOG(ERR, PMD, "%s failed rc:%d\n", \
+ __func__, rc); \
+ return rc; \
+ } \
+ if (resp->error_code) { \
+ rc = rte_le_to_cpu_16(resp->error_code); \
+ RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \
+ return rc; \
+ } \
+ }
+
+int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_set_rx_mask_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, CFA_L2_SET_RX_MASK, -1, resp);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.mask = 0;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_set_rx_mask_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t mask = 0;
+
+ HWRM_PREP(req, CFA_L2_SET_RX_MASK, -1, resp);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ /* FIXME add multicast flag, when multicast adding options is supported
+ * by ethtool.
+ */
+ if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
+ mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+ if (vnic->flags & BNXT_VNIC_INFO_ALLMULTI)
+ mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+ req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST |
+ HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
+ mask);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_set_filter(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_filter_alloc_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_filter_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t enables = 0;
+
+ HWRM_PREP(req, CFA_L2_FILTER_ALLOC, -1, resp);
+
+ req.flags = rte_cpu_to_le_32(filter->flags);
+
+ enables = filter->enables |
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
+ req.dst_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
+ memcpy(req.l2_addr, filter->l2_addr,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK)
+ memcpy(req.l2_addr_mask, filter->l2_addr_mask,
+ ETHER_ADDR_LEN);
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN)
+ req.l2_ovlan = filter->l2_ovlan;
+ if (enables &
+ HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
+ req.l2_ovlan_mask = filter->l2_ovlan_mask;
+
+ req.enables = rte_cpu_to_le_32(enables);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ filter->fw_l2_filter_id = rte_le_to_cpu_64(resp->l2_filter_id);
+
+ return rc;
+}
+
+int bnxt_hwrm_clear_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter)
+{
+ int rc = 0;
+ struct hwrm_cfa_l2_filter_free_input req = {.req_type = 0 };
+ struct hwrm_cfa_l2_filter_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, CFA_L2_FILTER_FREE, -1, resp);
+
+ req.l2_filter_id = rte_cpu_to_le_64(filter->fw_l2_filter_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ filter->fw_l2_filter_id = -1;
+
+ return 0;
+}
+
+int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_RSS_CFG, -1, resp);
+
+ req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
+
+ req.ring_grp_tbl_addr =
+ rte_cpu_to_le_64(vnic->rss_table_dma_addr);
+ req.hash_key_tbl_addr =
+ rte_cpu_to_le_64(vnic->rss_hash_key_dma_addr);
+ req.rss_ctx_idx = rte_cpu_to_le_16(vnic->fw_rss_cos_lb_ctx);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_set_dcb(struct bnxt *bp __rte_unused,
+ struct bnxt_vnic_info *vnic __rte_unused)
+{
+ return 0;
+}
+
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cos_lb_ctx_free_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_FREE, -1, resp);
+
+ req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->fw_rss_cos_lb_ctx);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {.req_type = 0 };
+ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp =
+ bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_ALLOC, -1, resp);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_cfg_input req = {.req_type = 0 };
+ struct hwrm_vnic_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, VNIC_CFG, -1, resp);
+
+ /* Only RSS support for now TBD: COS & LB */
+ req.enables =
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP |
+ HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE |
+ HWRM_VNIC_CFG_INPUT_ENABLES_MRU);
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+ req.dflt_ring_grp =
+ rte_cpu_to_le_16(bp->grp_info[vnic->start_grp_id].fw_grp_id);
+ req.rss_rule = rte_cpu_to_le_16(vnic->fw_rss_cos_lb_ctx);
+ req.cos_rule = rte_cpu_to_le_16(0xffff);
+ req.lb_rule = rte_cpu_to_le_16(0xffff);
+ req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+ ETHER_CRC_LEN + VLAN_TAG_SIZE);
+ if (vnic->func_default)
+ req.flags = 1;
+ if (vnic->vlan_strip)
+ req.flags |=
+ rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0;
+ struct hwrm_vnic_free_input req = {.req_type = 0 };
+ struct hwrm_vnic_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
+ return rc;
+
+ HWRM_PREP(req, VNIC_FREE, -1, resp);
+
+ req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ vnic->fw_vnic_id = INVALID_HW_RING_ID;
+ return rc;
+}
+
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ int rc = 0, i, j;
+ struct hwrm_vnic_alloc_input req = {.req_type = 0 };
+ struct hwrm_vnic_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ /* map ring groups to this vnic */
+ for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++) {
+ if (bp->grp_info[i].fw_grp_id == INVALID_HW_RING_ID) {
+ RTE_LOG(ERR, PMD,
+ "Not enough ring groups avail:%x req:%x\n", j,
+ (vnic->end_grp_id - vnic->start_grp_id) + 1);
+ break;
+ }
+ vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
+ }
+
+ vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+ vnic->ctx_is_rss_cos_lb = HW_CONTEXT_NONE;
+
+ HWRM_PREP(req, VNIC_ALLOC, -1, resp);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ vnic->fw_vnic_id = rte_le_to_cpu_16(resp->vnic_id);
+ return rc;
+}
+
+int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned idx)
+{
+ int rc = 0;
+ struct hwrm_ring_grp_alloc_input req = {.req_type = 0 };
+ struct hwrm_ring_grp_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_GRP_ALLOC, -1, resp);
+
+ req.cr = rte_cpu_to_le_16(bp->grp_info[idx].cp_fw_ring_id);
+ req.rr = rte_cpu_to_le_16(bp->grp_info[idx].rx_fw_ring_id);
+ req.ar = rte_cpu_to_le_16(bp->grp_info[idx].ag_fw_ring_id);
+ req.sc = rte_cpu_to_le_16(bp->grp_info[idx].fw_stats_ctx);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ bp->grp_info[idx].fw_grp_id =
+ rte_le_to_cpu_16(resp->ring_group_id);
+
+ return rc;
+}
+
+int bnxt_hwrm_ring_alloc(struct bnxt *bp,
+ struct bnxt_ring_struct *ring,
+ uint32_t ring_type, uint32_t map_index,
+ uint32_t stats_ctx_id)
+{
+ int rc = 0;
+ struct hwrm_ring_alloc_input req = {.req_type = 0 };
+ struct hwrm_ring_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_ALLOC, -1, resp);
+
+ req.enables = rte_cpu_to_le_32(0);
+
+ req.page_tbl_addr = rte_cpu_to_le_64(ring->bd_dma);
+ req.fbo = rte_cpu_to_le_32(0);
+ /* Association of ring index with doorbell index */
+ req.logical_id = rte_cpu_to_le_16(map_index);
+
+ switch (ring_type) {
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
+ req.queue_id = bp->cos_queue[0].id;
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_RX:
+ req.ring_type = ring_type;
+ req.cmpl_ring_id =
+ rte_cpu_to_le_16(bp->grp_info[map_index].cp_fw_ring_id);
+ req.length = rte_cpu_to_le_32(ring->ring_size);
+ req.stat_ctx_id = rte_cpu_to_le_16(stats_ctx_id);
+ req.enables = rte_cpu_to_le_32(rte_le_to_cpu_32(req.enables) |
+ HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);
+ break;
+ case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
+ req.ring_type = ring_type;
+ req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
+ req.length = rte_cpu_to_le_32(ring->ring_size);
+ break;
+ default:
+ RTE_LOG(ERR, PMD, "hwrm alloc invalid ring type %d\n",
+ ring_type);
+ return -1;
+ }
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc || resp->error_code) {
+ if (rc == 0 && resp->error_code)
+ rc = rte_le_to_cpu_16(resp->error_code);
+ switch (ring_type) {
+ case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+ RTE_LOG(ERR, PMD,
+ "hwrm_ring_alloc cp failed. rc:%d\n", rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_RX:
+ RTE_LOG(ERR, PMD,
+ "hwrm_ring_alloc rx failed. rc:%d\n", rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_TX:
+ RTE_LOG(ERR, PMD,
+ "hwrm_ring_alloc tx failed. rc:%d\n", rc);
+ return rc;
+ default:
+ RTE_LOG(ERR, PMD, "Invalid ring. rc:%d\n", rc);
+ return rc;
+ }
+ }
+
+ ring->fw_ring_id = rte_le_to_cpu_16(resp->ring_id);
+ return rc;
+}
+
+int bnxt_hwrm_ring_free(struct bnxt *bp,
+ struct bnxt_ring_struct *ring, uint32_t ring_type)
+{
+ int rc;
+ struct hwrm_ring_free_input req = {.req_type = 0 };
+ struct hwrm_ring_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_FREE, -1, resp);
+
+ req.ring_type = ring_type;
+ req.ring_id = rte_cpu_to_le_16(ring->fw_ring_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ if (rc || resp->error_code) {
+ if (rc == 0 && resp->error_code)
+ rc = rte_le_to_cpu_16(resp->error_code);
+
+ switch (ring_type) {
+ case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+ RTE_LOG(ERR, PMD, "hwrm_ring_free cp failed. rc:%d\n",
+ rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_RX:
+ RTE_LOG(ERR, PMD, "hwrm_ring_free rx failed. rc:%d\n",
+ rc);
+ return rc;
+ case HWRM_RING_FREE_INPUT_RING_TYPE_TX:
+ RTE_LOG(ERR, PMD, "hwrm_ring_free tx failed. rc:%d\n",
+ rc);
+ return rc;
+ default:
+ RTE_LOG(ERR, PMD, "Invalid ring, rc:%d\n", rc);
+ return rc;
+ }
+ }
+ return 0;
+}
+
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned idx)
+{
+ int rc;
+ struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_ALLOC, -1, resp);
+
+ req.update_period_ms = rte_cpu_to_le_32(1000);
+
+ req.seq_id = rte_cpu_to_le_16(bp->hwrm_cmd_seq++);
+ req.stats_dma_addr =
+ rte_cpu_to_le_64(cpr->hw_stats_map);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ cpr->hw_stats_ctx_id = rte_le_to_cpu_16(resp->stat_ctx_id);
+ bp->grp_info[idx].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+ return rc;
+}
+
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
+{
+ int rc = 0;
+ struct hwrm_stat_ctx_clr_stats_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_CLR_STATS, -1, resp);
+
+ if (cpr->hw_stats_ctx_id == (uint32_t)INVALID_STATS_CTX_ID)
+ return rc;
+
+ req.stat_ctx_id = rte_cpu_to_le_16(cpr->hw_stats_ctx_id);
+ req.seq_id = rte_cpu_to_le_16(bp->hwrm_cmd_seq++);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qcaps(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_qcaps_input req = {.req_type = 0 };
+ struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_QCAPS, -1, resp);
+
+ req.fid = rte_cpu_to_le_16(0xffff);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ pf->fw_fid = rte_le_to_cpu_32(resp->fid);
+ pf->port_id = resp->port_id;
+ memcpy(pf->mac_addr, resp->perm_mac_address, ETHER_ADDR_LEN);
+ pf->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+ pf->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+ pf->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+ pf->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+ pf->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+ pf->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
+ pf->first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+ pf->max_vfs = rte_le_to_cpu_16(resp->max_vfs);
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ vf->fw_fid = rte_le_to_cpu_32(resp->fid);
+ memcpy(vf->mac_addr, &resp->perm_mac_address, ETHER_ADDR_LEN);
+ vf->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+ vf->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+ vf->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+ vf->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+ vf->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+ vf->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
+ }
+
+ return rc;
+}
+
+int bnxt_hwrm_func_reset(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_reset_input req = {.req_type = 0 };
+ struct hwrm_func_reset_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_RESET, -1, resp);
+
+ req.enables = rte_cpu_to_le_32(0);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_qstats(struct bnxt *bp,
+ struct hwrm_func_qstats_output *stats)
+{
+ int rc = 0;
+ struct hwrm_func_qstats_input req = {.req_type = 0 };
+ struct hwrm_func_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_QSTATS, -1, resp);
+
+ req.fid = -1;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ if (stats)
+ memcpy(stats, resp, sizeof(*stats));
+
+ return rc;
+}
+
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_func_clr_stats_input req = {.req_type = 0 };
+ struct hwrm_func_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_CLR_STATS, -1, resp);
+
+ req.fid = -1;
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_ver_get(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_ver_get_input req = {.req_type = 0 };
+ struct hwrm_ver_get_output *resp = bp->hwrm_cmd_resp_addr;
+ uint32_t my_version;
+ uint32_t fw_version;
+
+ HWRM_PREP(req, VER_GET, -1, resp);
+
+ req.hwrm_intf_maj = HWRM_VERSION_MAJOR;
+ req.hwrm_intf_min = HWRM_VERSION_MINOR;
+ req.hwrm_intf_upd = HWRM_VERSION_UPDATE;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ RTE_LOG(INFO, PMD, "%d.%d.%d:%d.%d.%d\n",
+ resp->hwrm_intf_maj, resp->hwrm_intf_min,
+ resp->hwrm_intf_upd,
+ resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
+
+ my_version = HWRM_VERSION_MAJOR << 16;
+ my_version |= HWRM_VERSION_MINOR << 8;
+ my_version |= HWRM_VERSION_UPDATE;
+
+ fw_version = resp->hwrm_intf_maj << 16;
+ fw_version |= resp->hwrm_intf_min << 8;
+ fw_version |= resp->hwrm_intf_upd;
+
+#if HWRM_VERSION_MAJOR == 0
+ if (my_version != fw_version) {
+ RTE_LOG(ERR, PMD, "Unsupported firmware API version\n");
+ RTE_LOG(ERR, PMD, "This driver requires %u.%u.%u\n",
+ HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR,
+ HWRM_VERSION_UPDATE);
+ return -1;
+ }
+#else
+ if (resp->hwrm_intf_maj != HWRM_VERSION_MAJOR) {
+ RTE_LOG(ERR, PMD, "Unsupported firmware API version\n");
+ return -1;
+ }
+#endif
+
+ if (my_version != fw_version) {
+ RTE_LOG(INFO, PMD, "BNXT Driver/HWRM API mismatch.\n");
+ if (my_version < fw_version) {
+ RTE_LOG(INFO, PMD,
+ "Firmware API version is newer than driver.\n");
+ RTE_LOG(INFO, PMD,
+ "The driver may be missing features.\n");
+ } else {
+ RTE_LOG(INFO, PMD,
+ "Firmware API version is older than driver.\n");
+ RTE_LOG(INFO, PMD,
+ "Not all driver features may be functional.\n");
+ }
+ }
+
+ return rc;
+}
+
+int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_queue_qportcfg_input req = {.req_type = 0 };
+ struct hwrm_queue_qportcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, QUEUE_QPORTCFG, -1, resp);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+#define GET_QUEUE_INFO(x) \
+ bp->cos_queue[x].id = resp->queue_id##x; \
+ bp->cos_queue[x].profile = resp->queue_id##x##_service_profile
+
+ GET_QUEUE_INFO(0);
+ GET_QUEUE_INFO(1);
+ GET_QUEUE_INFO(2);
+ GET_QUEUE_INFO(3);
+ GET_QUEUE_INFO(4);
+ GET_QUEUE_INFO(5);
+ GET_QUEUE_INFO(6);
+ GET_QUEUE_INFO(7);
+
+ return rc;
+}
+
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx)
+{
+ int rc;
+ struct hwrm_ring_grp_free_input req = {.req_type = 0 };
+ struct hwrm_ring_grp_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, RING_GRP_FREE, -1, resp);
+
+ req.ring_group_id = rte_cpu_to_le_16(bp->grp_info[idx].fw_grp_id);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ bp->grp_info[idx].fw_grp_id = INVALID_HW_RING_ID;
+ return rc;
+}
+
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned idx)
+{
+ int rc;
+ struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
+ struct hwrm_stat_ctx_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, STAT_CTX_FREE, -1, resp);
+
+ req.stat_ctx_id = rte_cpu_to_le_16(cpr->hw_stats_ctx_id);
+ req.seq_id = rte_cpu_to_le_16(bp->hwrm_cmd_seq++);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ cpr->hw_stats_ctx_id = INVALID_STATS_CTX_ID;
+ bp->grp_info[idx].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
+ uint32_t *vf_req_fwd)
+{
+ int rc;
+ struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
+ struct hwrm_func_drv_rgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
+ req.flags = flags;
+ req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER;
+ req.ver_maj = BNXT_VER_MAJ;
+ req.ver_min = BNXT_VER_MIN;
+ req.ver_upd = BNXT_VER_UPD;
+
+ memcpy(req.vf_req_fwd, vf_req_fwd, sizeof(req.vf_req_fwd));
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)
+{
+ int rc;
+ struct hwrm_func_drv_unrgtr_input req = {.req_type = 0 };
+ struct hwrm_func_drv_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_DRV_UNRGTR, -1, resp);
+ req.flags = flags;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_pfvfbufs_register(struct bnxt *bp, phys_addr_t buf,
+ uint16_t buf_size)
+{
+ int rc;
+ struct hwrm_func_buf_rgtr_input req = {.req_type = 0 };
+ struct hwrm_func_buf_rgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_BUF_RGTR, -1, resp);
+
+ /* 1 buffer for all VFs */
+ req.enables = 0;
+ req.req_buf_len = buf_size;
+ req.req_buf_page_size = buf_size;
+ req.req_buf_num_pages = 1;
+ req.req_buf_page_addr0 = rte_cpu_to_le_64(buf);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd)
+{
+ int rc;
+ struct hwrm_exec_fwd_resp_input req = {.req_type = 0 };
+ struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, EXEC_FWD_RESP, -1, resp);
+
+ memcpy(req.encap_request, fwd_cmd,
+ sizeof(req.encap_request));
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_vf_alloc(struct bnxt *bp, uint16_t num_vfs)
+{
+ int rc;
+ struct hwrm_func_vf_alloc_input req = {.req_type = 0 };
+ struct hwrm_func_vf_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, FUNC_VF_ALLOC, -1, resp);
+
+ req.num_vfs = num_vfs;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+int bnxt_hwrm_func_vf_free(struct bnxt *bp, uint16_t num_vfs)
+{
+ int rc;
+ struct hwrm_func_vf_free_input req = {.req_type = 0 };
+ struct hwrm_func_vf_free_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (num_vfs == 0)
+ return 0;
+
+ HWRM_PREP(req, FUNC_VF_FREE, -1, resp);
+
+ req.num_vfs = num_vfs;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
+{
+ int rc = 0;
+ struct hwrm_port_phy_cfg_input req = {.req_type = 0};
+ struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, PORT_PHY_CFG, -1, resp);
+
+ req.flags = conf->phy_flags;
+ if (conf->link_up) {
+ req.force_link_speed = conf->link_speed;
+ /*
+ * Note, ChiMP FW 20.2.1 and 20.2.2 return an error when we set
+ * any auto mode, even "none".
+ */
+ if (req.auto_mode == HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE) {
+ req.flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
+ } else {
+ req.auto_mode = conf->auto_mode;
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
+ req.auto_link_speed_mask = conf->auto_link_speed_mask;
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;
+ req.auto_link_speed = conf->auto_link_speed;
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED;
+ }
+ req.auto_duplex = conf->duplex;
+ req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
+ req.auto_pause = conf->auto_pause;
+ /* Set force_pause if there is no auto or if there is a force */
+ if (req.auto_pause)
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;
+ else
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+ req.force_pause = conf->force_pause;
+ if (req.force_pause)
+ req.enables |=
+ HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+ } else {
+ req.flags &= ~HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
+ req.flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN;
+ req.force_link_speed = 0;
+ }
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
+ struct bnxt_link_info *link_info)
+{
+ int rc = 0;
+ struct hwrm_port_phy_qcfg_input req = {.req_type = 0};
+ struct hwrm_port_phy_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+ HWRM_PREP(req, PORT_PHY_QCFG, -1, resp);
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ link_info->phy_link_status = resp->link;
+ if (link_info->phy_link_status == HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK) {
+ link_info->link_up = 1;
+ link_info->link_speed = rte_le_to_cpu_16(resp->link_speed);
+ } else {
+ link_info->link_up = 0;
+ link_info->link_speed = 0;
+ }
+ link_info->duplex = resp->duplex;
+ link_info->pause = resp->pause;
+ link_info->auto_pause = resp->auto_pause;
+ link_info->force_pause = resp->force_pause;
+ link_info->auto_mode = resp->auto_mode;
+
+ link_info->support_speeds = rte_le_to_cpu_16(resp->support_speeds);
+ link_info->auto_link_speed = rte_le_to_cpu_16(resp->auto_link_speed);
+ link_info->preemphasis = rte_le_to_cpu_32(resp->preemphasis);
+ link_info->phy_ver[0] = resp->phy_maj;
+ link_info->phy_ver[1] = resp->phy_min;
+ link_info->phy_ver[2] = resp->phy_bld;
+
+ return rc;
+}
+
+int bnxt_hwrm_port_qstats(struct bnxt *bp,
+ struct hwrm_port_qstats_output *stats)
+{
+ int rc = 0;
+ struct hwrm_port_qstats_input req = {.req_type = 0 };
+ struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!BNXT_PF(bp))
+ return -1;
+
+ HWRM_PREP(req, PORT_QSTATS, -1, resp);
+ req.port_id = bp->pf.port_id;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ if (stats)
+ memcpy(stats, resp, sizeof(*stats));
+
+ return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+ int rc = 0;
+ struct hwrm_port_clr_stats_input req = {.req_type = 0 };
+ struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+
+ if (!BNXT_PF(bp))
+ return -1;
+
+ HWRM_PREP(req, PORT_CLR_STATS, -1, resp);
+ req.port_id = bp->pf.port_id;
+
+ rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+ HWRM_CHECK_RESULT;
+
+ return rc;
+}
+
+/*
+ * HWRM utility functions
+ */
+
+int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ unsigned i;
+ int rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq;
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+
+ if (i >= bp->rx_cp_nr_rings) {
+ txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
+ cpr = &txq->cp_ring;
+ } else {
+ rxq = bp->rx_queues[i];
+ cpr = &rxq->cp_ring;
+ }
+
+ rc = bnxt_hwrm_stat_clear(bp, cpr);
+ if (rc)
+ return rc;
+ }
+ return 0;
+}
+
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ unsigned i;
+ int rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq;
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_cp_ring_info *cpr;
+ unsigned idx = i + 1;
+
+ if (i >= bp->rx_cp_nr_rings) {
+ txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
+ cpr = &txq->cp_ring;
+ } else {
+ rxq = bp->rx_queues[i];
+ cpr = &rxq->cp_ring;
+ }
+
+ rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, idx);
+
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+void bnxt_free_hwrm_resources(struct bnxt *bp)
+{
+ /* Release memzone */
+ rte_free(bp->hwrm_cmd_resp_addr);
+ bp->hwrm_cmd_resp_addr = NULL;
+ bp->hwrm_cmd_resp_dma_addr = 0;
+}
+
+int bnxt_alloc_hwrm_resources(struct bnxt *bp)
+{
+ struct rte_pci_device *pdev = bp->pdev;
+ char type[RTE_MEMZONE_NAMESIZE];
+
+ sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x", pdev->addr.domain,
+ pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
+ bp->hwrm_cmd_resp_addr = rte_malloc(type, HWRM_RESP_LENGTH, 0);
+ if (bp->hwrm_cmd_resp_addr == NULL)
+ return -ENOMEM;
+ bp->hwrm_cmd_resp_dma_addr =
+ rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+ bp->max_req_len = HWRM_MAX_REQ_LEN;
+ rte_spinlock_init(&bp->hwrm_lock);
+
+ return 0;
+}
+
+static void bnxt_free_cp_ring(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned idx)
+{
+ struct bnxt_ring_struct *cp_ring = &cpr->cp_ring_struct;
+
+ bnxt_hwrm_ring_free(bp, cp_ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_CMPL);
+ cp_ring->fw_ring_id = INVALID_HW_RING_ID;
+ bp->grp_info[idx].cp_fw_ring_id = INVALID_HW_RING_ID;
+ memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct.ring_size *
+ sizeof(*cpr->cp_desc_ring));
+ cpr->cp_raw_cons = 0;
+}
+
+int bnxt_free_all_hwrm_rings(struct bnxt *bp)
+{
+ unsigned i;
+ int rc = 0;
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_tx_ring_info *txr = &txq->tx_ring;
+ struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
+ struct bnxt_cp_ring_info *cpr = &txq->cp_ring;
+ unsigned idx = bp->rx_cp_nr_rings + i + 1;
+
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_TX);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ memset(txr->tx_desc_ring, 0,
+ txr->tx_ring_struct.ring_size *
+ sizeof(*txr->tx_desc_ring));
+ memset(txr->tx_buf_ring, 0,
+ txr->tx_ring_struct.ring_size *
+ sizeof(*txr->tx_buf_ring));
+ txr->tx_prod = 0;
+ txr->tx_cons = 0;
+ }
+ if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID)
+ bnxt_free_cp_ring(bp, cpr, idx);
+ }
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_rx_ring_info *rxr = &rxq->rx_ring;
+ struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+ unsigned idx = i + 1;
+
+ if (ring->fw_ring_id != INVALID_HW_RING_ID) {
+ bnxt_hwrm_ring_free(bp, ring,
+ HWRM_RING_FREE_INPUT_RING_TYPE_RX);
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+ bp->grp_info[idx].rx_fw_ring_id = INVALID_HW_RING_ID;
+ memset(rxr->rx_desc_ring, 0,
+ rxr->rx_ring_struct.ring_size *
+ sizeof(*rxr->rx_desc_ring));
+ memset(rxr->rx_buf_ring, 0,
+ rxr->rx_ring_struct.ring_size *
+ sizeof(*rxr->rx_buf_ring));
+ rxr->rx_prod = 0;
+ }
+ if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID)
+ bnxt_free_cp_ring(bp, cpr, idx);
+ }
+
+ /* Default completion ring */
+ {
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+
+ if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID)
+ bnxt_free_cp_ring(bp, cpr, 0);
+ }
+
+ return rc;
+}
+
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
+{
+ uint16_t i;
+ uint32_t rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ unsigned idx = i + 1;
+
+ if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) {
+ RTE_LOG(ERR, PMD,
+ "Attempt to free invalid ring group %d\n",
+ idx);
+ continue;
+ }
+
+ rc = bnxt_hwrm_ring_grp_free(bp, idx);
+
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
+{
+ uint16_t i;
+ uint32_t rc = 0;
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ unsigned idx = i + 1;
+
+ if (bp->grp_info[idx].cp_fw_ring_id == INVALID_HW_RING_ID ||
+ bp->grp_info[idx].rx_fw_ring_id == INVALID_HW_RING_ID)
+ continue;
+
+ rc = bnxt_hwrm_ring_grp_alloc(bp, idx);
+
+ if (rc)
+ return rc;
+ }
+ return rc;
+}
+
+int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
+{
+ int rc;
+ unsigned i;
+ struct bnxt_cp_ring_info *cpr;
+
+ for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
+ unsigned idx = i + 1;
+
+ if (i >= bp->rx_cp_nr_rings)
+ cpr = &bp->tx_queues[i - bp->rx_cp_nr_rings]->cp_ring;
+ else
+ cpr = &bp->rx_queues[i]->cp_ring;
+ if (cpr->hw_stats_ctx_id != (uint32_t) INVALID_STATS_CTX_ID) {
+ rc = bnxt_hwrm_stat_ctx_free(bp, cpr, idx);
+ if (rc)
+ return rc;
+ }
+ }
+ return 0;
+}
+
+int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ int rc = 0;
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ rc = bnxt_hwrm_set_filter(bp, vnic, filter);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+ struct bnxt_filter_info *filter;
+ int rc = 0;
+
+ STAILQ_FOREACH(filter, &vnic->filter, next) {
+ rc = bnxt_hwrm_clear_filter(bp, filter);
+ if (rc)
+ break;
+ }
+ return rc;
+}
+
+void bnxt_free_all_hwrm_resources(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ unsigned i;
+
+ if (bp->vnic_info == NULL)
+ return;
+
+ vnic = &bp->vnic_info[0];
+ bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
+
+ /* VNIC resources */
+ for (i = 0; i < bp->nr_vnics; i++) {
+ struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+ bnxt_clear_hwrm_vnic_filters(bp, vnic);
+
+ bnxt_hwrm_vnic_ctx_free(bp, vnic);
+ bnxt_hwrm_vnic_free(bp, vnic);
+ }
+ /* Ring resources */
+ bnxt_free_all_hwrm_rings(bp);
+ bnxt_free_all_hwrm_ring_grps(bp);
+ bnxt_free_all_hwrm_stat_ctxs(bp);
+}
+
+static uint16_t bnxt_parse_hw_link_duplex(uint16_t hw_link_duplex)
+{
+ uint8_t eth_link_duplex = ETH_LINK_AUTONEG_DUPLEX;
+
+ switch (hw_link_duplex) {
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH:
+ break;
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF:
+ eth_link_duplex = ETH_LINK_HALF_DUPLEX;
+ break;
+ case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL:
+ eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+ break;
+ default:
+ RTE_LOG(ERR, PMD, "HWRM link duplex %d not defined\n",
+ hw_link_duplex);
+ break;
+ }
+ return eth_link_duplex;
+}
+
+static uint16_t bnxt_parse_eth_link_duplex(uint16_t eth_link_duplex)
+{
+ uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+ switch (eth_link_duplex) {
+ case ETH_LINK_AUTONEG_DUPLEX:
+ break;
+ case ETH_LINK_HALF_DUPLEX:
+ hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF;
+ break;
+ case ETH_LINK_FULL_DUPLEX:
+ hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL;
+ break;
+ default:
+ RTE_LOG(ERR, PMD,
+ "Unsupported link duplex mode %d; default to AUTO\n",
+ eth_link_duplex);
+ break;
+ }
+ return hw_link_duplex;
+}
+
+static uint16_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
+{
+ uint16_t eth_link_speed = ETH_LINK_SPEED_AUTONEG;
+
+ switch (hw_link_speed) {
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
+ eth_link_speed = ETH_LINK_SPEED_100;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
+ eth_link_speed = ETH_LINK_SPEED_1000;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
+ eth_link_speed = ETH_LINK_SPEED_2000;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB:
+ eth_link_speed = ETH_LINK_SPEED_2500;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
+ eth_link_speed = ETH_LINK_SPEED_10G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
+ eth_link_speed = ETH_LINK_SPEED_20G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
+ eth_link_speed = ETH_LINK_SPEED_25G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
+ eth_link_speed = ETH_LINK_SPEED_40G;
+ break;
+ case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
+ eth_link_speed = ETH_LINK_SPEED_50G;
+ break;
+ default:
+ RTE_LOG(ERR, PMD, "HWRM link speed %d not defined\n",
+ hw_link_speed);
+ break;
+ }
+ return eth_link_speed;
+}
+
+static uint16_t bnxt_parse_eth_link_speed(uint16_t conf_link_speed)
+{
+ uint16_t eth_link_speed = ETH_LINK_SPEED_AUTONEG;
+
+ switch (conf_link_speed) {
+ case ETH_LINK_SPEED_AUTONEG:
+ break;
+ case ETH_LINK_SPEED_100:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB;
+ break;
+ case ETH_LINK_SPEED_1000:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB;
+ break;
+ case ETH_LINK_SPEED_2000:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB;
+ break;
+ case ETH_LINK_SPEED_2500:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB;
+ break;
+ case ETH_LINK_SPEED_10G:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB;
+ break;
+ case ETH_LINK_SPEED_20G:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB;
+ break;
+ case ETH_LINK_SPEED_25G:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB;
+ break;
+ case ETH_LINK_SPEED_40G:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB;
+ break;
+ case ETH_LINK_SPEED_50G:
+ eth_link_speed = HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB;
+ break;
+ default:
+ RTE_LOG(ERR, PMD,
+ "Unsupported link speed %d; default to AUTO\n",
+ conf_link_speed);
+ break;
+ }
+ return eth_link_speed;
+}
+
+int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link)
+{
+ int rc = 0;
+ struct bnxt_link_info *link_info = &bp->link_info;
+
+ rc = bnxt_hwrm_port_phy_qcfg(bp, link_info);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Get link config failed with rc %d\n", rc);
+ goto exit;
+ }
+ if (link_info->link_up)
+ link->link_speed =
+ bnxt_parse_hw_link_speed(link_info->link_speed);
+ else
+ link->link_speed = ETH_LINK_SPEED_10;
+ link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
+ link->link_status = link_info->link_up;
+exit:
+ return rc;
+}
+
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
+{
+ int rc = 0;
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ struct bnxt_link_info link_req;
+ uint16_t speed;
+
+ memset(&link_req, 0, sizeof(link_req));
+ speed = bnxt_parse_eth_link_speed(dev_conf->link_speed);
+ link_req.link_up = link_up;
+ if (speed == ETH_LINK_SPEED_AUTONEG) {
+ link_req.phy_flags =
+ HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
+ link_req.auto_mode =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW;
+ /* TODO: Currently, only a subset of speeds are supported
+ in DPDK */
+ link_req.auto_link_speed_mask =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB |
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+ link_req.auto_link_speed =
+ HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB;
+ } else {
+ link_req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE;
+ link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE |
+ HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
+ link_req.link_speed = speed;
+ }
+ link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_duplex);
+ link_req.auto_pause = bp->link_info.auto_pause;
+ link_req.force_pause = bp->link_info.force_pause;
+
+ rc = bnxt_hwrm_port_phy_cfg(bp, &link_req);
+ if (rc) {
+ RTE_LOG(ERR, PMD,
+ "Set link config failed with rc %d\n", rc);
+ }
+ /* TODO: Do we need to reset PHY? */
+ return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
new file mode 100644
index 0000000..3fbad34
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -0,0 +1,105 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_HWRM_H_
+#define _BNXT_HWRM_H_
+
+#include <inttypes.h>
+#include <stdbool.h>
+
+struct bnxt;
+#define HWRM_SEQ_ID_INVALID -1U
+
+int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_set_filter(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_clear_filter(struct bnxt *bp,
+ struct bnxt_filter_info *filter);
+int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
+ struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_set_dcb(struct bnxt *bp __rte_unused,
+ struct bnxt_vnic_info *vnic __rte_unused);
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned idx);
+int bnxt_hwrm_ring_alloc(struct bnxt *bp,
+ struct bnxt_ring_struct *ring,
+ uint32_t ring_type, uint32_t map_index,
+ uint32_t stats_ctx_id);
+int bnxt_hwrm_ring_free(struct bnxt *bp,
+ struct bnxt_ring_struct *ring, uint32_t ring_type);
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned idx);
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_reset(struct bnxt *bp);
+int bnxt_hwrm_func_qstats(struct bnxt *bp,
+ struct hwrm_func_qstats_output *stats);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp);
+int bnxt_hwrm_ver_get(struct bnxt *bp);
+int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx);
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
+ struct bnxt_cp_ring_info *cpr, unsigned idx);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
+ uint32_t *vf_req_fwd);
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
+int bnxt_hwrm_func_pfvfbufs_register(struct bnxt *bp, phys_addr_t buf,
+ uint16_t buf_size);
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
+int bnxt_hwrm_func_vf_alloc(struct bnxt *bp, uint16_t num_vfs);
+int bnxt_hwrm_func_vf_free(struct bnxt *bp, uint16_t num_vfs);
+int bnxt_hwrm_port_qstats(struct bnxt *bp,
+ struct hwrm_port_qstats_output *stats);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
+int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
+void bnxt_free_hwrm_resources(struct bnxt *bp);
+int bnxt_alloc_hwrm_resources(struct bnxt *bp);
+int bnxt_free_all_hwrm_rings(struct bnxt *bp);
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+void bnxt_free_all_hwrm_resources(struct bnxt *bp);
+
+int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link);
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
+#endif
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
new file mode 100644
index 0000000..ca6368e
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -0,0 +1,154 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_irq.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Interrupts
+ */
+
+static void bnxt_int_handler(struct rte_intr_handle *handle __rte_unused,
+ void *param)
+{
+ struct rte_eth_dev *eth_dev = (struct rte_eth_dev *)param;
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ struct cmpl_base *cmp;
+
+ while (1) {
+ cons = RING_CMP(&cpr->cp_ring_struct, raw_cons);
+ cmp = &cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(cmp, raw_cons, &cpr->cp_ring_struct))
+ break;
+
+ switch (CMP_TYPE(cmp)) {
+ case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT:
+ /* Handle any async event */
+ bnxt_handle_async_event(bp, cmp);
+ break;
+ case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+ /* Handle HWRM forwarded responses */
+ bnxt_handle_fwd_req(bp, cmp);
+ break;
+ default:
+ /* Ignore any other events */
+ break;
+ }
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ }
+ B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+}
+
+void bnxt_free_int(struct bnxt *bp)
+{
+ struct bnxt_irq *irq;
+
+ irq = bp->irq_tbl;
+ if (irq) {
+ if (irq->requested) {
+ rte_intr_disable(&bp->pdev->intr_handle);
+ rte_intr_callback_unregister(&bp->pdev->intr_handle,
+ irq->handler,
+ (void *)bp->eth_dev);
+ irq->requested = 0;
+ }
+ rte_free((void *)bp->irq_tbl);
+ bp->irq_tbl = NULL;
+ }
+}
+
+void bnxt_disable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+
+ /* Only the default completion ring */
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+}
+
+void bnxt_enable_int(struct bnxt *bp)
+{
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+
+ B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
+}
+
+int bnxt_setup_int(struct bnxt *bp)
+{
+ uint16_t total_vecs;
+ const int len = sizeof(bp->irq_tbl[0].name);
+ int i, rc = 0;
+
+ /* DPDK host only supports 1 MSI-X vector */
+ total_vecs = 1;
+ bp->irq_tbl = rte_calloc("bnxt_irq_tbl", total_vecs,
+ sizeof(struct bnxt_irq), 0);
+ if (bp->irq_tbl) {
+ for (i = 0; i < total_vecs; i++) {
+ bp->irq_tbl[i].vector = i;
+ snprintf(bp->irq_tbl[i].name, len,
+ "%s-%d", bp->eth_dev->data->name, i);
+ bp->irq_tbl[i].handler = bnxt_int_handler;
+ }
+ } else {
+ rc = -ENOMEM;
+ goto setup_exit;
+ }
+ return 0;
+
+setup_exit:
+ RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+ return rc;
+}
+
+int bnxt_request_int(struct bnxt *bp)
+{
+ int rc = 0;
+
+ struct bnxt_irq *irq = bp->irq_tbl;
+
+ rte_intr_callback_register(&bp->pdev->intr_handle, irq->handler,
+ (void *)bp->eth_dev);
+ rte_intr_enable(&(bp->pdev->intr_handle));
+
+ irq->requested = 1;
+ return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_irq.h b/drivers/net/bnxt/bnxt_irq.h
new file mode 100644
index 0000000..e21bec5
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_irq.h
@@ -0,0 +1,51 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_IRQ_H_
+#define _BNXT_IRQ_H_
+
+struct bnxt_irq {
+ rte_intr_callback_fn handler;
+ unsigned int vector;
+ uint8_t requested;
+ char name[RTE_ETH_NAME_MAX_LEN + 2];
+};
+
+struct bnxt;
+void bnxt_free_int(struct bnxt *bp);
+void bnxt_disable_int(struct bnxt *bp);
+void bnxt_enable_int(struct bnxt *bp);
+int bnxt_setup_int(struct bnxt *bp);
+int bnxt_request_int(struct bnxt *bp);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
new file mode 100644
index 0000000..c3d8ef7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -0,0 +1,306 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <stdbool.h>
+
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_memzone.h>
+
+#include "bnxt.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_ring.h"
+#include "bnxt_rxq.h"
+#include "bnxt_txq.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Generic ring handling
+ */
+
+void bnxt_free_ring(struct bnxt_ring_struct *ring)
+{
+ /* The actual ring is reserved via rte_memzone_reserve API.
+ The current document/code indicates that:
+ "Note: A reserved zone cannot be freed."
+ */
+ if (ring->vmem_size && *ring->vmem) {
+ memset((char *)*ring->vmem, 0, ring->vmem_size);
+ *ring->vmem = NULL;
+ }
+}
+
+/*
+ * Ring groups
+ */
+
+void bnxt_init_ring_grps(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < MAX_NUM_RINGS; i++)
+ memset(&bp->grp_info[i], INVALID_HW_RING_ID,
+ sizeof(struct bnxt_ring_grp_info));
+}
+
+/*
+ * Allocates a completion ring with vmem and stats optionally also allocating
+ * a TX and/or RX ring. Passing NULL as tx_ring_info and/or rx_ring_info
+ * to not allocate them.
+ *
+ * Order in the allocation is:
+ * stats - Always non-zero length
+ * cp vmem - Always zero-length, supported for the bnxt_ring_struct abstraction
+ * tx vmem - Only non-zero length if tx_ring_info is not NULL
+ * rx vmem - Only non-zero length if rx_ring_info is not NULL
+ * cp bd ring - Always non-zero length
+ * tx bd ring - Only non-zero length if tx_ring_info is not NULL
+ * rx bd ring - Only non-zero length if rx_ring_info is not NULL
+ */
+int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
+ struct bnxt_tx_ring_info *tx_ring_info,
+ struct bnxt_rx_ring_info *rx_ring_info,
+ struct bnxt_cp_ring_info *cp_ring_info,
+ const char *suffix)
+{
+ struct bnxt_ring_struct *cp_ring = &cp_ring_info->cp_ring_struct;
+ struct bnxt_ring_struct *tx_ring;
+ struct bnxt_ring_struct *rx_ring;
+ struct rte_pci_device *pdev = bp->pdev;
+ const struct rte_memzone *mz = NULL;
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+
+ int stats_len = (tx_ring_info || rx_ring_info) ?
+ RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats)) : 0;
+
+ int cp_vmem_start = stats_len;
+ int cp_vmem_len = RTE_CACHE_LINE_ROUNDUP(cp_ring->vmem_size);
+
+ int tx_vmem_start = cp_vmem_start + cp_vmem_len;
+ int tx_vmem_len =
+ tx_ring_info ? RTE_CACHE_LINE_ROUNDUP(tx_ring_info->
+ tx_ring_struct.vmem_size) : 0;
+
+ int rx_vmem_start = tx_vmem_start + tx_vmem_len;
+ int rx_vmem_len =
+ rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
+ rx_ring_struct.vmem_size) : 0;
+
+ int cp_ring_start = rx_vmem_start + rx_vmem_len;
+ int cp_ring_len = RTE_CACHE_LINE_ROUNDUP(cp_ring->ring_size *
+ sizeof(struct cmpl_base));
+
+ int tx_ring_start = cp_ring_start + cp_ring_len;
+ int tx_ring_len = tx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(tx_ring_info->tx_ring_struct.ring_size *
+ sizeof(struct tx_bd_long)) : 0;
+
+ int rx_ring_start = tx_ring_start + tx_ring_len;
+ int rx_ring_len = rx_ring_info ?
+ RTE_CACHE_LINE_ROUNDUP(rx_ring_info->rx_ring_struct.ring_size *
+ sizeof(struct rx_prod_pkt_bd)) : 0;
+
+ int total_alloc_len = rx_ring_start + rx_ring_len;
+
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
+ pdev->addr.bus, pdev->addr.devid, pdev->addr.function, qidx,
+ suffix);
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ if (!mz) {
+ mz = rte_memzone_reserve(mz_name, total_alloc_len,
+ SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY);
+ if (mz == NULL)
+ return -ENOMEM;
+ }
+ memset(mz->addr, 0, mz->len);
+
+ if (tx_ring_info) {
+ tx_ring = &tx_ring_info->tx_ring_struct;
+
+ tx_ring->bd = ((char *)mz->addr + tx_ring_start);
+ tx_ring_info->tx_desc_ring = (struct tx_bd_long *)tx_ring->bd;
+ tx_ring->bd_dma = mz->phys_addr + tx_ring_start;
+ tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
+
+ if (!tx_ring->bd)
+ return -ENOMEM;
+ if (tx_ring->vmem_size) {
+ tx_ring->vmem =
+ (void **)((char *)mz->addr + tx_vmem_start);
+ tx_ring_info->tx_buf_ring =
+ (struct bnxt_sw_tx_bd *)tx_ring->vmem;
+ }
+ }
+
+ if (rx_ring_info) {
+ rx_ring = &rx_ring_info->rx_ring_struct;
+
+ rx_ring->bd = ((char *)mz->addr + rx_ring_start);
+ rx_ring_info->rx_desc_ring =
+ (struct rx_prod_pkt_bd *)rx_ring->bd;
+ rx_ring->bd_dma = mz->phys_addr + rx_ring_start;
+ rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
+
+ if (!rx_ring->bd)
+ return -ENOMEM;
+ if (rx_ring->vmem_size) {
+ rx_ring->vmem =
+ (void **)((char *)mz->addr + rx_vmem_start);
+ rx_ring_info->rx_buf_ring =
+ (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+ }
+ }
+
+ cp_ring->bd = ((char *)mz->addr + cp_ring_start);
+ cp_ring->bd_dma = mz->phys_addr + cp_ring_start;
+ cp_ring_info->cp_desc_ring = cp_ring->bd;
+ cp_ring_info->cp_desc_mapping = cp_ring->bd_dma;
+
+ if (!cp_ring->bd)
+ return -ENOMEM;
+ if (cp_ring->vmem_size)
+ *cp_ring->vmem = ((char *)mz->addr + stats_len);
+ if (stats_len) {
+ cp_ring_info->hw_stats = mz->addr;
+ cp_ring_info->hw_stats_map = mz->phys_addr;
+ }
+ cp_ring_info->hw_stats_ctx_id = INVALID_STATS_CTX_ID;
+ return 0;
+}
+
+/* ring_grp usage:
+ * [0] = default completion ring
+ * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings
+ * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings
+ */
+int bnxt_alloc_hwrm_rings(struct bnxt *bp)
+{
+ unsigned i;
+ int rc = 0;
+
+ /* Default completion ring */
+ {
+ struct bnxt_cp_ring_info *cpr = &bp->def_cp_ring;
+ struct bnxt_ring_struct *cp_ring = &cpr->cp_ring_struct;
+
+ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+ 0, INVALID_STATS_CTX_ID);
+ if (rc)
+ goto err_out;
+ cpr->cp_doorbell =
+ (char *)bp->eth_dev->pci_dev->mem_resource[2].addr;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+ bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id;
+ }
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+ struct bnxt_ring_struct *cp_ring = &cpr->cp_ring_struct;
+ struct bnxt_rx_ring_info *rxr = &rxq->rx_ring;
+ struct bnxt_ring_struct *ring = &rxr->rx_ring_struct;
+ unsigned idx = i + 1;
+
+ /* Rx cmpl */
+ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+ idx, INVALID_STATS_CTX_ID);
+ if (rc)
+ goto err_out;
+ cpr->cp_doorbell =
+ (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ idx * 0x80;
+ bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+
+ /* Rx ring */
+ rc = bnxt_hwrm_ring_alloc(bp, ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+ idx, cpr->hw_stats_ctx_id);
+ if (rc)
+ goto err_out;
+ rxr->rx_prod = 0;
+ rxr->rx_doorbell =
+ (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ idx * 0x80;
+ bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ if (bnxt_init_one_rx_ring(rxq)) {
+ RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!");
+ bnxt_rx_queue_release_op(rxq);
+ return -ENOMEM;
+ }
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ }
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_cp_ring_info *cpr = &txq->cp_ring;
+ struct bnxt_ring_struct *cp_ring = &cpr->cp_ring_struct;
+ struct bnxt_tx_ring_info *txr = &txq->tx_ring;
+ struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
+ unsigned idx = 1 + bp->rx_cp_nr_rings + i;
+
+ /* Tx cmpl */
+ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+ idx, INVALID_STATS_CTX_ID);
+ if (rc)
+ goto err_out;
+
+ cpr->cp_doorbell =
+ (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ idx * 0x80;
+ bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+
+ /* Tx ring */
+ rc = bnxt_hwrm_ring_alloc(bp, ring,
+ HWRM_RING_ALLOC_INPUT_RING_TYPE_TX,
+ idx, cpr->hw_stats_ctx_id);
+ if (rc)
+ goto err_out;
+
+ txr->tx_doorbell =
+ (char *)bp->eth_dev->pci_dev->mem_resource[2].addr +
+ idx * 0x80;
+ }
+
+err_out:
+ return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
new file mode 100644
index 0000000..0939998
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -0,0 +1,104 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_RING_H_
+#define _BNXT_RING_H_
+
+#include <inttypes.h>
+
+#include <rte_memory.h>
+
+#define RING_NEXT(ring, idx) (((idx) + 1) & (ring)->ring_mask)
+
+#define RTE_MBUF_DATA_DMA_ADDR(mb) \
+ ((uint64_t) ((mb)->buf_physaddr + (mb)->data_off))
+
+#define DB_IDX_MASK 0xffffff
+#define DB_IDX_VALID (0x1<<26)
+#define DB_IRQ_DIS (0x1<<27)
+#define DB_KEY_TX (0x0<<28)
+#define DB_KEY_RX (0x1<<28)
+#define DB_KEY_CP (0x2<<28)
+#define DB_KEY_ST (0x3<<28)
+#define DB_KEY_TX_PUSH (0x4<<28)
+#define DB_LONG_TX_PUSH (0x2<<24)
+
+#define DEFAULT_CP_RING_SIZE 256
+#define DEFAULT_RX_RING_SIZE 256
+#define DEFAULT_TX_RING_SIZE 256
+
+#define MAX_TPA 128
+
+/* TODO: These are derived from the Linux driver assuming 4k pages */
+#define MAX_RX_DESC_CNT (8 * 1024)
+#define MAX_TX_DESC_CNT (4 * 1024)
+#define MAX_CP_DESC_CNT (16 * 1024)
+
+#define INVALID_HW_RING_ID ((uint16_t) -1)
+
+struct bnxt_ring_struct {
+ void *bd;
+ phys_addr_t bd_dma;
+ uint32_t ring_size;
+ uint32_t ring_mask;
+
+ int vmem_size;
+ void **vmem;
+
+ uint16_t fw_ring_id; /* Ring id filled by Chimp FW */
+};
+
+struct bnxt_ring_grp_info {
+ uint16_t fw_stats_ctx;
+ uint16_t fw_grp_id;
+ uint16_t rx_fw_ring_id;
+ uint16_t cp_fw_ring_id;
+ uint16_t ag_fw_ring_id;
+};
+
+struct bnxt;
+struct bnxt_tx_queue;
+struct bnxt_rx_queue;
+struct bnxt_tx_ring_info;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
+void bnxt_free_ring(struct bnxt_ring_struct *ring);
+void bnxt_init_ring_grps(struct bnxt *bp);
+int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
+ struct bnxt_tx_ring_info *tx_ring_info,
+ struct bnxt_rx_ring_info *rx_ring_info,
+ struct bnxt_cp_ring_info *cp_ring_info,
+ const char *suffix);
+int bnxt_alloc_hwrm_rings(struct bnxt *bp);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
new file mode 100644
index 0000000..c829e4d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -0,0 +1,383 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * RX Queues
+ */
+
+void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+
+ /* 'Unreserve' rte_memzone */
+ /* N/A */
+
+ if (cpr->hw_stats)
+ cpr->hw_stats = NULL;
+}
+
+int bnxt_mq_rx_configure(struct bnxt *bp)
+{
+ struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+ unsigned i, j, nb_q_per_grp, ring_idx;
+ int start_grp_id, end_grp_id, rc = 0;
+ struct bnxt_vnic_info *vnic;
+ struct bnxt_filter_info *filter;
+ struct bnxt_rx_queue *rxq;
+
+ bp->nr_vnics = 0;
+
+ /* Single queue mode */
+ if (bp->rx_cp_nr_rings < 2) {
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ RTE_LOG(ERR, PMD, "VNIC alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
+ bp->nr_vnics++;
+
+ rxq = bp->eth_dev->data->rx_queues[0];
+ rxq->vnic = vnic;
+
+ vnic->func_default = true;
+ vnic->ff_pool_idx = 0;
+ vnic->start_grp_id = 1;
+ vnic->end_grp_id = vnic->start_grp_id +
+ bp->rx_cp_nr_rings - 1;
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+ goto out;
+ }
+
+ /* Multi-queue mode */
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_VMDQ_FLAG) {
+ /* VMDq ONLY, VMDq+RSS, VMDq+DCB, VMDq+DCB+RSS */
+ enum rte_eth_nb_pools pools;
+
+ switch (dev_conf->rxmode.mq_mode) {
+ case ETH_MQ_RX_VMDQ_DCB_RSS: {
+ const struct rte_eth_vmdq_dcb_conf *conf =
+ &dev_conf->rx_adv_conf.vmdq_dcb_conf;
+
+ /* Should only support 8 pools in this mode */
+ pools = conf->nb_queue_pools *
+ dev_conf->rx_adv_conf.dcb_rx_conf.nb_tcs;
+ break;
+ }
+ case ETH_MQ_RX_VMDQ_DCB: {
+ const struct rte_eth_vmdq_dcb_conf *conf =
+ &dev_conf->rx_adv_conf.vmdq_dcb_conf;
+
+ /* ETH_16/32_POOLs */
+ pools = conf->nb_queue_pools;
+ break;
+ }
+ case ETH_MQ_RX_VMDQ_RSS:
+ case ETH_MQ_RX_VMDQ_ONLY:
+ default: {
+ const struct rte_eth_vmdq_rx_conf *conf =
+ &dev_conf->rx_adv_conf.vmdq_rx_conf;
+
+ /* ETH_8/64_POOLs */
+ pools = conf->nb_queue_pools;
+ break;
+ }
+ }
+ /* For each pool, allocate MACVLAN CFA rule & VNIC */
+ if (!pools) {
+ RTE_LOG(ERR, PMD,
+ "VMDq pool not set, defaulted to 64\n");
+ pools = ETH_64_POOLS;
+ }
+ nb_q_per_grp = bp->rx_cp_nr_rings / pools;
+ start_grp_id = 1;
+ end_grp_id = start_grp_id + nb_q_per_grp - 1;
+
+ ring_idx = 0;
+ for (i = 0; i < pools; i++) {
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ RTE_LOG(ERR, PMD,
+ "VNIC alloc failed\n");
+ return -ENOMEM;
+ }
+ STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
+ bp->nr_vnics++;
+
+ for (j = 0; j < nb_q_per_grp; j++, ring_idx++) {
+ rxq = bp->eth_dev->data->rx_queues[ring_idx];
+ rxq->vnic = vnic;
+ }
+ if (i == 0)
+ vnic->func_default = true;
+ vnic->ff_pool_idx = i;
+ vnic->start_grp_id = start_grp_id;
+ vnic->end_grp_id = end_grp_id;
+
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ RTE_LOG(ERR, PMD,
+ "L2 filter alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ /* TODO: Configure & associate CFA rule for
+ each VNIC for each VMDq with MACVLAN, MACVLAN+TC */
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+ start_grp_id = end_grp_id + 1;
+ end_grp_id += nb_q_per_grp;
+ }
+ goto out;
+ }
+
+ /* Non-VMDq mode - RSS, DCB, RSS+DCB */
+ if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_DCB_RSS) {
+ const struct rte_eth_dcb_rx_conf *conf =
+ &dev_conf->rx_adv_conf.dcb_rx_conf;
+
+ /* In order to support DCB+RSS, each TC will
+ be assigned to one VNIC */
+ nb_q_per_grp = bp->rx_cp_nr_rings / conf->nb_tcs;
+ start_grp_id = 1;
+ end_grp_id = start_grp_id + nb_q_per_grp - 1;
+
+ ring_idx = 0;
+ for (i = 0; i < conf->nb_tcs; i++) {
+ /* Allocate & configure VNIC */
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ RTE_LOG(ERR, PMD, "VNIC alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
+ bp->nr_vnics++;
+
+ for (j = 0; j < nb_q_per_grp; j++, ring_idx++) {
+ rxq = bp->eth_dev->data->rx_queues[ring_idx];
+ rxq->vnic = vnic;
+ }
+ if (i == 0)
+ vnic->func_default = true;
+ vnic->ff_pool_idx = 0;
+ vnic->start_grp_id = start_grp_id;
+ vnic->end_grp_id = end_grp_id;
+
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
+ rc = -ENOMEM;
+ goto err_out;
+ }
+ /* TODO: Configure & associate CFA rule for
+ each VNIC for each TC */
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+ start_grp_id = end_grp_id + 1;
+ end_grp_id += nb_q_per_grp;
+ if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+ vnic->hash_type =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ }
+ } else {
+ /* Init default VNIC for RSS or DCB only */
+ vnic = bnxt_alloc_vnic(bp);
+ if (!vnic) {
+ RTE_LOG(ERR, PMD, "VNIC alloc failed\n");
+ return -ENOMEM;
+ }
+ /* Partition the rx queues for the single pool */
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ rxq = bp->eth_dev->data->rx_queues[i];
+ rxq->vnic = vnic;
+ }
+ STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
+ bp->nr_vnics++;
+
+ vnic->func_default = true;
+ vnic->ff_pool_idx = 0;
+ vnic->start_grp_id = 1;
+ vnic->end_grp_id = vnic->start_grp_id +
+ bp->rx_cp_nr_rings - 1;
+ filter = bnxt_alloc_filter(bp);
+ if (!filter) {
+ RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
+ return -ENOMEM;
+ }
+ STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+ if (dev_conf->rxmode.mq_mode == ETH_MQ_RX_DCB)
+ bnxt_hwrm_vnic_set_dcb(bp, 0);
+ else if (dev_conf->rxmode.mq_mode & ETH_MQ_RX_RSS_FLAG)
+ vnic->hash_type =
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+ HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+ }
+
+out:
+ return rc;
+
+err_out:
+ /* Free allocated vnic/filters */
+
+ return rc;
+}
+
+static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_sw_rx_bd *sw_ring;
+ uint16_t i;
+
+ if (rxq) {
+ sw_ring = rxq->rx_ring.rx_buf_ring;
+ if (sw_ring) {
+ for (i = 0; i < rxq->nb_rx_desc; i++) {
+ if (sw_ring[i].mbuf) {
+ rte_pktmbuf_free_seg(sw_ring[i].mbuf);
+ sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+ }
+}
+
+void bnxt_free_rx_mbufs(struct bnxt *bp)
+{
+ struct bnxt_rx_queue *rxq;
+ int i;
+
+ for (i = 0; i < (int)bp->rx_nr_rings; i++) {
+ rxq = bp->rx_queues[i];
+ bnxt_rx_queue_release_mbufs(rxq);
+ }
+}
+
+void bnxt_rx_queue_release_op(void *rx_queue)
+{
+ struct bnxt_rx_queue *rxq = (struct bnxt_rx_queue *)rx_queue;
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_ring_struct *ring;
+
+ if (rxq) {
+ bnxt_rx_queue_release_mbufs(rxq);
+
+ /* Free RX ring hardware descriptors */
+ rxr = &rxq->rx_ring;
+ ring = &rxr->rx_ring_struct;
+ bnxt_free_ring(ring);
+
+ /* Free RX completion ring hardware descriptors */
+ cpr = &rxq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ bnxt_free_ring(ring);
+
+ bnxt_free_rxq_stats(rxq);
+
+ rte_free(rxq);
+ }
+}
+
+int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_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 bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_rx_queue *rxq;
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_cp_ring_info *cpr;
+
+ if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
+ RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+ return -EINVAL;
+ }
+
+ if (eth_dev->data->rx_queues) {
+ rxq = eth_dev->data->rx_queues[queue_idx];
+ if (rxq)
+ bnxt_rx_queue_release_op(rxq);
+ }
+ rxq = rte_zmalloc_socket("bnxt_rx_queue", sizeof(struct bnxt_rx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (rxq == NULL) {
+ RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!");
+ return -ENOMEM;
+ }
+ rxq->bp = bp;
+ rxq->mb_pool = mp;
+ rxq->nb_rx_desc = nb_desc;
+ rxq->rx_free_thresh = rx_conf->rx_free_thresh;
+
+ bnxt_init_rx_ring_struct(rxq);
+
+ rxq->queue_id = queue_idx;
+ rxq->port_id = eth_dev->data->port_id;
+ rxq->crc_len =
+ (uint8_t) ((eth_dev->data->dev_conf.
+ rxmode.hw_strip_crc) ? 0 : ETHER_CRC_LEN);
+ rxr = &rxq->rx_ring;
+ cpr = &rxq->cp_ring;
+
+ eth_dev->data->rx_queues[queue_idx] = rxq;
+ /* Allocate RX ring hardware descriptors */
+ if (bnxt_alloc_rings(bp, queue_idx, NULL, rxr, cpr, "bnxt_rx_ring")) {
+ RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
+ bnxt_rx_queue_release_op(rxq);
+ return -ENOMEM;
+ }
+
+ return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
new file mode 100644
index 0000000..3ad65b5
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -0,0 +1,75 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_RQX_H_
+#define _BNXT_RQX_H_
+
+/* TODO make bnxt_rx_queue.cp_ring and bnxt_rx_queue.rx_ring pointers */
+#include "bnxt_rxr.h"
+
+struct bnxt;
+struct bnxt_rx_queue {
+ struct rte_mempool *mb_pool; /* mbuf pool for RX ring */
+ struct rte_mbuf *pkt_first_seg; /* 1st seg of pkt */
+ struct rte_mbuf *pkt_last_seg; /* Last seg of pkt */
+ uint64_t mbuf_initializer; /* val to init mbuf */
+ uint16_t nb_rx_desc; /* num of RX desc */
+ uint16_t rx_tail; /* cur val of RDT register */
+ uint16_t nb_rx_hold; /* num held free RX desc */
+ uint16_t rx_free_thresh; /* max free RX desc to hold */
+ uint16_t queue_id; /* RX queue index */
+ uint16_t reg_idx; /* RX queue register index */
+ uint8_t port_id; /* Device port identifier */
+ uint8_t crc_len; /* 0 if CRC stripped, 4 otherwise */
+
+ struct bnxt *bp;
+ struct bnxt_vnic_info *vnic;
+
+ uint32_t rx_buf_size;
+ uint32_t rx_buf_use_size; /* useable size */
+ struct bnxt_rx_ring_info rx_ring;
+ struct bnxt_cp_ring_info cp_ring;
+};
+
+void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
+int bnxt_mq_rx_configure(struct bnxt *bp);
+void bnxt_rx_queue_release_op(void *rx_queue);
+int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_rxconf *rx_conf,
+ struct rte_mempool *mp);
+void bnxt_free_rx_mbufs(struct bnxt *bp);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
new file mode 100644
index 0000000..6f95eb7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -0,0 +1,369 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+#include <stdbool.h>
+
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+#include <rte_memory.h>
+
+#include "bnxt.h"
+#include "bnxt_rxr.h"
+#include "bnxt_rxq.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * RX Ring handling
+ */
+
+static inline struct rte_mbuf *__bnxt_alloc_rx_data(struct rte_mempool *mb)
+{
+ struct rte_mbuf *data;
+
+ data = __rte_mbuf_raw_alloc(mb);
+ __rte_mbuf_sanity_check(data, 0);
+
+ return data;
+}
+
+static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
+ struct bnxt_rx_ring_info *rxr,
+ uint16_t prod)
+{
+ struct rx_prod_pkt_bd *rxbd = &rxr->rx_desc_ring[prod];
+ struct bnxt_sw_rx_bd *rx_buf = &rxr->rx_buf_ring[prod];
+ struct rte_mbuf *data;
+
+ data = __bnxt_alloc_rx_data(rxq->mb_pool);
+ if (!data)
+ return -ENOMEM;
+
+ rx_buf->mbuf = data;
+
+ rxbd->addr_hi =
+ rte_cpu_to_le_32(U64_TO_U32_HI
+ (RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf)));
+ rxbd->addr_lo =
+ rte_cpu_to_le_32(U64_TO_U32_LO
+ (RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf)));
+
+ return 0;
+}
+
+static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+ struct rte_mbuf *mbuf)
+{
+ uint16_t prod = rxr->rx_prod;
+ struct bnxt_sw_rx_bd *prod_rx_buf;
+ struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+ prod_rx_buf = &rxr->rx_buf_ring[prod];
+
+ prod_rx_buf->mbuf = mbuf;
+
+ prod_bd = &rxr->rx_desc_ring[prod];
+ cons_bd = &rxr->rx_desc_ring[cons];
+
+ prod_bd->addr_hi = cons_bd->addr_hi;
+ prod_bd->addr_lo = cons_bd->addr_lo;
+}
+
+static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+ struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
+{
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = &rxq->rx_ring;
+ struct rx_pkt_cmpl *rxcmp;
+ struct rx_pkt_cmpl_hi *rxcmp1;
+ uint32_t tmp_raw_cons = *raw_cons;
+ uint16_t cons, prod, cp_cons =
+ RING_CMP(&cpr->cp_ring_struct, tmp_raw_cons);
+ struct bnxt_sw_rx_bd *rx_buf;
+ struct rte_mbuf *mbuf;
+ int rc = 0;
+
+ rxcmp = (struct rx_pkt_cmpl *)
+ &cpr->cp_desc_ring[cp_cons];
+
+ tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+ cp_cons = RING_CMP(&cpr->cp_ring_struct, tmp_raw_cons);
+ rxcmp1 = (struct rx_pkt_cmpl_hi *)&cpr->cp_desc_ring[cp_cons];
+
+ if (!CMP_VALID(rxcmp1, tmp_raw_cons, &cpr->cp_ring_struct))
+ return -EBUSY;
+
+ prod = rxr->rx_prod;
+
+ /* EW - GRO deferred to phase 3 */
+ cons = rxcmp->opaque;
+ rx_buf = &rxr->rx_buf_ring[cons];
+ mbuf = rx_buf->mbuf;
+ rte_prefetch0(mbuf);
+
+ mbuf->nb_segs = 1;
+ mbuf->next = NULL;
+ mbuf->pkt_len = rxcmp->len;
+ mbuf->data_len = mbuf->pkt_len;
+ mbuf->port = rxq->port_id;
+ mbuf->ol_flags = 0;
+ if (rxcmp->flags_type & RX_PKT_CMPL_FLAGS_RSS_VALID) {
+ mbuf->hash.rss = rxcmp->rss_hash;
+ mbuf->ol_flags |= PKT_RX_RSS_HASH;
+ } else {
+ mbuf->hash.fdir.id = rxcmp1->cfa_code;
+ mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+ }
+ if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
+ mbuf->vlan_tci = rxcmp1->metadata &
+ (RX_PKT_CMPL_METADATA_VID_MASK |
+ RX_PKT_CMPL_METADATA_DE |
+ RX_PKT_CMPL_METADATA_PRI_MASK);
+ mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+ }
+
+ rx_buf->mbuf = NULL;
+ if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
+ /* Re-install the mbuf back to the rx ring */
+ bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+
+ rc = -EIO;
+ goto next_rx;
+ }
+ /*
+ * TODO: Redesign this....
+ * If the allocation fails, the packet does not get received.
+ * Simply returning this will result in slowly falling behind
+ * on the producer ring buffers.
+ * Instead, "filling up" the producer just before ringing the
+ * doorbell could be a better solution since it will let the
+ * producer ring starve until memory is available again pushing
+ * the drops into hardware and getting them out of the driver
+ * allowing recovery to a full producer ring.
+ *
+ * This could also help with cache usage by preventing per-packet
+ * calls in favour of a tight loop with the same function being called
+ * in it.
+ */
+ if (bnxt_alloc_rx_data(rxq, rxr, prod)) {
+ RTE_LOG(ERR, PMD, "mbuf alloc failed with prod=0x%x\n", prod);
+ rc = -ENOMEM;
+ goto next_rx;
+ }
+
+ /* All MBUFs are allocated with the same size under DPDK,
+ no optimization for rx_copy_thresh */
+
+ /* AGG buf operation is deferred */
+
+ /* EW - VLAN reception. Must compare against the ol_flags */
+
+ *rx_pkt = mbuf;
+next_rx:
+ rxr->rx_prod = RING_NEXT(&rxr->rx_ring_struct, prod);
+
+ *raw_cons = tmp_raw_cons;
+
+ return rc;
+}
+
+uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts)
+{
+ struct bnxt_rx_queue *rxq = rx_queue;
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+ struct bnxt_rx_ring_info *rxr = &rxq->rx_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ int nb_rx_pkts = 0;
+ bool rx_event = false;
+ struct rx_pkt_cmpl *rxcmp;
+
+ /* Handle RX burst request */
+ while (1) {
+ int rc;
+
+ cons = RING_CMP(&cpr->cp_ring_struct, raw_cons);
+ rte_prefetch0(&cpr->cp_desc_ring[cons]);
+ rxcmp = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(rxcmp, raw_cons, &cpr->cp_ring_struct))
+ break;
+
+ /* TODO: Avoid magic numbers... */
+ if ((CMP_TYPE(rxcmp) & 0x30) == 0x10) {
+ rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
+ if (likely(!rc))
+ nb_rx_pkts++;
+ else if (rc == -EBUSY) /* partial completion */
+ break;
+ rx_event = true;
+ }
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ if (nb_rx_pkts == nb_pkts)
+ break;
+ }
+ if (raw_cons == cpr->cp_raw_cons) {
+ /* For PMD, there is no need to keep on pushing to REARM
+ the doorbell if there are no new completions */
+ return nb_rx_pkts;
+ }
+ cpr->cp_raw_cons = raw_cons;
+
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+ if (rx_event)
+ B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+ return nb_rx_pkts;
+}
+
+void bnxt_free_rx_rings(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < (int)bp->rx_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_ring_struct *ring;
+
+ if (!rxq)
+ continue;
+
+ rxr = &rxq->rx_ring;
+
+ rte_free(rxr->rx_tpa);
+ rxr->rx_tpa = NULL;
+
+ ring = &rxr->rx_ring_struct;
+ bnxt_free_ring(ring);
+
+ cpr = &rxq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ bnxt_free_ring(ring);
+
+ rte_free(rxq);
+ bp->rx_queues[i] = NULL;
+ }
+}
+
+void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt *bp = rxq->bp;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_ring_struct *ring;
+
+ rxq->rx_buf_use_size = bp->eth_dev->data->mtu +
+ ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE;
+ rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
+
+ rxr = &rxq->rx_ring;
+ ring = &rxr->rx_ring_struct;
+ ring->ring_size = rte_align32pow2(rxq->nb_rx_desc);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)rxr->rx_desc_ring;
+ ring->bd_dma = rxr->rx_desc_mapping;
+ ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+ ring->vmem = (void **)&rxr->rx_buf_ring;
+
+ cpr = &rxq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ ring->ring_size = rxr->rx_ring_struct.ring_size * 2;
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)cpr->cp_desc_ring;
+ ring->bd_dma = cpr->cp_desc_mapping;
+ ring->vmem_size = 0;
+ ring->vmem = NULL;
+}
+
+static void bnxt_init_rxbds(struct bnxt_ring_struct *ring, uint32_t type,
+ uint16_t len)
+{
+ uint32_t j;
+ struct rx_prod_pkt_bd *rx_bd_ring = (struct rx_prod_pkt_bd *)ring->bd;
+
+ if (!rx_bd_ring)
+ return;
+ for (j = 0; j < ring->ring_size; j++) {
+ rx_bd_ring[j].flags_type = type;
+ rx_bd_ring[j].len = len;
+ rx_bd_ring[j].opaque = j;
+ }
+}
+
+int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
+{
+ struct bnxt_rx_ring_info *rxr;
+ struct bnxt_ring_struct *ring;
+ uint32_t prod, type;
+ unsigned i;
+
+ type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+
+/* XXX
+ if (NET_IP_ALIGN == 2)
+ type |= RX_BD_FLAGS_SOP;
+*/
+
+ rxr = &rxq->rx_ring;
+ ring = &rxr->rx_ring_struct;
+ bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
+
+ prod = rxr->rx_prod;
+ for (i = 0; i < ring->ring_size; i++) {
+ if (bnxt_alloc_rx_data(rxq, rxr, prod) != 0) {
+ RTE_LOG(WARNING, PMD,
+ "init'ed rx ring %d with %d/%d mbufs only\n",
+ rxq->queue_id, i, ring->ring_size);
+ break;
+ }
+ rxr->rx_prod = prod;
+ prod = RING_NEXT(&rxr->rx_ring_struct, prod);
+ }
+
+ if (rxr->rx_tpa) {
+ struct rte_mbuf *data;
+
+ for (i = 0; i < MAX_TPA; i++) {
+ data = __bnxt_alloc_rx_data(rxq->mb_pool);
+ if (!data)
+ return -ENOMEM;
+
+ rxr->rx_tpa[i].data = data;
+ rxr->rx_tpa[i].mapping =
+ rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(data));
+ }
+ }
+
+ return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
new file mode 100644
index 0000000..ecbca69
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -0,0 +1,73 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_RXR_H_
+#define _BNXT_RXR_H_
+
+#define B_RX_DB(db, prod) \
+ (*(uint32_t *)db = (DB_KEY_RX | prod))
+
+struct bnxt_tpa_info {
+ struct rte_mbuf *data;
+ phys_addr_t mapping;
+ uint16_t len;
+ uint32_t flags2;
+ uint32_t metadata;
+ uint32_t rss_hash;
+};
+
+struct bnxt_sw_rx_bd {
+ struct rte_mbuf *mbuf; /* data associated with RX descriptor */
+};
+
+struct bnxt_rx_ring_info {
+ uint16_t rx_prod;
+ void *rx_doorbell;
+
+ struct rx_prod_pkt_bd *rx_desc_ring;
+ struct bnxt_sw_rx_bd *rx_buf_ring; /* sw ring */
+
+ phys_addr_t rx_desc_mapping;
+
+ struct bnxt_tpa_info *rx_tpa;
+
+ struct bnxt_ring_struct rx_ring_struct;
+};
+
+uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts);
+void bnxt_free_rx_rings(struct bnxt *bp);
+void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq);
+int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
new file mode 100644
index 0000000..34ebecf
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -0,0 +1,190 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_stats.h"
+#include "bnxt_txq.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * Statistics functions
+ */
+
+void bnxt_free_stats(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < (int)bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+
+ bnxt_free_txq_stats(txq);
+ }
+ for (i = 0; i < (int)bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+
+ bnxt_free_rxq_stats(rxq);
+ }
+}
+
+void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_stats *bnxt_stats)
+{
+ unsigned i;
+ struct bnxt *bp = eth_dev->data->dev_private;
+#ifndef FUNC_QSTATS_BROKEN
+ struct hwrm_func_qstats_output fstats;
+#endif
+#ifndef PORT_QSTATS_BROKEN
+ struct hwrm_port_qstats_output pstats;
+#endif
+
+ memset(bnxt_stats, 0, sizeof(*bnxt_stats));
+
+ for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+ struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+ struct bnxt_cp_ring_info *cpr = &rxq->cp_ring;
+ struct ctx_hw_stats64 *hw_stats =
+ (struct ctx_hw_stats64 *)cpr->hw_stats;
+
+ bnxt_stats->q_ipackets[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_ucast_pkts);
+ bnxt_stats->q_ipackets[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_mcast_pkts);
+ bnxt_stats->q_ipackets[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_bcast_pkts);
+
+ bnxt_stats->q_ibytes[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_ucast_bytes);
+ bnxt_stats->q_ibytes[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_mcast_bytes);
+ bnxt_stats->q_ibytes[i] +=
+ rte_le_to_cpu_64(hw_stats->rx_bcast_bytes);
+
+ /*
+ * TBD: No clear mapping to this... we don't seem
+ * to have a stat specifically for dropped due to
+ * insufficient mbufs.
+ */
+ bnxt_stats->q_errors[i] = 0;
+
+ /* These get replaced once the *_QSTATS commands work */
+ bnxt_stats->ipackets += bnxt_stats->q_ipackets[i];
+ bnxt_stats->ibytes += bnxt_stats->q_ibytes[i];
+ bnxt_stats->imissed += bnxt_stats->q_errors[i];
+ bnxt_stats->ierrors +=
+ rte_le_to_cpu_64(hw_stats->rx_err_pkts);
+ bnxt_stats->imcasts +=
+ rte_le_to_cpu_64(hw_stats->rx_mcast_pkts);
+ }
+
+ for (i = 0; i < bp->tx_cp_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_cp_ring_info *cpr = &txq->cp_ring;
+ struct ctx_hw_stats64 *hw_stats =
+ (struct ctx_hw_stats64 *)cpr->hw_stats;
+
+ bnxt_stats->q_opackets[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_ucast_pkts);
+ bnxt_stats->q_opackets[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_mcast_pkts);
+ bnxt_stats->q_opackets[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_bcast_pkts);
+
+ bnxt_stats->q_obytes[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_ucast_bytes);
+ bnxt_stats->q_obytes[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_mcast_bytes);
+ bnxt_stats->q_obytes[i] +=
+ rte_le_to_cpu_64(hw_stats->tx_bcast_bytes);
+
+ /* These get replaced once the *_QSTATS commands work */
+ bnxt_stats->opackets += bnxt_stats->q_opackets[i];
+ bnxt_stats->obytes += bnxt_stats->q_obytes[i];
+ bnxt_stats->oerrors += rte_le_to_cpu_64(hw_stats->tx_drop_pkts);
+ bnxt_stats->oerrors += rte_le_to_cpu_64(hw_stats->tx_err_pkts);
+ }
+
+#ifndef FUNC_QSTATS_BROKEN
+ if (bnxt_hwrm_func_qstats(bp, &fstats) == 0) {
+ bnxt_stats->ipackets = fstats.rx_ucast_pkts +
+ fstats.rx_mcast_pkts + fstats.rx_bcast_pkts +
+ fstats.rx_err_pkts;
+ bnxt_stats->opackets = fstats.tx_ucast_pkts +
+ fstats.tx_mcast_pkts + fstats.tx_bcast_pkts +
+ fstats.tx_err_pkts;
+ bnxt_stats->ibytes = fstats.rx_ucast_bytes +
+ fstats.rx_mcast_bytes + fstats.rx_bcast_bytes;
+ bnxt_stats->obytes = fstats.tx_ucast_bytes +
+ fstats.tx_mcast_bytes + fstats.tx_bcast_bytes;
+ bnxt_stats->ierrors = fstats.rx_err_pkts;
+ bnxt_stats->oerrors = fstats.tx_err_pkts;
+ bnxt_stats->imcasts = fstats.rx_mcast_pkts;
+ /*
+ * TBD: No clear mapping to this... we don't seem
+ * to have a stat specifically for dropped due to
+ * insufficient mbufs.
+ */
+ bnxt_stats->imissed = 0;
+ }
+#endif
+
+#ifndef PORT_QSTATS_BROKEN
+ if (bnxt_hwrm_port_qstats(bp, &pstats) != 0)
+ return;
+
+ bnxt_stats->ipackets = pstats.rx_total_pkts;
+ bnxt_stats->opackets = pstats.tx_good_pkts;
+ bnxt_stats->ibytes = pstats.rx_bytes;
+ bnxt_stats->obytes = pstats.tx_bytes;
+ bnxt_stats->ibadcrc = pstats.rx_fcs_err_pkts;
+ bnxt_stats->ibadlen = pstats.rx_ovrsz_pkts;
+ bnxt_stats->ierrors = pstats.rx_total_pkts - pstats.rx_good_pkts;
+ bnxt_stats->oerrors = pstats.tx_err_pkts;
+ bnxt_stats->imcasts = pstats.rx_mcast_pkts;
+#endif
+}
+
+void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+ bnxt_clear_all_hwrm_stat_ctxs(bp);
+ bnxt_hwrm_func_clr_stats(bp);
+ bnxt_hwrm_port_clr_stats(bp);
+}
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
new file mode 100644
index 0000000..65408a4
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -0,0 +1,44 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_STATS_H_
+#define _BNXT_STATS_H_
+
+#include <rte_ethdev.h>
+
+void bnxt_free_stats(struct bnxt *bp);
+void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
+ struct rte_eth_stats *bnxt_stats);
+void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
new file mode 100644
index 0000000..426ff13
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -0,0 +1,164 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_txq.h"
+
+/*
+ * TX Queues
+ */
+
+void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_cp_ring_info *cpr = &txq->cp_ring;
+
+ /* 'Unreserve' rte_memzone */
+ /* N/A */
+
+ if (cpr->hw_stats)
+ cpr->hw_stats = NULL;
+}
+
+static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_sw_tx_bd *sw_ring;
+ uint16_t i;
+
+ sw_ring = txq->tx_ring.tx_buf_ring;
+ if (sw_ring) {
+ for (i = 0; i < txq->tx_ring.tx_ring_struct.ring_size; i++) {
+ if (sw_ring[i].mbuf) {
+ rte_pktmbuf_free(sw_ring[i].mbuf);
+ sw_ring[i].mbuf = NULL;
+ }
+ }
+ }
+}
+
+void bnxt_free_tx_mbufs(struct bnxt *bp)
+{
+ struct bnxt_tx_queue *txq;
+ int i;
+
+ for (i = 0; i < (int)bp->tx_nr_rings; i++) {
+ txq = bp->tx_queues[i];
+ bnxt_tx_queue_release_mbufs(txq);
+ }
+}
+
+void bnxt_tx_queue_release_op(void *tx_queue)
+{
+ struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_ring_struct *ring;
+
+ if (txq) {
+ /* Free TX ring hardware descriptors */
+ bnxt_tx_queue_release_mbufs(txq);
+ txr = &txq->tx_ring;
+ ring = &txr->tx_ring_struct;
+ bnxt_free_ring(ring);
+
+ /* Free TX completion ring hardware descriptors */
+ cpr = &txq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ bnxt_free_ring(ring);
+
+ bnxt_free_txq_stats(txq);
+
+ rte_free(txq);
+ }
+}
+
+int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf)
+{
+ struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+ struct bnxt_tx_queue *txq;
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_cp_ring_info *cpr;
+
+ if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {
+ RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+ return -EINVAL;
+ }
+
+ if (eth_dev->data->tx_queues) {
+ txq = eth_dev->data->tx_queues[queue_idx];
+ if (txq) {
+ bnxt_tx_queue_release_op(txq);
+ txq = NULL;
+ }
+ }
+ txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
+ RTE_CACHE_LINE_SIZE, socket_id);
+ if (txq == NULL) {
+ RTE_LOG(ERR, PMD, "bnxt_tx_queue allocation failed!");
+ return -ENOMEM;
+ }
+ txq->bp = bp;
+ txq->nb_tx_desc = nb_desc;
+ txq->tx_free_thresh = tx_conf->tx_free_thresh;
+
+ bnxt_init_tx_ring_struct(txq);
+
+ txq->queue_id = queue_idx;
+ txq->port_id = eth_dev->data->port_id;
+
+ txr = &txq->tx_ring;
+ cpr = &txq->cp_ring;
+
+ /* Allocate TX ring hardware descriptors */
+ if (bnxt_alloc_rings(bp, queue_idx, txr, NULL, cpr, "bnxt_tx_ring")) {
+ RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for tx_ring failed!");
+ bnxt_tx_queue_release_op(txq);
+ return -ENOMEM;
+ }
+
+ if (bnxt_init_one_tx_ring(txq)) {
+ RTE_LOG(ERR, PMD, "bnxt_init_one_tx_ring failed!");
+ bnxt_tx_queue_release_op(txq);
+ return -ENOMEM;
+ }
+
+ eth_dev->data->tx_queues[queue_idx] = txq;
+ return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_txq.h b/drivers/net/bnxt/bnxt_txq.h
new file mode 100644
index 0000000..4372527
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.h
@@ -0,0 +1,76 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_TXQ_H_
+#define _BNXT_TXQ_H_
+
+/* TODO make bnxt_tx_queue.cp_ring and bnxt_tx_queue.tx_ring pointers */
+#include "bnxt_txr.h"
+
+struct bnxt_tx_queue {
+ uint16_t nb_tx_desc; /* number of TX descriptors */
+ uint16_t tx_free_thresh;/* minimum TX before freeing */
+ /** Index to last TX descriptor to have been cleaned. */
+ uint16_t last_desc_cleaned;
+ /** Total number of TX descriptors ready to be allocated. */
+ uint16_t tx_next_dd; /* next desc to scan for DD bit */
+ uint16_t tx_next_rs; /* next desc to set RS bit */
+ uint16_t queue_id; /* TX queue index */
+ uint16_t reg_idx; /* TX queue register index */
+ uint8_t port_id; /* Device port identifier */
+ uint8_t pthresh; /* Prefetch threshold register */
+ uint8_t hthresh; /* Host threshold register */
+ uint8_t wthresh; /* Write-back threshold reg */
+ uint32_t txq_flags; /* Holds flags for this TXq */
+ uint32_t ctx_curr; /* Hardware context states */
+ uint8_t tx_deferred_start; /* not in global dev start */
+
+ struct bnxt *bp;
+ int index;
+ int tx_wake_thresh;
+ struct bnxt_tx_ring_info tx_ring;
+
+ unsigned cp_nr_rings;
+ struct bnxt_cp_ring_info cp_ring;
+};
+
+void bnxt_free_txq_stats(struct bnxt_tx_queue *txq);
+void bnxt_free_tx_mbufs(struct bnxt *bp);
+void bnxt_tx_queue_release_op(void *tx_queue);
+int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
+ uint16_t queue_idx,
+ uint16_t nb_desc,
+ unsigned int socket_id,
+ const struct rte_eth_txconf *tx_conf);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
new file mode 100644
index 0000000..61348fc
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -0,0 +1,326 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_byteorder.h>
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_txq.h"
+#include "bnxt_txr.h"
+#include "hsi_struct_def_dpdk.h"
+#include <stdbool.h>
+
+/*
+ * TX Ring handling
+ */
+
+void bnxt_free_tx_rings(struct bnxt *bp)
+{
+ int i;
+
+ for (i = 0; i < (int)bp->tx_nr_rings; i++) {
+ struct bnxt_tx_queue *txq = bp->tx_queues[i];
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_ring_struct *ring;
+
+ if (!txq)
+ continue;
+
+ txr = &txq->tx_ring;
+
+ ring = &txr->tx_ring_struct;
+ bnxt_free_ring(ring);
+
+ cpr = &txq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ bnxt_free_ring(ring);
+
+ rte_free(txq);
+ bp->tx_queues[i] = NULL;
+ }
+}
+
+int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_tx_ring_info *txr = &txq->tx_ring;
+ struct bnxt_ring_struct *ring = &txr->tx_ring_struct;
+
+ txq->tx_wake_thresh = ring->ring_size / 2;
+ ring->fw_ring_id = INVALID_HW_RING_ID;
+
+ return 0;
+}
+
+void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_cp_ring_info *cpr;
+ struct bnxt_tx_ring_info *txr;
+ struct bnxt_ring_struct *ring;
+
+ txr = &txq->tx_ring;
+ ring = &txr->tx_ring_struct;
+ ring->ring_size = rte_align32pow2(txq->nb_tx_desc + 1);
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)txr->tx_desc_ring;
+ ring->bd_dma = txr->tx_desc_mapping;
+ ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_tx_bd);
+ ring->vmem = (void **)&txr->tx_buf_ring;
+
+ cpr = &txq->cp_ring;
+ ring = &cpr->cp_ring_struct;
+ ring->ring_size = txr->tx_ring_struct.ring_size;
+ ring->ring_mask = ring->ring_size - 1;
+ ring->bd = (void *)cpr->cp_desc_ring;
+ ring->bd_dma = cpr->cp_desc_mapping;
+ ring->vmem_size = 0;
+ ring->vmem = NULL;
+}
+
+static inline uint32_t bnxt_tx_avail(struct bnxt_tx_ring_info *txr)
+{
+ /* Tell compiler to fetch tx indices from memory. */
+ rte_compiler_barrier();
+
+ return txr->tx_ring_struct.ring_size -
+ ((txr->tx_prod - txr->tx_cons) &
+ txr->tx_ring_struct.ring_mask) - 1;
+}
+
+static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
+ struct bnxt_tx_queue *txq)
+{
+ struct bnxt_tx_ring_info *txr = &txq->tx_ring;
+ struct tx_bd_long *txbd;
+ struct tx_bd_long_hi *txbd1;
+ uint32_t vlan_tag_flags, cfa_action;
+ bool long_bd = false;
+ uint16_t last_prod = 0;
+ struct rte_mbuf *m_seg;
+ struct bnxt_sw_tx_bd *tx_buf;
+ static const uint32_t lhint_arr[4] = {
+ TX_BD_LONG_FLAGS_LHINT_LT512,
+ TX_BD_LONG_FLAGS_LHINT_LT1K,
+ TX_BD_LONG_FLAGS_LHINT_LT2K,
+ TX_BD_LONG_FLAGS_LHINT_LT2K
+ };
+
+ if (tx_pkt->ol_flags & (PKT_TX_TCP_SEG | PKT_TX_TCP_CKSUM |
+ PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM |
+ PKT_TX_VLAN_PKT))
+ long_bd = true;
+
+ tx_buf = &txr->tx_buf_ring[txr->tx_prod];
+ tx_buf->mbuf = tx_pkt;
+ tx_buf->nr_bds = long_bd + tx_pkt->nb_segs;
+ last_prod = (txr->tx_prod + tx_buf->nr_bds - 1) &
+ txr->tx_ring_struct.ring_mask;
+
+ if (unlikely(bnxt_tx_avail(txr) < tx_buf->nr_bds))
+ return -ENOMEM;
+
+ txbd = &txr->tx_desc_ring[txr->tx_prod];
+ txbd->opaque = txr->tx_prod;
+ txbd->flags_type = tx_buf->nr_bds << TX_BD_LONG_FLAGS_BD_CNT_SFT;
+ txbd->len = tx_pkt->data_len;
+ if (txbd->len >= 2014)
+ txbd->flags_type |= TX_BD_LONG_FLAGS_LHINT_GTE2K;
+ else
+ txbd->flags_type |= lhint_arr[txbd->len >> 9];
+ txbd->addr_hi =
+ rte_cpu_to_le_32(U64_TO_U32_HI
+ (RTE_MBUF_DATA_DMA_ADDR(tx_buf->mbuf)));
+ txbd->addr_lo =
+ rte_cpu_to_le_32(U64_TO_U32_LO
+ (RTE_MBUF_DATA_DMA_ADDR(tx_buf->mbuf)));
+
+ if (long_bd) {
+ txbd->flags_type |= TX_BD_LONG_TYPE_TX_BD_LONG;
+ vlan_tag_flags = 0;
+ cfa_action = 0;
+ if (tx_buf->mbuf->ol_flags & PKT_TX_VLAN_PKT) {
+ /* shurd: Should this mask at
+ * TX_BD_LONG_CFA_META_VLAN_VID_MASK?
+ */
+ vlan_tag_flags = TX_BD_LONG_CFA_META_KEY_VLAN_TAG |
+ tx_buf->mbuf->vlan_tci;
+ /* Currently supports 8021Q, 8021AD vlan offloads
+ * QINQ1, QINQ2, QINQ3 vlan headers are deprecated
+ */
+ /* DPDK only supports 802.11q VLAN packets */
+ vlan_tag_flags |=
+ TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;
+ }
+
+ txr->tx_prod = RING_NEXT(&txr->tx_ring_struct, txr->tx_prod);
+
+ txbd1 = (struct tx_bd_long_hi *)
+ &txr->tx_desc_ring[txr->tx_prod];
+ txbd1->lflags = 0;
+ txbd1->cfa_meta = vlan_tag_flags;
+ txbd1->cfa_action = cfa_action;
+
+ if (tx_pkt->ol_flags & PKT_TX_TCP_SEG) {
+ /* TSO */
+ txbd1->lflags = TX_BD_LONG_LFLAGS_LSO;
+ txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
+ tx_pkt->l4_len;
+ txbd1->mss = tx_pkt->tso_segsz;
+
+ } else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM |
+ PKT_TX_UDP_CKSUM)) {
+ /* TCP/UDP CSO */
+ txbd1->lflags = TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM;
+ txbd1->mss = 0;
+
+ } else if (tx_pkt->ol_flags & PKT_TX_IP_CKSUM) {
+ /* IP CSO */
+ txbd1->lflags = TX_BD_LONG_LFLAGS_IP_CHKSUM;
+ txbd1->mss = 0;
+ }
+ } else {
+ txbd->flags_type |= TX_BD_SHORT_TYPE_TX_BD_SHORT;
+ }
+
+ m_seg = tx_pkt->next;
+ /* i is set at the end of the if(long_bd) block */
+ while (txr->tx_prod < last_prod) {
+ txr->tx_prod = RING_NEXT(&txr->tx_ring_struct, txr->tx_prod);
+ tx_buf = &txr->tx_buf_ring[txr->tx_prod];
+
+ txbd = &txr->tx_desc_ring[txr->tx_prod];
+ txbd->addr_hi =
+ rte_cpu_to_le_32(U64_TO_U32_HI
+ (RTE_MBUF_DATA_DMA_ADDR(m_seg)));
+ txbd->addr_lo =
+ rte_cpu_to_le_32(U64_TO_U32_LO
+ (RTE_MBUF_DATA_DMA_ADDR(m_seg)));
+ txbd->flags_type = TX_BD_SHORT_TYPE_TX_BD_SHORT;
+ txbd->len = m_seg->data_len;
+
+ m_seg = m_seg->next;
+ }
+
+ txbd->flags_type |= TX_BD_LONG_FLAGS_PACKET_END;
+
+ txr->tx_prod = RING_NEXT(&txr->tx_ring_struct, txr->tx_prod);
+
+ return 0;
+}
+
+static void bnxt_tx_cmp(struct bnxt_tx_queue *txq, int nr_pkts)
+{
+ struct bnxt_tx_ring_info *txr = &txq->tx_ring;
+ uint16_t cons = txr->tx_cons;
+ int i, j;
+
+ for (i = 0; i < nr_pkts; i++) {
+ struct bnxt_sw_tx_bd *tx_buf;
+ struct rte_mbuf *mbuf;
+
+ tx_buf = &txr->tx_buf_ring[cons];
+ cons = RING_NEXT(&txr->tx_ring_struct, cons);
+ mbuf = tx_buf->mbuf;
+ tx_buf->mbuf = NULL;
+
+ /* EW - no need to unmap DMA memory? */
+
+ for (j = 1; j < tx_buf->nr_bds; j++)
+ cons = RING_NEXT(&txr->tx_ring_struct, cons);
+ rte_pktmbuf_free(mbuf);
+ }
+
+ txr->tx_cons = cons;
+}
+
+static int bnxt_handle_tx_cp(struct bnxt_tx_queue *txq)
+{
+ struct bnxt_cp_ring_info *cpr = &txq->cp_ring;
+ uint32_t raw_cons = cpr->cp_raw_cons;
+ uint32_t cons;
+ int nb_tx_pkts = 0;
+ struct tx_cmpl *txcmp;
+
+ if ((txq->tx_ring.tx_ring_struct.ring_size -
+ (bnxt_tx_avail(&txq->tx_ring))) >
+ txq->tx_free_thresh) {
+ while (1) {
+ cons = RING_CMP(&cpr->cp_ring_struct, raw_cons);
+ txcmp = (struct tx_cmpl *)&cpr->cp_desc_ring[cons];
+
+ if (!CMP_VALID(txcmp, raw_cons, &cpr->cp_ring_struct))
+ break;
+
+ if (CMP_TYPE(txcmp) == TX_CMPL_TYPE_TX_L2)
+ nb_tx_pkts++;
+ else
+ RTE_LOG(DEBUG, PMD,
+ "Unhandled CMP type %02x\n",
+ CMP_TYPE(txcmp));
+ raw_cons = NEXT_RAW_CMP(raw_cons);
+ }
+ if (nb_tx_pkts)
+ bnxt_tx_cmp(txq, nb_tx_pkts);
+ cpr->cp_raw_cons = raw_cons;
+ B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
+ }
+ return nb_tx_pkts;
+}
+
+uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts)
+{
+ struct bnxt_tx_queue *txq = tx_queue;
+ uint16_t nb_tx_pkts = 0;
+ uint16_t db_mask = txq->tx_ring.tx_ring_struct.ring_size >> 2;
+ uint16_t last_db_mask = 0;
+
+ /* Handle TX completions */
+ bnxt_handle_tx_cp(txq);
+
+ /* Handle TX burst request */
+ for (nb_tx_pkts = 0; nb_tx_pkts < nb_pkts; nb_tx_pkts++) {
+ if (bnxt_start_xmit(tx_pkts[nb_tx_pkts], txq)) {
+ break;
+ } else if ((nb_tx_pkts & db_mask) != last_db_mask) {
+ B_TX_DB(txq->tx_ring.tx_doorbell, txq->tx_ring.tx_prod);
+ last_db_mask = nb_tx_pkts & db_mask;
+ }
+ }
+ if (nb_tx_pkts)
+ B_TX_DB(txq->tx_ring.tx_doorbell, txq->tx_ring.tx_prod);
+
+ return nb_tx_pkts;
+}
diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h
new file mode 100644
index 0000000..d5cc68c
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -0,0 +1,71 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_TXR_H_
+#define _BNXT_TXR_H_
+
+#define MAX_TX_RINGS 16
+#define BNXT_TX_PUSH_THRESH 92
+
+#define B_TX_DB(db, prod) \
+ (*(uint32_t *)db = (DB_KEY_TX | prod))
+
+struct bnxt_tx_ring_info {
+ uint16_t tx_prod;
+ uint16_t tx_cons;
+ void *tx_doorbell;
+
+ struct tx_bd_long *tx_desc_ring;
+ struct bnxt_sw_tx_bd *tx_buf_ring;
+
+ phys_addr_t tx_desc_mapping;
+
+#define BNXT_DEV_STATE_CLOSING 0x1
+ uint32_t dev_state;
+
+ struct bnxt_ring_struct tx_ring_struct;
+};
+
+struct bnxt_sw_tx_bd {
+ struct rte_mbuf *mbuf; /* mbuf associated with TX descriptor */
+ uint8_t is_gso;
+ unsigned short nr_bds;
+};
+
+void bnxt_free_tx_rings(struct bnxt *bp);
+int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq);
+void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq);
+uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
+ uint16_t nb_pkts);
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
new file mode 100644
index 0000000..e8c0658
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -0,0 +1,285 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 <inttypes.h>
+
+#include <rte_memzone.h>
+#include <rte_malloc.h>
+
+#include "bnxt.h"
+#include "bnxt_vnic.h"
+#include "hsi_struct_def_dpdk.h"
+
+/*
+ * VNIC Functions
+ */
+
+static void prandom_bytes(void *dest_ptr, size_t len)
+{
+ char *dest = (char *)dest_ptr;
+ uint64_t rb;
+
+ while (len) {
+ rb = rte_rand();
+ if (len >= 8) {
+ memcpy(dest, &rb, 8);
+ len -= 8;
+ dest += 8;
+ } else {
+ memcpy(dest, &rb, len);
+ dest += len;
+ len = 0;
+ }
+ }
+}
+
+void bnxt_init_vnics(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ uint16_t max_vnics;
+ int i, j;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_vnics = pf->max_vnics;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_vnics = vf->max_vnics;
+ }
+ STAILQ_INIT(&bp->free_vnic_list);
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ vnic->fw_vnic_id = INVALID_HW_RING_ID;
+ vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+ vnic->ctx_is_rss_cos_lb = HW_CONTEXT_NONE;
+
+ for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
+ vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;
+
+ prandom_bytes(vnic->rss_hash_key, HW_HASH_KEY_SIZE);
+ STAILQ_INIT(&vnic->filter);
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic, next);
+ }
+ for (i = 0; i < MAX_FF_POOLS; i++)
+ STAILQ_INIT(&bp->ff_pool[i]);
+}
+
+int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int pool)
+{
+ struct bnxt_vnic_info *temp;
+
+ temp = STAILQ_FIRST(&bp->ff_pool[pool]);
+ while (temp) {
+ if (temp == vnic) {
+ STAILQ_REMOVE(&bp->ff_pool[pool], vnic,
+ bnxt_vnic_info, next);
+ vnic->fw_vnic_id = INVALID_HW_RING_ID;
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, vnic,
+ next);
+ return 0;
+ }
+ temp = STAILQ_NEXT(temp, next);
+ }
+ RTE_LOG(ERR, PMD, "VNIC %p is not found in pool[%d]\n", vnic, pool);
+ return -EINVAL;
+}
+
+struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+
+ /* Find the 1st unused vnic from the free_vnic_list pool*/
+ vnic = STAILQ_FIRST(&bp->free_vnic_list);
+ if (!vnic) {
+ RTE_LOG(ERR, PMD, "No more free VNIC resources\n");
+ return NULL;
+ }
+ STAILQ_REMOVE_HEAD(&bp->free_vnic_list, next);
+ return vnic;
+}
+
+void bnxt_free_all_vnics(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *temp, *next;
+ int i;
+
+ for (i = 0; i < MAX_FF_POOLS; i++) {
+ temp = STAILQ_FIRST(&bp->ff_pool[i]);
+ while (temp) {
+ next = STAILQ_NEXT(temp, next);
+ STAILQ_REMOVE(&bp->ff_pool[i], temp, bnxt_vnic_info,
+ next);
+ STAILQ_INSERT_TAIL(&bp->free_vnic_list, temp, next);
+ temp = next;
+ }
+ }
+}
+
+void bnxt_free_vnic_attributes(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+
+ STAILQ_FOREACH(vnic, &bp->free_vnic_list, next) {
+ if (vnic->rss_table) {
+ /* 'Unreserve' the rss_table */
+ /* N/A */
+
+ vnic->rss_table = NULL;
+ }
+
+ if (vnic->rss_hash_key) {
+ /* 'Unreserve' the rss_hash_key */
+ /* N/A */
+
+ vnic->rss_hash_key = NULL;
+ }
+ }
+}
+
+int bnxt_alloc_vnic_attributes(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ struct rte_pci_device *pdev = bp->pdev;
+ const struct rte_memzone *mz;
+ char mz_name[RTE_MEMZONE_NAMESIZE];
+ int entry_length = RTE_CACHE_LINE_ROUNDUP(
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
+ HW_HASH_KEY_SIZE);
+ uint16_t max_vnics;
+ int i, rc = 0;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_vnics = pf->max_vnics;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_vnics = vf->max_vnics;
+ }
+ snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+ "bnxt_%04x:%02x:%02x:%02x_vnicattr", pdev->addr.domain,
+ pdev->addr.bus, pdev->addr.devid, pdev->addr.function);
+ mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+ mz = rte_memzone_lookup(mz_name);
+ if (!mz) {
+ mz = rte_memzone_reserve(mz_name,
+ entry_length * max_vnics,
+ SOCKET_ID_ANY,
+ RTE_MEMZONE_2MB |
+ RTE_MEMZONE_SIZE_HINT_ONLY);
+ if (!mz)
+ return -ENOMEM;
+ }
+
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+
+ /* Allocate rss table and hash key */
+ vnic->rss_table =
+ (void *)((char *)mz->addr + (entry_length * i));
+ memset(vnic->rss_table, -1, entry_length);
+
+ vnic->rss_table_dma_addr = mz->phys_addr + (entry_length * i);
+ vnic->rss_hash_key = (void *)((char *)vnic->rss_table +
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table));
+
+ vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
+ HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+
+ if (!vnic->rss_table) {
+ rc = -ENOMEM;
+ goto out;
+ }
+ }
+ return 0;
+
+out:
+ return rc;
+}
+
+void bnxt_free_vnic_mem(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic;
+ uint16_t max_vnics, i;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_vnics = pf->max_vnics;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_vnics = vf->max_vnics;
+ }
+ for (i = 0; i < max_vnics; i++) {
+ vnic = &bp->vnic_info[i];
+ if (vnic->fw_vnic_id != INVALID_HW_RING_ID) {
+ RTE_LOG(ERR, PMD, "VNIC is not freed yet!\n");
+ /* Call HWRM to free VNIC */
+ }
+ vnic->fw_vnic_id = INVALID_HW_RING_ID;
+ }
+
+ rte_free(bp->vnic_info);
+ bp->vnic_info = NULL;
+}
+
+int bnxt_alloc_vnic_mem(struct bnxt *bp)
+{
+ struct bnxt_vnic_info *vnic_mem;
+ uint16_t max_vnics;
+
+ if (BNXT_PF(bp)) {
+ struct bnxt_pf_info *pf = &bp->pf;
+
+ max_vnics = pf->max_vnics;
+ } else {
+ struct bnxt_vf_info *vf = &bp->vf;
+
+ max_vnics = vf->max_vnics;
+ }
+ /* Allocate memory for VNIC pool and filter pool */
+ vnic_mem = rte_zmalloc("bnxt_vnic_info",
+ max_vnics * sizeof(struct bnxt_vnic_info), 0);
+ if (vnic_mem == NULL) {
+ RTE_LOG(ERR, PMD, "Failed to alloc memory for %d VNICs",
+ max_vnics);
+ return -ENOMEM;
+ }
+ bp->vnic_info = vnic_mem;
+ return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
new file mode 100644
index 0000000..9671ba4
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -0,0 +1,80 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _BNXT_VNIC_H_
+#define _BNXT_VNIC_H_
+
+#include <sys/queue.h>
+#include <stdbool.h>
+
+struct bnxt_vnic_info {
+ STAILQ_ENTRY(bnxt_vnic_info) next;
+ uint8_t ff_pool_idx;
+
+ uint16_t fw_vnic_id; /* returned by Chimp during alloc */
+ uint16_t fw_rss_cos_lb_ctx;
+ uint16_t ctx_is_rss_cos_lb;
+#define MAX_NUM_TRAFFIC_CLASSES 8
+#define MAX_NUM_RSS_QUEUES_PER_VNIC 16
+#define MAX_QUEUES_PER_VNIC (MAX_NUM_RSS_QUEUES_PER_VNIC + \
+ MAX_NUM_TRAFFIC_CLASSES)
+ uint16_t start_grp_id;
+ uint16_t end_grp_id;
+ uint16_t fw_grp_ids[MAX_QUEUES_PER_VNIC];
+ uint16_t hash_type;
+ phys_addr_t rss_table_dma_addr;
+ uint16_t *rss_table;
+ phys_addr_t rss_hash_key_dma_addr;
+ void *rss_hash_key;
+ uint32_t flags;
+#define BNXT_VNIC_INFO_PROMISC (1 << 0)
+#define BNXT_VNIC_INFO_ALLMULTI (1 << 1)
+
+ bool vlan_strip;
+ bool func_default;
+
+ STAILQ_HEAD(, bnxt_filter_info) filter;
+};
+
+struct bnxt;
+void bnxt_init_vnics(struct bnxt *bp);
+int bnxt_free_vnic(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+ int pool);
+struct bnxt_vnic_info *bnxt_alloc_vnic(struct bnxt *bp);
+void bnxt_free_all_vnics(struct bnxt *bp);
+void bnxt_free_vnic_attributes(struct bnxt *bp);
+int bnxt_alloc_vnic_attributes(struct bnxt *bp);
+void bnxt_free_vnic_mem(struct bnxt *bp);
+int bnxt_alloc_vnic_mem(struct bnxt *bp);
+
+#endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
new file mode 100644
index 0000000..5c20c17
--- /dev/null
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -0,0 +1,1832 @@
+/*-
+ * BSD LICENSE
+ *
+ * Copyright(c) 2014-2015 Broadcom 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:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name of Broadcom 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 _HSI_STRUCT_DEF_H_
+#define _HSI_STRUCT_DEF_H_
+
+struct ctx_hw_stats64 {
+ uint64_t rx_ucast_pkts;
+ uint64_t rx_mcast_pkts;
+ uint64_t rx_bcast_pkts;
+ uint64_t rx_drop_pkts;
+ uint64_t rx_err_pkts;
+ uint64_t rx_ucast_bytes;
+ uint64_t rx_mcast_bytes;
+ uint64_t rx_bcast_bytes;
+ uint64_t tx_ucast_pkts;
+ uint64_t tx_mcast_pkts;
+ uint64_t tx_bcast_pkts;
+ uint64_t tx_drop_pkts;
+ uint64_t tx_err_pkts;
+ uint64_t tx_ucast_bytes;
+ uint64_t tx_mcast_bytes;
+ uint64_t tx_bcast_bytes;
+ uint64_t tpa_pkts;
+ uint64_t tpa_bytes;
+ uint64_t tpa_events;
+ uint64_t tpa_aborts;
+} ctx_hw_stats64_t;
+
+struct ctx_hw_stats {
+ uint32_t rx_ucast_pkts_lo;
+ uint32_t rx_ucast_pkts_hi;
+ uint32_t rx_mcast_pkts_lo;
+ uint32_t rx_mcast_pkts_hi;
+ uint32_t rx_bcast_pkts_lo;
+ uint32_t rx_bcast_pkts_hi;
+ uint32_t rx_discard_pkts_lo;
+ uint32_t rx_discard_pkts_hi;
+ uint32_t rx_drop_pkts_lo;
+ uint32_t rx_drop_pkts_hi;
+ uint32_t rx_ucast_bytes_lo;
+ uint32_t rx_ucast_bytes_hi;
+ uint32_t rx_mcast_bytes_lo;
+ uint32_t rx_mcast_bytes_hi;
+ uint32_t rx_bcast_bytes_lo;
+ uint32_t rx_bcast_bytes_hi;
+ uint32_t tx_ucast_pkts_lo;
+ uint32_t tx_ucast_pkts_hi;
+ uint32_t tx_mcast_pkts_lo;
+ uint32_t tx_mcast_pkts_hi;
+ uint32_t tx_bcast_pkts_lo;
+ uint32_t tx_bcast_pkts_hi;
+ uint32_t tx_discard_pkts_lo;
+ uint32_t tx_discard_pkts_hi;
+ uint32_t tx_drop_pkts_lo;
+ uint32_t tx_drop_pkts_hi;
+ uint32_t tx_ucast_bytes_lo;
+ uint32_t tx_ucast_bytes_hi;
+ uint32_t tx_mcast_bytes_lo;
+ uint32_t tx_mcast_bytes_hi;
+ uint32_t tx_bcast_bytes_lo;
+ uint32_t tx_bcast_bytes_hi;
+ uint32_t tpa_pkts_lo;
+ uint32_t tpa_pkts_hi;
+ uint32_t tpa_bytes_lo;
+ uint32_t tpa_bytes_hi;
+ uint32_t tpa_events_lo;
+ uint32_t tpa_events_hi;
+ uint32_t tpa_aborts_lo;
+ uint32_t tpa_aborts_hi;
+} __attribute__((packed));
+#define TX_BD_SHORT_TYPE_TX_BD_SHORT (UINT32_C(0x0) << 0)
+
+struct tx_bd_long {
+ uint16_t flags_type;
+#define TX_BD_LONG_TYPE_MASK UINT32_C(0x3f)
+#define TX_BD_LONG_TYPE_SFT 0
+#define TX_BD_LONG_TYPE_TX_BD_LONG (UINT32_C(0x10) << 0)
+#define TX_BD_LONG_FLAGS_PACKET_END UINT32_C(0x40)
+#define TX_BD_LONG_FLAGS_NO_CMPL UINT32_C(0x80)
+#define TX_BD_LONG_FLAGS_BD_CNT_MASK UINT32_C(0x1f00)
+#define TX_BD_LONG_FLAGS_BD_CNT_SFT 8
+#define TX_BD_LONG_FLAGS_LHINT_MASK UINT32_C(0x6000)
+#define TX_BD_LONG_FLAGS_LHINT_SFT 13
+#define TX_BD_LONG_FLAGS_LHINT_LT512 (UINT32_C(0x0) << 13)
+#define TX_BD_LONG_FLAGS_LHINT_LT1K (UINT32_C(0x1) << 13)
+#define TX_BD_LONG_FLAGS_LHINT_LT2K (UINT32_C(0x2) << 13)
+#define TX_BD_LONG_FLAGS_LHINT_GTE2K (UINT32_C(0x3) << 13)
+#define TX_BD_LONG_FLAGS_COAL_NOW UINT32_C(0x8000)
+#define TX_BD_LONG_FLAGS_MASK UINT32_C(0xffc0)
+#define TX_BD_LONG_FLAGS_SFT 6
+ uint16_t len;
+ uint32_t opaque;
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+} __attribute__((packed));
+
+struct tx_bd_long_hi {
+ uint16_t lflags;
+#define TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM UINT32_C(0x1)
+#define TX_BD_LONG_LFLAGS_IP_CHKSUM UINT32_C(0x2)
+#define TX_BD_LONG_LFLAGS_NOCRC UINT32_C(0x4)
+#define TX_BD_LONG_LFLAGS_STAMP UINT32_C(0x8)
+#define TX_BD_LONG_LFLAGS_T_IP_CHKSUM UINT32_C(0x10)
+#define TX_BD_LONG_LFLAGS_LSO UINT32_C(0x20)
+#define TX_BD_LONG_LFLAGS_IPID_FMT UINT32_C(0x40)
+#define TX_BD_LONG_LFLAGS_T_IPID UINT32_C(0x80)
+#define TX_BD_LONG_LFLAGS_ROCE_CRC UINT32_C(0x100)
+#define TX_BD_LONG_LFLAGS_FCOE_CRC UINT32_C(0x200)
+ uint16_t hdr_size;
+#define TX_BD_LONG_HDR_SIZE_MASK UINT32_C(0x1ff)
+#define TX_BD_LONG_HDR_SIZE_SFT 0
+ uint32_t mss;
+#define TX_BD_LONG_MSS_MASK UINT32_C(0x7fff)
+#define TX_BD_LONG_MSS_SFT 0
+ uint16_t unused_2;
+ uint16_t cfa_action;
+ uint32_t cfa_meta;
+#define TX_BD_LONG_CFA_META_VLAN_VID_MASK UINT32_C(0xfff)
+#define TX_BD_LONG_CFA_META_VLAN_VID_SFT 0
+#define TX_BD_LONG_CFA_META_VLAN_DE UINT32_C(0x1000)
+#define TX_BD_LONG_CFA_META_VLAN_PRI_MASK UINT32_C(0xe000)
+#define TX_BD_LONG_CFA_META_VLAN_PRI_SFT 13
+#define TX_BD_LONG_CFA_META_VLAN_TPID_MASK UINT32_C(0x70000)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_SFT 16
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8 (UINT32_C(0x0) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100 (UINT32_C(0x1) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100 (UINT32_C(0x2) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200 (UINT32_C(0x3) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300 (UINT32_C(0x4) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG (UINT32_C(0x5) << 16)
+#define TX_BD_LONG_CFA_META_VLAN_RESERVED_MASK UINT32_C(0xff80000)
+#define TX_BD_LONG_CFA_META_VLAN_RESERVED_SFT 19
+#define TX_BD_LONG_CFA_META_KEY_MASK UINT32_C(0xf0000000)
+#define TX_BD_LONG_CFA_META_KEY_SFT 28
+#define TX_BD_LONG_CFA_META_KEY_NONE (UINT32_C(0x0) << 28)
+#define TX_BD_LONG_CFA_META_KEY_VLAN_TAG (UINT32_C(0x1) << 28)
+} __attribute__((packed));
+
+struct rx_prod_pkt_bd {
+ uint16_t flags_type;
+#define RX_PROD_PKT_BD_TYPE_MASK UINT32_C(0x3f)
+#define RX_PROD_PKT_BD_TYPE_SFT 0
+#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT (UINT32_C(0x4) << 0)
+#define RX_PROD_PKT_BD_FLAGS_SOP_PAD UINT32_C(0x40)
+#define RX_PROD_PKT_BD_FLAGS_EOP_PAD UINT32_C(0x80)
+#define RX_PROD_PKT_BD_FLAGS_BUFFERS_MASK UINT32_C(0x300)
+#define RX_PROD_PKT_BD_FLAGS_BUFFERS_SFT 8
+#define RX_PROD_PKT_BD_FLAGS_MASK UINT32_C(0xffc0)
+#define RX_PROD_PKT_BD_FLAGS_SFT 6
+ uint16_t len;
+ uint32_t opaque;
+ uint32_t addr_lo;
+ uint32_t addr_hi;
+} __attribute__((packed));
+
+struct cmpl_base {
+ uint16_t type;
+#define CMPL_BASE_TYPE_MASK UINT32_C(0x3f)
+#define CMPL_BASE_TYPE_SFT 0
+#define CMPL_BASE_TYPE_TX_L2 (UINT32_C(0x0) << 0)
+#define CMPL_BASE_TYPE_RX_L2 (UINT32_C(0x11) << 0)
+#define CMPL_BASE_TYPE_RX_AGG (UINT32_C(0x12) << 0)
+#define CMPL_BASE_TYPE_RX_TPA_START (UINT32_C(0x13) << 0)
+#define CMPL_BASE_TYPE_RX_TPA_END (UINT32_C(0x15) << 0)
+#define CMPL_BASE_TYPE_STAT_EJECT (UINT32_C(0x1a) << 0)
+#define CMPL_BASE_TYPE_HWRM_DONE (UINT32_C(0x20) << 0)
+#define CMPL_BASE_TYPE_HWRM_FWD_REQ (UINT32_C(0x22) << 0)
+#define CMPL_BASE_TYPE_HWRM_FWD_RESP (UINT32_C(0x24) << 0)
+#define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT (UINT32_C(0x2e) << 0)
+#define CMPL_BASE_TYPE_CQ_NOTIFICATION (UINT32_C(0x30) << 0)
+#define CMPL_BASE_TYPE_SRQ_EVENT (UINT32_C(0x32) << 0)
+#define CMPL_BASE_TYPE_DBQ_EVENT (UINT32_C(0x34) << 0)
+#define CMPL_BASE_TYPE_QP_EVENT (UINT32_C(0x38) << 0)
+#define CMPL_BASE_TYPE_FUNC_EVENT (UINT32_C(0x3a) << 0)
+ uint16_t info1;
+ uint32_t info2;
+ uint32_t info3_v;
+#define CMPL_BASE_V UINT32_C(0x1)
+#define CMPL_BASE_INFO3_MASK UINT32_C(0xfffffffe)
+#define CMPL_BASE_INFO3_SFT 1
+ uint32_t info4;
+} __attribute__((packed));
+
+struct tx_cmpl {
+ uint16_t flags_type;
+#define TX_CMPL_TYPE_MASK UINT32_C(0x3f)
+#define TX_CMPL_TYPE_SFT 0
+#define TX_CMPL_TYPE_TX_L2 (UINT32_C(0x0) << 0)
+#define TX_CMPL_FLAGS_ERROR UINT32_C(0x40)
+#define TX_CMPL_FLAGS_PUSH UINT32_C(0x80)
+#define TX_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+#define TX_CMPL_FLAGS_SFT 6
+ uint16_t unused_0;
+ uint32_t opaque;
+ uint16_t errors_v;
+#define TX_CMPL_V UINT32_C(0x1)
+#define TX_CMPL_ERRORS_BUFFER_ERROR_MASK UINT32_C(0xe)
+#define TX_CMPL_ERRORS_BUFFER_ERROR_SFT 1
+#define TX_CMPL_ERRORS_BUFFER_ERROR_NO_ERROR (UINT32_C(0x0) << 1)
+#define TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT (UINT32_C(0x2) << 1)
+#define TX_CMPL_ERRORS_ZERO_LENGTH_PKT UINT32_C(0x10)
+#define TX_CMPL_ERRORS_EXCESSIVE_BD_LENGTH UINT32_C(0x20)
+#define TX_CMPL_ERRORS_DMA_ERROR UINT32_C(0x40)
+#define TX_CMPL_ERRORS_HINT_TOO_SHORT UINT32_C(0x80)
+#define TX_CMPL_ERRORS_POISON_TLP_ERROR UINT32_C(0x100)
+#define TX_CMPL_ERRORS_MASK UINT32_C(0xfffe)
+#define TX_CMPL_ERRORS_SFT 1
+ uint16_t unused_1;
+ uint32_t unused_2;
+} __attribute__((packed));
+
+struct rx_pkt_cmpl {
+ uint16_t flags_type;
+#define RX_PKT_CMPL_TYPE_MASK UINT32_C(0x3f)
+#define RX_PKT_CMPL_TYPE_SFT 0
+#define RX_PKT_CMPL_TYPE_RX_L2 (UINT32_C(0x11) << 0)
+#define RX_PKT_CMPL_FLAGS_ERROR UINT32_C(0x40)
+#define RX_PKT_CMPL_FLAGS_PLACEMENT_MASK UINT32_C(0x380)
+#define RX_PKT_CMPL_FLAGS_PLACEMENT_SFT 7
+#define RX_PKT_CMPL_FLAGS_PLACEMENT_NORMAL (UINT32_C(0x0) << 7)
+#define RX_PKT_CMPL_FLAGS_PLACEMENT_JUMBO (UINT32_C(0x1) << 7)
+#define RX_PKT_CMPL_FLAGS_PLACEMENT_HDS (UINT32_C(0x2) << 7)
+#define RX_PKT_CMPL_FLAGS_RSS_VALID UINT32_C(0x400)
+#define RX_PKT_CMPL_FLAGS_ITYPE_MASK UINT32_C(0xf000)
+#define RX_PKT_CMPL_FLAGS_ITYPE_SFT 12
+#define RX_PKT_CMPL_FLAGS_ITYPE_NOT_KNOWN (UINT32_C(0x0) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_IP (UINT32_C(0x1) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_TCP (UINT32_C(0x2) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_UDP (UINT32_C(0x3) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_FCOE (UINT32_C(0x4) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_ROCE (UINT32_C(0x5) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_ICMP (UINT32_C(0x7) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_WO_TIMESTAMP (UINT32_C(0x8) << 12)
+#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP (UINT32_C(0x9) << 12)
+#define RX_PKT_CMPL_FLAGS_MASK UINT32_C(0xffc0)
+#define RX_PKT_CMPL_FLAGS_SFT 6
+ uint16_t len;
+ uint32_t opaque;
+ uint8_t agg_bufs_v1;
+#define RX_PKT_CMPL_V1 UINT32_C(0x1)
+#define RX_PKT_CMPL_AGG_BUFS_MASK UINT32_C(0x3e)
+#define RX_PKT_CMPL_AGG_BUFS_SFT 1
+ uint8_t rss_hash_type;
+ uint8_t payload_offset;
+ uint8_t unused_1;
+ uint32_t rss_hash;
+} __attribute__((packed));
+
+struct rx_pkt_cmpl_hi {
+ uint32_t flags2;
+#define RX_PKT_CMPL_FLAGS2_IP_CS_CALC UINT32_C(0x1)
+#define RX_PKT_CMPL_FLAGS2_L4_CS_CALC UINT32_C(0x2)
+#define RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC UINT32_C(0x4)
+#define RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC UINT32_C(0x8)
+#define RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+#define RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT 4
+#define RX_PKT_CMPL_FLAGS2_META_FORMAT_NONE (UINT32_C(0x0) << 4)
+#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+#define RX_PKT_CMPL_FLAGS2_IP_TYPE UINT32_C(0x100)
+ uint32_t metadata;
+#define RX_PKT_CMPL_METADATA_VID_MASK UINT32_C(0xfff)
+#define RX_PKT_CMPL_METADATA_VID_SFT 0
+#define RX_PKT_CMPL_METADATA_DE UINT32_C(0x1000)
+#define RX_PKT_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+#define RX_PKT_CMPL_METADATA_PRI_SFT 13
+#define RX_PKT_CMPL_METADATA_TPID_MASK UINT32_C(0xffff0000)
+#define RX_PKT_CMPL_METADATA_TPID_SFT 16
+ uint16_t errors_v2;
+#define RX_PKT_CMPL_V2 UINT32_C(0x1)
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK UINT32_C(0xe)
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_SFT 1
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NO_BUFFER (UINT32_C(0x0) << 1)
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_DID_NOT_FIT (UINT32_C(0x1) << 1)
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP (UINT32_C(0x2) << 1)
+#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT (UINT32_C(0x3) << 1)
+#define RX_PKT_CMPL_ERRORS_IP_CS_ERROR UINT32_C(0x10)
+#define RX_PKT_CMPL_ERRORS_L4_CS_ERROR UINT32_C(0x20)
+#define RX_PKT_CMPL_ERRORS_T_IP_CS_ERROR UINT32_C(0x40)
+#define RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR UINT32_C(0x80)
+#define RX_PKT_CMPL_ERRORS_CRC_ERROR UINT32_C(0x100)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_MASK UINT32_C(0xe00)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_SFT 9
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_NO_ERROR (UINT32_C(0x0) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_VERSION (UINT32_C(0x1) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_HDR_LEN (UINT32_C(0x2) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_TUNNEL_TOTAL_ERROR (UINT32_C(0x3) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_IP_TOTAL_ERROR (UINT32_C(0x4) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_UDP_TOTAL_ERROR (UINT32_C(0x5) << 9)
+#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL (UINT32_C(0x6) << 9)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_MASK UINT32_C(0xf000)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_SFT 12
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_NO_ERROR (UINT32_C(0x0) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_VERSION (UINT32_C(0x1) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_HDR_LEN (UINT32_C(0x2) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_TTL (UINT32_C(0x3) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_IP_TOTAL_ERROR (UINT32_C(0x4) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_UDP_TOTAL_ERROR (UINT32_C(0x5) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN (UINT32_C(0x6) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL \
+ (UINT32_C(0x7) << 12)
+#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN (UINT32_C(0x8) << 12)
+#define RX_PKT_CMPL_ERRORS_MASK UINT32_C(0xfffe)
+#define RX_PKT_CMPL_ERRORS_SFT 1
+ uint16_t cfa_code;
+ uint32_t reorder;
+#define RX_PKT_CMPL_REORDER_MASK UINT32_C(0xffffff)
+#define RX_PKT_CMPL_REORDER_SFT 0
+} __attribute__((packed));
+
+struct hwrm_fwd_req_cmpl {
+ uint16_t req_len_type;
+#define HWRM_FWD_REQ_CMPL_TYPE_MASK UINT32_C(0x3f)
+#define HWRM_FWD_REQ_CMPL_TYPE_SFT 0
+#define HWRM_FWD_REQ_CMPL_TYPE_HWRM_FWD_REQ (UINT32_C(0x22) << 0)
+#define HWRM_FWD_REQ_CMPL_REQ_LEN_MASK UINT32_C(0xffc0)
+#define HWRM_FWD_REQ_CMPL_REQ_LEN_SFT 6
+ uint16_t source_id;
+ uint32_t unused_0;
+ uint64_t req_buf_addr_v;
+#define HWRM_FWD_REQ_CMPL_V UINT32_C(0x1)
+#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_MASK UINT32_C(0xfffffffe)
+#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT 1
+} __attribute__((packed));
+
+struct hwrm_async_event_cmpl {
+ uint16_t type;
+#define HWRM_ASYNC_EVENT_CMPL_TYPE_MASK UINT32_C(0x3f)
+#define HWRM_ASYNC_EVENT_CMPL_TYPE_SFT 0
+#define HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT (UINT32_C(0x2e) << 0)
+ uint16_t event_id;
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE (UINT32_C(0x0) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE (UINT32_C(0x1) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE (UINT32_C(0x2) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE (UINT32_C(0x3) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+ (UINT32_C(0x4) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+ (UINT32_C(0x5) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD (UINT32_C(0x10) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD (UINT32_C(0x11) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD (UINT32_C(0x20) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD (UINT32_C(0x21) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR (UINT32_C(0x30) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE (UINT32_C(0x31) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+ (UINT32_C(0x32) << 0)
+#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR (UINT32_C(0xff) << 0)
+ uint32_t event_data2;
+ uint8_t opaque_v;
+#define HWRM_ASYNC_EVENT_CMPL_V UINT32_C(0x1)
+#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK UINT32_C(0xfe)
+#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT 1
+ uint8_t timestamp_lo;
+ uint16_t timestamp_hi;
+ uint32_t event_data1;
+} __attribute__((packed));
+#define HWRM_VERSION_MAJOR 1
+#define HWRM_VERSION_MINOR 0
+#define HWRM_VERSION_UPDATE 0
+#define HWRM_VERSION_STR "1.0.0"
+#define HWRM_NA_SIGNATURE ((uint32_t)(-1))
+#define HWRM_MAX_REQ_LEN (128)
+#define HWRM_MAX_RESP_LEN (176)
+#define HW_HASH_INDEX_SIZE 0x80
+#define HW_HASH_KEY_SIZE 40
+#define HWRM_RESP_VALID_KEY 1
+
+struct input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+struct output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+} __attribute__((packed));
+
+struct cmd_nums {
+ uint16_t req_type;
+#define HWRM_VER_GET (UINT32_C(0x0))
+#define HWRM_FUNC_BUF_UNRGTR (UINT32_C(0xe))
+#define HWRM_FUNC_VF_CFG (UINT32_C(0xf))
+#define RESERVED1 (UINT32_C(0x10))
+#define HWRM_FUNC_RESET (UINT32_C(0x11))
+#define HWRM_FUNC_GETFID (UINT32_C(0x12))
+#define HWRM_FUNC_VF_ALLOC (UINT32_C(0x13))
+#define HWRM_FUNC_VF_FREE (UINT32_C(0x14))
+#define HWRM_FUNC_QCAPS (UINT32_C(0x15))
+#define HWRM_FUNC_QCFG (UINT32_C(0x16))
+#define HWRM_FUNC_CFG (UINT32_C(0x17))
+#define HWRM_FUNC_QSTATS (UINT32_C(0x18))
+#define HWRM_FUNC_CLR_STATS (UINT32_C(0x19))
+#define HWRM_FUNC_DRV_UNRGTR (UINT32_C(0x1a))
+#define HWRM_FUNC_VF_RESC_FREE (UINT32_C(0x1b))
+#define HWRM_FUNC_VF_VNIC_IDS_QUERY (UINT32_C(0x1c))
+#define HWRM_FUNC_DRV_RGTR (UINT32_C(0x1d))
+#define HWRM_FUNC_DRV_QVER (UINT32_C(0x1e))
+#define HWRM_FUNC_BUF_RGTR (UINT32_C(0x1f))
+#define HWRM_PORT_PHY_CFG (UINT32_C(0x20))
+#define HWRM_PORT_MAC_CFG (UINT32_C(0x21))
+#define RESERVED2 (UINT32_C(0x22))
+#define HWRM_PORT_QSTATS (UINT32_C(0x23))
+#define HWRM_PORT_LPBK_QSTATS (UINT32_C(0x24))
+#define HWRM_PORT_CLR_STATS (UINT32_C(0x25))
+#define HWRM_PORT_LPBK_CLR_STATS (UINT32_C(0x26))
+#define HWRM_PORT_PHY_QCFG (UINT32_C(0x27))
+#define HWRM_PORT_MAC_QCFG (UINT32_C(0x28))
+#define HWRM_PORT_BLINK_LED (UINT32_C(0x29))
+#define HWRM_QUEUE_QPORTCFG (UINT32_C(0x30))
+#define HWRM_QUEUE_QCFG (UINT32_C(0x31))
+#define HWRM_QUEUE_CFG (UINT32_C(0x32))
+#define HWRM_QUEUE_BUFFERS_QCFG (UINT32_C(0x33))
+#define HWRM_QUEUE_BUFFERS_CFG (UINT32_C(0x34))
+#define HWRM_QUEUE_PFCENABLE_QCFG (UINT32_C(0x35))
+#define HWRM_QUEUE_PFCENABLE_CFG (UINT32_C(0x36))
+#define HWRM_QUEUE_PRI2COS_QCFG (UINT32_C(0x37))
+#define HWRM_QUEUE_PRI2COS_CFG (UINT32_C(0x38))
+#define HWRM_QUEUE_COS2BW_QCFG (UINT32_C(0x39))
+#define HWRM_QUEUE_COS2BW_CFG (UINT32_C(0x3a))
+#define HWRM_VNIC_ALLOC (UINT32_C(0x40))
+#define HWRM_VNIC_FREE (UINT32_C(0x41))
+#define HWRM_VNIC_CFG (UINT32_C(0x42))
+#define HWRM_VNIC_QCFG (UINT32_C(0x43))
+#define HWRM_VNIC_TPA_CFG (UINT32_C(0x44))
+#define HWRM_VNIC_TPA_QCFG (UINT32_C(0x45))
+#define HWRM_VNIC_RSS_CFG (UINT32_C(0x46))
+#define HWRM_VNIC_RSS_QCFG (UINT32_C(0x47))
+#define HWRM_VNIC_PLCMODES_CFG (UINT32_C(0x48))
+#define HWRM_VNIC_PLCMODES_QCFG (UINT32_C(0x49))
+#define HWRM_RING_ALLOC (UINT32_C(0x50))
+#define HWRM_RING_FREE (UINT32_C(0x51))
+#define HWRM_RING_CMPL_RING_QAGGINT_PARAMS (UINT32_C(0x52))
+#define HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS (UINT32_C(0x53))
+#define HWRM_RING_RESET (UINT32_C(0x5e))
+#define HWRM_RING_GRP_ALLOC (UINT32_C(0x60))
+#define HWRM_RING_GRP_FREE (UINT32_C(0x61))
+#define HWRM_VNIC_RSS_COS_LB_CTX_ALLOC (UINT32_C(0x70))
+#define HWRM_VNIC_RSS_COS_LB_CTX_FREE (UINT32_C(0x71))
+#define HWRM_CFA_L2_FILTER_ALLOC (UINT32_C(0x90))
+#define HWRM_CFA_L2_FILTER_FREE (UINT32_C(0x91))
+#define HWRM_CFA_L2_FILTER_CFG (UINT32_C(0x92))
+#define HWRM_CFA_L2_SET_RX_MASK (UINT32_C(0x93))
+#define RESERVED3 (UINT32_C(0x94))
+#define HWRM_CFA_TUNNEL_FILTER_ALLOC (UINT32_C(0x95))
+#define HWRM_CFA_TUNNEL_FILTER_FREE (UINT32_C(0x96))
+#define HWRM_CFA_ENCAP_RECORD_ALLOC (UINT32_C(0x97))
+#define HWRM_CFA_ENCAP_RECORD_FREE (UINT32_C(0x98))
+#define HWRM_CFA_NTUPLE_FILTER_ALLOC (UINT32_C(0x99))
+#define HWRM_CFA_NTUPLE_FILTER_FREE (UINT32_C(0x9a))
+#define HWRM_CFA_NTUPLE_FILTER_CFG (UINT32_C(0x9b))
+#define HWRM_CFA_EM_FLOW_ALLOC (UINT32_C(0x9c))
+#define HWRM_CFA_EM_FLOW_FREE (UINT32_C(0x9d))
+#define HWRM_CFA_EM_FLOW_CFG (UINT32_C(0x9e))
+#define HWRM_TUNNEL_DST_PORT_QUERY (UINT32_C(0xa0))
+#define HWRM_TUNNEL_DST_PORT_ALLOC (UINT32_C(0xa1))
+#define HWRM_TUNNEL_DST_PORT_FREE (UINT32_C(0xa2))
+#define HWRM_STAT_CTX_ALLOC (UINT32_C(0xb0))
+#define HWRM_STAT_CTX_FREE (UINT32_C(0xb1))
+#define HWRM_STAT_CTX_QUERY (UINT32_C(0xb2))
+#define HWRM_STAT_CTX_CLR_STATS (UINT32_C(0xb3))
+#define HWRM_FW_RESET (UINT32_C(0xc0))
+#define HWRM_FW_QSTATUS (UINT32_C(0xc1))
+#define HWRM_EXEC_FWD_RESP (UINT32_C(0xd0))
+#define HWRM_REJECT_FWD_RESP (UINT32_C(0xd1))
+#define HWRM_FWD_RESP (UINT32_C(0xd2))
+#define HWRM_FWD_ASYNC_EVENT_CMPL (UINT32_C(0xd3))
+#define HWRM_TEMP_MONITOR_QUERY (UINT32_C(0xe0))
+#define HWRM_DBG_DUMP (UINT32_C(0xff14))
+#define HWRM_NVM_MODIFY (UINT32_C(0xfff4))
+#define HWRM_NVM_VERIFY_UPDATE (UINT32_C(0xfff5))
+#define HWRM_NVM_GET_DEV_INFO (UINT32_C(0xfff6))
+#define HWRM_NVM_ERASE_DIR_ENTRY (UINT32_C(0xfff7))
+#define HWRM_NVM_MOD_DIR_ENTRY (UINT32_C(0xfff8))
+#define HWRM_NVM_FIND_DIR_ENTRY (UINT32_C(0xfff9))
+#define HWRM_NVM_GET_DIR_ENTRIES (UINT32_C(0xfffa))
+#define HWRM_NVM_GET_DIR_INFO (UINT32_C(0xfffb))
+#define HWRM_NVM_READ (UINT32_C(0xfffd))
+#define HWRM_NVM_WRITE (UINT32_C(0xfffe))
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct ret_codes {
+ uint16_t error_code;
+#define HWRM_ERR_CODE_SUCCESS (UINT32_C(0x0))
+#define HWRM_ERR_CODE_FAIL (UINT32_C(0x1))
+#define HWRM_ERR_CODE_INVALID_PARAMS (UINT32_C(0x2))
+#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED (UINT32_C(0x3))
+#define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR (UINT32_C(0x4))
+#define HWRM_ERR_CODE_INVALID_FLAGS (UINT32_C(0x5))
+#define HWRM_ERR_CODE_INVALID_ENABLES (UINT32_C(0x6))
+#define HWRM_ERR_CODE_HWRM_ERROR (UINT32_C(0xf))
+#define HWRM_ERR_CODE_UNKNOWN_ERR (UINT32_C(0xfffe))
+#define HWRM_ERR_CODE_CMD_NOT_SUPPORTED (UINT32_C(0xffff))
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_ver_get_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint8_t hwrm_intf_maj;
+ uint8_t hwrm_intf_min;
+ uint8_t hwrm_intf_upd;
+ uint8_t unused_0[5];
+} __attribute__((packed));
+
+struct hwrm_ver_get_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint8_t hwrm_intf_maj;
+ uint8_t hwrm_intf_min;
+ uint8_t hwrm_intf_upd;
+ uint8_t hwrm_intf_rsvd;
+ uint8_t hwrm_fw_maj;
+ uint8_t hwrm_fw_min;
+ uint8_t hwrm_fw_bld;
+ uint8_t hwrm_fw_rsvd;
+ uint8_t mgmt_fw_maj;
+ uint8_t mgmt_fw_min;
+ uint8_t mgmt_fw_bld;
+ uint8_t mgmt_fw_rsvd;
+ uint8_t netctrl_fw_maj;
+ uint8_t netctrl_fw_min;
+ uint8_t netctrl_fw_bld;
+ uint8_t netctrl_fw_rsvd;
+ uint32_t reserved1;
+ uint8_t roce_fw_maj;
+ uint8_t roce_fw_min;
+ uint8_t roce_fw_bld;
+ uint8_t roce_fw_rsvd;
+ char hwrm_fw_name[16];
+ char mgmt_fw_name[16];
+ char netctrl_fw_name[16];
+ uint32_t reserved2[4];
+ char roce_fw_name[16];
+ uint16_t chip_num;
+ uint8_t chip_rev;
+ uint8_t chip_metal;
+ uint8_t chip_bond_id;
+ uint8_t chip_platform_type;
+#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_ASIC (UINT32_C(0x0) << 0)
+#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA (UINT32_C(0x1) << 0)
+#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM (UINT32_C(0x2) << 0)
+ uint16_t max_req_win_len;
+ uint16_t max_resp_len;
+ uint16_t def_req_timeout;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_reset_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t enables;
+#define HWRM_FUNC_RESET_INPUT_ENABLES_VF_ID_VALID UINT32_C(0x1)
+ uint16_t vf_id;
+ uint8_t func_reset_level;
+#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETALL (UINT32_C(0x0) << 0)
+#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETME (UINT32_C(0x1) << 0)
+#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+ (UINT32_C(0x2) << 0)
+#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETVF (UINT32_C(0x3) << 0)
+ uint8_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_func_reset_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_vf_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t enables;
+#define HWRM_FUNC_VF_ALLOC_INPUT_ENABLES_FIRST_VF_ID UINT32_C(0x1)
+ uint16_t first_vf_id;
+ uint16_t num_vfs;
+} __attribute__((packed));
+
+struct hwrm_func_vf_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint16_t first_vf_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t unused_4;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_vf_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t enables;
+#define HWRM_FUNC_VF_FREE_INPUT_ENABLES_FIRST_VF_ID UINT32_C(0x1)
+ uint16_t first_vf_id;
+ uint16_t num_vfs;
+} __attribute__((packed));
+
+struct hwrm_func_vf_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_qcaps_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t fid;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_func_qcaps_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint16_t fid;
+ uint16_t port_id;
+ uint32_t flags;
+#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED UINT32_C(0x1)
+#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING UINT32_C(0x2)
+ uint8_t perm_mac_address[6];
+ uint16_t max_rsscos_ctx;
+ uint16_t max_cmpl_rings;
+ uint16_t max_tx_rings;
+ uint16_t max_rx_rings;
+ uint16_t max_l2_ctxs;
+ uint16_t max_vnics;
+ uint16_t first_vf_id;
+ uint16_t max_vfs;
+ uint16_t max_stat_ctx;
+ uint32_t max_encap_records;
+ uint32_t max_decap_records;
+ uint32_t max_tx_em_flows;
+ uint32_t max_tx_wm_flows;
+ uint32_t max_rx_em_flows;
+ uint32_t max_rx_wm_flows;
+ uint32_t max_mcast_filters;
+ uint32_t max_flow_id;
+ uint32_t max_hw_ring_grps;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_qstats_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t fid;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_func_qstats_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint64_t tx_ucast_pkts;
+ uint64_t tx_mcast_pkts;
+ uint64_t tx_bcast_pkts;
+ uint64_t tx_err_pkts;
+ uint64_t tx_drop_pkts;
+ uint64_t tx_ucast_bytes;
+ uint64_t tx_mcast_bytes;
+ uint64_t tx_bcast_bytes;
+ uint64_t rx_ucast_pkts;
+ uint64_t rx_mcast_pkts;
+ uint64_t rx_bcast_pkts;
+ uint64_t rx_err_pkts;
+ uint64_t rx_drop_pkts;
+ uint64_t rx_ucast_bytes;
+ uint64_t rx_mcast_bytes;
+ uint64_t rx_bcast_bytes;
+ uint64_t rx_agg_pkts;
+ uint64_t rx_agg_bytes;
+ uint64_t rx_agg_events;
+ uint64_t rx_agg_aborts;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_clr_stats_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t fid;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_func_clr_stats_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_drv_rgtr_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_ALL_MODE UINT32_C(0x1)
+#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE UINT32_C(0x2)
+ uint32_t enables;
+#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE UINT32_C(0x1)
+#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER UINT32_C(0x2)
+#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_TIMESTAMP UINT32_C(0x4)
+#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD UINT32_C(0x8)
+#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD UINT32_C(0x10)
+ uint16_t os_type;
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN (UINT32_C(0x0) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER (UINT32_C(0x1) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS (UINT32_C(0xe) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS (UINT32_C(0x1d) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX (UINT32_C(0x24) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD (UINT32_C(0x2a) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI (UINT32_C(0x68) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864 (UINT32_C(0x73) << 0)
+#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2 (UINT32_C(0x74) << 0)
+ uint8_t ver_maj;
+ uint8_t ver_min;
+ uint8_t ver_upd;
+ uint8_t unused_0;
+ uint16_t unused_1;
+ uint32_t timestamp;
+ uint32_t unused_2;
+ uint32_t vf_req_fwd[8];
+ uint32_t async_event_fwd[8];
+} __attribute__((packed));
+
+struct hwrm_func_drv_rgtr_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_drv_unrgtr_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN UINT32_C(0x1)
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_func_drv_unrgtr_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_func_buf_rgtr_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t enables;
+#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID UINT32_C(0x1)
+#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR UINT32_C(0x2)
+ uint16_t vf_id;
+ uint16_t req_buf_num_pages;
+ uint16_t req_buf_page_size;
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_16B (UINT32_C(0x4) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_4K (UINT32_C(0xc) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_8K (UINT32_C(0xd) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_64K (UINT32_C(0x10) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_2M (UINT32_C(0x16) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_4M (UINT32_C(0x17) << 0)
+#define HWRM_FUNC_BUF_RGTR_INPUT_REQ_BUF_PAGE_SIZE_1G (UINT32_C(0x1e) << 0)
+ uint16_t req_buf_len;
+ uint16_t resp_buf_len;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint64_t req_buf_page_addr0;
+ uint64_t req_buf_page_addr1;
+ uint64_t req_buf_page_addr2;
+ uint64_t req_buf_page_addr3;
+ uint64_t req_buf_page_addr4;
+ uint64_t req_buf_page_addr5;
+ uint64_t req_buf_page_addr6;
+ uint64_t req_buf_page_addr7;
+ uint64_t req_buf_page_addr8;
+ uint64_t req_buf_page_addr9;
+ uint64_t error_buf_addr;
+ uint64_t resp_buf_addr;
+} __attribute__((packed));
+
+struct hwrm_func_buf_rgtr_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_port_phy_cfg_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY UINT32_C(0x1)
+#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN UINT32_C(0x2)
+#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE UINT32_C(0x4)
+#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG UINT32_C(0x8)
+ uint32_t enables;
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE UINT32_C(0x1)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX UINT32_C(0x2)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE UINT32_C(0x4)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED UINT32_C(0x8)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK UINT32_C(0x10)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_WIRESPEED UINT32_C(0x20)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_LPBK UINT32_C(0x40)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_PREEMPHASIS UINT32_C(0x80)
+#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE UINT32_C(0x100)
+ uint16_t port_id;
+ uint16_t force_link_speed;
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB (UINT32_C(0xa) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB (UINT32_C(0x14) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB (UINT32_C(0x64) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB (UINT32_C(0x190) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)
+ uint8_t auto_mode;
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED (UINT32_C(0x2) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW (UINT32_C(0x3) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_MASK (UINT32_C(0x4) << 0)
+ uint8_t auto_duplex;
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH (UINT32_C(0x2) << 0)
+ uint8_t auto_pause;
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX UINT32_C(0x2)
+ uint8_t unused_0;
+ uint16_t auto_link_speed;
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB (UINT32_C(0xa) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB (UINT32_C(0x14) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB (UINT32_C(0x64) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB (UINT32_C(0x190) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)
+ uint16_t auto_link_speed_mask;
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MBHD UINT32_C(0x1)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB UINT32_C(0x2)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GBHD UINT32_C(0x4)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB UINT32_C(0x8)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2GB UINT32_C(0x10)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB UINT32_C(0x20)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB UINT32_C(0x40)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB UINT32_C(0x80)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB UINT32_C(0x100)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB UINT32_C(0x200)
+#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB UINT32_C(0x400)
+ uint8_t wirespeed;
+#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_OFF (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_ON (UINT32_C(0x1) << 0)
+ uint8_t lpbk;
+#define HWRM_PORT_PHY_CFG_INPUT_LPBK_NONE (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE (UINT32_C(0x2) << 0)
+ uint8_t force_pause;
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX UINT32_C(0x2)
+ uint8_t unused_1;
+ uint32_t preemphasis;
+ uint32_t unused_2;
+} __attribute__((packed));
+
+struct hwrm_port_phy_cfg_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_port_phy_qcfg_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t port_id;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_port_phy_qcfg_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint8_t link;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK (UINT32_C(0x2) << 0)
+ uint8_t unused_0;
+ uint16_t link_speed;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB (UINT32_C(0xa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB (UINT32_C(0x14) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB (UINT32_C(0x64) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB (UINT32_C(0x190) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)
+ uint8_t duplex;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL (UINT32_C(0x1) << 0)
+ uint8_t pause;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX UINT32_C(0x2)
+ uint16_t support_speeds;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB UINT32_C(0x2)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GBHD UINT32_C(0x4)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB UINT32_C(0x8)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2GB UINT32_C(0x10)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB UINT32_C(0x20)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB UINT32_C(0x40)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB UINT32_C(0x80)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB UINT32_C(0x100)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB UINT32_C(0x200)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB UINT32_C(0x400)
+ uint16_t force_link_speed;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB (UINT32_C(0xa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB (UINT32_C(0x14) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB (UINT32_C(0x64) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB (UINT32_C(0x190) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)
+ uint8_t auto_mode;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED (UINT32_C(0x2) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW (UINT32_C(0x3) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_MASK (UINT32_C(0x4) << 0)
+ uint8_t auto_pause;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX UINT32_C(0x2)
+ uint16_t auto_link_speed;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB (UINT32_C(0xa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB (UINT32_C(0x14) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB (UINT32_C(0x64) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB (UINT32_C(0x190) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)
+ uint16_t auto_link_speed_mask;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MBHD UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MB UINT32_C(0x2)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GBHD UINT32_C(0x4)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GB UINT32_C(0x8)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2GB UINT32_C(0x10)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2_5GB UINT32_C(0x20)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10GB UINT32_C(0x40)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_20GB UINT32_C(0x80)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_25GB UINT32_C(0x100)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_40GB UINT32_C(0x200)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_50GB UINT32_C(0x400)
+ uint8_t wirespeed;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_OFF (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_ON (UINT32_C(0x1) << 0)
+ uint8_t lpbk;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE (UINT32_C(0x2) << 0)
+ uint8_t force_pause;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX UINT32_C(0x2)
+ uint8_t reserved1;
+ uint32_t preemphasis;
+ uint8_t phy_maj;
+ uint8_t phy_min;
+ uint8_t phy_bld;
+ uint8_t phy_type;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR4 (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4 (UINT32_C(0x2) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR4 (UINT32_C(0x3) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR4 (UINT32_C(0x4) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2 (UINT32_C(0x5) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX4 (UINT32_C(0x6) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR (UINT32_C(0x7) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET (UINT32_C(0x8) << 0)
+ uint8_t media_type;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC (UINT32_C(0x2) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE (UINT32_C(0x3) << 0)
+ uint8_t transceiver_type;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_TRANSCEIVER_TYPE_XCVR_INTERNAL \
+ (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_TRANSCEIVER_TYPE_XCVR_EXTERNAL \
+ (UINT32_C(0x2) << 0)
+ uint8_t phy_addr;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK UINT32_C(0x1f)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_SFT 0
+ uint8_t unused_2;
+ uint16_t link_partner_adv_speeds;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB UINT32_C(0x2)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD UINT32_C(0x4)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GB UINT32_C(0x8)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB UINT32_C(0x10)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2_5GB UINT32_C(0x20)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10GB UINT32_C(0x40)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_20GB UINT32_C(0x80)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_25GB UINT32_C(0x100)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_40GB UINT32_C(0x200)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_50GB UINT32_C(0x400)
+ uint8_t link_partner_adv_auto_mode;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
+ (UINT32_C(0x0) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
+ (UINT32_C(0x2) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
+ (UINT32_C(0x3) << 0)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_MASK \
+ (UINT32_C(0x4) << 0)
+ uint8_t link_partner_adv_pause;
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX UINT32_C(0x1)
+#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX UINT32_C(0x2)
+ uint8_t unused_3;
+ uint8_t unused_4;
+ uint8_t unused_5;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_port_qstats_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t port_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2[3];
+ uint8_t unused_3;
+ uint64_t tx_stat_host_addr;
+ uint64_t rx_stat_host_addr;
+} __attribute__((packed));
+
+struct hwrm_port_qstats_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint16_t tx_stat_size;
+ uint16_t rx_stat_size;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_port_clr_stats_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t port_id;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_port_clr_stats_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_queue_qportcfg_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH UINT32_C(0x1)
+#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX (UINT32_C(0x1) << 0)
+ uint16_t port_id;
+ uint16_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_queue_qportcfg_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint8_t max_configurable_queues;
+ uint8_t max_configurable_lossless_queues;
+ uint8_t queue_cfg_allowed;
+ uint8_t queue_buffers_cfg_allowed;
+ uint8_t queue_pfcenable_cfg_allowed;
+ uint8_t queue_pri2cos_cfg_allowed;
+ uint8_t queue_cos2bw_cfg_allowed;
+ uint8_t queue_id0;
+ uint8_t queue_id0_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id1;
+ uint8_t queue_id1_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id2;
+ uint8_t queue_id2_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id3;
+ uint8_t queue_id3_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id4;
+ uint8_t queue_id4_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id5;
+ uint8_t queue_id5_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id6;
+ uint8_t queue_id6_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t queue_id7;
+ uint8_t queue_id7_service_profile;
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+ (UINT32_C(0x0) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+ (UINT32_C(0x1) << 0)
+#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+ (UINT32_C(0xff) << 0)
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT UINT32_C(0x1)
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_vnic_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t vnic_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t vnic_id;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_vnic_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_cfg_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT UINT32_C(0x1)
+#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE UINT32_C(0x2)
+#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE UINT32_C(0x4)
+ uint32_t enables;
+#define HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP UINT32_C(0x1)
+#define HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE UINT32_C(0x2)
+#define HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE UINT32_C(0x4)
+#define HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE UINT32_C(0x8)
+#define HWRM_VNIC_CFG_INPUT_ENABLES_MRU UINT32_C(0x10)
+ uint16_t vnic_id;
+ uint16_t dflt_ring_grp;
+ uint16_t rss_rule;
+ uint16_t cos_rule;
+ uint16_t lb_rule;
+ uint16_t mru;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_vnic_cfg_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cfg_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t hash_type;
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 UINT32_C(0x1)
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4 UINT32_C(0x2)
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 UINT32_C(0x4)
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6 UINT32_C(0x8)
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6 UINT32_C(0x10)
+#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6 UINT32_C(0x20)
+ uint32_t unused_0;
+ uint64_t ring_grp_tbl_addr;
+ uint64_t hash_key_tbl_addr;
+ uint16_t rss_ctx_idx;
+ uint16_t unused_1[3];
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cfg_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint16_t rss_cos_lb_ctx_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t unused_4;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cos_lb_ctx_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t rss_cos_lb_ctx_id;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_ring_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t enables;
+#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED1 UINT32_C(0x1)
+#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED2 UINT32_C(0x2)
+#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED3 UINT32_C(0x4)
+#define HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID UINT32_C(0x8)
+#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED4 UINT32_C(0x10)
+#define HWRM_RING_ALLOC_INPUT_ENABLES_MAX_BW_VALID UINT32_C(0x20)
+ uint8_t ring_type;
+#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL (UINT32_C(0x0) << 0)
+#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX (UINT32_C(0x1) << 0)
+#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX (UINT32_C(0x2) << 0)
+ uint8_t unused_0;
+ uint16_t unused_1;
+ uint64_t page_tbl_addr;
+ uint32_t fbo;
+ uint8_t page_size;
+ uint8_t page_tbl_depth;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint32_t length;
+ uint16_t logical_id;
+ uint16_t cmpl_ring_id;
+ uint16_t queue_id;
+ uint8_t unused_4;
+ uint8_t unused_5;
+ uint32_t reserved1;
+ uint16_t reserved2;
+ uint8_t unused_6;
+ uint8_t unused_7;
+ uint32_t reserved3;
+ uint32_t stat_ctx_id;
+ uint32_t reserved4;
+ uint32_t max_bw;
+ uint8_t int_mode;
+#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY (UINT32_C(0x0) << 0)
+#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD (UINT32_C(0x1) << 0)
+#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX (UINT32_C(0x2) << 0)
+#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL (UINT32_C(0x3) << 0)
+ uint8_t unused_8[3];
+} __attribute__((packed));
+
+struct hwrm_ring_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint16_t ring_id;
+ uint16_t logical_ring_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_ring_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint8_t ring_type;
+#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL (UINT32_C(0x0) << 0)
+#define HWRM_RING_FREE_INPUT_RING_TYPE_TX (UINT32_C(0x1) << 0)
+#define HWRM_RING_FREE_INPUT_RING_TYPE_RX (UINT32_C(0x2) << 0)
+ uint8_t unused_0;
+ uint16_t ring_id;
+ uint32_t unused_1;
+} __attribute__((packed));
+
+struct hwrm_ring_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_ring_grp_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint16_t cr;
+ uint16_t rr;
+ uint16_t ar;
+ uint16_t sc;
+} __attribute__((packed));
+
+struct hwrm_ring_grp_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t ring_group_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_ring_grp_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t ring_group_id;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_ring_grp_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_filter_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t flags;
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH UINT32_C(0x1)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_TX (UINT32_C(0x0) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX (UINT32_C(0x1) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK UINT32_C(0x2)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP UINT32_C(0x4)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST UINT32_C(0x8)
+ uint32_t enables;
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR UINT32_C(0x1)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK UINT32_C(0x2)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN UINT32_C(0x4)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK UINT32_C(0x8)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN UINT32_C(0x10)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK UINT32_C(0x20)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR UINT32_C(0x40)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR_MASK UINT32_C(0x80)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN UINT32_C(0x100)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN_MASK UINT32_C(0x200)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN UINT32_C(0x400)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN_MASK UINT32_C(0x800)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE UINT32_C(0x1000)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID UINT32_C(0x2000)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE UINT32_C(0x4000)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID UINT32_C(0x8000)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID UINT32_C(0x10000)
+ uint8_t l2_addr[6];
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t l2_addr_mask[6];
+ uint16_t l2_ovlan;
+ uint16_t l2_ovlan_mask;
+ uint16_t l2_ivlan;
+ uint16_t l2_ivlan_mask;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t t_l2_addr[6];
+ uint8_t unused_4;
+ uint8_t unused_5;
+ uint8_t t_l2_addr_mask[6];
+ uint16_t t_l2_ovlan;
+ uint16_t t_l2_ovlan_mask;
+ uint16_t t_l2_ivlan;
+ uint16_t t_l2_ivlan_mask;
+ uint8_t src_type;
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_NPORT (UINT32_C(0x0) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF (UINT32_C(0x1) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF (UINT32_C(0x2) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC (UINT32_C(0x3) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG (UINT32_C(0x4) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE (UINT32_C(0x5) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO (UINT32_C(0x6) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG (UINT32_C(0x7) << 0)
+ uint8_t unused_6;
+ uint32_t src_id;
+ uint8_t tunnel_type;
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+ (UINT32_C(0x0) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN (UINT32_C(0x1) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE (UINT32_C(0x2) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE (UINT32_C(0x3) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP (UINT32_C(0x4) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE (UINT32_C(0x5) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS (UINT32_C(0x6) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT (UINT32_C(0x7) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE (UINT32_C(0x8) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+ (UINT32_C(0xff) << 0)
+ uint8_t unused_7;
+ uint16_t dst_id;
+ uint16_t mirror_vnic_id;
+ uint8_t pri_hint;
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER (UINT32_C(0x0) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+ (UINT32_C(0x1) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+ (UINT32_C(0x2) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX (UINT32_C(0x3) << 0)
+#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN (UINT32_C(0x4) << 0)
+ uint8_t unused_8;
+ uint32_t unused_9;
+ uint64_t l2_filter_id_hint;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_filter_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint64_t l2_filter_id;
+ uint32_t flow_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_filter_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint64_t l2_filter_id;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_filter_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_set_rx_mask_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t vnic_id;
+ uint32_t mask;
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_RESERVED UINT32_C(0x1)
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST UINT32_C(0x2)
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST UINT32_C(0x4)
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST UINT32_C(0x8)
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS UINT32_C(0x10)
+#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST UINT32_C(0x20)
+ uint64_t mc_tbl_addr;
+ uint32_t num_mc_entries;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_cfa_l2_set_rx_mask_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_alloc_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint64_t stats_dma_addr;
+ uint32_t update_period_ms;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_alloc_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t stat_ctx_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_free_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t stat_ctx_id;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_free_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t stat_ctx_id;
+ uint8_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_clr_stats_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t stat_ctx_id;
+ uint32_t unused_0;
+} __attribute__((packed));
+
+struct hwrm_stat_ctx_clr_stats_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+
+struct hwrm_exec_fwd_resp_input {
+ uint16_t req_type;
+ uint16_t cmpl_ring;
+ uint16_t seq_id;
+ uint16_t target_id;
+ uint64_t resp_addr;
+ uint32_t encap_request[26];
+ uint16_t encap_resp_target_id;
+ uint16_t unused_0[3];
+} __attribute__((packed));
+
+struct hwrm_exec_fwd_resp_output {
+ uint16_t error_code;
+ uint16_t req_type;
+ uint16_t seq_id;
+ uint16_t resp_len;
+ uint32_t unused_0;
+ uint8_t unused_1;
+ uint8_t unused_2;
+ uint8_t unused_3;
+ uint8_t valid;
+} __attribute__((packed));
+#endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
new file mode 100644
index 0000000..ef35398
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -0,0 +1,4 @@
+DPDK_2.0 {
+
+ local: *;
+};
--
1.9.1
next prev parent reply other threads:[~2016-03-04 21:05 UTC|newest]
Thread overview: 142+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-02 21:36 [dpdk-dev] [PATCH] drivers/net/bnxt New " Stephen Hurd
2016-03-02 21:44 ` Stephen Hemminger
2016-03-02 21:58 ` Thomas Monjalon
2016-03-03 4:08 ` [dpdk-dev] [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
2016-03-03 7:53 ` Simon Kågström
2016-03-03 9:28 ` Thomas Monjalon
2016-03-03 10:22 ` Simon Kågström
2016-03-03 4:08 ` [dpdk-dev] [PATCH 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 3/7] drivers/net/bnxt new driver " Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 5/7] build: add bnxt PMD to build Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 6/7] doc: Add bnxt to overview table Stephen Hurd
2016-03-03 4:08 ` [dpdk-dev] [PATCH 7/7] doc: add guide for new bnxt driver Stephen Hurd
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 0/7] drivers/net/bnxt: new Broadcom " Stephen Hurd
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
2016-04-19 12:41 ` Bruce Richardson
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
2016-04-19 13:01 ` Bruce Richardson
2016-03-04 21:05 ` Stephen Hurd [this message]
2016-03-04 23:02 ` [dpdk-dev] [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hemminger
2016-03-04 23:58 ` Stephen Hurd
2016-04-19 14:19 ` Bruce Richardson
2016-04-19 20:51 ` Stephen Hurd
2016-04-20 11:01 ` Bruce Richardson
2016-04-20 21:32 ` Stephen Hurd
2016-04-21 10:00 ` Bruce Richardson
2016-04-21 10:11 ` Thomas Monjalon
2016-05-06 19:25 ` [dpdk-dev] [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 02/40] bnxt: add HWRM init code Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 03/40] bnxt: add driver register/unregister support Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 04/40] bnxt: add dev infos get operation Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 05/40] bnxt: add dev configure operation Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 06/40] bnxt: add vnic functions and structs Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 07/40] bnxt: declare ring structs and free() func Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 08/40] bnxt: add completion ring support Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 12/40] bnxt: statistics operations Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 13/40] bnxt: initial Tx ring code Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 14/40] bnxt: initial Rx " Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 15/40] bnxt: alloc/free ring information Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 16/40] bnxt: add HWRM function reset command Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 18/40] bnxt: add HWRM vnic free function Stephen Hurd
2016-05-06 19:25 ` [dpdk-dev] [PATCH 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 25/40] bnxt: add ring group " Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 26/40] bnxt: add HWRM stat context free function Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 27/40] bnxt: add struct forward decl Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 28/40] bnxt: add ring allocation and group init Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 31/40] bnxt: add start/stop/link update operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 33/40] bnxt: add all multicast " Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 34/40] bnxt: add device close operation Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 36/40] bnxt: add dev set link up/down operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 37/40] bnxt: add reta update/query operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 38/40] bnxt: add RSS device operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 39/40] bnxt: add flow control operations Stephen Hurd
2016-05-06 19:26 ` [dpdk-dev] [PATCH 40/40] bnxt: cleanup null pointer checks Stephen Hurd
2016-05-11 4:53 ` [dpdk-dev] [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Panu Matilainen
2016-05-11 20:59 ` Stephen Hurd
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 " Stephen Hurd
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 02/40] bnxt: add HWRM init code Stephen Hurd
2016-05-25 15:05 ` Bruce Richardson
2016-05-25 23:35 ` Stephen Hurd
2016-05-26 9:01 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 03/40] bnxt: add driver register/unregister support Stephen Hurd
2016-05-25 15:11 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 04/40] bnxt: add dev infos get operation Stephen Hurd
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 05/40] bnxt: add dev configure operation Stephen Hurd
2016-05-25 15:25 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 06/40] bnxt: add vnic functions and structs Stephen Hurd
2016-05-25 16:14 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 07/40] bnxt: declare ring structs and free() func Stephen Hurd
2016-05-25 16:37 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 08/40] bnxt: add completion ring support Stephen Hurd
2016-05-25 17:33 ` Bruce Richardson
2016-05-26 9:38 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
2016-05-25 17:51 ` Bruce Richardson
2016-05-13 22:45 ` [dpdk-dev] [PATCH v2 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 12/40] bnxt: statistics operations Stephen Hurd
2016-05-26 9:40 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 13/40] bnxt: initial Tx ring code Stephen Hurd
2016-05-26 10:40 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 14/40] bnxt: initial Rx " Stephen Hurd
2016-05-26 10:52 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 15/40] bnxt: alloc/free ring information Stephen Hurd
2016-05-26 10:59 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 16/40] bnxt: add HWRM function reset command Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 18/40] bnxt: add HWRM vnic free function Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
2016-05-26 12:04 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
2016-05-26 12:06 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
2016-05-26 12:14 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
2016-05-26 12:23 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
2016-05-26 12:45 ` Bruce Richardson
2016-05-26 13:19 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 25/40] bnxt: add ring group " Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 26/40] bnxt: add HWRM stat context free function Stephen Hurd
2016-05-26 13:15 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 27/40] bnxt: add struct forward decl Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 28/40] bnxt: add ring allocation and group init Stephen Hurd
2016-05-26 13:24 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
2016-05-26 13:25 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
2016-05-26 13:39 ` Bruce Richardson
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 31/40] bnxt: add start/stop/link update operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 33/40] bnxt: add all multicast " Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 34/40] bnxt: add device close operation Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 36/40] bnxt: add dev set link up/down operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 37/40] bnxt: add reta update/query operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 38/40] bnxt: add RSS device operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 39/40] bnxt: add flow control operations Stephen Hurd
2016-05-13 22:46 ` [dpdk-dev] [PATCH v2 40/40] bnxt: cleanup null pointer checks Stephen Hurd
2016-05-26 15:20 ` Bruce Richardson
2016-05-25 15:02 ` [dpdk-dev] [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Bruce Richardson
2016-05-25 20:59 ` Stephen Hurd
2016-05-26 9:05 ` Bruce Richardson
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 5/7] build: add bnxt PMD to build Stephen Hurd
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 6/7] doc: Add bnxt to overview table Stephen Hurd
2016-03-04 21:05 ` [dpdk-dev] [PATCH v3 7/7] doc: add guide for new bnxt driver Stephen Hurd
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1457125528-128877-4-git-send-email-stephen.hurd@broadcom.com \
--to=stephen.hurd@broadcom.com \
--cc=dev@dpdk.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).