All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] drivers/net/bnxt New driver for Broadcom bnxt
@ 2016-03-02 21:36 Stephen Hurd
  2016-03-02 21:44 ` Stephen Hemminger
                   ` (2 more replies)
  0 siblings, 3 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-02 21:36 UTC (permalink / raw)
  To: dev

Initial new driver for Broadcom bnxt (Cumulus) devices.
- Adds drivers/net/bnxt and the librte_pmd_bnxt
- Adds bnxt PCI IDs
- Adds support for 2/2.5/25/50Gbps modes to rte_ethdev.h

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 MAINTAINERS                                     |    4 +
 config/common_bsdapp                            |    5 +
 config/common_linuxapp                          |    5 +
 drivers/net/Makefile                            |    1 +
 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                  | 1434 +++++++++++++++++
 drivers/net/bnxt/bnxt_filter.c                  |  175 +++
 drivers/net/bnxt/bnxt_filter.h                  |   74 +
 drivers/net/bnxt/bnxt_hwrm.c                    | 1536 +++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h                    |  103 ++
 drivers/net/bnxt/bnxt_irq.c                     |  155 ++
 drivers/net/bnxt/bnxt_irq.h                     |   51 +
 drivers/net/bnxt/bnxt_ring.c                    |  305 ++++
 drivers/net/bnxt/bnxt_ring.h                    |  104 ++
 drivers/net/bnxt/bnxt_rxq.c                     |  384 +++++
 drivers/net/bnxt/bnxt_rxq.h                     |   77 +
 drivers/net/bnxt/bnxt_rxr.c                     |  370 +++++
 drivers/net/bnxt/bnxt_rxr.h                     |   73 +
 drivers/net/bnxt/bnxt_stats.c                   |  222 +++
 drivers/net/bnxt/bnxt_stats.h                   |   44 +
 drivers/net/bnxt/bnxt_txq.c                     |  165 ++
 drivers/net/bnxt/bnxt_txq.h                     |   81 +
 drivers/net/bnxt/bnxt_txr.c                     |  316 ++++
 drivers/net/bnxt/bnxt_txr.h                     |   71 +
 drivers/net/bnxt/bnxt_vnic.c                    |  284 ++++
 drivers/net/bnxt/bnxt_vnic.h                    |   79 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h          | 1869 +++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map       |    4 +
 lib/librte_eal/common/include/rte_pci_dev_ids.h |   45 +-
 lib/librte_ether/rte_ethdev.h                   |    4 +
 mk/rte.app.mk                                   |    1 +
 34 files changed, 8587 insertions(+), 5 deletions(-)
 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/MAINTAINERS b/MAINTAINERS
index 628bc05..6ee6c3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -359,6 +359,10 @@ F: drivers/crypto/aesni_mb/
 Intel QuickAssist
 F: drivers/crypto/qat/
 
+Broadcom bnxt
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+F: drivers/net/bnxt/
+
 
 Packet processing
 -----------------
diff --git a/config/common_bsdapp b/config/common_bsdapp
index 696382c..f37c7bb 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -276,6 +276,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f1638db..35f544b 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -280,6 +280,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6e4497e..6f0d64b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
+DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt
 DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
 DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
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..20a9c0a
--- /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)
+
+//	uint32_t		rx_copy_thresh;
+	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..7e7df3b
--- /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..1fd5d15
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -0,0 +1,1434 @@
+/*-
+ *   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;	// Minimum RX Producer Buffer BD length field
+	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 = 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_NONFRAG_IPV4_UDP:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_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_NONFRAG_IPV6_UDP:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_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_UDP:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 |
+//                          HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+		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_UDP_IPV4:
+//                      rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV4_UDP;
+//                      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_UDP_IPV6:
+//                      rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV6_UDP;
+//                      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;
+//              case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 | HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6:
+//                      rss_conf->rss_hf = ETH_RSS_UDP;
+//                      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 == true) ||
+	    (!on && vnic->vlan_strip == false)) {
+		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,
+//        .rx_queue_count       = bnxt_rx_queue_count_op,
+//        .rx_descriptor_done   = bnxt_rx_descriptor_done_op,
+	.tx_queue_setup = bnxt_tx_queue_setup_op,
+	.tx_queue_release = bnxt_tx_queue_release_op,
+//        .rx_queue_start       = bnxt_rx_queue_start_op,
+//        .rx_queue_stop        = bnxt_rx_queue_stop_op,
+//        .tx_queue_start       = bnxt_tx_queue_start_op,
+//        .tx_queue_stop        = bnxt_tx_queue_stop_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,
+#if 0				// Phase 2/3
+	.dev_led_on = bnxt_dev_led_on_op,
+	.dev_led_off = bnxt_dev_led_off_op,
+	.queue_stats_mapping_set = bnxt_queue_stats_mapping_set_op,
+	.vlan_tpid_set = bnxt_vlan_tpid_set_op,
+	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.priority_flow_ctrl_set = bnxt_priority_flow_ctrl_set_op,
+	.uc_hash_table_set = bnxt_uc_hash_table_set_op,
+	.uc_all_hash_table_set = bnxt_uc_all_hash_table_set_op,
+	.mirror_rule_set = bnxt_mirror_rule_set_op,
+	.mirror_rule_reset = bnxt_mirror_rule_reset_op,
+	.set_vf_rx_mode = bnxt_set_vf_rx_mode_op,
+	.set_vf_rx = bnxt_set_vf_rx_op,
+	.set_vf_tx = bnxt_set_vf_tx_op,
+	.set_vf_vlan_filter = bnxt_set_vf_vlan_filter_op,
+	.set_queue_rate_limit = bnxt_set_queue_rate_limit_op,
+	.set_vf_rate_limit = bnxt_set_vf_rate_limit_op,
+	.fdir_add_signature_filter = bnxt_fdir_add_signature_filter_op,
+	.fdir_update_signature_filter = bnxt_fdir_update_signature_filter_op,
+	.fdir_remove_signature_filter = bnxt_fdir_remove_signature_filter_op,
+	.fdir_infos_get = bnxt_fdir_info_get_op,
+	.fdir_add_perfect_filter = bnxt_fdir_add_perfect_filter_op,
+	.fdir_update_perfect_filter = bnxt_fdir_update_perfect_filter_op,
+	.fdir_remove_perfect_filter = bnxt_fdir_remove_perfect_filter_op,
+	.fdir_set_masks = bnxt_fdir_set_masks_op,
+	.add_syn_filter = bnxt_add_syn_filter_op,
+	.remove_syn_filter = bnxt_remove_syn_filter_op,
+	.get_syn_filter = bnxt_get_syn_filter_op,
+	.add_ethertype_filter = bnxt_add_ethertype_filter_op,
+	.remove_ethertype_filter = bnxt_remove_ethertype_filter_op,
+	.get_ethertype_filter = bnxt_get_ethertype_filter_op,
+	.add_5tuple_filter = bnxt_add_5tuple_filter_op,
+	.remove_5tuple_filter = bnxt_remove_5tuple_filter_op,
+	.get_5tuple_filter = bnxt_get_5tuple_filter_op,
+#endif
+};
+
+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);
+
+	// Function 2 and 3 don't work in FPGA
+	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;
+	}
+
+	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(&eth_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 %lx, 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..0fd7330
--- /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..2996ba7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -0,0 +1,1536 @@
+/*-
+ *   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;
+	volatile 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 = (volatile uint8_t *)bp->bar0 + i;
+		*(volatile uint32_t *)bar = *data;
+		data++;
+	}
+
+	for (; i < bp->max_req_len; i += 4) {
+		bar = (volatile 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 = (volatile 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;
+RTE_LOG(ERR, PMD, "Forcing link down\n");
+	}
+
+	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..eab5a3d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -0,0 +1,103 @@
+/*-
+ *   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..76f0c60
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -0,0 +1,155 @@
+/*-
+ *   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..f668664
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -0,0 +1,305 @@
+/*-
+ *   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;
+	if ((mz = rte_memzone_lookup(mz_name)) == NULL) {
+		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..751e80c
--- /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..423073c
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -0,0 +1,384 @@
+/*-
+ *   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..44e142d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -0,0 +1,77 @@
+/*-
+ *   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 */
+	//uint8_t			drop_en; /* If not 0, set SRRCTL.Drop_En */
+	//uint8_t			rx_deferred_start; /* not in global dev start */
+
+	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..9f76ae1
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -0,0 +1,370 @@
+/*-
+ *   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..ba25736
--- /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..2db763a
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -0,0 +1,222 @@
+/*-
+ *   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 replaces 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 replaces 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;
+		// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */
+		// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */
+		// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */
+
+		/* We don't have separate XON/XOFF stats. */
+		// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */
+		// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */
+		// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */
+		// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */
+		/**< Total number of queue packets received that are dropped. */
+		// bnxt_stats->ilbpackets;
+		/**< Total number of good packets received from loopback,VF Only */
+		// bnxt_stats->olbpackets;
+		/**< Total number of good packets transmitted to loopback,VF Only */
+		// bnxt_stats->ilbbytes;
+		/**< Total number of good bytes received from loopback,VF Only */
+		// bnxt_stats->olbbytes;
+		/**< Total number of good bytes transmitted to loopback,VF Only */
+	}
+#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;
+	// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */
+	// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */
+	// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */
+
+	/* We don't have separate XON/XOFF stats. */
+	// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */
+	// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */
+	// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */
+	// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */
+	/**< Total number of queue packets received that are dropped. */
+	// bnxt_stats->ilbpackets;
+	/**< Total number of good packets received from loopback,VF Only */
+	// bnxt_stats->olbpackets;
+	/**< Total number of good packets transmitted to loopback,VF Only */
+	// bnxt_stats->ilbbytes;
+	/**< Total number of good bytes received from loopback,VF Only */
+	// bnxt_stats->olbbytes;
+	/**< Total number of good bytes transmitted to loopback,VF Only */
+#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..a1048b8
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -0,0 +1,165 @@
+/*-
+ *   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..0f499ac
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.h
@@ -0,0 +1,81 @@
+/*-
+ *   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_tail;       /* current value of TDT reg */
+	uint16_t		tx_free_thresh;/* minimum TX before freeing */
+	/** Number of TX descriptors to use before RS bit is set. */
+//	uint16_t		tx_rs_thresh;
+	/** Number of TX descriptors used since RS bit was set. */
+//	uint16_t		nb_tx_used;
+	/** 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..b6edda8
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -0,0 +1,316 @@
+/*-
+ *   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;
+
+	// Setup tx_buf
+	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;
+
+	// Setup txbd
+	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 = 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..1533b23
--- /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..46b0f87
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -0,0 +1,284 @@
+/*-
+ *   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;
+	if ((mz = rte_memzone_lookup(mz_name)) == NULL) {
+		mz = rte_memzone_reserve(mz_name,
+					 entry_length * max_vnics,
+					 SOCKET_ID_ANY,
+					 RTE_MEMZONE_2MB |
+					 RTE_MEMZONE_SIZE_HINT_ONLY);
+		if (mz == NULL)
+			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..d989d96
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -0,0 +1,79 @@
+/*-
+ *   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..df14be5
--- /dev/null
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -0,0 +1,1869 @@
+/*-
+ *   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_
+
+typedef 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)) ctx_hw_stats_t, *pctx_hw_stats_t;
+#define TX_BD_SHORT_TYPE_TX_BD_SHORT (UINT32_C(0x0) << 0)
+
+typedef 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)) tx_bd_long_t, *ptx_bd_long_t;
+
+typedef 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)) tx_bd_long_hi_t, *ptx_bd_long_hi_t;
+
+typedef 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)) rx_prod_pkt_bd_t, *prx_prod_pkt_bd_t;
+
+typedef 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)) cmpl_base_t, *pcmpl_base_t;
+
+typedef 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)) tx_cmpl_t, *ptx_cmpl_t;
+
+typedef 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)) rx_pkt_cmpl_t, *prx_pkt_cmpl_t;
+
+typedef 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)) rx_pkt_cmpl_hi_t, *prx_pkt_cmpl_hi_t;
+
+typedef 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)) hwrm_fwd_req_cmpl_t, *phwrm_fwd_req_cmpl_t;
+
+typedef 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)) hwrm_async_event_cmpl_t, *phwrm_async_event_cmpl_t;
+#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
+
+typedef struct input
+{
+    uint16_t req_type;
+    uint16_t cmpl_ring;
+    uint16_t seq_id;
+    uint16_t target_id;
+    uint64_t resp_addr;
+} __attribute__((packed)) input_t, *pinput_t;
+
+typedef struct output
+{
+    uint16_t error_code;
+    uint16_t req_type;
+    uint16_t seq_id;
+    uint16_t resp_len;
+} __attribute__((packed)) output_t, *poutput_t;
+
+typedef 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)) cmd_nums_t, *pcmd_nums_t;
+
+typedef 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)) ret_codes_t, *pret_codes_t;
+
+typedef 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)) hwrm_ver_get_input_t, *phwrm_ver_get_input_t;
+
+typedef 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)) hwrm_ver_get_output_t, *phwrm_ver_get_output_t;
+
+typedef 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)) hwrm_func_reset_input_t, *phwrm_func_reset_input_t;
+
+typedef 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)) hwrm_func_reset_output_t, *phwrm_func_reset_output_t;
+
+typedef 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)) hwrm_func_vf_alloc_input_t, *phwrm_func_vf_alloc_input_t;
+
+typedef 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)) hwrm_func_vf_alloc_output_t, *phwrm_func_vf_alloc_output_t;
+
+typedef 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)) hwrm_func_vf_free_input_t, *phwrm_func_vf_free_input_t;
+
+typedef 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)) hwrm_func_vf_free_output_t, *phwrm_func_vf_free_output_t;
+
+typedef 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)) hwrm_func_qcaps_input_t, *phwrm_func_qcaps_input_t;
+
+typedef 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)) hwrm_func_qcaps_output_t, *phwrm_func_qcaps_output_t;
+
+typedef 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)) hwrm_func_qstats_input_t, *phwrm_func_qstats_input_t;
+
+typedef 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)) hwrm_func_qstats_output_t, *phwrm_func_qstats_output_t;
+
+typedef 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)) hwrm_func_clr_stats_input_t, *phwrm_func_clr_stats_input_t;
+
+typedef 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)) hwrm_func_clr_stats_output_t, *phwrm_func_clr_stats_output_t;
+
+typedef 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)) hwrm_func_drv_rgtr_input_t, *phwrm_func_drv_rgtr_input_t;
+
+typedef 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)) hwrm_func_drv_rgtr_output_t, *phwrm_func_drv_rgtr_output_t;
+
+typedef 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)) hwrm_func_drv_unrgtr_input_t, *phwrm_func_drv_unrgtr_input_t;
+
+typedef 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)) hwrm_func_drv_unrgtr_output_t, *phwrm_func_drv_unrgtr_output_t;
+
+typedef 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)) hwrm_func_buf_rgtr_input_t, *phwrm_func_buf_rgtr_input_t;
+
+typedef 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)) hwrm_func_buf_rgtr_output_t, *phwrm_func_buf_rgtr_output_t;
+
+typedef 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)) hwrm_port_phy_cfg_input_t, *phwrm_port_phy_cfg_input_t;
+
+typedef 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)) hwrm_port_phy_cfg_output_t, *phwrm_port_phy_cfg_output_t;
+
+typedef 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)) hwrm_port_phy_qcfg_input_t, *phwrm_port_phy_qcfg_input_t;
+
+typedef 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)) hwrm_port_phy_qcfg_output_t, *phwrm_port_phy_qcfg_output_t;
+
+typedef 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)) hwrm_port_qstats_input_t, *phwrm_port_qstats_input_t;
+
+typedef 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)) hwrm_port_qstats_output_t, *phwrm_port_qstats_output_t;
+
+typedef 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)) hwrm_port_clr_stats_input_t, *phwrm_port_clr_stats_input_t;
+
+typedef 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)) hwrm_port_clr_stats_output_t, *phwrm_port_clr_stats_output_t;
+
+typedef 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)) hwrm_queue_qportcfg_input_t, *phwrm_queue_qportcfg_input_t;
+
+typedef 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)) hwrm_queue_qportcfg_output_t, *phwrm_queue_qportcfg_output_t;
+
+typedef 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)) hwrm_vnic_alloc_input_t, *phwrm_vnic_alloc_input_t;
+
+typedef 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)) hwrm_vnic_alloc_output_t, *phwrm_vnic_alloc_output_t;
+
+typedef 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)) hwrm_vnic_free_input_t, *phwrm_vnic_free_input_t;
+
+typedef 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)) hwrm_vnic_free_output_t, *phwrm_vnic_free_output_t;
+
+typedef 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)) hwrm_vnic_cfg_input_t, *phwrm_vnic_cfg_input_t;
+
+typedef 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)) hwrm_vnic_cfg_output_t, *phwrm_vnic_cfg_output_t;
+
+typedef 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)) hwrm_vnic_rss_cfg_input_t, *phwrm_vnic_rss_cfg_input_t;
+
+typedef 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)) hwrm_vnic_rss_cfg_output_t, *phwrm_vnic_rss_cfg_output_t;
+
+typedef 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)) hwrm_vnic_rss_cos_lb_ctx_alloc_input_t, *phwrm_vnic_rss_cos_lb_ctx_alloc_input_t;
+
+typedef 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)) hwrm_vnic_rss_cos_lb_ctx_alloc_output_t, *phwrm_vnic_rss_cos_lb_ctx_alloc_output_t;
+
+typedef 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)) hwrm_vnic_rss_cos_lb_ctx_free_input_t, *phwrm_vnic_rss_cos_lb_ctx_free_input_t;
+
+typedef 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)) hwrm_vnic_rss_cos_lb_ctx_free_output_t, *phwrm_vnic_rss_cos_lb_ctx_free_output_t;
+
+typedef 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)) hwrm_ring_alloc_input_t, *phwrm_ring_alloc_input_t;
+
+typedef 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)) hwrm_ring_alloc_output_t, *phwrm_ring_alloc_output_t;
+
+typedef 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)) hwrm_ring_free_input_t, *phwrm_ring_free_input_t;
+
+typedef 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)) hwrm_ring_free_output_t, *phwrm_ring_free_output_t;
+
+typedef 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)) hwrm_ring_grp_alloc_input_t, *phwrm_ring_grp_alloc_input_t;
+
+typedef 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)) hwrm_ring_grp_alloc_output_t, *phwrm_ring_grp_alloc_output_t;
+
+typedef 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)) hwrm_ring_grp_free_input_t, *phwrm_ring_grp_free_input_t;
+
+typedef 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)) hwrm_ring_grp_free_output_t, *phwrm_ring_grp_free_output_t;
+
+typedef 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)) hwrm_cfa_l2_filter_alloc_input_t, *phwrm_cfa_l2_filter_alloc_input_t;
+
+typedef 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)) hwrm_cfa_l2_filter_alloc_output_t, *phwrm_cfa_l2_filter_alloc_output_t;
+
+typedef 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)) hwrm_cfa_l2_filter_free_input_t, *phwrm_cfa_l2_filter_free_input_t;
+
+typedef 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)) hwrm_cfa_l2_filter_free_output_t, *phwrm_cfa_l2_filter_free_output_t;
+
+typedef 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)) hwrm_cfa_l2_set_rx_mask_input_t, *phwrm_cfa_l2_set_rx_mask_input_t;
+
+typedef 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)) hwrm_cfa_l2_set_rx_mask_output_t, *phwrm_cfa_l2_set_rx_mask_output_t;
+
+typedef 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)) hwrm_stat_ctx_alloc_input_t, *phwrm_stat_ctx_alloc_input_t;
+
+typedef 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)) hwrm_stat_ctx_alloc_output_t, *phwrm_stat_ctx_alloc_output_t;
+
+typedef 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)) hwrm_stat_ctx_free_input_t, *phwrm_stat_ctx_free_input_t;
+
+typedef 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)) hwrm_stat_ctx_free_output_t, *phwrm_stat_ctx_free_output_t;
+
+typedef 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)) hwrm_stat_ctx_clr_stats_input_t, *phwrm_stat_ctx_clr_stats_input_t;
+
+typedef 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)) hwrm_stat_ctx_clr_stats_output_t, *phwrm_stat_ctx_clr_stats_output_t;
+
+typedef 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)) hwrm_exec_fwd_resp_input_t, *phwrm_exec_fwd_resp_input_t;
+
+typedef 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)) hwrm_exec_fwd_resp_output_t, *phwrm_exec_fwd_resp_output_t;
+#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: *;
+};
diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index d088191..9a8f254 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -63,11 +63,11 @@
  * This file contains a list of the PCI device IDs recognised by DPDK, which
  * can be used to fill out an array of structures describing the devices.
  *
- * Currently four families of devices are recognised: those supported by the
- * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
- * driver which is a para virtualization driver running in guest virtual machine.
- * The inclusion of these in an array built using this file depends on the
- * definition of
+ * Currently five families of devices are recognised: those supported by the
+ * IGB driver, by EM driver, those supported by the IXGBE driver, by BNXT
+ * driver, and by virtio driver which is a para virtualization driver running
+ * in guest virtual machine.  The inclusion of these in an array built using
+ * this file depends on the definition of
  * RTE_PCI_DEV_ID_DECL_EM
  * RTE_PCI_DEV_ID_DECL_IGB
  * RTE_PCI_DEV_ID_DECL_IGBVF
@@ -76,6 +76,7 @@
  * RTE_PCI_DEV_ID_DECL_I40E
  * RTE_PCI_DEV_ID_DECL_I40EVF
  * RTE_PCI_DEV_ID_DECL_VIRTIO
+ * RTE_PCI_DEV_ID_DECL_BNXT
  * at the time when this file is included.
  *
  * In order to populate an array, the user of this file must define this macro:
@@ -167,6 +168,15 @@
 #define PCI_VENDOR_ID_VMWARE 0x15AD
 #endif
 
+#ifndef PCI_VENDOR_ID_BROADCOM
+/** Vendor ID used by Broadcom devices */
+#define PCI_VENDOR_ID_BROADCOM 0x14E4
+#endif
+
+#ifndef RTE_PCI_DEV_ID_DECL_BNXT
+#define RTE_PCI_DEV_ID_DECL_BNXT(vendor, dev)
+#endif
+
 #ifndef PCI_VENDOR_ID_CISCO
 /** Vendor ID used by Cisco VIC devices */
 #define PCI_VENDOR_ID_CISCO 0x1137
@@ -592,6 +602,30 @@ RTE_PCI_DEV_ID_DECL_VIRTIO(PCI_VENDOR_ID_QUMRANET, QUMRANET_DEV_ID_VIRTIO)
 
 RTE_PCI_DEV_ID_DECL_VMXNET3(PCI_VENDOR_ID_VMWARE, VMWARE_DEV_ID_VMXNET3)
 
+/****************** Broadcom BNXT devices ******************/
+
+#define BROADCOM_DEV_ID_57301			0x16c8
+#define BROADCOM_DEV_ID_57302			0x16c9
+#define BROADCOM_DEV_ID_57304_PF		0x16ca
+#define BROADCOM_DEV_ID_57304_VF		0x16cb
+#define BROADCOM_DEV_ID_57304_MF		0x16cc
+#define BROADCOM_DEV_ID_57402			0x16d0
+#define BROADCOM_DEV_ID_57404			0x16d1
+#define BROADCOM_DEV_ID_57406_PF		0x16d2
+#define BROADCOM_DEV_ID_57406_VF		0x16d3
+#define BROADCOM_DEV_ID_57406_MF		0x16d4
+
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_MF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF)
+
 /*************** Virtual FM10K devices from fm10k_type.h ***************/
 
 #define FM10K_DEV_ID_VF                   0x15A5
@@ -665,5 +699,6 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #undef RTE_PCI_DEV_ID_DECL_I40EVF
 #undef RTE_PCI_DEV_ID_DECL_VIRTIO
 #undef RTE_PCI_DEV_ID_DECL_VMXNET3
+#undef RTE_PCI_DEV_ID_DECL_BNXT
 #undef RTE_PCI_DEV_ID_DECL_FM10K
 #undef RTE_PCI_DEV_ID_DECL_FM10KVF
diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..cb40bbb 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -254,10 +254,14 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
 #define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
 #define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
+#define ETH_LINK_SPEED_2000     2000    /**< 2 gigabits/second. */
+#define ETH_LINK_SPEED_2500     2500    /**< 2.5 gigabits/second. */
 #define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
 #define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
+#define ETH_LINK_SPEED_25G      25000	/**< 25 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+#define ETH_LINK_SPEED_50G      50000   /**< 50 gigabits/second. */
 
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8ecab41..2b5153e 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,6 +144,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCH] drivers/net/bnxt New driver for Broadcom bnxt
  2016-03-02 21:36 [PATCH] drivers/net/bnxt New driver for Broadcom bnxt Stephen Hurd
@ 2016-03-02 21:44 ` Stephen Hemminger
  2016-03-02 21:58 ` Thomas Monjalon
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
  2 siblings, 0 replies; 142+ messages in thread
From: Stephen Hemminger @ 2016-03-02 21:44 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

Please split into pieces, at a minimum:
  * changes to base DPDK code, you are changing lib/librte_ether
  * driver files
  * config to enable, MAINTAINERS etc.

Also lots and lots of checkpatch errors:

Results of: DPDK_CHECKPATCH_PATH=$HOME/kernel/linux/scripts/checkpatch.pl ./scripts/checkpatches.sh /tmp/bnxt.mbox

ERROR:C99_COMMENTS: do not use C99 // comments
#311: FILE: drivers/net/bnxt/bnxt.h:45:
+// TODO make bnxt.def_cp_ring a pointer to avoid this...

ERROR:OPEN_BRACE: open brace '{' following enum go on the same line
#333: FILE: drivers/net/bnxt/bnxt.h:67:
+enum bnxt_hw_context
+{

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#344: FILE: drivers/net/bnxt/bnxt.h:78:
+^Iuint16_t ^Ifw_fid;$

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#416: FILE: drivers/net/bnxt/bnxt.h:150:
+	#define BNXT_FLAG_DCB_ENABLED	(1<<0)
 	                             	  ^

CHECK:BIT_MACRO: Prefer using the BIT macro
#416: FILE: drivers/net/bnxt/bnxt.h:150:
+	#define BNXT_FLAG_DCB_ENABLED	(1<<0)

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#417: FILE: drivers/net/bnxt/bnxt.h:151:
+	#define BNXT_FLAG_VF		(1<<1)
 	                    		  ^

CHECK:BIT_MACRO: Prefer using the BIT macro
#417: FILE: drivers/net/bnxt/bnxt.h:151:
+	#define BNXT_FLAG_VF		(1<<1)

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#418: FILE: drivers/net/bnxt/bnxt.h:152:
+	#define BNXT_FLAG_LRO		(1<<2)
 	                     		  ^

CHECK:BIT_MACRO: Prefer using the BIT macro
#418: FILE: drivers/net/bnxt/bnxt.h:152:
+	#define BNXT_FLAG_LRO		(1<<2)

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#419: FILE: drivers/net/bnxt/bnxt.h:153:
+	#define BNXT_FLAG_GRO		(1<<3)
 	                     		  ^

CHECK:BIT_MACRO: Prefer using the BIT macro
#419: FILE: drivers/net/bnxt/bnxt.h:153:
+	#define BNXT_FLAG_GRO		(1<<3)

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#420: FILE: drivers/net/bnxt/bnxt.h:154:
+	#define BNXT_FLAG_160B_TCAM	(1<<16)
 	                           	  ^

CHECK:BIT_MACRO: Prefer using the BIT macro
#420: FILE: drivers/net/bnxt/bnxt.h:154:
+	#define BNXT_FLAG_160B_TCAM	(1<<16)

ERROR:C99_COMMENTS: do not use C99 // comments
#425: FILE: drivers/net/bnxt/bnxt.h:159:
+//	uint32_t		rx_copy_thresh;

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#544: FILE: drivers/net/bnxt/bnxt_cpr.c:55:
+		/* Can just prompt the update_op routine to do a qcfg
+		   instead of doing the actual qcfg */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#544: FILE: drivers/net/bnxt/bnxt_cpr.c:55:
+		   instead of doing the actual qcfg */

ERROR:C99_COMMENTS: do not use C99 // comments
#670: FILE: drivers/net/bnxt/bnxt_cpr.h:37:
+// TODO make bnxt_cp_ring_info.cp_ring_struct a pointer to avoid this.

WARNING:LONG_LINE: line over 80 characters
#675: FILE: drivers/net/bnxt/bnxt_cpr.h:42:
+	(!!(((struct cmpl_base *)(cmp))->info3_v & CMPL_BASE_V) ==			\

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#689: FILE: drivers/net/bnxt/bnxt_cpr.h:56:
+#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))

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#693: FILE: drivers/net/bnxt/bnxt_cpr.h:60:
+#define B_CP_DIS_DB(cpr, raw_cons)					\
+		*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS |	\
+				RING_CMP(&cpr->cp_ring_struct, raw_cons))

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#699: FILE: drivers/net/bnxt/bnxt_cpr.h:66:
+^Ivoid ^I^I^I*cp_doorbell;$

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#724: FILE: drivers/net/bnxt/bnxt_cpr.h:91:
+#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

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#728: FILE: drivers/net/bnxt/bnxt_cpr.h:95:
+#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

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#732: FILE: drivers/net/bnxt/bnxt_cpr.h:99:
+#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

WARNING:LONG_LINE: line over 80 characters
#815: FILE: drivers/net/bnxt/bnxt_ethdev.c:59:
+#define DRV_MODULE_VERSION	STRIFY(BNXT_VER_MAJ) "." STRIFY(BNXT_VER_MIN) "." STRIFY(BNXT_VER_UPD)

CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#821: FILE: drivers/net/bnxt/bnxt_ethdev.c:65:
+static struct rte_pci_id bnxt_pci_id_map[] = {
+

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#919: FILE: drivers/net/bnxt/bnxt_ethdev.c:163:
+	/* bp->flags needs to be revisited for other stateless offload
+	   features */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#919: FILE: drivers/net/bnxt/bnxt_ethdev.c:163:
+	   features */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#954: FILE: drivers/net/bnxt/bnxt_ethdev.c:198:
+			/* Fill the RSS hash & redirection table with
+			   ring group ids for all VNICs */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#954: FILE: drivers/net/bnxt/bnxt_ethdev.c:198:
+			   ring group ids for all VNICs */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#1040: FILE: drivers/net/bnxt/bnxt_ethdev.c:284:
+	dev_info->min_rx_bufsize = 1;	// Minimum RX Producer Buffer BD length field

ERROR:C99_COMMENTS: do not use C99 // comments
#1040: FILE: drivers/net/bnxt/bnxt_ethdev.c:284:
+	dev_info->min_rx_bufsize = 1;	// Minimum RX Producer Buffer BD length field

CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#1095: FILE: drivers/net/bnxt/bnxt_ethdev.c:339:
+	vpool = vrxq = 0;

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1174: FILE: drivers/net/bnxt/bnxt_ethdev.c:418:
+	/* The FPGA needs about 10ms of settle time to DMA
+	   the last few completions.

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1175: FILE: drivers/net/bnxt/bnxt_ethdev.c:419:
+	   100ms is the experimental value for reliability purposes */

ERROR:PRINTF_0xDECIMAL: Prefixing 0x with decimal output is defective
#1224: FILE: drivers/net/bnxt/bnxt_ethdev.c:468:
+				"Failed to free VFs with rc = 0x%d!", rc);

ERROR:PRINTF_0xDECIMAL: Prefixing 0x with decimal output is defective
#1264: FILE: drivers/net/bnxt/bnxt_ethdev.c:508:
+				"Failed to retrieve link rc = 0x%d!", rc);

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1406: FILE: drivers/net/bnxt/bnxt_ethdev.c:650:
+	/* If RSS enablement were different than dev_configure,
+	   then return -EINVAL */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1406: FILE: drivers/net/bnxt/bnxt_ethdev.c:650:
+	   then return -EINVAL */

ERROR:C99_COMMENTS: do not use C99 // comments
#1422: FILE: drivers/net/bnxt/bnxt_ethdev.c:666:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;

ERROR:C99_COMMENTS: do not use C99 // comments
#1431: FILE: drivers/net/bnxt/bnxt_ethdev.c:675:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;

ERROR:C99_COMMENTS: do not use C99 // comments
#1438: FILE: drivers/net/bnxt/bnxt_ethdev.c:682:
+//              hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 |

ERROR:C99_COMMENTS: do not use C99 // comments
#1439: FILE: drivers/net/bnxt/bnxt_ethdev.c:683:
+//                          HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1451: FILE: drivers/net/bnxt/bnxt_ethdev.c:695:
+			/* Use the supplied key if the key length is
+			   acceptable and the rss_key is not NULL */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1451: FILE: drivers/net/bnxt/bnxt_ethdev.c:695:
+			   acceptable and the rss_key is not NULL */

ERROR:C99_COMMENTS: do not use C99 // comments
#1484: FILE: drivers/net/bnxt/bnxt_ethdev.c:728:
+//              case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4:

ERROR:C99_COMMENTS: do not use C99 // comments
#1485: FILE: drivers/net/bnxt/bnxt_ethdev.c:729:
+//                      rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV4_UDP;

ERROR:C99_COMMENTS: do not use C99 // comments
#1486: FILE: drivers/net/bnxt/bnxt_ethdev.c:730:
+//                      break;

ERROR:C99_COMMENTS: do not use C99 // comments
#1493: FILE: drivers/net/bnxt/bnxt_ethdev.c:737:
+//              case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6:

ERROR:C99_COMMENTS: do not use C99 // comments
#1494: FILE: drivers/net/bnxt/bnxt_ethdev.c:738:
+//                      rss_conf->rss_hf = ETH_RSS_NONFRAG_IPV6_UDP;

ERROR:C99_COMMENTS: do not use C99 // comments
#1495: FILE: drivers/net/bnxt/bnxt_ethdev.c:739:
+//                      break;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#1500: FILE: drivers/net/bnxt/bnxt_ethdev.c:744:
+//              case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 | HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6:

ERROR:C99_COMMENTS: do not use C99 // comments
#1500: FILE: drivers/net/bnxt/bnxt_ethdev.c:744:
+//              case HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4 | HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6:

ERROR:C99_COMMENTS: do not use C99 // comments
#1501: FILE: drivers/net/bnxt/bnxt_ethdev.c:745:
+//                      rss_conf->rss_hf = ETH_RSS_UDP;

ERROR:C99_COMMENTS: do not use C99 // comments
#1502: FILE: drivers/net/bnxt/bnxt_ethdev.c:746:
+//                      break;

ERROR:SPACING: spaces required around that ':' (ctx:VxE)
#1503: FILE: drivers/net/bnxt/bnxt_ethdev.c:747:
+		default:
 		       ^

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1537: FILE: drivers/net/bnxt/bnxt_ethdev.c:781:
+	/* TODO: If the device is active:
+	   - Close NIC

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1559: FILE: drivers/net/bnxt/bnxt_ethdev.c:803:
+	/* Loop through all VNICs from the specified filter flow pools to
+	   remove the corresponding MAC addr filter */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1559: FILE: drivers/net/bnxt/bnxt_ethdev.c:803:
+	   remove the corresponding MAC addr filter */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1626: FILE: drivers/net/bnxt/bnxt_ethdev.c:870:
+		/* For each VNIC and each associated filter(s)
+		   if VLAN exists && VLAN matches vlan_id

WARNING:LONG_LINE: line over 80 characters
#1638: FILE: drivers/net/bnxt/bnxt_ethdev.c:882:
+				    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN &&

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1649: FILE: drivers/net/bnxt/bnxt_ethdev.c:893:
+					/* Need to examine to see if the MAC
+					   filter already existed or not before

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1650: FILE: drivers/net/bnxt/bnxt_ethdev.c:894:
+					   allocating a new one */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1662: FILE: drivers/net/bnxt/bnxt_ethdev.c:906:
+					/* Inherit MAC from the previous
+					   filter */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#1662: FILE: drivers/net/bnxt/bnxt_ethdev.c:906:
+					   filter */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1691: FILE: drivers/net/bnxt/bnxt_ethdev.c:935:
+		/* For each VNIC and each associated filter(s)
+		   if VLAN exists:

WARNING:LONG_LINE: line over 80 characters
#1706: FILE: drivers/net/bnxt/bnxt_ethdev.c:950:
+				    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN) {

WARNING:LONG_LINE: line over 80 characters
#1736: FILE: drivers/net/bnxt/bnxt_ethdev.c:980:
+					HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |

WARNING:LONG_LINE: line over 80 characters
#1737: FILE: drivers/net/bnxt/bnxt_ethdev.c:981:
+					HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;

CHECK:BOOL_COMPARISON: Using comparison to true is error prone
#1782: FILE: drivers/net/bnxt/bnxt_ethdev.c:1026:
+	if ((on && vnic->vlan_strip == true) ||

CHECK:BOOL_COMPARISON: Using comparison to false is error prone
#1783: FILE: drivers/net/bnxt/bnxt_ethdev.c:1027:
+	    (!on && vnic->vlan_strip == false)) {

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#1797: FILE: drivers/net/bnxt/bnxt_ethdev.c:1041:
+	/* TODO: If there are other rx queues that belong to the same VNIC,
+		 we have the following options:

ERROR:SWITCH_CASE_INDENT_LEVEL: switch and case should be at the same indent
#1830: FILE: drivers/net/bnxt/bnxt_ethdev.c:1074:
+	switch(bp->link_info.pause) {
+		case 0:
[...]
+		case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX:
[...]
+		case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:
[...]
+		case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:

ERROR:SPACING: space required before the open parenthesis '('
#1830: FILE: drivers/net/bnxt/bnxt_ethdev.c:1074:
+	switch(bp->link_info.pause) {

WARNING:LONG_LINE: line over 80 characters
#1840: FILE: drivers/net/bnxt/bnxt_ethdev.c:1084:
+		case HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX | HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX:

ERROR:SWITCH_CASE_INDENT_LEVEL: switch and case should be at the same indent
#1852: FILE: drivers/net/bnxt/bnxt_ethdev.c:1096:
+	switch(fc_conf->mode) {
+		case RTE_FC_NONE:
[...]
+		case RTE_FC_RX_PAUSE:
[...]
+		case RTE_FC_TX_PAUSE:
[...]
+		case RTE_FC_FULL:

ERROR:SPACING: space required before the open parenthesis '('
#1852: FILE: drivers/net/bnxt/bnxt_ethdev.c:1096:
+	switch(fc_conf->mode) {

WARNING:LONG_LINE: line over 80 characters
#1859: FILE: drivers/net/bnxt/bnxt_ethdev.c:1103:
+				bp->link_info.auto_pause = HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#1862: FILE: drivers/net/bnxt/bnxt_ethdev.c:1106:
+			}
+			else {

WARNING:LONG_LINE: line over 80 characters
#1864: FILE: drivers/net/bnxt/bnxt_ethdev.c:1108:
+				bp->link_info.force_pause = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;

WARNING:LONG_LINE: line over 80 characters
#1869: FILE: drivers/net/bnxt/bnxt_ethdev.c:1113:
+				bp->link_info.auto_pause = HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX;

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#1872: FILE: drivers/net/bnxt/bnxt_ethdev.c:1116:
+			}
+			else {

WARNING:LONG_LINE: line over 80 characters
#1874: FILE: drivers/net/bnxt/bnxt_ethdev.c:1118:
+				bp->link_info.force_pause = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX;

WARNING:LONG_LINE: line over 80 characters
#1879: FILE: drivers/net/bnxt/bnxt_ethdev.c:1123:
+				bp->link_info.auto_pause = HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX |

WARNING:LONG_LINE: line over 80 characters
#1880: FILE: drivers/net/bnxt/bnxt_ethdev.c:1124:
+						HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX;

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#1883: FILE: drivers/net/bnxt/bnxt_ethdev.c:1127:
+			}
+			else {

WARNING:LONG_LINE: line over 80 characters
#1885: FILE: drivers/net/bnxt/bnxt_ethdev.c:1129:
+				bp->link_info.force_pause = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX |

WARNING:LONG_LINE: line over 80 characters
#1886: FILE: drivers/net/bnxt/bnxt_ethdev.c:1130:
+						HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX;

ERROR:C99_COMMENTS: do not use C99 // comments
#1909: FILE: drivers/net/bnxt/bnxt_ethdev.c:1153:
+//        .rx_queue_count       = bnxt_rx_queue_count_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1910: FILE: drivers/net/bnxt/bnxt_ethdev.c:1154:
+//        .rx_descriptor_done   = bnxt_rx_descriptor_done_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1913: FILE: drivers/net/bnxt/bnxt_ethdev.c:1157:
+//        .rx_queue_start       = bnxt_rx_queue_start_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1914: FILE: drivers/net/bnxt/bnxt_ethdev.c:1158:
+//        .rx_queue_stop        = bnxt_rx_queue_stop_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1915: FILE: drivers/net/bnxt/bnxt_ethdev.c:1159:
+//        .tx_queue_start       = bnxt_tx_queue_start_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1916: FILE: drivers/net/bnxt/bnxt_ethdev.c:1160:
+//        .tx_queue_stop        = bnxt_tx_queue_stop_op,

ERROR:C99_COMMENTS: do not use C99 // comments
#1933: FILE: drivers/net/bnxt/bnxt_ethdev.c:1177:
+#if 0				// Phase 2/3

CHECK:REDUNDANT_CODE: if this code is redundant consider removing it
#1933: FILE: drivers/net/bnxt/bnxt_ethdev.c:1177:
+#if 0				// Phase 2/3

WARNING:BRACES: braces {} are not necessary for single statement blocks
#2003: FILE: drivers/net/bnxt/bnxt_ethdev.c:1247:
+	if (bp->bar0) {
+		bp->bar0 = NULL;
+	}

ERROR:C99_COMMENTS: do not use C99 // comments
#2022: FILE: drivers/net/bnxt/bnxt_ethdev.c:1266:
+	// Function 2 and 3 don't work in FPGA

CHECK:LOGICAL_CONTINUATIONS: Logical continuations should be on the previous line
#2024: FILE: drivers/net/bnxt/bnxt_ethdev.c:1268:
+	if (eth_dev->pci_dev->addr.function >= 2
+	    && eth_dev->pci_dev->addr.function < 4) {

CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#2135: FILE: drivers/net/bnxt/bnxt_ethdev.c:1379:
+
+		}

WARNING:LONG_LINE: line over 80 characters
#2260: FILE: drivers/net/bnxt/bnxt_filter.c:64:
+				HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK;

CHECK:SPACING: No space is necessary after a cast
#2581: FILE: drivers/net/bnxt/bnxt_hwrm.c:124:
+				valid = (uint8_t *) resp + resp->resp_len - 1;

WARNING:TRAILING_SEMICOLON: macros should not use a trailing semicolon
#2602: FILE: drivers/net/bnxt/bnxt_hwrm.c:145:
+#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);

ERROR:SPACING: space prohibited after that open parenthesis '('
#2604: FILE: drivers/net/bnxt/bnxt_hwrm.c:147:
+	req.req_type = rte_cpu_to_le_16( HWRM_##type ); \

ERROR:SPACING: space prohibited before that close parenthesis ')'
#2604: FILE: drivers/net/bnxt/bnxt_hwrm.c:147:
+	req.req_type = rte_cpu_to_le_16( HWRM_##type ); \

ERROR:SPACING: space prohibited after that open parenthesis '('
#2605: FILE: drivers/net/bnxt/bnxt_hwrm.c:148:
+	req.cmpl_ring = rte_cpu_to_le_16( cr ); \

ERROR:SPACING: space prohibited before that close parenthesis ')'
#2605: FILE: drivers/net/bnxt/bnxt_hwrm.c:148:
+	req.cmpl_ring = rte_cpu_to_le_16( cr ); \

ERROR:SPACING: space prohibited after that open parenthesis '('
#2606: FILE: drivers/net/bnxt/bnxt_hwrm.c:149:
+	req.seq_id = rte_cpu_to_le_16( bp->hwrm_cmd_seq++ ); \

ERROR:SPACING: space prohibited before that close parenthesis ')'
#2606: FILE: drivers/net/bnxt/bnxt_hwrm.c:149:
+	req.seq_id = rte_cpu_to_le_16( bp->hwrm_cmd_seq++ ); \

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#2611: FILE: drivers/net/bnxt/bnxt_hwrm.c:154:
+#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; \
+	}

WARNING:MACRO_WITH_FLOW_CONTROL: Macros with flow control statements should be avoided
#2611: FILE: drivers/net/bnxt/bnxt_hwrm.c:154:
+#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; \
+	}

CHECK:BRACES: Blank lines aren't necessary after an open brace '{'
#2862: FILE: drivers/net/bnxt/bnxt_hwrm.c:405:
+	for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++) {
+

CHECK:SPACING: space preferred before that '|' (ctx:ExE)
#2936: FILE: drivers/net/bnxt/bnxt_hwrm.c:479:
+					       |
 					       ^

WARNING:LONG_LINE: line over 80 characters
#2937: FILE: drivers/net/bnxt/bnxt_hwrm.c:480:
+					       HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID);

WARNING:LONG_LINE: line over 80 characters
#3124: FILE: drivers/net/bnxt/bnxt_hwrm.c:667:
+int bnxt_hwrm_func_qstats(struct bnxt *bp, struct hwrm_func_qstats_output *stats)

ERROR:SPACING: spaces required around that '==' (ctx:VxV)
#3190: FILE: drivers/net/bnxt/bnxt_hwrm.c:733:
+#if HWRM_VERSION_MAJOR==0
                       ^

WARNING:LONG_LINE: line over 80 characters
#3194: FILE: drivers/net/bnxt/bnxt_hwrm.c:737:
+			HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);

ERROR:SPACING: space required before the open parenthesis '('
#3204: FILE: drivers/net/bnxt/bnxt_hwrm.c:747:
+	if(my_version != fw_version) {

WARNING:LONG_LINE_STRING: line over 80 characters
#3207: FILE: drivers/net/bnxt/bnxt_hwrm.c:750:
+			RTE_LOG(INFO, PMD, "Firmware API version is newer than driver.\n");

WARNING:LONG_LINE_STRING: line over 80 characters
#3208: FILE: drivers/net/bnxt/bnxt_hwrm.c:751:
+			RTE_LOG(INFO, PMD, "The driver may be missing features.\n");

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#3210: FILE: drivers/net/bnxt/bnxt_hwrm.c:753:
+		}
+		else {

WARNING:LONG_LINE_STRING: line over 80 characters
#3211: FILE: drivers/net/bnxt/bnxt_hwrm.c:754:
+			RTE_LOG(INFO, PMD, "Firmware API version is older than driver.\n");

WARNING:LONG_LINE_STRING: line over 80 characters
#3212: FILE: drivers/net/bnxt/bnxt_hwrm.c:755:
+			RTE_LOG(INFO, PMD, "Not all driver features may be functional.\n");

WARNING:TRAILING_SEMICOLON: macros should not use a trailing semicolon
#3231: FILE: drivers/net/bnxt/bnxt_hwrm.c:774:
+#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;

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#3422: FILE: drivers/net/bnxt/bnxt_hwrm.c:965:
+		}
+		else {

WARNING:LONG_LINE: line over 80 characters
#3424: FILE: drivers/net/bnxt/bnxt_hwrm.c:967:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;

WARNING:LONG_LINE: line over 80 characters
#3426: FILE: drivers/net/bnxt/bnxt_hwrm.c:969:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK;

WARNING:LONG_LINE: line over 80 characters
#3428: FILE: drivers/net/bnxt/bnxt_hwrm.c:971:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED;

ERROR:C99_COMMENTS: do not use C99 // comments
#3433: FILE: drivers/net/bnxt/bnxt_hwrm.c:976:
+		// Set force_pause if there is no auto or if there is a force

WARNING:LONG_LINE: line over 80 characters
#3435: FILE: drivers/net/bnxt/bnxt_hwrm.c:978:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;

WARNING:LONG_LINE: line over 80 characters
#3437: FILE: drivers/net/bnxt/bnxt_hwrm.c:980:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;

WARNING:LONG_LINE: line over 80 characters
#3440: FILE: drivers/net/bnxt/bnxt_hwrm.c:983:
+			req.enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#3442: FILE: drivers/net/bnxt/bnxt_hwrm.c:985:
+	}
+	else {

WARNING:LONG_LINE: line over 80 characters
#3493: FILE: drivers/net/bnxt/bnxt_hwrm.c:1036:
+int bnxt_hwrm_port_qstats(struct bnxt *bp, struct hwrm_port_qstats_output *stats)

WARNING:LONG_LINE: line over 80 characters
#3616: FILE: drivers/net/bnxt/bnxt_hwrm.c:1159:
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr, unsigned idx)

WARNING:LONG_LINE: line over 80 characters
#3624: FILE: drivers/net/bnxt/bnxt_hwrm.c:1167:
+	memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct.ring_size * sizeof(*cpr->cp_desc_ring));

WARNING:LONG_LINE: line over 80 characters
#3644: FILE: drivers/net/bnxt/bnxt_hwrm.c:1187:
+			memset(txr->tx_desc_ring, 0, txr->tx_ring_struct.ring_size * sizeof(*txr->tx_desc_ring));

WARNING:LONG_LINE: line over 80 characters
#3645: FILE: drivers/net/bnxt/bnxt_hwrm.c:1188:
+			memset(txr->tx_buf_ring, 0, txr->tx_ring_struct.ring_size * sizeof(*txr->tx_buf_ring));

WARNING:BRACES: braces {} are not necessary for single statement blocks
#3649: FILE: drivers/net/bnxt/bnxt_hwrm.c:1192:
+		if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID) {
+			bnxt_free_cp_ring(bp, cpr, idx);
+		}

WARNING:LONG_LINE: line over 80 characters
#3666: FILE: drivers/net/bnxt/bnxt_hwrm.c:1209:
+			memset(rxr->rx_desc_ring, 0, rxr->rx_ring_struct.ring_size * sizeof(*rxr->rx_desc_ring));

WARNING:LONG_LINE: line over 80 characters
#3667: FILE: drivers/net/bnxt/bnxt_hwrm.c:1210:
+			memset(rxr->rx_buf_ring, 0, rxr->rx_ring_struct.ring_size * sizeof(*rxr->rx_buf_ring));

WARNING:ONE_SEMICOLON: Statements terminations use 1 semicolon
#3668: FILE: drivers/net/bnxt/bnxt_hwrm.c:1211:
+			rxr->rx_prod = 0;;

WARNING:BRACES: braces {} are not necessary for single statement blocks
#3670: FILE: drivers/net/bnxt/bnxt_hwrm.c:1213:
+		if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID) {
+			bnxt_free_cp_ring(bp, cpr, idx);
+		}

WARNING:BRACES: braces {} are not necessary for single statement blocks
#3679: FILE: drivers/net/bnxt/bnxt_hwrm.c:1222:
+		if (cpr->cp_ring_struct.fw_ring_id != INVALID_HW_RING_ID) {
+			bnxt_free_cp_ring(bp, cpr, 0);
+		}

CHECK:SPACING: No space is necessary after a cast
#3743: FILE: drivers/net/bnxt/bnxt_hwrm.c:1286:
+		if (cpr->hw_stats_ctx_id != (uint32_t) INVALID_STATS_CTX_ID) {

WARNING:LONG_LINE: line over 80 characters
#3942: FILE: drivers/net/bnxt/bnxt_hwrm.c:1485:
+		link->link_speed = bnxt_parse_hw_link_speed(link_info->link_speed);

WARNING:LONG_LINE: line over 80 characters
#3964: FILE: drivers/net/bnxt/bnxt_hwrm.c:1507:
+		link_req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW;

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#3966: FILE: drivers/net/bnxt/bnxt_hwrm.c:1509:
+		/* TODO: Currently, only a subset of speeds are supported
+		   in DPDK */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#3966: FILE: drivers/net/bnxt/bnxt_hwrm.c:1509:
+		   in DPDK */

WARNING:LONG_LINE: line over 80 characters
#3975: FILE: drivers/net/bnxt/bnxt_hwrm.c:1518:
+		link_req.auto_link_speed = HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB;

WARNING:LONG_LINE: line over 80 characters
#4071: FILE: drivers/net/bnxt/bnxt_hwrm.h:72:
+int bnxt_hwrm_func_qstats(struct bnxt *bp, struct hwrm_func_qstats_output *stats);

WARNING:LONG_LINE: line over 80 characters
#4086: FILE: drivers/net/bnxt/bnxt_hwrm.h:87:
+int bnxt_hwrm_port_qstats(struct bnxt *bp, struct hwrm_port_qstats_output *stats);

CHECK:BRACES: Blank lines aren't necessary before a close brace '}'
#4188: FILE: drivers/net/bnxt/bnxt_irq.c:80:
+
+}

CHECK:UNNECESSARY_PARENTHESES: Unnecessary parentheses around bp->pdev->intr_handle
#4259: FILE: drivers/net/bnxt/bnxt_irq.c:151:
+	rte_intr_enable(&(bp->pdev->intr_handle));

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#4380: FILE: drivers/net/bnxt/bnxt_ring.c:54:
+	/* The actual ring is reserved via rte_memzone_reserve API.
+	   The current document/code indicates that:

ERROR:ASSIGN_IN_IF: do not use assignment in if condition
#4466: FILE: drivers/net/bnxt/bnxt_ring.c:140:
+	if ((mz = rte_memzone_lookup(mz_name)) == NULL) {

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#4680: FILE: drivers/net/bnxt/bnxt_ring.h:43:
+#define RTE_MBUF_DATA_DMA_ADDR(mb) \
+	(uint64_t) ((mb)->buf_physaddr + (mb)->data_off)

CHECK:SPACING: No space is necessary after a cast
#4681: FILE: drivers/net/bnxt/bnxt_ring.h:44:
+	(uint64_t) ((mb)->buf_physaddr + (mb)->data_off)

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4684: FILE: drivers/net/bnxt/bnxt_ring.h:47:
+#define DB_IDX_VALID						(0x1<<26)
                     						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4685: FILE: drivers/net/bnxt/bnxt_ring.h:48:
+#define DB_IRQ_DIS						(0x1<<27)
                   						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4686: FILE: drivers/net/bnxt/bnxt_ring.h:49:
+#define DB_KEY_TX						(0x0<<28)
                  						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4687: FILE: drivers/net/bnxt/bnxt_ring.h:50:
+#define DB_KEY_RX						(0x1<<28)
                  						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4688: FILE: drivers/net/bnxt/bnxt_ring.h:51:
+#define DB_KEY_CP						(0x2<<28)
                  						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4689: FILE: drivers/net/bnxt/bnxt_ring.h:52:
+#define DB_KEY_ST						(0x3<<28)
                  						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4690: FILE: drivers/net/bnxt/bnxt_ring.h:53:
+#define DB_KEY_TX_PUSH						(0x4<<28)
                       						    ^

CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
#4691: FILE: drivers/net/bnxt/bnxt_ring.h:54:
+#define DB_LONG_TX_PUSH						(0x2<<24)
                        						    ^

ERROR:C99_COMMENTS: do not use C99 // comments
#4699: FILE: drivers/net/bnxt/bnxt_ring.h:62:
+// TODO: These are derived from the Linux driver assuming 4k pages

CHECK:SPACING: No space is necessary after a cast
#4704: FILE: drivers/net/bnxt/bnxt_ring.h:67:
+#define INVALID_HW_RING_ID      ((uint16_t) -1)

WARNING:BRACES: braces {} are not necessary for single statement blocks
#4803: FILE: drivers/net/bnxt/bnxt_rxq.c:56:
+	if (cpr->hw_stats) {
+		cpr->hw_stats = NULL;
+	}

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#4921: FILE: drivers/net/bnxt/bnxt_rxq.c:174:
+			/* TODO: Configure & associate CFA rule for
+			   each VNIC for each VMDq with MACVLAN, MACVLAN+TC */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#4921: FILE: drivers/net/bnxt/bnxt_rxq.c:174:
+			   each VNIC for each VMDq with MACVLAN, MACVLAN+TC */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#4936: FILE: drivers/net/bnxt/bnxt_rxq.c:189:
+		/* In order to support DCB+RSS, each TC will
+		   be assigned to one VNIC */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#4936: FILE: drivers/net/bnxt/bnxt_rxq.c:189:
+		   be assigned to one VNIC */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#4970: FILE: drivers/net/bnxt/bnxt_rxq.c:223:
+			/* TODO: Configure & associate CFA rule for
+			   each VNIC for each TC */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#4970: FILE: drivers/net/bnxt/bnxt_rxq.c:223:
+			   each VNIC for each TC */

CHECK:SPACING: No space is necessary after a cast
#5117: FILE: drivers/net/bnxt/bnxt_rxq.c:370:
+	    (uint8_t) ((eth_dev->data->dev_conf.

ERROR:C99_COMMENTS: do not use C99 // comments
#5174: FILE: drivers/net/bnxt/bnxt_rxq.h:37:
+// TODO make bnxt_rx_queue.cp_ring and bnxt_rx_queue.rx_ring pointers

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5191: FILE: drivers/net/bnxt/bnxt_rxq.h:54:
+	//uint8_t			drop_en; /* If not 0, set SRRCTL.Drop_En */

ERROR:C99_COMMENTS: do not use C99 // comments
#5191: FILE: drivers/net/bnxt/bnxt_rxq.h:54:
+	//uint8_t			drop_en; /* If not 0, set SRRCTL.Drop_En */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5192: FILE: drivers/net/bnxt/bnxt_rxq.h:55:
+	//uint8_t			rx_deferred_start; /* not in global dev start */

ERROR:C99_COMMENTS: do not use C99 // comments
#5192: FILE: drivers/net/bnxt/bnxt_rxq.h:55:
+	//uint8_t			rx_deferred_start; /* not in global dev start */

ERROR:POINTER_LOCATION: "foo * bar" should be "foo *bar"
#5323: FILE: drivers/net/bnxt/bnxt_rxr.c:103:
+			    struct bnxt_rx_queue *rxq, uint32_t * raw_cons)

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#5364: FILE: drivers/net/bnxt/bnxt_rxr.c:144:
+	}
+	else {

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#5406: FILE: drivers/net/bnxt/bnxt_rxr.c:186:
+	/* All MBUFs are allocated with the same size under DPDK,
+	   no optimization for rx_copy_thresh */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#5406: FILE: drivers/net/bnxt/bnxt_rxr.c:186:
+	   no optimization for rx_copy_thresh */

ERROR:C99_COMMENTS: do not use C99 // comments
#5444: FILE: drivers/net/bnxt/bnxt_rxr.c:224:
+		// TODO: Avoid magic numbers...

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#5459: FILE: drivers/net/bnxt/bnxt_rxr.c:239:
+		/* For PMD, there is no need to keep on pushing to REARM
+		   the doorbell if there are no new completions */

WARNING:BLOCK_COMMENT_STYLE: Block comments use a trailing */ on a separate line
#5459: FILE: drivers/net/bnxt/bnxt_rxr.c:239:
+		   the doorbell if there are no new completions */

WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
#5555: FILE: drivers/net/bnxt/bnxt_rxr.c:335:
+/* XXX
+	if (NET_IP_ALIGN == 2)

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#5633: FILE: drivers/net/bnxt/bnxt_rxr.h:37:
+#define B_RX_DB(db, prod)						\
+		*(uint32_t *)db = (DB_KEY_RX | prod)

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#5651: FILE: drivers/net/bnxt/bnxt_rxr.h:55:
+^Ivoid ^I^I^I*rx_doorbell;$

ERROR:C99_COMMENTS: do not use C99 // comments
#5779: FILE: drivers/net/bnxt/bnxt_stats.c:104:
+		// These get replaces once the *_QSTATS commands work

WARNING:LONG_LINE: line over 80 characters
#5784: FILE: drivers/net/bnxt/bnxt_stats.c:109:
+		bnxt_stats->imcasts += rte_le_to_cpu_64(hw_stats->rx_mcast_pkts);

ERROR:C99_COMMENTS: do not use C99 // comments
#5807: FILE: drivers/net/bnxt/bnxt_stats.c:132:
+		// These get replaces once the *_QSTATS commands work

WARNING:LINE_CONTINUATIONS: Avoid unnecessary line continuations
#5816: FILE: drivers/net/bnxt/bnxt_stats.c:141:
+		bnxt_stats->ipackets = fstats.rx_ucast_pkts + \

WARNING:LINE_CONTINUATIONS: Avoid unnecessary line continuations
#5819: FILE: drivers/net/bnxt/bnxt_stats.c:144:
+		bnxt_stats->opackets = fstats.tx_ucast_pkts + \

WARNING:LINE_CONTINUATIONS: Avoid unnecessary line continuations
#5822: FILE: drivers/net/bnxt/bnxt_stats.c:147:
+		bnxt_stats->ibytes = fstats.rx_ucast_bytes + \

WARNING:LINE_CONTINUATIONS: Avoid unnecessary line continuations
#5824: FILE: drivers/net/bnxt/bnxt_stats.c:149:
+		bnxt_stats->obytes = fstats.tx_ucast_bytes + \

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5835: FILE: drivers/net/bnxt/bnxt_stats.c:160:
+		// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5835: FILE: drivers/net/bnxt/bnxt_stats.c:160:
+		// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5836: FILE: drivers/net/bnxt/bnxt_stats.c:161:
+		// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5836: FILE: drivers/net/bnxt/bnxt_stats.c:161:
+		// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5837: FILE: drivers/net/bnxt/bnxt_stats.c:162:
+		// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5837: FILE: drivers/net/bnxt/bnxt_stats.c:162:
+		// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5840: FILE: drivers/net/bnxt/bnxt_stats.c:165:
+		// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5840: FILE: drivers/net/bnxt/bnxt_stats.c:165:
+		// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5841: FILE: drivers/net/bnxt/bnxt_stats.c:166:
+		// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5841: FILE: drivers/net/bnxt/bnxt_stats.c:166:
+		// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5842: FILE: drivers/net/bnxt/bnxt_stats.c:167:
+		// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5842: FILE: drivers/net/bnxt/bnxt_stats.c:167:
+		// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5843: FILE: drivers/net/bnxt/bnxt_stats.c:168:
+		// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5843: FILE: drivers/net/bnxt/bnxt_stats.c:168:
+		// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5845: FILE: drivers/net/bnxt/bnxt_stats.c:170:
+		// bnxt_stats->ilbpackets;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5846: FILE: drivers/net/bnxt/bnxt_stats.c:171:
+		/**< Total number of good packets received from loopback,VF Only */

ERROR:C99_COMMENTS: do not use C99 // comments
#5847: FILE: drivers/net/bnxt/bnxt_stats.c:172:
+		// bnxt_stats->olbpackets;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5848: FILE: drivers/net/bnxt/bnxt_stats.c:173:
+		/**< Total number of good packets transmitted to loopback,VF Only */

ERROR:C99_COMMENTS: do not use C99 // comments
#5849: FILE: drivers/net/bnxt/bnxt_stats.c:174:
+		// bnxt_stats->ilbbytes;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5850: FILE: drivers/net/bnxt/bnxt_stats.c:175:
+		/**< Total number of good bytes received from loopback,VF Only */

ERROR:C99_COMMENTS: do not use C99 // comments
#5851: FILE: drivers/net/bnxt/bnxt_stats.c:176:
+		// bnxt_stats->olbbytes;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5852: FILE: drivers/net/bnxt/bnxt_stats.c:177:
+		/**< Total number of good bytes transmitted to loopback,VF Only */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5869: FILE: drivers/net/bnxt/bnxt_stats.c:194:
+	// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5869: FILE: drivers/net/bnxt/bnxt_stats.c:194:
+	// bnxt_stats->rx_nombuf += ; /**< Total number of RX mbuf allocation failures. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5870: FILE: drivers/net/bnxt/bnxt_stats.c:195:
+	// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5870: FILE: drivers/net/bnxt/bnxt_stats.c:195:
+	// bnxt_stats->fdirmatch += ; /**< Total number of RX packets matching a filter. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5871: FILE: drivers/net/bnxt/bnxt_stats.c:196:
+	// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5871: FILE: drivers/net/bnxt/bnxt_stats.c:196:
+	// bnxt_stats->fdirmiss;  /**< Total number of RX packets not matching any filter. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5874: FILE: drivers/net/bnxt/bnxt_stats.c:199:
+	// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5874: FILE: drivers/net/bnxt/bnxt_stats.c:199:
+	// bnxt_stats->tx_pause_xon += ;  /**< Total nb. of XON pause frame sent. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5875: FILE: drivers/net/bnxt/bnxt_stats.c:200:
+	// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5875: FILE: drivers/net/bnxt/bnxt_stats.c:200:
+	// bnxt_stats->rx_pause_xon;  /**< Total nb. of XON pause frame received. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5876: FILE: drivers/net/bnxt/bnxt_stats.c:201:
+	// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5876: FILE: drivers/net/bnxt/bnxt_stats.c:201:
+	// bnxt_stats->tx_pause_xoff; /**< Total nb. of XOFF pause frame sent. */

WARNING:LONG_LINE_COMMENT: line over 80 characters
#5877: FILE: drivers/net/bnxt/bnxt_stats.c:202:
+	// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5877: FILE: drivers/net/bnxt/bnxt_stats.c:202:
+	// bnxt_stats->rx_pause_xoff; /**< Total nb. of XOFF pause frame received. */

ERROR:C99_COMMENTS: do not use C99 // comments
#5879: FILE: drivers/net/bnxt/bnxt_stats.c:204:
+	// bnxt_stats->ilbpackets;

ERROR:C99_COMMENTS: do not use C99 // comments
#5881: FILE: drivers/net/bnxt/bnxt_stats.c:206:
+	// bnxt_stats->olbpackets;

ERROR:C99_COMMENTS: do not use C99 // comments
#5883: FILE: drivers/net/bnxt/bnxt_stats.c:208:
+	// bnxt_stats->ilbbytes;

ERROR:C99_COMMENTS: do not use C99 // comments
#5885: FILE: drivers/net/bnxt/bnxt_stats.c:210:
+	// bnxt_stats->olbbytes;

WARNING:BRACES: braces {} are not necessary for single statement blocks
#6005: FILE: drivers/net/bnxt/bnxt_txq.c:52:
+	if (cpr->hw_stats) {
+		cpr->hw_stats = NULL;
+	}

ERROR:C99_COMMENTS: do not use C99 // comments
#6161: FILE: drivers/net/bnxt/bnxt_txq.h:37:
+// TODO make bnxt_tx_queue.cp_ring and bnxt_tx_queue.tx_ring pointers

ERROR:C99_COMMENTS: do not use C99 // comments
#6166: FILE: drivers/net/bnxt/bnxt_txq.h:42:
+	//uint16_t		tx_tail;       /* current value of TDT reg */

ERROR:C99_COMMENTS: do not use C99 // comments
#6169: FILE: drivers/net/bnxt/bnxt_txq.h:45:
+//	uint16_t		tx_rs_thresh;

ERROR:C99_COMMENTS: do not use C99 // comments
#6171: FILE: drivers/net/bnxt/bnxt_txq.h:47:
+//	uint16_t		nb_tx_used;

WARNING:LONG_LINE: line over 80 characters
#6328: FILE: drivers/net/bnxt/bnxt_txr.c:117:
+	return txr->tx_ring_struct.ring_size - ((txr->tx_prod - txr->tx_cons) & txr->tx_ring_struct.ring_mask) - 1;

WARNING:LONG_LINE: line over 80 characters
#6350: FILE: drivers/net/bnxt/bnxt_txr.c:139:
+				PKT_TX_UDP_CKSUM | PKT_TX_IP_CKSUM | PKT_TX_VLAN_PKT))

ERROR:C99_COMMENTS: do not use C99 // comments
#6353: FILE: drivers/net/bnxt/bnxt_txr.c:142:
+	// Setup tx_buf

WARNING:LONG_LINE: line over 80 characters
#6357: FILE: drivers/net/bnxt/bnxt_txr.c:146:
+	last_prod = (txr->tx_prod + tx_buf->nr_bds - 1) & txr->tx_ring_struct.ring_mask;

ERROR:C99_COMMENTS: do not use C99 // comments
#6362: FILE: drivers/net/bnxt/bnxt_txr.c:151:
+	// Setup txbd

CHECK:MULTIPLE_ASSIGNMENTS: multiple assignments should be avoided
#6380: FILE: drivers/net/bnxt/bnxt_txr.c:169:
+		vlan_tag_flags = cfa_action = 0;

WARNING:LONG_LINE_COMMENT: line over 80 characters
#6382: FILE: drivers/net/bnxt/bnxt_txr.c:171:
+			// shurd: Should this mask at TX_BD_LONG_CFA_META_VLAN_VID_MASK?

ERROR:C99_COMMENTS: do not use C99 // comments
#6382: FILE: drivers/net/bnxt/bnxt_txr.c:171:
+			// shurd: Should this mask at TX_BD_LONG_CFA_META_VLAN_VID_MASK?

WARNING:LONG_LINE: line over 80 characters
#6389: FILE: drivers/net/bnxt/bnxt_txr.c:178:
+			vlan_tag_flags |= TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100;

WARNING:LONG_LINE: line over 80 characters
#6394: FILE: drivers/net/bnxt/bnxt_txr.c:183:
+		txbd1 = (struct tx_bd_long_hi *)&txr->tx_desc_ring[txr->tx_prod];

WARNING:LONG_LINE: line over 80 characters
#6406: FILE: drivers/net/bnxt/bnxt_txr.c:195:
+		} else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM | PKT_TX_UDP_CKSUM)) {

ERROR:ELSE_AFTER_BRACE: else should follow close brace '}'
#6417: FILE: drivers/net/bnxt/bnxt_txr.c:206:
+	}
+	else {

ERROR:SPACING: spaces required around that '=' (ctx:VxV)
#6464: FILE: drivers/net/bnxt/bnxt_txr.c:253:
+		for (j=1; j<tx_buf->nr_bds; j++)
 		      ^

ERROR:SPACING: spaces required around that '<' (ctx:VxV)
#6464: FILE: drivers/net/bnxt/bnxt_txr.c:253:
+		for (j=1; j<tx_buf->nr_bds; j++)
 		           ^

WARNING:LONG_LINE: line over 80 characters
#6480: FILE: drivers/net/bnxt/bnxt_txr.c:269:
+	if ((txq->tx_ring.tx_ring_struct.ring_size - (bnxt_tx_avail(&txq->tx_ring))) >

WARNING:LONG_LINE: line over 80 characters
#6492: FILE: drivers/net/bnxt/bnxt_txr.c:281:
+				RTE_LOG(DEBUG, PMD, "Unhandled CMP type %02x\n", CMP_TYPE(txcmp));

CHECK:BRACES: braces {} should be used on all arms of this statement
#6516: FILE: drivers/net/bnxt/bnxt_txr.c:305:
+		if (bnxt_start_xmit(tx_pkts[nb_tx_pkts], txq))
[...]
+		else if((nb_tx_pkts & db_mask) != last_db_mask) {
[...]

ERROR:SPACING: space required before the open parenthesis '('
#6518: FILE: drivers/net/bnxt/bnxt_txr.c:307:
+		else if((nb_tx_pkts & db_mask) != last_db_mask) {

ERROR:COMPLEX_MACRO: Macros with complex values should be enclosed in parentheses
#6573: FILE: drivers/net/bnxt/bnxt_txr.h:40:
+#define B_TX_DB(db, prod)						\
+		*(uint32_t *)db = (DB_KEY_TX | prod)

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#6579: FILE: drivers/net/bnxt/bnxt_txr.h:46:
+^Ivoid ^I^I^I*tx_doorbell;$

ERROR:ASSIGN_IN_IF: do not use assignment in if condition
#6807: FILE: drivers/net/bnxt/bnxt_vnic.c:197:
+	if ((mz = rte_memzone_lookup(mz_name)) == NULL) {

WARNING:LONG_LINE: line over 80 characters
#6949: FILE: drivers/net/bnxt/bnxt_vnic.h:49:
+#define MAX_QUEUES_PER_VNIC	(MAX_NUM_RSS_QUEUES_PER_VNIC + MAX_NUM_TRAFFIC_CLASSES)

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#6954: FILE: drivers/net/bnxt/bnxt_vnic.h:54:
+^Iphys_addr_t ^Irss_table_dma_addr;$

WARNING:SPACE_BEFORE_TAB: please, no space before tabs
#6956: FILE: drivers/net/bnxt/bnxt_vnic.h:56:
+^Iphys_addr_t ^Irss_hash_key_dma_addr;$

CHECK:BIT_MACRO: Prefer using the BIT macro
#6959: FILE: drivers/net/bnxt/bnxt_vnic.h:59:
+#define BNXT_VNIC_INFO_PROMISC			(1 << 0)

CHECK:BIT_MACRO: Prefer using the BIT macro
#6960: FILE: drivers/net/bnxt/bnxt_vnic.h:60:
+#define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7023: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:38:
+    uint64_t rx_ucast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7024: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:39:
+    uint64_t rx_mcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7025: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:40:
+    uint64_t rx_bcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7026: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:41:
+    uint64_t rx_drop_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7027: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:42:
+    uint64_t rx_err_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7028: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:43:
+    uint64_t rx_ucast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7029: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:44:
+    uint64_t rx_mcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7030: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:45:
+    uint64_t rx_bcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7031: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:46:
+    uint64_t tx_ucast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7032: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:47:
+    uint64_t tx_mcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7033: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:48:
+    uint64_t tx_bcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7034: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:49:
+    uint64_t tx_drop_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7035: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:50:
+    uint64_t tx_err_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7036: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:51:
+    uint64_t tx_ucast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7037: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:52:
+    uint64_t tx_mcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7038: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:53:
+    uint64_t tx_bcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7039: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:54:
+    uint64_t tpa_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7040: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:55:
+    uint64_t tpa_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7041: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:56:
+    uint64_t tpa_events;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7042: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:57:
+    uint64_t tpa_aborts;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7045: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:60:
+struct ctx_hw_stats
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7046: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:61:
+    uint32_t rx_ucast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7047: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:62:
+    uint32_t rx_ucast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7048: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:63:
+    uint32_t rx_mcast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7049: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:64:
+    uint32_t rx_mcast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7050: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:65:
+    uint32_t rx_bcast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7051: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:66:
+    uint32_t rx_bcast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7052: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:67:
+    uint32_t rx_discard_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7053: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:68:
+    uint32_t rx_discard_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7054: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:69:
+    uint32_t rx_drop_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7055: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:70:
+    uint32_t rx_drop_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7056: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:71:
+    uint32_t rx_ucast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7057: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:72:
+    uint32_t rx_ucast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7058: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:73:
+    uint32_t rx_mcast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7059: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:74:
+    uint32_t rx_mcast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7060: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:75:
+    uint32_t rx_bcast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7061: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:76:
+    uint32_t rx_bcast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7062: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:77:
+    uint32_t tx_ucast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7063: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:78:
+    uint32_t tx_ucast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7064: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:79:
+    uint32_t tx_mcast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7065: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:80:
+    uint32_t tx_mcast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7066: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:81:
+    uint32_t tx_bcast_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7067: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:82:
+    uint32_t tx_bcast_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7068: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:83:
+    uint32_t tx_discard_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7069: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:84:
+    uint32_t tx_discard_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7070: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:85:
+    uint32_t tx_drop_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7071: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:86:
+    uint32_t tx_drop_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7072: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:87:
+    uint32_t tx_ucast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7073: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:88:
+    uint32_t tx_ucast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7074: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:89:
+    uint32_t tx_mcast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7075: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:90:
+    uint32_t tx_mcast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7076: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:91:
+    uint32_t tx_bcast_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7077: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:92:
+    uint32_t tx_bcast_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7078: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:93:
+    uint32_t tpa_pkts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7079: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:94:
+    uint32_t tpa_pkts_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7080: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:95:
+    uint32_t tpa_bytes_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7081: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:96:
+    uint32_t tpa_bytes_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7082: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:97:
+    uint32_t tpa_events_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7083: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:98:
+    uint32_t tpa_events_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7084: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:99:
+    uint32_t tpa_aborts_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7085: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:100:
+    uint32_t tpa_aborts_hi;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7090: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:105:
+typedef struct tx_bd_long
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7091: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:106:
+    uint16_t flags_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7108: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:123:
+    uint16_t len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7109: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:124:
+    uint32_t opaque;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7110: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:125:
+    uint32_t addr_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7111: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:126:
+    uint32_t addr_hi;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7115: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:130:
+typedef struct tx_bd_long_hi
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7116: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:131:
+    uint16_t lflags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7127: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:142:
+    uint16_t hdr_size;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7130: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:145:
+    uint32_t mss;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7133: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:148:
+    uint16_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7134: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:149:
+    uint16_t cfa_action;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7135: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:150:
+    uint32_t cfa_meta;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7158: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:173:
+typedef struct rx_prod_pkt_bd
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7159: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:174:
+    uint16_t flags_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7169: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:184:
+    uint16_t len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7170: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:185:
+    uint32_t opaque;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7171: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:186:
+    uint32_t addr_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7172: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:187:
+    uint32_t addr_hi;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7176: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:191:
+typedef struct cmpl_base
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7177: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:192:
+    uint16_t type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7195: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:210:
+    uint16_t info1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7196: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:211:
+    uint32_t info2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7197: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:212:
+    uint32_t info3_v;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7201: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:216:
+    uint32_t info4;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7205: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:220:
+typedef struct tx_cmpl
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7206: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:221:
+    uint16_t flags_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7214: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:229:
+    uint16_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7215: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:230:
+    uint32_t opaque;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7216: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:231:
+    uint16_t errors_v;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7229: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:244:
+    uint16_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7230: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:245:
+    uint32_t unused_2;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7234: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:249:
+typedef struct rx_pkt_cmpl
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7235: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:250:
+    uint16_t flags_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7259: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:274:
+    uint16_t len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7260: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:275:
+    uint32_t opaque;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7261: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:276:
+    uint8_t agg_bufs_v1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7265: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:280:
+    uint8_t rss_hash_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7266: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:281:
+    uint8_t payload_offset;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7267: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:282:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7268: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:283:
+    uint32_t rss_hash;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7272: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:287:
+typedef struct rx_pkt_cmpl_hi
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7273: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:288:
+    uint32_t flags2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7283: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:298:
+    uint32_t metadata;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7291: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:306:
+    uint16_t errors_v2;$

WARNING:LONG_LINE: line over 80 characters
#7309: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:324:
+    #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_TUNNEL_TOTAL_ERROR (UINT32_C(0x3) << 9)

WARNING:LONG_LINE: line over 80 characters
#7311: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:326:
+    #define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_UDP_TOTAL_ERROR (UINT32_C(0x5) << 9)

WARNING:LONG_LINE: line over 80 characters
#7322: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:337:
+    #define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL (UINT32_C(0x7) << 12)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7326: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:341:
+    uint16_t cfa_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7327: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:342:
+    uint32_t reorder;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7333: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:348:
+typedef struct hwrm_fwd_req_cmpl
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7334: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:349:
+    uint16_t req_len_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7340: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:355:
+    uint16_t source_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7341: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:356:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7342: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:357:
+    uint64_t req_buf_addr_v;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7349: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:364:
+typedef struct hwrm_async_event_cmpl
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7350: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:365:
+    uint16_t type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7354: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:369:
+    uint16_t event_id;$

WARNING:LONG_LINE: line over 80 characters
#7355: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:370:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#7357: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:372:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE (UINT32_C(0x2) << 0)

WARNING:LONG_LINE: line over 80 characters
#7358: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:373:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE (UINT32_C(0x3) << 0)

WARNING:LONG_LINE: line over 80 characters
#7359: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:374:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED (UINT32_C(0x4) << 0)

WARNING:LONG_LINE: line over 80 characters
#7360: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:375:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED (UINT32_C(0x5) << 0)

WARNING:LONG_LINE: line over 80 characters
#7361: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:376:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD (UINT32_C(0x10) << 0)

WARNING:LONG_LINE: line over 80 characters
#7366: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:381:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE (UINT32_C(0x31) << 0)

WARNING:LONG_LINE: line over 80 characters
#7367: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:382:
+    #define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE (UINT32_C(0x32) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7369: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:384:
+    uint32_t event_data2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7370: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:385:
+    uint8_t opaque_v;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7374: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:389:
+    uint8_t timestamp_lo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7375: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:390:
+    uint16_t timestamp_hi;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7376: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:391:
+    uint32_t event_data1;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7390: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:405:
+typedef struct input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7391: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:406:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7392: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:407:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7393: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:408:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7394: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:409:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7395: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:410:
+    uint64_t resp_addr;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7399: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:414:
+typedef struct output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7400: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:415:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7401: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:416:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7402: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:417:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7403: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:418:
+    uint16_t resp_len;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7407: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:422:
+typedef struct cmd_nums
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7408: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:423:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7508: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:523:
+    uint16_t unused_0[3];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7512: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:527:
+typedef struct ret_codes
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7513: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:528:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7524: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:539:
+    uint16_t unused_0[3];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7528: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:543:
+typedef struct hwrm_ver_get_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7529: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:544:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7530: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:545:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7531: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:546:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7532: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:547:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7533: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:548:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7534: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:549:
+    uint8_t hwrm_intf_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7535: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:550:
+    uint8_t hwrm_intf_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7536: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:551:
+    uint8_t hwrm_intf_upd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7537: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:552:
+    uint8_t unused_0[5];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7541: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:556:
+typedef struct hwrm_ver_get_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7542: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:557:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7543: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:558:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7544: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:559:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7545: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:560:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7546: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:561:
+    uint8_t hwrm_intf_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7547: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:562:
+    uint8_t hwrm_intf_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7548: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:563:
+    uint8_t hwrm_intf_upd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7549: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:564:
+    uint8_t hwrm_intf_rsvd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7550: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:565:
+    uint8_t hwrm_fw_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7551: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:566:
+    uint8_t hwrm_fw_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7552: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:567:
+    uint8_t hwrm_fw_bld;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7553: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:568:
+    uint8_t hwrm_fw_rsvd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7554: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:569:
+    uint8_t mgmt_fw_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7555: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:570:
+    uint8_t mgmt_fw_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7556: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:571:
+    uint8_t mgmt_fw_bld;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7557: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:572:
+    uint8_t mgmt_fw_rsvd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7558: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:573:
+    uint8_t netctrl_fw_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7559: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:574:
+    uint8_t netctrl_fw_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7560: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:575:
+    uint8_t netctrl_fw_bld;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7561: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:576:
+    uint8_t netctrl_fw_rsvd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7562: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:577:
+    uint32_t reserved1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7563: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:578:
+    uint8_t roce_fw_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7564: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:579:
+    uint8_t roce_fw_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7565: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:580:
+    uint8_t roce_fw_bld;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7566: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:581:
+    uint8_t roce_fw_rsvd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7567: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:582:
+    char hwrm_fw_name[16];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7568: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:583:
+    char mgmt_fw_name[16];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7569: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:584:
+    char netctrl_fw_name[16];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7570: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:585:
+    uint32_t reserved2[4];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7571: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:586:
+    char roce_fw_name[16];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7572: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:587:
+    uint16_t chip_num;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7573: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:588:
+    uint8_t chip_rev;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7574: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:589:
+    uint8_t chip_metal;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7575: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:590:
+    uint8_t chip_bond_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7576: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:591:
+    uint8_t chip_platform_type;$

WARNING:LONG_LINE: line over 80 characters
#7579: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:594:
+    #define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM (UINT32_C(0x2) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7580: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:595:
+    uint16_t max_req_win_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7581: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:596:
+    uint16_t max_resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7582: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:597:
+    uint16_t def_req_timeout;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7583: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:598:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7584: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:599:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7585: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:600:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7586: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:601:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7590: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:605:
+typedef struct hwrm_func_reset_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7591: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:606:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7592: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:607:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7593: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:608:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7594: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:609:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7595: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:610:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7596: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:611:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7598: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:613:
+    uint16_t vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7599: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:614:
+    uint8_t func_reset_level;$

WARNING:LONG_LINE: line over 80 characters
#7602: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:617:
+    #define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN (UINT32_C(0x2) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7604: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:619:
+    uint8_t unused_0;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7608: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:623:
+typedef struct hwrm_func_reset_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7609: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:624:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7610: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:625:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7611: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:626:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7612: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:627:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7613: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:628:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7614: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:629:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7615: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:630:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7616: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:631:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7617: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:632:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7621: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:636:
+typedef struct hwrm_func_vf_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7622: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:637:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7623: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:638:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7624: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:639:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7625: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:640:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7626: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:641:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7627: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:642:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7629: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:644:
+    uint16_t first_vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7630: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:645:
+    uint16_t num_vfs;$

WARNING:LONG_LINE: line over 80 characters
#7631: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:646:
+} __attribute__((packed)) hwrm_func_vf_alloc_input_t, *phwrm_func_vf_alloc_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7634: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:649:
+typedef struct hwrm_func_vf_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7635: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:650:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7636: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:651:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7637: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:652:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7638: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:653:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7639: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:654:
+    uint16_t first_vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7640: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:655:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7641: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:656:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7642: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:657:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7643: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:658:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7644: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:659:
+    uint8_t unused_4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7645: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:660:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7646: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:661:
+} __attribute__((packed)) hwrm_func_vf_alloc_output_t, *phwrm_func_vf_alloc_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7649: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:664:
+typedef struct hwrm_func_vf_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7650: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:665:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7651: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:666:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7652: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:667:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7653: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:668:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7654: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:669:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7655: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:670:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7657: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:672:
+    uint16_t first_vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7658: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:673:
+    uint16_t num_vfs;$

WARNING:LONG_LINE: line over 80 characters
#7659: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:674:
+} __attribute__((packed)) hwrm_func_vf_free_input_t, *phwrm_func_vf_free_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7662: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:677:
+typedef struct hwrm_func_vf_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7663: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:678:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7664: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:679:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7665: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:680:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7666: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:681:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7667: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:682:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7668: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:683:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7669: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:684:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7670: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:685:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7671: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:686:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7672: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:687:
+} __attribute__((packed)) hwrm_func_vf_free_output_t, *phwrm_func_vf_free_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7675: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:690:
+typedef struct hwrm_func_qcaps_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7676: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:691:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7677: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:692:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7678: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:693:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7679: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:694:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7680: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:695:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7681: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:696:
+    uint16_t fid;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7682: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:697:
+    uint16_t unused_0[3];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7686: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:701:
+typedef struct hwrm_func_qcaps_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7687: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:702:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7688: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:703:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7689: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:704:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7690: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:705:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7691: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:706:
+    uint16_t fid;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7692: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:707:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7693: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:708:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7696: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:711:
+    uint8_t perm_mac_address[6];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7697: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:712:
+    uint16_t max_rsscos_ctx;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7698: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:713:
+    uint16_t max_cmpl_rings;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7699: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:714:
+    uint16_t max_tx_rings;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7700: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:715:
+    uint16_t max_rx_rings;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7701: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:716:
+    uint16_t max_l2_ctxs;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7702: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:717:
+    uint16_t max_vnics;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7703: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:718:
+    uint16_t first_vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7704: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:719:
+    uint16_t max_vfs;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7705: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:720:
+    uint16_t max_stat_ctx;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7706: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:721:
+    uint32_t max_encap_records;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7707: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:722:
+    uint32_t max_decap_records;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7708: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:723:
+    uint32_t max_tx_em_flows;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7709: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:724:
+    uint32_t max_tx_wm_flows;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7710: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:725:
+    uint32_t max_rx_em_flows;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7711: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:726:
+    uint32_t max_rx_wm_flows;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7712: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:727:
+    uint32_t max_mcast_filters;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7713: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:728:
+    uint32_t max_flow_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7714: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:729:
+    uint32_t max_hw_ring_grps;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7715: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:730:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7716: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:731:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7717: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:732:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7718: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:733:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7722: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:737:
+typedef struct hwrm_func_qstats_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7723: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:738:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7724: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:739:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7725: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:740:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7726: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:741:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7727: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:742:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7728: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:743:
+    uint16_t fid;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7729: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:744:
+    uint16_t unused_0[3];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7733: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:748:
+typedef struct hwrm_func_qstats_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7734: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:749:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7735: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:750:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7736: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:751:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7737: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:752:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7738: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:753:
+    uint64_t tx_ucast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7739: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:754:
+    uint64_t tx_mcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7740: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:755:
+    uint64_t tx_bcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7741: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:756:
+    uint64_t tx_err_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7742: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:757:
+    uint64_t tx_drop_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7743: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:758:
+    uint64_t tx_ucast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7744: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:759:
+    uint64_t tx_mcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7745: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:760:
+    uint64_t tx_bcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7746: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:761:
+    uint64_t rx_ucast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7747: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:762:
+    uint64_t rx_mcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7748: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:763:
+    uint64_t rx_bcast_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7749: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:764:
+    uint64_t rx_err_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7750: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:765:
+    uint64_t rx_drop_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7751: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:766:
+    uint64_t rx_ucast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7752: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:767:
+    uint64_t rx_mcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7753: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:768:
+    uint64_t rx_bcast_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7754: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:769:
+    uint64_t rx_agg_pkts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7755: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:770:
+    uint64_t rx_agg_bytes;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7756: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:771:
+    uint64_t rx_agg_events;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7757: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:772:
+    uint64_t rx_agg_aborts;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7758: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:773:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7759: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:774:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7760: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:775:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7761: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:776:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7762: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:777:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7763: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:778:
+} __attribute__((packed)) hwrm_func_qstats_output_t, *phwrm_func_qstats_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7766: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:781:
+typedef struct hwrm_func_clr_stats_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7767: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:782:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7768: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:783:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7769: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:784:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7770: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:785:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7771: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:786:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7772: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:787:
+    uint16_t fid;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7773: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:788:
+    uint16_t unused_0[3];$

WARNING:LONG_LINE: line over 80 characters
#7774: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:789:
+} __attribute__((packed)) hwrm_func_clr_stats_input_t, *phwrm_func_clr_stats_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7777: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:792:
+typedef struct hwrm_func_clr_stats_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7778: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:793:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7779: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:794:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7780: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:795:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7781: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:796:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7782: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:797:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7783: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:798:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7784: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:799:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7785: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:800:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7786: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:801:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7787: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:802:
+} __attribute__((packed)) hwrm_func_clr_stats_output_t, *phwrm_func_clr_stats_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7790: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:805:
+typedef struct hwrm_func_drv_rgtr_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7791: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:806:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7792: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:807:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7793: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:808:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7794: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:809:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7795: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:810:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7796: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:811:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7799: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:814:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7805: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:820:
+    uint16_t os_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7815: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:830:
+    uint8_t ver_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7816: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:831:
+    uint8_t ver_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7817: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:832:
+    uint8_t ver_upd;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7818: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:833:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7819: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:834:
+    uint16_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7820: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:835:
+    uint32_t timestamp;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7821: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:836:
+    uint32_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7822: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:837:
+    uint32_t vf_req_fwd[8];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7823: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:838:
+    uint32_t async_event_fwd[8];$

WARNING:LONG_LINE: line over 80 characters
#7824: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:839:
+} __attribute__((packed)) hwrm_func_drv_rgtr_input_t, *phwrm_func_drv_rgtr_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7827: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:842:
+typedef struct hwrm_func_drv_rgtr_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7828: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:843:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7829: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:844:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7830: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:845:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7831: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:846:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7832: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:847:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7833: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:848:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7834: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:849:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7835: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:850:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7836: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:851:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7837: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:852:
+} __attribute__((packed)) hwrm_func_drv_rgtr_output_t, *phwrm_func_drv_rgtr_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7840: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:855:
+typedef struct hwrm_func_drv_unrgtr_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7841: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:856:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7842: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:857:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7843: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:858:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7844: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:859:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7845: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:860:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7846: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:861:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7848: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:863:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#7849: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:864:
+} __attribute__((packed)) hwrm_func_drv_unrgtr_input_t, *phwrm_func_drv_unrgtr_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7852: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:867:
+typedef struct hwrm_func_drv_unrgtr_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7853: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:868:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7854: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:869:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7855: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:870:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7856: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:871:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7857: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:872:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7858: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:873:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7859: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:874:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7860: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:875:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7861: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:876:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7862: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:877:
+} __attribute__((packed)) hwrm_func_drv_unrgtr_output_t, *phwrm_func_drv_unrgtr_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7865: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:880:
+typedef struct hwrm_func_buf_rgtr_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7866: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:881:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7867: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:882:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7868: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:883:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7869: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:884:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7870: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:885:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7871: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:886:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7874: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:889:
+    uint16_t vf_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7875: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:890:
+    uint16_t req_buf_num_pages;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7876: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:891:
+    uint16_t req_buf_page_size;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7884: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:899:
+    uint16_t req_buf_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7885: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:900:
+    uint16_t resp_buf_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7886: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:901:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7887: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:902:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7888: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:903:
+    uint64_t req_buf_page_addr0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7889: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:904:
+    uint64_t req_buf_page_addr1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7890: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:905:
+    uint64_t req_buf_page_addr2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7891: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:906:
+    uint64_t req_buf_page_addr3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7892: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:907:
+    uint64_t req_buf_page_addr4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7893: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:908:
+    uint64_t req_buf_page_addr5;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7894: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:909:
+    uint64_t req_buf_page_addr6;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7895: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:910:
+    uint64_t req_buf_page_addr7;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7896: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:911:
+    uint64_t req_buf_page_addr8;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7897: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:912:
+    uint64_t req_buf_page_addr9;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7898: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:913:
+    uint64_t error_buf_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7899: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:914:
+    uint64_t resp_buf_addr;$

WARNING:LONG_LINE: line over 80 characters
#7900: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:915:
+} __attribute__((packed)) hwrm_func_buf_rgtr_input_t, *phwrm_func_buf_rgtr_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7903: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:918:
+typedef struct hwrm_func_buf_rgtr_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7904: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:919:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7905: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:920:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7906: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:921:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7907: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:922:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7908: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:923:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7909: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:924:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7910: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:925:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7911: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:926:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7912: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:927:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#7913: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:928:
+} __attribute__((packed)) hwrm_func_buf_rgtr_output_t, *phwrm_func_buf_rgtr_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#7916: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:931:
+typedef struct hwrm_port_phy_cfg_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7917: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:932:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7918: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:933:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7919: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:934:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7920: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:935:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7921: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:936:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7922: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:937:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7927: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:942:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7937: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:952:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7938: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:953:
+    uint16_t force_link_speed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7948: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:963:
+    uint8_t auto_mode;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7954: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:969:
+    uint8_t auto_duplex;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7958: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:973:
+    uint8_t auto_pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7961: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:976:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7962: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:977:
+    uint16_t auto_link_speed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7972: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:987:
+    uint16_t auto_link_speed_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7984: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:999:
+    uint8_t wirespeed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7987: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1002:
+    uint8_t lpbk;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7991: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1006:
+    uint8_t force_pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7994: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1009:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7995: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1010:
+    uint32_t preemphasis;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#7996: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1011:
+    uint32_t unused_2;$

WARNING:LONG_LINE: line over 80 characters
#7997: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1012:
+} __attribute__((packed)) hwrm_port_phy_cfg_input_t, *phwrm_port_phy_cfg_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8000: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1015:
+typedef struct hwrm_port_phy_cfg_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8001: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1016:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8002: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1017:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8003: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1018:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8004: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1019:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8005: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1020:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8006: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1021:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8007: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1022:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8008: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1023:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8009: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1024:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8010: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1025:
+} __attribute__((packed)) hwrm_port_phy_cfg_output_t, *phwrm_port_phy_cfg_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8013: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1028:
+typedef struct hwrm_port_phy_qcfg_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8014: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1029:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8015: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1030:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8016: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1031:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8017: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1032:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8018: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1033:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8019: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1034:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8020: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1035:
+    uint16_t unused_0[3];$

WARNING:LONG_LINE: line over 80 characters
#8021: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1036:
+} __attribute__((packed)) hwrm_port_phy_qcfg_input_t, *phwrm_port_phy_qcfg_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8024: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1039:
+typedef struct hwrm_port_phy_qcfg_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8025: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1040:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8026: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1041:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8027: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1042:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8028: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1043:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8029: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1044:
+    uint8_t link;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8033: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1048:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8034: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1049:
+    uint16_t link_speed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8044: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1059:
+    uint8_t duplex;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8047: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1062:
+    uint8_t pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8050: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1065:
+    uint16_t support_speeds;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8062: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1077:
+    uint16_t force_link_speed;$

WARNING:LONG_LINE: line over 80 characters
#8063: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1078:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8066: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1081:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)

WARNING:LONG_LINE: line over 80 characters
#8067: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1082:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB (UINT32_C(0x64) << 0)

WARNING:LONG_LINE: line over 80 characters
#8068: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1083:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB (UINT32_C(0xc8) << 0)

WARNING:LONG_LINE: line over 80 characters
#8069: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1084:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB (UINT32_C(0xfa) << 0)

WARNING:LONG_LINE: line over 80 characters
#8070: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1085:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB (UINT32_C(0x190) << 0)

WARNING:LONG_LINE: line over 80 characters
#8071: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1086:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8072: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1087:
+    uint8_t auto_mode;$

WARNING:LONG_LINE: line over 80 characters
#8076: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1091:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW (UINT32_C(0x3) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8078: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1093:
+    uint8_t auto_pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8081: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1096:
+    uint16_t auto_link_speed;$

WARNING:LONG_LINE: line over 80 characters
#8085: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1100:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB (UINT32_C(0x19) << 0)

WARNING:LONG_LINE: line over 80 characters
#8089: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1104:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB (UINT32_C(0x190) << 0)

WARNING:LONG_LINE: line over 80 characters
#8090: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1105:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB (UINT32_C(0x1f4) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8091: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1106:
+    uint16_t auto_link_speed_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8103: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1118:
+    uint8_t wirespeed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8106: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1121:
+    uint8_t lpbk;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8110: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1125:
+    uint8_t force_pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8113: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1128:
+    uint8_t reserved1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8114: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1129:
+    uint32_t preemphasis;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8115: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1130:
+    uint8_t phy_maj;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8116: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1131:
+    uint8_t phy_min;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8117: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1132:
+    uint8_t phy_bld;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8118: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1133:
+    uint8_t phy_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8127: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1142:
+    uint8_t media_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8131: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1146:
+    uint8_t transceiver_type;$

WARNING:LONG_LINE: line over 80 characters
#8132: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1147:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_TRANSCEIVER_TYPE_XCVR_INTERNAL (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8133: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1148:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_TRANSCEIVER_TYPE_XCVR_EXTERNAL (UINT32_C(0x2) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8134: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1149:
+    uint8_t phy_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8137: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1152:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8138: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1153:
+    uint16_t link_partner_adv_speeds;$

WARNING:LONG_LINE: line over 80 characters
#8139: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1154:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD UINT32_C(0x1)

WARNING:LONG_LINE: line over 80 characters
#8140: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1155:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB UINT32_C(0x2)

WARNING:LONG_LINE: line over 80 characters
#8141: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1156:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD UINT32_C(0x4)

WARNING:LONG_LINE: line over 80 characters
#8144: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1159:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2_5GB UINT32_C(0x20)

WARNING:LONG_LINE: line over 80 characters
#8145: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1160:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10GB UINT32_C(0x40)

WARNING:LONG_LINE: line over 80 characters
#8146: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1161:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_20GB UINT32_C(0x80)

WARNING:LONG_LINE: line over 80 characters
#8147: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1162:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_25GB UINT32_C(0x100)

WARNING:LONG_LINE: line over 80 characters
#8148: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1163:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_40GB UINT32_C(0x200)

WARNING:LONG_LINE: line over 80 characters
#8149: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1164:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_50GB UINT32_C(0x400)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8150: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1165:
+    uint8_t link_partner_adv_auto_mode;$

WARNING:LONG_LINE: line over 80 characters
#8151: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1166:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8152: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1167:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8153: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1168:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED (UINT32_C(0x2) << 0)

WARNING:LONG_LINE: line over 80 characters
#8154: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1169:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW (UINT32_C(0x3) << 0)

WARNING:LONG_LINE: line over 80 characters
#8155: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1170:
+    #define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_MASK (UINT32_C(0x4) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8156: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1171:
+    uint8_t link_partner_adv_pause;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8159: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1174:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8160: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1175:
+    uint8_t unused_4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8161: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1176:
+    uint8_t unused_5;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8162: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1177:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8163: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1178:
+} __attribute__((packed)) hwrm_port_phy_qcfg_output_t, *phwrm_port_phy_qcfg_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8166: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1181:
+typedef struct hwrm_port_qstats_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8167: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1182:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8168: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1183:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8169: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1184:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8170: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1185:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8171: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1186:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8172: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1187:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8173: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1188:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8174: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1189:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8175: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1190:
+    uint8_t unused_2[3];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8176: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1191:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8177: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1192:
+    uint64_t tx_stat_host_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8178: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1193:
+    uint64_t rx_stat_host_addr;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8182: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1197:
+typedef struct hwrm_port_qstats_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8183: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1198:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8184: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1199:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8185: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1200:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8186: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1201:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8187: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1202:
+    uint16_t tx_stat_size;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8188: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1203:
+    uint16_t rx_stat_size;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8189: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1204:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8190: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1205:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8191: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1206:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8192: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1207:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8193: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1208:
+} __attribute__((packed)) hwrm_port_qstats_output_t, *phwrm_port_qstats_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8196: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1211:
+typedef struct hwrm_port_clr_stats_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8197: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1212:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8198: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1213:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8199: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1214:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8200: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1215:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8201: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1216:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8202: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1217:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8203: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1218:
+    uint16_t unused_0[3];$

WARNING:LONG_LINE: line over 80 characters
#8204: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1219:
+} __attribute__((packed)) hwrm_port_clr_stats_input_t, *phwrm_port_clr_stats_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8207: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1222:
+typedef struct hwrm_port_clr_stats_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8208: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1223:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8209: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1224:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8210: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1225:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8211: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1226:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8212: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1227:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8213: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1228:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8214: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1229:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8215: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1230:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8216: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1231:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8217: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1232:
+} __attribute__((packed)) hwrm_port_clr_stats_output_t, *phwrm_port_clr_stats_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8220: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1235:
+typedef struct hwrm_queue_qportcfg_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8221: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1236:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8222: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1237:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8223: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1238:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8224: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1239:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8225: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1240:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8226: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1241:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8230: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1245:
+    uint16_t port_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8231: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1246:
+    uint16_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8232: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1247:
+} __attribute__((packed)) hwrm_queue_qportcfg_input_t, *phwrm_queue_qportcfg_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8235: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1250:
+typedef struct hwrm_queue_qportcfg_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8236: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1251:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8237: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1252:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8238: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1253:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8239: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1254:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8240: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1255:
+    uint8_t max_configurable_queues;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8241: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1256:
+    uint8_t max_configurable_lossless_queues;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8242: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1257:
+    uint8_t queue_cfg_allowed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8243: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1258:
+    uint8_t queue_buffers_cfg_allowed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8244: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1259:
+    uint8_t queue_pfcenable_cfg_allowed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8245: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1260:
+    uint8_t queue_pri2cos_cfg_allowed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8246: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1261:
+    uint8_t queue_cos2bw_cfg_allowed;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8247: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1262:
+    uint8_t queue_id0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8248: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1263:
+    uint8_t queue_id0_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8249: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1264:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8250: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1265:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8251: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1266:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8252: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1267:
+    uint8_t queue_id1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8253: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1268:
+    uint8_t queue_id1_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8254: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1269:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8255: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1270:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8256: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1271:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8257: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1272:
+    uint8_t queue_id2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8258: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1273:
+    uint8_t queue_id2_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8259: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1274:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8260: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1275:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8261: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1276:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8262: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1277:
+    uint8_t queue_id3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8263: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1278:
+    uint8_t queue_id3_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8264: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1279:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8265: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1280:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8266: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1281:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8267: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1282:
+    uint8_t queue_id4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8268: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1283:
+    uint8_t queue_id4_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8269: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1284:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8270: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1285:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8271: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1286:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8272: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1287:
+    uint8_t queue_id5;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8273: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1288:
+    uint8_t queue_id5_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8274: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1289:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8275: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1290:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8276: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1291:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8277: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1292:
+    uint8_t queue_id6;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8278: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1293:
+    uint8_t queue_id6_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8279: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1294:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8280: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1295:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8281: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1296:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8282: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1297:
+    uint8_t queue_id7;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8283: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1298:
+    uint8_t queue_id7_service_profile;$

WARNING:LONG_LINE: line over 80 characters
#8284: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1299:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8285: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1300:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8286: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1301:
+    #define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8287: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1302:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8288: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1303:
+} __attribute__((packed)) hwrm_queue_qportcfg_output_t, *phwrm_queue_qportcfg_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8291: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1306:
+typedef struct hwrm_vnic_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8292: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1307:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8293: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1308:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8294: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1309:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8295: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1310:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8296: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1311:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8297: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1312:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8299: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1314:
+    uint32_t unused_0;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8303: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1318:
+typedef struct hwrm_vnic_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8304: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1319:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8305: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1320:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8306: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1321:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8307: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1322:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8308: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1323:
+    uint32_t vnic_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8309: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1324:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8310: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1325:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8311: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1326:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8312: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1327:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8316: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1331:
+typedef struct hwrm_vnic_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8317: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1332:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8318: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1333:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8319: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1334:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8320: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1335:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8321: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1336:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8322: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1337:
+    uint32_t vnic_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8323: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1338:
+    uint32_t unused_0;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8327: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1342:
+typedef struct hwrm_vnic_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8328: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1343:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8329: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1344:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8330: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1345:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8331: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1346:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8332: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1347:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8333: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1348:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8334: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1349:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8335: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1350:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8336: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1351:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8340: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1355:
+typedef struct hwrm_vnic_cfg_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8341: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1356:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8342: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1357:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8343: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1358:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8344: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1359:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8345: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1360:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8346: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1361:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8350: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1365:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8356: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1371:
+    uint16_t vnic_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8357: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1372:
+    uint16_t dflt_ring_grp;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8358: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1373:
+    uint16_t rss_rule;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8359: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1374:
+    uint16_t cos_rule;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8360: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1375:
+    uint16_t lb_rule;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8361: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1376:
+    uint16_t mru;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8362: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1377:
+    uint32_t unused_0;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8366: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1381:
+typedef struct hwrm_vnic_cfg_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8367: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1382:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8368: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1383:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8369: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1384:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8370: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1385:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8371: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1386:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8372: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1387:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8373: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1388:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8374: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1389:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8375: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1390:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8379: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1394:
+typedef struct hwrm_vnic_rss_cfg_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8380: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1395:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8381: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1396:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8382: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1397:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8383: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1398:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8384: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1399:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8385: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1400:
+    uint32_t hash_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8392: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1407:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8393: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1408:
+    uint64_t ring_grp_tbl_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8394: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1409:
+    uint64_t hash_key_tbl_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8395: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1410:
+    uint16_t rss_ctx_idx;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8396: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1411:
+    uint16_t unused_1[3];$

WARNING:LONG_LINE: line over 80 characters
#8397: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1412:
+} __attribute__((packed)) hwrm_vnic_rss_cfg_input_t, *phwrm_vnic_rss_cfg_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8400: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1415:
+typedef struct hwrm_vnic_rss_cfg_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8401: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1416:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8402: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1417:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8403: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1418:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8404: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1419:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8405: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1420:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8406: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1421:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8407: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1422:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8408: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1423:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8409: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1424:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8410: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1425:
+} __attribute__((packed)) hwrm_vnic_rss_cfg_output_t, *phwrm_vnic_rss_cfg_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8413: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1428:
+typedef struct hwrm_vnic_rss_cos_lb_ctx_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8414: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1429:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8415: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1430:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8416: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1431:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8417: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1432:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8418: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1433:
+    uint64_t resp_addr;$

WARNING:LONG_LINE: line over 80 characters
#8419: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1434:
+} __attribute__((packed)) hwrm_vnic_rss_cos_lb_ctx_alloc_input_t, *phwrm_vnic_rss_cos_lb_ctx_alloc_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8422: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1437:
+typedef struct hwrm_vnic_rss_cos_lb_ctx_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8423: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1438:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8424: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1439:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8425: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1440:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8426: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1441:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8427: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1442:
+    uint16_t rss_cos_lb_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8428: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1443:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8429: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1444:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8430: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1445:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8431: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1446:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8432: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1447:
+    uint8_t unused_4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8433: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1448:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8434: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1449:
+} __attribute__((packed)) hwrm_vnic_rss_cos_lb_ctx_alloc_output_t, *phwrm_vnic_rss_cos_lb_ctx_alloc_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8437: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1452:
+typedef struct hwrm_vnic_rss_cos_lb_ctx_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8438: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1453:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8439: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1454:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8440: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1455:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8441: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1456:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8442: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1457:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8443: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1458:
+    uint16_t rss_cos_lb_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8444: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1459:
+    uint16_t unused_0[3];$

WARNING:LONG_LINE: line over 80 characters
#8445: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1460:
+} __attribute__((packed)) hwrm_vnic_rss_cos_lb_ctx_free_input_t, *phwrm_vnic_rss_cos_lb_ctx_free_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8448: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1463:
+typedef struct hwrm_vnic_rss_cos_lb_ctx_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8449: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1464:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8450: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1465:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8451: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1466:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8452: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1467:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8453: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1468:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8454: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1469:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8455: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1470:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8456: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1471:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8457: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1472:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8458: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1473:
+} __attribute__((packed)) hwrm_vnic_rss_cos_lb_ctx_free_output_t, *phwrm_vnic_rss_cos_lb_ctx_free_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8461: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1476:
+typedef struct hwrm_ring_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8462: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1477:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8463: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1478:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8464: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1479:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8465: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1480:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8466: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1481:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8467: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1482:
+    uint32_t enables;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8474: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1489:
+    uint8_t ring_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8478: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1493:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8479: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1494:
+    uint16_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8480: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1495:
+    uint64_t page_tbl_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8481: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1496:
+    uint32_t fbo;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8482: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1497:
+    uint8_t page_size;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8483: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1498:
+    uint8_t page_tbl_depth;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8484: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1499:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8485: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1500:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8486: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1501:
+    uint32_t length;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8487: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1502:
+    uint16_t logical_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8488: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1503:
+    uint16_t cmpl_ring_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8489: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1504:
+    uint16_t queue_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8490: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1505:
+    uint8_t unused_4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8491: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1506:
+    uint8_t unused_5;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8492: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1507:
+    uint32_t reserved1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8493: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1508:
+    uint16_t reserved2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8494: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1509:
+    uint8_t unused_6;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8495: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1510:
+    uint8_t unused_7;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8496: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1511:
+    uint32_t reserved3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8497: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1512:
+    uint32_t stat_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8498: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1513:
+    uint32_t reserved4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8499: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1514:
+    uint32_t max_bw;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8500: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1515:
+    uint8_t int_mode;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8505: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1520:
+    uint8_t unused_8[3];$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8509: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1524:
+typedef struct hwrm_ring_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8510: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1525:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8511: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1526:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8512: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1527:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8513: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1528:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8514: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1529:
+    uint16_t ring_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8515: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1530:
+    uint16_t logical_ring_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8516: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1531:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8517: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1532:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8518: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1533:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8519: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1534:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8523: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1538:
+typedef struct hwrm_ring_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8524: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1539:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8525: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1540:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8526: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1541:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8527: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1542:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8528: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1543:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8529: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1544:
+    uint8_t ring_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8533: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1548:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8534: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1549:
+    uint16_t ring_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8535: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1550:
+    uint32_t unused_1;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8539: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1554:
+typedef struct hwrm_ring_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8540: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1555:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8541: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1556:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8542: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1557:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8543: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1558:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8544: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1559:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8545: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1560:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8546: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1561:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8547: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1562:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8548: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1563:
+    uint8_t valid;$

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8552: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1567:
+typedef struct hwrm_ring_grp_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8553: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1568:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8554: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1569:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8555: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1570:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8556: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1571:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8557: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1572:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8558: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1573:
+    uint16_t cr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8559: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1574:
+    uint16_t rr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8560: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1575:
+    uint16_t ar;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8561: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1576:
+    uint16_t sc;$

WARNING:LONG_LINE: line over 80 characters
#8562: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1577:
+} __attribute__((packed)) hwrm_ring_grp_alloc_input_t, *phwrm_ring_grp_alloc_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8565: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1580:
+typedef struct hwrm_ring_grp_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8566: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1581:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8567: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1582:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8568: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1583:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8569: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1584:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8570: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1585:
+    uint32_t ring_group_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8571: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1586:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8572: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1587:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8573: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1588:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8574: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1589:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8575: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1590:
+} __attribute__((packed)) hwrm_ring_grp_alloc_output_t, *phwrm_ring_grp_alloc_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8578: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1593:
+typedef struct hwrm_ring_grp_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8579: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1594:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8580: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1595:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8581: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1596:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8582: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1597:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8583: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1598:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8584: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1599:
+    uint32_t ring_group_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8585: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1600:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8586: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1601:
+} __attribute__((packed)) hwrm_ring_grp_free_input_t, *phwrm_ring_grp_free_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8589: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1604:
+typedef struct hwrm_ring_grp_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8590: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1605:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8591: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1606:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8592: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1607:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8593: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1608:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8594: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1609:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8595: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1610:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8596: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1611:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8597: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1612:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8598: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1613:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8599: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1614:
+} __attribute__((packed)) hwrm_ring_grp_free_output_t, *phwrm_ring_grp_free_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8602: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1617:
+typedef struct hwrm_cfa_l2_filter_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8603: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1618:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8604: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1619:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8605: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1620:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8606: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1621:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8607: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1622:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8608: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1623:
+    uint32_t flags;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8615: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1630:
+    uint32_t enables;$

WARNING:LONG_LINE: line over 80 characters
#8625: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1640:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN_MASK UINT32_C(0x200)

WARNING:LONG_LINE: line over 80 characters
#8627: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1642:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN_MASK UINT32_C(0x800)

WARNING:LONG_LINE: line over 80 characters
#8632: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1647:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID UINT32_C(0x10000)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8633: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1648:
+    uint8_t l2_addr[6];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8634: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1649:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8635: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1650:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8636: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1651:
+    uint8_t l2_addr_mask[6];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8637: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1652:
+    uint16_t l2_ovlan;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8638: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1653:
+    uint16_t l2_ovlan_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8639: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1654:
+    uint16_t l2_ivlan;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8640: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1655:
+    uint16_t l2_ivlan_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8641: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1656:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8642: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1657:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8643: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1658:
+    uint8_t t_l2_addr[6];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8644: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1659:
+    uint8_t unused_4;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8645: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1660:
+    uint8_t unused_5;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8646: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1661:
+    uint8_t t_l2_addr_mask[6];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8647: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1662:
+    uint16_t t_l2_ovlan;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8648: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1663:
+    uint16_t t_l2_ovlan_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8649: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1664:
+    uint16_t t_l2_ivlan;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8650: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1665:
+    uint16_t t_l2_ivlan_mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8651: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1666:
+    uint8_t src_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8660: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1675:
+    uint8_t unused_6;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8661: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1676:
+    uint32_t src_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8662: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1677:
+    uint8_t tunnel_type;$

WARNING:LONG_LINE: line over 80 characters
#8663: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1678:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8664: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1679:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8665: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1680:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE (UINT32_C(0x2) << 0)

WARNING:LONG_LINE: line over 80 characters
#8666: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1681:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE (UINT32_C(0x3) << 0)

WARNING:LONG_LINE: line over 80 characters
#8668: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1683:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE (UINT32_C(0x5) << 0)

WARNING:LONG_LINE: line over 80 characters
#8671: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1686:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE (UINT32_C(0x8) << 0)

WARNING:LONG_LINE: line over 80 characters
#8672: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1687:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL (UINT32_C(0xff) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8673: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1688:
+    uint8_t unused_7;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8674: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1689:
+    uint16_t dst_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8675: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1690:
+    uint16_t mirror_vnic_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8676: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1691:
+    uint8_t pri_hint;$

WARNING:LONG_LINE: line over 80 characters
#8677: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1692:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER (UINT32_C(0x0) << 0)

WARNING:LONG_LINE: line over 80 characters
#8678: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1693:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER (UINT32_C(0x1) << 0)

WARNING:LONG_LINE: line over 80 characters
#8679: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1694:
+    #define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER (UINT32_C(0x2) << 0)

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8682: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1697:
+    uint8_t unused_8;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8683: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1698:
+    uint32_t unused_9;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8684: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1699:
+    uint64_t l2_filter_id_hint;$

WARNING:LONG_LINE: line over 80 characters
#8685: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1700:
+} __attribute__((packed)) hwrm_cfa_l2_filter_alloc_input_t, *phwrm_cfa_l2_filter_alloc_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8688: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1703:
+typedef struct hwrm_cfa_l2_filter_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8689: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1704:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8690: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1705:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8691: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1706:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8692: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1707:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8693: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1708:
+    uint64_t l2_filter_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8694: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1709:
+    uint32_t flow_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8695: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1710:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8696: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1711:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8697: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1712:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8698: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1713:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8699: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1714:
+} __attribute__((packed)) hwrm_cfa_l2_filter_alloc_output_t, *phwrm_cfa_l2_filter_alloc_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8702: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1717:
+typedef struct hwrm_cfa_l2_filter_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8703: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1718:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8704: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1719:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8705: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1720:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8706: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1721:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8707: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1722:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8708: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1723:
+    uint64_t l2_filter_id;$

WARNING:LONG_LINE: line over 80 characters
#8709: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1724:
+} __attribute__((packed)) hwrm_cfa_l2_filter_free_input_t, *phwrm_cfa_l2_filter_free_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8712: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1727:
+typedef struct hwrm_cfa_l2_filter_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8713: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1728:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8714: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1729:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8715: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1730:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8716: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1731:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8717: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1732:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8718: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1733:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8719: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1734:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8720: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1735:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8721: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1736:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8722: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1737:
+} __attribute__((packed)) hwrm_cfa_l2_filter_free_output_t, *phwrm_cfa_l2_filter_free_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8725: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1740:
+typedef struct hwrm_cfa_l2_set_rx_mask_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8726: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1741:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8727: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1742:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8728: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1743:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8729: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1744:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8730: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1745:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8731: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1746:
+    uint32_t vnic_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8732: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1747:
+    uint32_t mask;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8739: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1754:
+    uint64_t mc_tbl_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8740: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1755:
+    uint32_t num_mc_entries;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8741: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1756:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8742: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1757:
+} __attribute__((packed)) hwrm_cfa_l2_set_rx_mask_input_t, *phwrm_cfa_l2_set_rx_mask_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8745: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1760:
+typedef struct hwrm_cfa_l2_set_rx_mask_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8746: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1761:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8747: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1762:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8748: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1763:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8749: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1764:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8750: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1765:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8751: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1766:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8752: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1767:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8753: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1768:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8754: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1769:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8755: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1770:
+} __attribute__((packed)) hwrm_cfa_l2_set_rx_mask_output_t, *phwrm_cfa_l2_set_rx_mask_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8758: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1773:
+typedef struct hwrm_stat_ctx_alloc_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8759: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1774:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8760: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1775:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8761: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1776:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8762: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1777:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8763: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1778:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8764: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1779:
+    uint64_t stats_dma_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8765: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1780:
+    uint32_t update_period_ms;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8766: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1781:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8767: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1782:
+} __attribute__((packed)) hwrm_stat_ctx_alloc_input_t, *phwrm_stat_ctx_alloc_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8770: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1785:
+typedef struct hwrm_stat_ctx_alloc_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8771: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1786:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8772: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1787:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8773: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1788:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8774: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1789:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8775: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1790:
+    uint32_t stat_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8776: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1791:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8777: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1792:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8778: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1793:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8779: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1794:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8780: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1795:
+} __attribute__((packed)) hwrm_stat_ctx_alloc_output_t, *phwrm_stat_ctx_alloc_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8783: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1798:
+typedef struct hwrm_stat_ctx_free_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8784: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1799:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8785: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1800:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8786: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1801:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8787: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1802:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8788: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1803:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8789: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1804:
+    uint32_t stat_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8790: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1805:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8791: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1806:
+} __attribute__((packed)) hwrm_stat_ctx_free_input_t, *phwrm_stat_ctx_free_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8794: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1809:
+typedef struct hwrm_stat_ctx_free_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8795: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1810:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8796: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1811:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8797: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1812:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8798: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1813:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8799: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1814:
+    uint32_t stat_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8800: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1815:
+    uint8_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8801: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1816:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8802: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1817:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8803: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1818:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8804: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1819:
+} __attribute__((packed)) hwrm_stat_ctx_free_output_t, *phwrm_stat_ctx_free_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8807: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1822:
+typedef struct hwrm_stat_ctx_clr_stats_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8808: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1823:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8809: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1824:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8810: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1825:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8811: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1826:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8812: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1827:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8813: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1828:
+    uint32_t stat_ctx_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8814: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1829:
+    uint32_t unused_0;$

WARNING:LONG_LINE: line over 80 characters
#8815: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1830:
+} __attribute__((packed)) hwrm_stat_ctx_clr_stats_input_t, *phwrm_stat_ctx_clr_stats_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8818: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1833:
+typedef struct hwrm_stat_ctx_clr_stats_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8819: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1834:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8820: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1835:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8821: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1836:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8822: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1837:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8823: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1838:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8824: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1839:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8825: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1840:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8826: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1841:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8827: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1842:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8828: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1843:
+} __attribute__((packed)) hwrm_stat_ctx_clr_stats_output_t, *phwrm_stat_ctx_clr_stats_output_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8831: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1846:
+typedef struct hwrm_exec_fwd_resp_input
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8832: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1847:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8833: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1848:
+    uint16_t cmpl_ring;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8834: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1849:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8835: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1850:
+    uint16_t target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8836: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1851:
+    uint64_t resp_addr;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8837: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1852:
+    uint32_t encap_request[26];$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8838: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1853:
+    uint16_t encap_resp_target_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8839: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1854:
+    uint16_t unused_0[3];$

WARNING:LONG_LINE: line over 80 characters
#8840: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1855:
+} __attribute__((packed)) hwrm_exec_fwd_resp_input_t, *phwrm_exec_fwd_resp_input_t;

ERROR:OPEN_BRACE: open brace '{' following struct go on the same line
#8843: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1858:
+typedef struct hwrm_exec_fwd_resp_output
+{

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8844: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1859:
+    uint16_t error_code;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8845: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1860:
+    uint16_t req_type;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8846: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1861:
+    uint16_t seq_id;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8847: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1862:
+    uint16_t resp_len;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8848: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1863:
+    uint32_t unused_0;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8849: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1864:
+    uint8_t unused_1;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8850: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1865:
+    uint8_t unused_2;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8851: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1866:
+    uint8_t unused_3;$

WARNING:LEADING_SPACE: please, no spaces at the start of a line
#8852: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1867:
+    uint8_t valid;$

WARNING:LONG_LINE: line over 80 characters
#8853: FILE: drivers/net/bnxt/hsi_struct_def_dpdk.h:1868:
+} __attribute__((packed)) hwrm_exec_fwd_resp_output_t, *phwrm_exec_fwd_resp_output_t;

total: 179 errors, 1139 warnings, 8661 lines checked

0/1 valid patch

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH] drivers/net/bnxt New driver for Broadcom bnxt
  2016-03-02 21:36 [PATCH] drivers/net/bnxt New driver for Broadcom bnxt Stephen Hurd
  2016-03-02 21:44 ` Stephen Hemminger
@ 2016-03-02 21:58 ` Thomas Monjalon
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
  2 siblings, 0 replies; 142+ messages in thread
From: Thomas Monjalon @ 2016-03-02 21:58 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

Please do not submit some disabled code and avoid #ifdef.

2016-03-02 13:36, Stephen Hurd:
> +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,
> +//        .rx_queue_count       = bnxt_rx_queue_count_op,
> +//        .rx_descriptor_done   = bnxt_rx_descriptor_done_op,
> +       .tx_queue_setup = bnxt_tx_queue_setup_op,
> +       .tx_queue_release = bnxt_tx_queue_release_op,
> +//        .rx_queue_start       = bnxt_rx_queue_start_op,
> +//        .rx_queue_stop        = bnxt_rx_queue_stop_op,
> +//        .tx_queue_start       = bnxt_tx_queue_start_op,
> +//        .tx_queue_stop        = bnxt_tx_queue_stop_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,
> +#if 0                          // Phase 2/3
> +       .dev_led_on = bnxt_dev_led_on_op,
> +       .dev_led_off = bnxt_dev_led_off_op,
> +       .queue_stats_mapping_set = bnxt_queue_stats_mapping_set_op,
> +       .vlan_tpid_set = bnxt_vlan_tpid_set_op,
> +       .vlan_offload_set = bnxt_vlan_offload_set_op,
> +       .priority_flow_ctrl_set = bnxt_priority_flow_ctrl_set_op,
> +       .uc_hash_table_set = bnxt_uc_hash_table_set_op,
> +       .uc_all_hash_table_set = bnxt_uc_all_hash_table_set_op,
> +       .mirror_rule_set = bnxt_mirror_rule_set_op,
> +       .mirror_rule_reset = bnxt_mirror_rule_reset_op,
> +       .set_vf_rx_mode = bnxt_set_vf_rx_mode_op,
> +       .set_vf_rx = bnxt_set_vf_rx_op,
> +       .set_vf_tx = bnxt_set_vf_tx_op,
> +       .set_vf_vlan_filter = bnxt_set_vf_vlan_filter_op,
> +       .set_queue_rate_limit = bnxt_set_queue_rate_limit_op,
> +       .set_vf_rate_limit = bnxt_set_vf_rate_limit_op,
> +       .fdir_add_signature_filter = bnxt_fdir_add_signature_filter_op,
> +       .fdir_update_signature_filter = bnxt_fdir_update_signature_filter_op,
> +       .fdir_remove_signature_filter = bnxt_fdir_remove_signature_filter_op,
> +       .fdir_infos_get = bnxt_fdir_info_get_op,
> +       .fdir_add_perfect_filter = bnxt_fdir_add_perfect_filter_op,
> +       .fdir_update_perfect_filter = bnxt_fdir_update_perfect_filter_op,
> +       .fdir_remove_perfect_filter = bnxt_fdir_remove_perfect_filter_op,
> +       .fdir_set_masks = bnxt_fdir_set_masks_op,
> +       .add_syn_filter = bnxt_add_syn_filter_op,
> +       .remove_syn_filter = bnxt_remove_syn_filter_op,
> +       .get_syn_filter = bnxt_get_syn_filter_op,
> +       .add_ethertype_filter = bnxt_add_ethertype_filter_op,
> +       .remove_ethertype_filter = bnxt_remove_ethertype_filter_op,
> +       .get_ethertype_filter = bnxt_get_ethertype_filter_op,
> +       .add_5tuple_filter = bnxt_add_5tuple_filter_op,
> +       .remove_5tuple_filter = bnxt_remove_5tuple_filter_op,
> +       .get_5tuple_filter = bnxt_get_5tuple_filter_op,
> +#endif
> +};

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver
  2016-03-02 21:36 [PATCH] drivers/net/bnxt New driver for Broadcom bnxt Stephen Hurd
  2016-03-02 21:44 ` Stephen Hemminger
  2016-03-02 21:58 ` Thomas Monjalon
@ 2016-03-03  4:08 ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
                     ` (14 more replies)
  2 siblings, 15 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

New driver for Broadcom NetXtreme-C family of controllers and cards
capable of up to 50Gbps link with 30Mpps throughput.

v2:
* Split into multiple patches
* Add nic guide
* Add features in overview.rst

Stephen Hurd (7):
  lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  lib/librte_eal: Add PCI IDs for Broadcom bnxt
  drivers/net/bnxt new driver for Broadcom bnxt
  maintainers: claim drivers/net/bnxt
  build: add bnxt PMD to build
  doc: Add bnxt to overview table
  doc: add guide for new bnxt driver

 MAINTAINERS                                     |    4 +
 config/common_bsdapp                            |    5 +
 config/common_linuxapp                          |    5 +
 doc/guides/nics/bnxt.rst                        |   49 +
 doc/guides/nics/overview.rst                    |   64 +-
 drivers/net/Makefile                            |    1 +
 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 +
 lib/librte_eal/common/include/rte_pci_dev_ids.h |   45 +-
 lib/librte_ether/rte_ethdev.h                   |    4 +
 mk/rte.app.mk                                   |    1 +
 36 files changed, 8568 insertions(+), 37 deletions(-)
 create mode 100644 doc/guides/nics/bnxt.rst
 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

-- 
1.9.1

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  7:53     ` Simon Kågström
  2016-03-03  4:08   ` [PATCH 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
                     ` (13 subsequent siblings)
  14 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Add additional ETH_LINK_SPEED_* macros for 2, 2.5, 25, and 50 Gbps links

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 lib/librte_ether/rte_ethdev.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..cb40bbb 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -254,10 +254,14 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
 #define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
 #define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
+#define ETH_LINK_SPEED_2000     2000    /**< 2 gigabits/second. */
+#define ETH_LINK_SPEED_2500     2500    /**< 2.5 gigabits/second. */
 #define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
 #define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
+#define ETH_LINK_SPEED_25G      25000	/**< 25 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+#define ETH_LINK_SPEED_50G      50000   /**< 50 gigabits/second. */
 
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
  2016-03-03  4:08   ` [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 3/7] drivers/net/bnxt new driver " Stephen Hurd
                     ` (12 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Add Broadcom Vendor ID and RTE_PCI_DEV_ID_DECL_BNXT() macro.
Add Device IDs for Broadcom bnxt devices.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 lib/librte_eal/common/include/rte_pci_dev_ids.h | 45 ++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index d088191..9a8f254 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -63,11 +63,11 @@
  * This file contains a list of the PCI device IDs recognised by DPDK, which
  * can be used to fill out an array of structures describing the devices.
  *
- * Currently four families of devices are recognised: those supported by the
- * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
- * driver which is a para virtualization driver running in guest virtual machine.
- * The inclusion of these in an array built using this file depends on the
- * definition of
+ * Currently five families of devices are recognised: those supported by the
+ * IGB driver, by EM driver, those supported by the IXGBE driver, by BNXT
+ * driver, and by virtio driver which is a para virtualization driver running
+ * in guest virtual machine.  The inclusion of these in an array built using
+ * this file depends on the definition of
  * RTE_PCI_DEV_ID_DECL_EM
  * RTE_PCI_DEV_ID_DECL_IGB
  * RTE_PCI_DEV_ID_DECL_IGBVF
@@ -76,6 +76,7 @@
  * RTE_PCI_DEV_ID_DECL_I40E
  * RTE_PCI_DEV_ID_DECL_I40EVF
  * RTE_PCI_DEV_ID_DECL_VIRTIO
+ * RTE_PCI_DEV_ID_DECL_BNXT
  * at the time when this file is included.
  *
  * In order to populate an array, the user of this file must define this macro:
@@ -167,6 +168,15 @@
 #define PCI_VENDOR_ID_VMWARE 0x15AD
 #endif
 
+#ifndef PCI_VENDOR_ID_BROADCOM
+/** Vendor ID used by Broadcom devices */
+#define PCI_VENDOR_ID_BROADCOM 0x14E4
+#endif
+
+#ifndef RTE_PCI_DEV_ID_DECL_BNXT
+#define RTE_PCI_DEV_ID_DECL_BNXT(vendor, dev)
+#endif
+
 #ifndef PCI_VENDOR_ID_CISCO
 /** Vendor ID used by Cisco VIC devices */
 #define PCI_VENDOR_ID_CISCO 0x1137
@@ -592,6 +602,30 @@ RTE_PCI_DEV_ID_DECL_VIRTIO(PCI_VENDOR_ID_QUMRANET, QUMRANET_DEV_ID_VIRTIO)
 
 RTE_PCI_DEV_ID_DECL_VMXNET3(PCI_VENDOR_ID_VMWARE, VMWARE_DEV_ID_VMXNET3)
 
+/****************** Broadcom BNXT devices ******************/
+
+#define BROADCOM_DEV_ID_57301			0x16c8
+#define BROADCOM_DEV_ID_57302			0x16c9
+#define BROADCOM_DEV_ID_57304_PF		0x16ca
+#define BROADCOM_DEV_ID_57304_VF		0x16cb
+#define BROADCOM_DEV_ID_57304_MF		0x16cc
+#define BROADCOM_DEV_ID_57402			0x16d0
+#define BROADCOM_DEV_ID_57404			0x16d1
+#define BROADCOM_DEV_ID_57406_PF		0x16d2
+#define BROADCOM_DEV_ID_57406_VF		0x16d3
+#define BROADCOM_DEV_ID_57406_MF		0x16d4
+
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_MF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF)
+
 /*************** Virtual FM10K devices from fm10k_type.h ***************/
 
 #define FM10K_DEV_ID_VF                   0x15A5
@@ -665,5 +699,6 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #undef RTE_PCI_DEV_ID_DECL_I40EVF
 #undef RTE_PCI_DEV_ID_DECL_VIRTIO
 #undef RTE_PCI_DEV_ID_DECL_VMXNET3
+#undef RTE_PCI_DEV_ID_DECL_BNXT
 #undef RTE_PCI_DEV_ID_DECL_FM10K
 #undef RTE_PCI_DEV_ID_DECL_FM10KVF
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
  2016-03-03  4:08   ` [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
  2016-03-03  4:08   ` [PATCH 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
                     ` (11 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

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>
---
 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..f846a5a
--- /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(&eth_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 %lx, 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

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 4/7] maintainers: claim drivers/net/bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (2 preceding siblings ...)
  2016-03-03  4:08   ` [PATCH 3/7] drivers/net/bnxt new driver " Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 5/7] build: add bnxt PMD to build Stephen Hurd
                     ` (10 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Claim ownership of new drivers/net/bnxt driver.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 628bc05..6ee6c3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -359,6 +359,10 @@ F: drivers/crypto/aesni_mb/
 Intel QuickAssist
 F: drivers/crypto/qat/
 
+Broadcom bnxt
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+F: drivers/net/bnxt/
+
 
 Packet processing
 -----------------
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 5/7] build: add bnxt PMD to build
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (3 preceding siblings ...)
  2016-03-03  4:08   ` [PATCH 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 6/7] doc: Add bnxt to overview table Stephen Hurd
                     ` (9 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 config/common_bsdapp   | 5 +++++
 config/common_linuxapp | 5 +++++
 drivers/net/Makefile   | 1 +
 mk/rte.app.mk          | 1 +
 4 files changed, 12 insertions(+)

diff --git a/config/common_bsdapp b/config/common_bsdapp
index 696382c..f37c7bb 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -276,6 +276,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f1638db..35f544b 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -280,6 +280,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6e4497e..6f0d64b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
+DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt
 DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
 DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8ecab41..2b5153e 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,6 +144,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 6/7] doc: Add bnxt to overview table
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (4 preceding siblings ...)
  2016-03-03  4:08   ` [PATCH 5/7] build: add bnxt PMD to build Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-03  4:08   ` [PATCH 7/7] doc: add guide for new bnxt driver Stephen Hurd
                     ` (8 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 doc/guides/nics/overview.rst | 64 ++++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index d4c6ff4..e606bdf 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -74,38 +74,38 @@ Most of these differences are summarized below.
 
 .. table:: Features availability in networking drivers
 
-   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-   Feature              a b b b c e e i i i i i i i i i i f f m m m n n p r s v v v x
-                        f n n o x 1 n 4 4 4 4 g g x x x x m m l l p f u c i z i i m e
-                        p x x n g 0 i 0 0 0 0 b b g g g g 1 1 x x i p l a n e r r x n
-                        a 2 2 d b 0 c e e e e   v b b b b 0 0 4 5 p   l p g d t t n v
-                        c x x i e 0     . v v   f e e e e k k     e         a i i e i
-                        k   v n         . f f       . v v   .               t o o t r
-                        e   f g         .   .       . f f   .               a   . 3 t
-                        t               v   v       v   v   v               2   v
-                                        e   e       e   e   e                   e
-                                        c   c       c   c   c                   c
-   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-   link status
+   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   Feature              a b b b b c e e i i i i i i i i i i f f m m m n n p r s v v v x
+                        f n n n o x 1 n 4 4 4 4 g g x x x x m m l l p f u c i z i i m e
+                        p x x x n g 0 i 0 0 0 0 b b g g g g 1 1 x x i p l a n e r r x n
+                        a 2 2 t d b 0 c e e e e   v b b b b 0 0 4 5 p   l p g d t t n v
+                        c x x   i e 0     . v v   f e e e e k k     e         a i i e i
+                        k   v   n         . f f       . v v   .               t o o t r
+                        e   f   g         .   .       . f f   .               a   . 3 t
+                        t                 v   v       v   v   v               2   v
+                                          e   e       e   e   e                   e
+                                          c   c       c   c   c                   c
+   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   link status                X
    link status event
    Rx interrupt
-   queue start/stop
-   MTU update
-   jumbo frame
+   queue start/stop           X
+   MTU update                 X
+   jumbo frame                X
    scattered Rx
    LRO
    TSO
-   promiscuous mode
-   allmulticast mode
-   unicast MAC filter
-   multicast MAC filter
-   RSS hash
-   RSS key update
-   RSS reta update
+   promiscuous mode           X
+   allmulticast mode          X
+   unicast MAC filter         X
+   multicast MAC filter       X
+   RSS hash                   X
+   RSS key update             X
+   RSS reta update            X
    VMDq
    SR-IOV
    DCB
-   VLAN filter
+   VLAN filter                X
    ethertype filter
    n-tuple filter
    SYN filter
@@ -116,23 +116,23 @@ Most of these differences are summarized below.
    flow control
    rate limitation
    traffic mirroring
-   CRC offload
+   CRC offload                X
    VLAN offload
    QinQ offload
-   L3 checksum offload
-   L4 checksum offload
+   L3 checksum offload        X
+   L4 checksum offload        X
    inner L3 checksum
    inner L4 checksum
    packet type parsing
    timesync
-   basic stats
+   basic stats                X
    extended stats
-   stats per queue
+   stats per queue            X
    EEPROM dump
    registers dump
    multiprocess aware
-   BSD nic_uio
-   Linux UIO
+   BSD nic_uio                X
+   Linux UIO                  X
    Linux VFIO
    other kdrv
    ARMv7
@@ -140,7 +140,7 @@ Most of these differences are summarized below.
    Power8
    TILE-Gx
    x86-32
-   x86-64
+   x86-64                     X
    usage doc
    design doc
    perf doc
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 7/7] doc: add guide for new bnxt driver
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (5 preceding siblings ...)
  2016-03-03  4:08   ` [PATCH 6/7] doc: Add bnxt to overview table Stephen Hurd
@ 2016-03-03  4:08   ` Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 0/7] drivers/net/bnxt: new Broadcom " Stephen Hurd
                     ` (7 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-03  4:08 UTC (permalink / raw)
  To: dev

Initial guide for bnxt driver, documents current limitations and
provides information link.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 doc/guides/nics/bnxt.rst | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 doc/guides/nics/bnxt.rst

diff --git a/doc/guides/nics/bnxt.rst b/doc/guides/nics/bnxt.rst
new file mode 100644
index 0000000..fdfa3a6
--- /dev/null
+++ b/doc/guides/nics/bnxt.rst
@@ -0,0 +1,49 @@
+..  BSD LICENSE
+    Copyright 2016 Broadcom Limited
+
+    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 Limited 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.
+
+bnxt poll mode driver library
+=============================
+
+The bnxt poll mode library (**librte_pmd_bnxt**) implements support for
+**Broadcom NetXtreme® C-Series**.  These adapters support Standards-
+compliant 10/25/50Gbps 30MPPS full-duplex throughput.
+
+Information about this family of adapters can be found in the 
+`NetXtreme® Brand section <https://www.broadcom.com/products/ethernet-communication-and-switching?technology%5B%5D=88>`_
+of the `Broadcom web site <http://www.broadcom.com/>`_.
+
+Limitations
+-----------
+
+With the current driver, allocated mbufs must be large enough to hold
+the entire received frame.  If the mbufs are not large enough, the
+packets will be dropped.  This is most limiting when jumbo frames are
+used.
+
+SR-IOV is not supported.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  2016-03-03  4:08   ` [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
  0 siblings, 1 reply; 142+ messages in thread
From: Simon Kågström @ 2016-03-03  7:53 UTC (permalink / raw)
  To: Stephen Hurd, dev

Hi!

On 2016-03-03 05:08, Stephen Hurd wrote:
> Add additional ETH_LINK_SPEED_* macros for 2, 2.5, 25, and 50 Gbps links
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> ---
>  lib/librte_ether/rte_ethdev.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..cb40bbb 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -254,10 +254,14 @@ struct rte_eth_link {
>  #define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
>  #define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
>  #define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
> +#define ETH_LINK_SPEED_2000     2000    /**< 2 gigabits/second. */
> +#define ETH_LINK_SPEED_2500     2500    /**< 2.5 gigabits/second. */
>  #define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
>  #define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
>  #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
> +#define ETH_LINK_SPEED_25G      25000	/**< 25 gigabits/second. */
>  #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> +#define ETH_LINK_SPEED_50G      50000   /**< 50 gigabits/second. */

I realize this is a more general question, but is it really meaningful
to have macros for all possible link speeds? We're working on a PMD
driver with a channelized interface exposed as DPDK ports. Each channel
can be configured with an arbitrary speed, so e.g., 1337 Mbps is also
possible.

To me, it would seem more natural to just have a number in mbits for the
link speed.

// Simon

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  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
  0 siblings, 1 reply; 142+ messages in thread
From: Thomas Monjalon @ 2016-03-03  9:28 UTC (permalink / raw)
  To: Simon Kågström, Stephen Hurd; +Cc: dev

Hi,

2016-03-03 08:53, Simon Kågström:
> Hi!
> 
> On 2016-03-03 05:08, Stephen Hurd wrote:
> > Add additional ETH_LINK_SPEED_* macros for 2, 2.5, 25, and 50 Gbps links

Stephen,
you could be interested in the rework done by Marc Sune:
	http://dpdk.org/dev/patchwork/patch/10919/

> I realize this is a more general question, but is it really meaningful
> to have macros for all possible link speeds? We're working on a PMD
> driver with a channelized interface exposed as DPDK ports. Each channel
> can be configured with an arbitrary speed, so e.g., 1337 Mbps is also
> possible.

What is the benefit? Why not negotiate the maximum capability of the peer?

> To me, it would seem more natural to just have a number in mbits for the
> link speed.

Please jump in the thread initiated by Marc Sune months ago.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  2016-03-03  9:28       ` Thomas Monjalon
@ 2016-03-03 10:22         ` Simon Kågström
  0 siblings, 0 replies; 142+ messages in thread
From: Simon Kågström @ 2016-03-03 10:22 UTC (permalink / raw)
  To: Thomas Monjalon, Stephen Hurd; +Cc: dev

On 2016-03-03 10:28, Thomas Monjalon wrote:
> 2016-03-03 08:53, Simon Kågström:

>> I realize this is a more general question, but is it really meaningful
>> to have macros for all possible link speeds? We're working on a PMD
>> driver with a channelized interface exposed as DPDK ports. Each channel
>> can be configured with an arbitrary speed, so e.g., 1337 Mbps is also
>> possible.
> 
> What is the benefit? Why not negotiate the maximum capability of the peer?

Communication is channelized over a backplane, and each channel has a
specific (and configurable) capacity.

>> To me, it would seem more natural to just have a number in mbits for the
>> link speed.
> 
> Please jump in the thread initiated by Marc Sune months ago.

OK. I haven't been following the DPDK mailing list for a while, so I
wasn't aware of this.

// Simon

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH v3 0/7] drivers/net/bnxt: new Broadcom bnxt driver
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (6 preceding siblings ...)
  2016-03-03  4:08   ` [PATCH 7/7] doc: add guide for new bnxt driver Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
                     ` (6 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

New driver for Broadcom NetXtreme-C family of controllers and cards
capable of up to 50Gbps link with 30Mpps throughput.

v2:
* Split into multiple patches
* Add nic guide
* Add features in overview.rst

v3:
* Fix incorrect format specifier compilation error on i686
  (PRIx64 instead of lx for uint64_t)

Stephen Hurd (7):
  lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  lib/librte_eal: Add PCI IDs for Broadcom bnxt
  drivers/net/bnxt new driver for Broadcom bnxt
  maintainers: claim drivers/net/bnxt
  build: add bnxt PMD to build
  doc: Add bnxt to overview table
  doc: add guide for new bnxt driver

 MAINTAINERS                                     |    4 +
 config/common_bsdapp                            |    5 +
 config/common_linuxapp                          |    5 +
 doc/guides/nics/bnxt.rst                        |   49 +
 doc/guides/nics/overview.rst                    |   64 +-
 drivers/net/Makefile                            |    1 +
 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 +
 lib/librte_eal/common/include/rte_pci_dev_ids.h |   45 +-
 lib/librte_ether/rte_ethdev.h                   |    4 +
 mk/rte.app.mk                                   |    1 +
 36 files changed, 8568 insertions(+), 37 deletions(-)
 create mode 100644 doc/guides/nics/bnxt.rst
 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

-- 
1.9.1

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (7 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 0/7] drivers/net/bnxt: new Broadcom " Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-04-19 12:41     ` Bruce Richardson
  2016-03-04 21:05   ` [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
                     ` (5 subsequent siblings)
  14 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Add additional ETH_LINK_SPEED_* macros for 2, 2.5, 25, and 50 Gbps links

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 lib/librte_ether/rte_ethdev.h | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
index 16da821..cb40bbb 100644
--- a/lib/librte_ether/rte_ethdev.h
+++ b/lib/librte_ether/rte_ethdev.h
@@ -254,10 +254,14 @@ struct rte_eth_link {
 #define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
 #define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
 #define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
+#define ETH_LINK_SPEED_2000     2000    /**< 2 gigabits/second. */
+#define ETH_LINK_SPEED_2500     2500    /**< 2.5 gigabits/second. */
 #define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
 #define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
 #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
+#define ETH_LINK_SPEED_25G      25000	/**< 25 gigabits/second. */
 #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
+#define ETH_LINK_SPEED_50G      50000   /**< 50 gigabits/second. */
 
 #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
 #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (8 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-04-19 13:01     ` Bruce Richardson
  2016-03-04 21:05   ` [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hurd
                     ` (4 subsequent siblings)
  14 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Add Broadcom Vendor ID and RTE_PCI_DEV_ID_DECL_BNXT() macro.
Add Device IDs for Broadcom bnxt devices.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 lib/librte_eal/common/include/rte_pci_dev_ids.h | 45 ++++++++++++++++++++++---
 1 file changed, 40 insertions(+), 5 deletions(-)

diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index d088191..9a8f254 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -63,11 +63,11 @@
  * This file contains a list of the PCI device IDs recognised by DPDK, which
  * can be used to fill out an array of structures describing the devices.
  *
- * Currently four families of devices are recognised: those supported by the
- * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
- * driver which is a para virtualization driver running in guest virtual machine.
- * The inclusion of these in an array built using this file depends on the
- * definition of
+ * Currently five families of devices are recognised: those supported by the
+ * IGB driver, by EM driver, those supported by the IXGBE driver, by BNXT
+ * driver, and by virtio driver which is a para virtualization driver running
+ * in guest virtual machine.  The inclusion of these in an array built using
+ * this file depends on the definition of
  * RTE_PCI_DEV_ID_DECL_EM
  * RTE_PCI_DEV_ID_DECL_IGB
  * RTE_PCI_DEV_ID_DECL_IGBVF
@@ -76,6 +76,7 @@
  * RTE_PCI_DEV_ID_DECL_I40E
  * RTE_PCI_DEV_ID_DECL_I40EVF
  * RTE_PCI_DEV_ID_DECL_VIRTIO
+ * RTE_PCI_DEV_ID_DECL_BNXT
  * at the time when this file is included.
  *
  * In order to populate an array, the user of this file must define this macro:
@@ -167,6 +168,15 @@
 #define PCI_VENDOR_ID_VMWARE 0x15AD
 #endif
 
+#ifndef PCI_VENDOR_ID_BROADCOM
+/** Vendor ID used by Broadcom devices */
+#define PCI_VENDOR_ID_BROADCOM 0x14E4
+#endif
+
+#ifndef RTE_PCI_DEV_ID_DECL_BNXT
+#define RTE_PCI_DEV_ID_DECL_BNXT(vendor, dev)
+#endif
+
 #ifndef PCI_VENDOR_ID_CISCO
 /** Vendor ID used by Cisco VIC devices */
 #define PCI_VENDOR_ID_CISCO 0x1137
@@ -592,6 +602,30 @@ RTE_PCI_DEV_ID_DECL_VIRTIO(PCI_VENDOR_ID_QUMRANET, QUMRANET_DEV_ID_VIRTIO)
 
 RTE_PCI_DEV_ID_DECL_VMXNET3(PCI_VENDOR_ID_VMWARE, VMWARE_DEV_ID_VMXNET3)
 
+/****************** Broadcom BNXT devices ******************/
+
+#define BROADCOM_DEV_ID_57301			0x16c8
+#define BROADCOM_DEV_ID_57302			0x16c9
+#define BROADCOM_DEV_ID_57304_PF		0x16ca
+#define BROADCOM_DEV_ID_57304_VF		0x16cb
+#define BROADCOM_DEV_ID_57304_MF		0x16cc
+#define BROADCOM_DEV_ID_57402			0x16d0
+#define BROADCOM_DEV_ID_57404			0x16d1
+#define BROADCOM_DEV_ID_57406_PF		0x16d2
+#define BROADCOM_DEV_ID_57406_VF		0x16d3
+#define BROADCOM_DEV_ID_57406_MF		0x16d4
+
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_MF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF)
+
 /*************** Virtual FM10K devices from fm10k_type.h ***************/
 
 #define FM10K_DEV_ID_VF                   0x15A5
@@ -665,5 +699,6 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #undef RTE_PCI_DEV_ID_DECL_I40EVF
 #undef RTE_PCI_DEV_ID_DECL_VIRTIO
 #undef RTE_PCI_DEV_ID_DECL_VMXNET3
+#undef RTE_PCI_DEV_ID_DECL_BNXT
 #undef RTE_PCI_DEV_ID_DECL_FM10K
 #undef RTE_PCI_DEV_ID_DECL_FM10KVF
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (9 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-03-04 23:02     ` Stephen Hemminger
  2016-04-19 14:19     ` Bruce Richardson
  2016-03-04 21:05   ` [PATCH v3 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
                     ` (3 subsequent siblings)
  14 siblings, 2 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

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(&eth_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

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 4/7] maintainers: claim drivers/net/bnxt
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (10 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 5/7] build: add bnxt PMD to build Stephen Hurd
                     ` (2 subsequent siblings)
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Claim ownership of new drivers/net/bnxt driver.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 MAINTAINERS | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/MAINTAINERS b/MAINTAINERS
index 628bc05..6ee6c3c 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -359,6 +359,10 @@ F: drivers/crypto/aesni_mb/
 Intel QuickAssist
 F: drivers/crypto/qat/
 
+Broadcom bnxt
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+F: drivers/net/bnxt/
+
 
 Packet processing
 -----------------
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 5/7] build: add bnxt PMD to build
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (11 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 6/7] doc: Add bnxt to overview table Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 7/7] doc: add guide for new bnxt driver Stephen Hurd
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 config/common_bsdapp   | 5 +++++
 config/common_linuxapp | 5 +++++
 drivers/net/Makefile   | 1 +
 mk/rte.app.mk          | 1 +
 4 files changed, 12 insertions(+)

diff --git a/config/common_bsdapp b/config/common_bsdapp
index 696382c..f37c7bb 100644
--- a/config/common_bsdapp
+++ b/config/common_bsdapp
@@ -276,6 +276,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/config/common_linuxapp b/config/common_linuxapp
index f1638db..35f544b 100644
--- a/config/common_linuxapp
+++ b/config/common_linuxapp
@@ -280,6 +280,11 @@ CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_TX_FREE=n
 CONFIG_RTE_LIBRTE_VMXNET3_DEBUG_DRIVER=n
 
 #
+# Compile burst-oriented BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile example software rings based PMD
 #
 CONFIG_RTE_LIBRTE_PMD_RING=y
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6e4497e..6f0d64b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -41,6 +41,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_FM10K_PMD) += fm10k
 DIRS-$(CONFIG_RTE_LIBRTE_I40E_PMD) += i40e
 DIRS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD) += ixgbe
 DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
+DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt
 DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
 DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 8ecab41..2b5153e 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -144,6 +144,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_I40E_PMD)       += -lrte_pmd_i40e
 _LDLIBS-$(CONFIG_RTE_LIBRTE_FM10K_PMD)      += -lrte_pmd_fm10k
 _LDLIBS-$(CONFIG_RTE_LIBRTE_IXGBE_PMD)      += -lrte_pmd_ixgbe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_E1000_PMD)      += -lrte_pmd_e1000
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 6/7] doc: Add bnxt to overview table
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (12 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 5/7] build: add bnxt PMD to build Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  2016-03-04 21:05   ` [PATCH v3 7/7] doc: add guide for new bnxt driver Stephen Hurd
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 doc/guides/nics/overview.rst | 64 ++++++++++++++++++++++----------------------
 1 file changed, 32 insertions(+), 32 deletions(-)

diff --git a/doc/guides/nics/overview.rst b/doc/guides/nics/overview.rst
index d4c6ff4..e606bdf 100644
--- a/doc/guides/nics/overview.rst
+++ b/doc/guides/nics/overview.rst
@@ -74,38 +74,38 @@ Most of these differences are summarized below.
 
 .. table:: Features availability in networking drivers
 
-   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-   Feature              a b b b c e e i i i i i i i i i i f f m m m n n p r s v v v x
-                        f n n o x 1 n 4 4 4 4 g g x x x x m m l l p f u c i z i i m e
-                        p x x n g 0 i 0 0 0 0 b b g g g g 1 1 x x i p l a n e r r x n
-                        a 2 2 d b 0 c e e e e   v b b b b 0 0 4 5 p   l p g d t t n v
-                        c x x i e 0     . v v   f e e e e k k     e         a i i e i
-                        k   v n         . f f       . v v   .               t o o t r
-                        e   f g         .   .       . f f   .               a   . 3 t
-                        t               v   v       v   v   v               2   v
-                                        e   e       e   e   e                   e
-                                        c   c       c   c   c                   c
-   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
-   link status
+   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   Feature              a b b b b c e e i i i i i i i i i i f f m m m n n p r s v v v x
+                        f n n n o x 1 n 4 4 4 4 g g x x x x m m l l p f u c i z i i m e
+                        p x x x n g 0 i 0 0 0 0 b b g g g g 1 1 x x i p l a n e r r x n
+                        a 2 2 t d b 0 c e e e e   v b b b b 0 0 4 5 p   l p g d t t n v
+                        c x x   i e 0     . v v   f e e e e k k     e         a i i e i
+                        k   v   n         . f f       . v v   .               t o o t r
+                        e   f   g         .   .       . f f   .               a   . 3 t
+                        t                 v   v       v   v   v               2   v
+                                          e   e       e   e   e                   e
+                                          c   c       c   c   c                   c
+   ==================== = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
+   link status                X
    link status event
    Rx interrupt
-   queue start/stop
-   MTU update
-   jumbo frame
+   queue start/stop           X
+   MTU update                 X
+   jumbo frame                X
    scattered Rx
    LRO
    TSO
-   promiscuous mode
-   allmulticast mode
-   unicast MAC filter
-   multicast MAC filter
-   RSS hash
-   RSS key update
-   RSS reta update
+   promiscuous mode           X
+   allmulticast mode          X
+   unicast MAC filter         X
+   multicast MAC filter       X
+   RSS hash                   X
+   RSS key update             X
+   RSS reta update            X
    VMDq
    SR-IOV
    DCB
-   VLAN filter
+   VLAN filter                X
    ethertype filter
    n-tuple filter
    SYN filter
@@ -116,23 +116,23 @@ Most of these differences are summarized below.
    flow control
    rate limitation
    traffic mirroring
-   CRC offload
+   CRC offload                X
    VLAN offload
    QinQ offload
-   L3 checksum offload
-   L4 checksum offload
+   L3 checksum offload        X
+   L4 checksum offload        X
    inner L3 checksum
    inner L4 checksum
    packet type parsing
    timesync
-   basic stats
+   basic stats                X
    extended stats
-   stats per queue
+   stats per queue            X
    EEPROM dump
    registers dump
    multiprocess aware
-   BSD nic_uio
-   Linux UIO
+   BSD nic_uio                X
+   Linux UIO                  X
    Linux VFIO
    other kdrv
    ARMv7
@@ -140,7 +140,7 @@ Most of these differences are summarized below.
    Power8
    TILE-Gx
    x86-32
-   x86-64
+   x86-64                     X
    usage doc
    design doc
    perf doc
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v3 7/7] doc: add guide for new bnxt driver
  2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
                     ` (13 preceding siblings ...)
  2016-03-04 21:05   ` [PATCH v3 6/7] doc: Add bnxt to overview table Stephen Hurd
@ 2016-03-04 21:05   ` Stephen Hurd
  14 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 21:05 UTC (permalink / raw)
  To: dev

Initial guide for bnxt driver, documents current limitations and
provides information link.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 doc/guides/nics/bnxt.rst | 49 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 49 insertions(+)
 create mode 100644 doc/guides/nics/bnxt.rst

diff --git a/doc/guides/nics/bnxt.rst b/doc/guides/nics/bnxt.rst
new file mode 100644
index 0000000..fdfa3a6
--- /dev/null
+++ b/doc/guides/nics/bnxt.rst
@@ -0,0 +1,49 @@
+..  BSD LICENSE
+    Copyright 2016 Broadcom Limited
+
+    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 Limited 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.
+
+bnxt poll mode driver library
+=============================
+
+The bnxt poll mode library (**librte_pmd_bnxt**) implements support for
+**Broadcom NetXtreme® C-Series**.  These adapters support Standards-
+compliant 10/25/50Gbps 30MPPS full-duplex throughput.
+
+Information about this family of adapters can be found in the 
+`NetXtreme® Brand section <https://www.broadcom.com/products/ethernet-communication-and-switching?technology%5B%5D=88>`_
+of the `Broadcom web site <http://www.broadcom.com/>`_.
+
+Limitations
+-----------
+
+With the current driver, allocated mbufs must be large enough to hold
+the entire received frame.  If the mbufs are not large enough, the
+packets will be dropped.  This is most limiting when jumbo frames are
+used.
+
+SR-IOV is not supported.
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-03-04 21:05   ` [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hurd
@ 2016-03-04 23:02     ` Stephen Hemminger
  2016-03-04 23:58       ` Stephen Hurd
  2016-04-19 14:19     ` Bruce Richardson
  1 sibling, 1 reply; 142+ messages in thread
From: Stephen Hemminger @ 2016-03-04 23:02 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri,  4 Mar 2016 13:05:24 -0800
Stephen Hurd <stephen.hurd@broadcom.com> wrote:

> 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

Looks good, I just have a couple of functionality comments.

1. Driver does not appear to support Link State interrupt. Not a big
   deal, but would be good to have.

2. Driver does not support hotplug

3. Since driver does not support scattered receive, it should check
   and error out on enable_scatter (ditto for other features in rxmode).
   This will save pain in future when some application asks device to do
   something it can not do.

4. Does driver support SECONDARY process model, it appears secondary
   device will reset hardware.

5. Driver does not supper per-receive queue data interrupts.
   This is necessary for power-saving NAPI like code.




 

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-03-04 23:02     ` Stephen Hemminger
@ 2016-03-04 23:58       ` Stephen Hurd
  0 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-03-04 23:58 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: dev

On Fri, Mar 4, 2016 at 3:02 PM, Stephen Hemminger <
stephen@networkplumber.org> wrote:

>
> > New driver for Broadcom bnxt (NexXtreme C-series) devices.>
>
> Looks good, I just have a couple of functionality comments.
>
> 1. Driver does not appear to support Link State interrupt. Not a big
>    deal, but would be good to have.
>

Correct, it currently doesn't, but this is on The List of things to do.


> 2. Driver does not support hotplug
>

I haven't looked into enabling this at all yet.


> 3. Since driver does not support scattered receive, it should check
>    and error out on enable_scatter (ditto for other features in rxmode).
>    This will save pain in future when some application asks device to do
>    something it can not do.
>

Good catch, will do.

4. Does driver support SECONDARY process model, it appears secondary
>    device will reset hardware.
>

I don't actually know what this is, I'll look into it.

5. Driver does not supper per-receive queue data interrupts.
>    This is necessary for power-saving NAPI like code.
>

This is also on The List.

As a somewhat-related process question, should I be submitting this as a
growing patch series until the merge window opens up again, or should I
submit further changes as new patches?  I'm not really sure on this point,
and have been holding off adding the header comment commits until I figured
out the right answer.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds
  2016-03-04 21:05   ` [PATCH v3 1/7] lib/librte_ether: Add 2/2.5/25/50Gbps link speeds Stephen Hurd
@ 2016-04-19 12:41     ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-04-19 12:41 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Thomas Monjalon

On Fri, Mar 04, 2016 at 01:05:22PM -0800, Stephen Hurd wrote:
> Add additional ETH_LINK_SPEED_* macros for 2, 2.5, 25, and 50 Gbps links
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> ---
>  lib/librte_ether/rte_ethdev.h | 4 ++++
>  1 file changed, 4 insertions(+)
> 
> diff --git a/lib/librte_ether/rte_ethdev.h b/lib/librte_ether/rte_ethdev.h
> index 16da821..cb40bbb 100644
> --- a/lib/librte_ether/rte_ethdev.h
> +++ b/lib/librte_ether/rte_ethdev.h
> @@ -254,10 +254,14 @@ struct rte_eth_link {
>  #define ETH_LINK_SPEED_10       10      /**< 10 megabits/second. */
>  #define ETH_LINK_SPEED_100      100     /**< 100 megabits/second. */
>  #define ETH_LINK_SPEED_1000     1000    /**< 1 gigabits/second. */
> +#define ETH_LINK_SPEED_2000     2000    /**< 2 gigabits/second. */
> +#define ETH_LINK_SPEED_2500     2500    /**< 2.5 gigabits/second. */
>  #define ETH_LINK_SPEED_10000    10000   /**< 10 gigabits/second. */
>  #define ETH_LINK_SPEED_10G      10000   /**< alias of 10 gigabits/second. */
>  #define ETH_LINK_SPEED_20G      20000   /**< 20 gigabits/second. */
> +#define ETH_LINK_SPEED_25G      25000	/**< 25 gigabits/second. */
>  #define ETH_LINK_SPEED_40G      40000   /**< 40 gigabits/second. */
> +#define ETH_LINK_SPEED_50G      50000   /**< 50 gigabits/second. */
>  
>  #define ETH_LINK_AUTONEG_DUPLEX 0       /**< Auto-negotiate duplex. */
>  #define ETH_LINK_HALF_DUPLEX    1       /**< Half-duplex connection. */
> -- 
Hi Stephen,

there were some link speed changes in Rel 16.04, so this patch needs an update
to apply. Hopefully most of the changes in it are no longer needed following the
rework.

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt
  2016-03-04 21:05   ` [PATCH v3 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
@ 2016-04-19 13:01     ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-04-19 13:01 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Thomas Monjalon

On Fri, Mar 04, 2016 at 01:05:23PM -0800, Stephen Hurd wrote:
> Add Broadcom Vendor ID and RTE_PCI_DEV_ID_DECL_BNXT() macro.
> Add Device IDs for Broadcom bnxt devices.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> ---
>  lib/librte_eal/common/include/rte_pci_dev_ids.h | 45 ++++++++++++++++++++++---
>  1 file changed, 40 insertions(+), 5 deletions(-)
> 
> diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
> index d088191..9a8f254 100644
> --- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
> +++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
> @@ -63,11 +63,11 @@
>   * This file contains a list of the PCI device IDs recognised by DPDK, which
>   * can be used to fill out an array of structures describing the devices.
>   *
> - * Currently four families of devices are recognised: those supported by the
> - * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
> - * driver which is a para virtualization driver running in guest virtual machine.
> - * The inclusion of these in an array built using this file depends on the
> - * definition of
> + * Currently five families of devices are recognised: those supported by the
> + * IGB driver, by EM driver, those supported by the IXGBE driver, by BNXT
> + * driver, and by virtio driver which is a para virtualization driver running
> + * in guest virtual machine.  The inclusion of these in an array built using
> + * this file depends on the definition of
>   * RTE_PCI_DEV_ID_DECL_EM
>   * RTE_PCI_DEV_ID_DECL_IGB
>   * RTE_PCI_DEV_ID_DECL_IGBVF
> @@ -76,6 +76,7 @@
>   * RTE_PCI_DEV_ID_DECL_I40E
>   * RTE_PCI_DEV_ID_DECL_I40EVF
>   * RTE_PCI_DEV_ID_DECL_VIRTIO
> + * RTE_PCI_DEV_ID_DECL_BNXT
>   * at the time when this file is included.
>   *
>   * In order to populate an array, the user of this file must define this macro:
> @@ -167,6 +168,15 @@
>  #define PCI_VENDOR_ID_VMWARE 0x15AD
>  #endif
>  
> +#ifndef PCI_VENDOR_ID_BROADCOM
> +/** Vendor ID used by Broadcom devices */
> +#define PCI_VENDOR_ID_BROADCOM 0x14E4
> +#endif
> +
> +#ifndef RTE_PCI_DEV_ID_DECL_BNXT
> +#define RTE_PCI_DEV_ID_DECL_BNXT(vendor, dev)
> +#endif
> +

This macro definition looks to be in the wrong place in the file. The device
definitions are all placed above the vendor declarations.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-03-04 21:05   ` [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hurd
  2016-03-04 23:02     ` Stephen Hemminger
@ 2016-04-19 14:19     ` Bruce Richardson
  2016-04-19 20:51       ` Stephen Hurd
  1 sibling, 1 reply; 142+ messages in thread
From: Bruce Richardson @ 2016-04-19 14:19 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Thomas Monjalon

On Fri, Mar 04, 2016 at 01:05:24PM -0800, Stephen Hurd wrote:
> 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

This seems a single huge commit. Can this be split up into separate commits
with self-contained changes in each one, e.g. a feature per commit, starting
with basic init, then RX and TX etc. etc.?

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-04-19 14:19     ` Bruce Richardson
@ 2016-04-19 20:51       ` Stephen Hurd
  2016-04-20 11:01         ` Bruce Richardson
  0 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-04-19 20:51 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, Thomas Monjalon

On Tue, Apr 19, 2016 at 7:19 AM, Bruce Richardson <
bruce.richardson@intel.com> wrote:

> On Fri, Mar 04, 2016 at 01:05:24PM -0800, Stephen Hurd wrote:
> > New driver for Broadcom bnxt (NexXtreme C-series) devices.
>
> This seems a single huge commit. Can this be split up into separate commits
> with self-contained changes in each one, e.g. a feature per commit,
> starting
> with basic init, then RX and TX etc. etc.?
>

I suppose it could, I'm not sure what the value of that approach would be
though... it would just be a long process of copy/paste/commit/repeat.
Internally, it was developed as a port/rewrite of another driver, so we
don't actually have history without a large commit.

Assuming each individual commit needs to be buildable, this will end up
burning a lot of time, and I doubt each separate commit could be reasonably
tested.


-- 
Stephen Hurd

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-04-19 20:51       ` Stephen Hurd
@ 2016-04-20 11:01         ` Bruce Richardson
  2016-04-20 21:32           ` Stephen Hurd
  0 siblings, 1 reply; 142+ messages in thread
From: Bruce Richardson @ 2016-04-20 11:01 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Thomas Monjalon

On Tue, Apr 19, 2016 at 01:51:32PM -0700, Stephen Hurd wrote:
> On Tue, Apr 19, 2016 at 7:19 AM, Bruce Richardson <
> bruce.richardson@intel.com> wrote:
> 
> > On Fri, Mar 04, 2016 at 01:05:24PM -0800, Stephen Hurd wrote:
> > > New driver for Broadcom bnxt (NexXtreme C-series) devices.
> >
> > This seems a single huge commit. Can this be split up into separate commits
> > with self-contained changes in each one, e.g. a feature per commit,
> > starting
> > with basic init, then RX and TX etc. etc.?
> >
> 
> I suppose it could, I'm not sure what the value of that approach would be
> though... it would just be a long process of copy/paste/commit/repeat.
> Internally, it was developed as a port/rewrite of another driver, so we
> don't actually have history without a large commit.
> 
> Assuming each individual commit needs to be buildable, this will end up
> burning a lot of time, and I doubt each separate commit could be reasonably
> tested.
> 
> 
It's not for testing, more for code review and to help understand the code [though
as you say, we do need to ensure that each commit doesn't actually break the 
build]. 
Right now, the driver code goes in as a single commit - which makes it a hard
enough task to review and see what is in there. One suggestion that hopefully
wouldn't be too much work might be to split the code up into: basic device
init code, RX and TX functions, and then any additional features based on top
of that [ideally one patch per added feature].

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-04-20 11:01         ` Bruce Richardson
@ 2016-04-20 21:32           ` Stephen Hurd
  2016-04-21 10:00             ` Bruce Richardson
  0 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-04-20 21:32 UTC (permalink / raw)
  To: Bruce Richardson, Ajit Kumar Khaparde; +Cc: dev, Thomas Monjalon

> It's not for testing, more for code review and to help understand the code
> [though
> as you say, we do need to ensure that each commit doesn't actually break
> the
> build].
> Right now, the driver code goes in as a single commit - which makes it a
> hard
> enough task to review and see what is in there. One suggestion that
> hopefully
> wouldn't be too much work might be to split the code up into: basic device
> init code, RX and TX functions, and then any additional features based on
> top
> of that [ideally one patch per added feature].
>

The current driver doesn't have much beyond basic TX/RX, but we can give it
a shot.  "Too much work" is relative of course, but splitting it into
self-contained easily understood chunks will absolutely be a lot of work.

Adding Ajit who will also be working on this.  Since he's coming up to
speed on the driver code, this could be a good way for him to fully
familiarize himself with it.

-- 
Stephen Hurd

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  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               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
  0 siblings, 2 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-04-21 10:00 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: Ajit Kumar Khaparde, dev, Thomas Monjalon

On Wed, Apr 20, 2016 at 02:32:18PM -0700, Stephen Hurd wrote:
> > It's not for testing, more for code review and to help understand the code
> > [though
> > as you say, we do need to ensure that each commit doesn't actually break
> > the
> > build].
> > Right now, the driver code goes in as a single commit - which makes it a
> > hard
> > enough task to review and see what is in there. One suggestion that
> > hopefully
> > wouldn't be too much work might be to split the code up into: basic device
> > init code, RX and TX functions, and then any additional features based on
> > top
> > of that [ideally one patch per added feature].
> >
> 
> The current driver doesn't have much beyond basic TX/RX, but we can give it
> a shot.  "Too much work" is relative of course, but splitting it into
> self-contained easily understood chunks will absolutely be a lot of work.
> 
> Adding Ajit who will also be working on this.  Since he's coming up to
> speed on the driver code, this could be a good way for him to fully
> familiarize himself with it.
> 
Sure, thanks. Any splitting you can do at all would be appreciated and help with
reviews.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v3 3/7] drivers/net/bnxt new driver for Broadcom bnxt
  2016-04-21 10:00             ` Bruce Richardson
@ 2016-04-21 10:11               ` Thomas Monjalon
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
  1 sibling, 0 replies; 142+ messages in thread
From: Thomas Monjalon @ 2016-04-21 10:11 UTC (permalink / raw)
  To: Bruce Richardson, Stephen Hurd; +Cc: Ajit Kumar Khaparde, dev

2016-04-21 11:00, Bruce Richardson:
> On Wed, Apr 20, 2016 at 02:32:18PM -0700, Stephen Hurd wrote:
> > > It's not for testing, more for code review and to help understand the code
> > > [though
> > > as you say, we do need to ensure that each commit doesn't actually break
> > > the
> > > build].
> > > Right now, the driver code goes in as a single commit - which makes it a
> > > hard
> > > enough task to review and see what is in there. One suggestion that
> > > hopefully
> > > wouldn't be too much work might be to split the code up into: basic device
> > > init code, RX and TX functions, and then any additional features based on
> > > top
> > > of that [ideally one patch per added feature].
> > >
> > 
> > The current driver doesn't have much beyond basic TX/RX, but we can give it
> > a shot.  "Too much work" is relative of course, but splitting it into
> > self-contained easily understood chunks will absolutely be a lot of work.
> > 
> > Adding Ajit who will also be working on this.  Since he's coming up to
> > speed on the driver code, this could be a good way for him to fully
> > familiarize himself with it.
> > 
> Sure, thanks. Any splitting you can do at all would be appreciated and help with
> reviews.

I'd add that it helps newcomers to understand the driver by reading the
git history.
Thanks

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-04-21 10:00             ` Bruce Richardson
  2016-04-21 10:11               ` Thomas Monjalon
@ 2016-05-06 19:25               ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 02/40] bnxt: add HWRM init code Stephen Hurd
                                   ` (39 more replies)
  1 sibling, 40 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Initial skeleton simply fails init.
Add nic guide and tie into build system.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 MAINTAINERS                                     |   5 ++
 config/common_base                              |   5 ++
 doc/guides/nics/bnxt.rst                        |  49 +++++++++++
 drivers/net/Makefile                            |   1 +
 drivers/net/bnxt/Makefile                       |  63 ++++++++++++++
 drivers/net/bnxt/bnxt_ethdev.c                  | 104 ++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map       |   4 +
 lib/librte_eal/common/include/rte_pci_dev_ids.h |  40 +++++++--
 mk/rte.app.mk                                   |   1 +
 9 files changed, 267 insertions(+), 5 deletions(-)
 create mode 100644 doc/guides/nics/bnxt.rst
 create mode 100644 drivers/net/bnxt/Makefile
 create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index 1953ea2..9a32cdf 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -396,6 +396,11 @@ M: Declan Doherty <declan.doherty@intel.com>
 F: drivers/crypto/null/
 F: doc/guides/cryptodevs/null.rst
 
+Broadcom BNXT PMD
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+F: drivers/net/bnxt/
+F: doc/guides/nics/bnxt.rst
+
 
 Packet processing
 -----------------
diff --git a/config/common_base b/config/common_base
index 1a54e4c..08e617a 100644
--- a/config/common_base
+++ b/config/common_base
@@ -245,6 +245,11 @@ CONFIG_RTE_LIBRTE_NFP_PMD=n
 CONFIG_RTE_LIBRTE_NFP_DEBUG=n
 
 #
+# Compile burst-oriented Broadcom BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile software PMD backed by SZEDATA2 device
 #
 CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
diff --git a/doc/guides/nics/bnxt.rst b/doc/guides/nics/bnxt.rst
new file mode 100644
index 0000000..2669e98
--- /dev/null
+++ b/doc/guides/nics/bnxt.rst
@@ -0,0 +1,49 @@
+..  BSD LICENSE
+    Copyright 2016 Broadcom Limited
+
+    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 Limited 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.
+
+bnxt poll mode driver library
+=============================
+
+The bnxt poll mode library (**librte_pmd_bnxt**) implements support for
+**Broadcom NetXtreme® C-Series**.  These adapters support Standards-
+compliant 10/25/50Gbps 30MPPS full-duplex throughput.
+
+Information about this family of adapters can be found in the
+`NetXtreme® Brand section <https://www.broadcom.com/products/ethernet-communication-and-switching?technology%5B%5D=88>`_
+of the `Broadcom web site <http://www.broadcom.com/>`_.
+
+Limitations
+-----------
+
+With the current driver, allocated mbufs must be large enough to hold
+the entire received frame.  If the mbufs are not large enough, the
+packets will be dropped.  This is most limiting when jumbo frames are
+used.
+
+SR-IOV is not supported.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 3386a67..ba03bca 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -45,6 +45,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
 DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
 DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
+DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_RING) += ring
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
new file mode 100644
index 0000000..89b4a27
--- /dev/null
+++ b/drivers/net/bnxt/Makefile
@@ -0,0 +1,63 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2014 6WIND S.A.
+#   Copyright(c) Broadcom Limited.
+#   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 += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.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_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
new file mode 100644
index 0000000..d6c0d51
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -0,0 +1,104 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+#define DRV_MODULE_NAME		"bnxt"
+static const char bnxt_version[] =
+	"Broadcom Cumulus driver " DRV_MODULE_NAME "\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},
+};
+
+/*
+ * Initialization
+ */
+
+static int
+bnxt_dev_init(struct rte_eth_dev *eth_dev)
+{
+	static int version_printed;
+
+	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);
+	return -EPERM;
+}
+
+static int
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused) {
+	return 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 = 32 /* this must be non-zero apparently */,
+};
+
+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/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
new file mode 100644
index 0000000..349c6e1
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -0,0 +1,4 @@
+DPDK_16.04 {
+
+	local: *;
+};
diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index cf7b548..af26e11 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -63,11 +63,12 @@
  * This file contains a list of the PCI device IDs recognised by DPDK, which
  * can be used to fill out an array of structures describing the devices.
  *
- * Currently four families of devices are recognised: those supported by the
- * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
- * driver which is a para virtualization driver running in guest virtual machine.
- * The inclusion of these in an array built using this file depends on the
- * definition of
+ * Currently five families of devices are recognised: those supported by the
+ * IGB driver, by EM driver, those supported by the IXGBE driver, those
+ * supported by the BNXT driver, and by virtio driver which is a para
+ * virtualization driver running in guest virtual machine. The inclusion of
+ * these in an array built using this file depends on the definition of
+ * RTE_PCI_DEV_ID_DECL_BNXT
  * RTE_PCI_DEV_ID_DECL_EM
  * RTE_PCI_DEV_ID_DECL_IGB
  * RTE_PCI_DEV_ID_DECL_IGBVF
@@ -152,6 +153,10 @@
 #define RTE_PCI_DEV_ID_DECL_BNX2XVF(vend, dev)
 #endif
 
+#ifndef RTE_PCI_DEV_ID_DECL_BNXT
+#define RTE_PCI_DEV_ID_DECL_BNXT(vend, dev)
+#endif
+
 #ifndef PCI_VENDOR_ID_INTEL
 /** Vendor ID used by Intel devices */
 #define PCI_VENDOR_ID_INTEL 0x8086
@@ -686,6 +691,30 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57811_MF)
 RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #endif
 
+/****************** Broadcom bnxt devices ******************/
+
+#define BROADCOM_DEV_ID_57301                  0x16c8
+#define BROADCOM_DEV_ID_57302                  0x16c9
+#define BROADCOM_DEV_ID_57304_PF               0x16ca
+#define BROADCOM_DEV_ID_57304_VF               0x16cb
+#define BROADCOM_DEV_ID_57304_MF               0x16cc
+#define BROADCOM_DEV_ID_57402                  0x16d0
+#define BROADCOM_DEV_ID_57404                  0x16d1
+#define BROADCOM_DEV_ID_57406_PF               0x16d2
+#define BROADCOM_DEV_ID_57406_VF               0x16d3
+#define BROADCOM_DEV_ID_57406_MF               0x16d4
+
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_MF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF)
+
 /*
  * Undef all RTE_PCI_DEV_ID_DECL_* here.
  */
@@ -702,3 +731,4 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #undef RTE_PCI_DEV_ID_DECL_VMXNET3
 #undef RTE_PCI_DEV_ID_DECL_FM10K
 #undef RTE_PCI_DEV_ID_DECL_FM10KVF
+#undef RTE_PCI_DEV_ID_DECL_BNXT
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index c66e491..0c1e5cd 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -142,6 +142,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lrte_pmd_szedata2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lrte_pmd_mpipe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 02/40] bnxt: add HWRM init code
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 03/40] bnxt: add driver register/unregister support Stephen Hurd
                                   ` (38 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Start adding HWRM support.
Initial commit just performs necessary HWRM queries for init, then
fails as before.

Thee used HWRM calls so far:
bnxt_hwrm_func_qcaps:
	Queries device capabilities.

bnxt_hwrm_ver_get:
	Gets the firmware version and interface specifications.
	Returns an error if the firmware on the device is not
	supported by the driver and ensures the response space
	is large enough for the largest possible response.

bnxt_hwrm_queue_qportcfg:
	Required to get the default queue ID.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: David Christensen <david.christensen@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                | 114 ++++
 drivers/net/bnxt/bnxt_ethdev.c         | 113 ++++
 drivers/net/bnxt/bnxt_hwrm.c           | 324 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  53 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 954 +++++++++++++++++++++++++++++++++
 6 files changed, 1559 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt.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/hsi_struct_def_dpdk.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 89b4a27..bb2be76 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -49,6 +49,7 @@ 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
 
 #
 # Export include files
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
new file mode 100644
index 0000000..0f816ed
--- /dev/null
+++ b/drivers/net/bnxt/bnxt.h
@@ -0,0 +1,114 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+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;
+};
+
+#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_VF		(1<<1)
+#define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
+#define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
+
+#define MAX_NUM_MAC_ADDR	32
+	uint8_t			mac_addr[ETHER_ADDR_LEN];
+
+	uint16_t			hwrm_cmd_seq;
+	void				*hwrm_cmd_resp_addr;
+	phys_addr_t			hwrm_cmd_resp_dma_addr;
+	rte_spinlock_t			hwrm_lock;
+	uint16_t			max_req_len;
+	uint16_t			max_resp_len;
+
+	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
+
+	struct bnxt_pf_info		pf;
+	struct bnxt_vf_info		vf;
+};
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d6c0d51..a74cc6c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -39,6 +39,9 @@
 #include <rte_malloc.h>
 #include <rte_cycles.h>
 
+#include "bnxt.h"
+#include "bnxt_hwrm.h"
+
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
 	"Broadcom Cumulus driver " DRV_MODULE_NAME "\n";
@@ -49,14 +52,69 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	rte_free(eth_dev->data->mac_addrs);
+	bnxt_free_hwrm_resources(bp);
+}
+
 /*
  * Initialization
  */
 
+static struct eth_dev_ops bnxt_dev_ops = {
+	.dev_close = bnxt_dev_close_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);
@@ -69,7 +127,62 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	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(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
 	return -EPERM;
+
+error_free:
+	bnxt_dev_close_op(eth_dev);
+error:
+	return rc;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
new file mode 100644
index 0000000..5b66721
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -0,0 +1,324 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_hwrm.h"
+#include "hsi_struct_def_dpdk.h"
+
+#define HWRM_CMD_TIMEOUT		2000
+
+/*
+ * 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_locked(struct bnxt *bp, void *msg,
+					uint32_t msg_len)
+{
+	unsigned i;
+	struct input *req = msg;
+	struct output *resp = bp->hwrm_cmd_resp_addr;
+	uint32_t *data = msg;
+	uint8_t *bar;
+	uint8_t *valid;
+
+	/* 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++;
+	}
+
+	/* Zero the rest of the request space */
+	for (; i < bp->max_req_len; i += 4) {
+		bar = (uint8_t *)bp->bar0 + i;
+		*(volatile uint32_t *)bar = 0;
+	}
+
+	/* Ring channel doorbell */
+	bar = (uint8_t *)bp->bar0 + 0x100;
+	*(volatile uint32_t *)bar = 1;
+
+	/* Poll for the valid bit */
+	for (i = 0; i < HWRM_CMD_TIMEOUT; i++) {
+		/* Sanity check on the resp->resp_len */
+		rte_rmb();
+		if (resp->resp_len && resp->resp_len <=
+		    bp->max_resp_len) {
+			/* 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;
+	}
+	return 0;
+
+err_ret:
+	return -1;
+}
+
+static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
+{
+	int rc;
+
+	rte_spinlock_lock(&bp->hwrm_lock);
+	rc = bnxt_hwrm_send_message_locked(bp, msg, msg_len);
+	rte_spinlock_unlock(&bp->hwrm_lock);
+	return rc;
+}
+
+#define HWRM_PREP(req, type, cr, resp) \
+	memset(bp->hwrm_cmd_resp_addr, 0, bp->max_resp_len); \
+	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_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_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;
+	uint16_t max_resp_len;
+	char type[RTE_MEMZONE_NAMESIZE];
+
+	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;
+
+	/*
+	 * Hold the lock since we may be adjusting the response pointers.
+	 */
+	rte_spinlock_lock(&bp->hwrm_lock);
+	rc = bnxt_hwrm_send_message_locked(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 (resp->hwrm_intf_maj != HWRM_VERSION_MAJOR) {
+		RTE_LOG(ERR, PMD, "Unsupported firmware API version\n");
+		rc = -EINVAL;
+		goto error;
+	}
+
+	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");
+		}
+	}
+
+	if (bp->max_req_len > resp->max_req_win_len) {
+		RTE_LOG(ERR, PMD, "Unsupported request length\n");
+		rc = -EINVAL;
+	}
+	bp->max_req_len = resp->max_req_win_len;
+	max_resp_len = resp->max_resp_len;
+	if (bp->max_resp_len != max_resp_len) {
+		sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x",
+			bp->pdev->addr.domain, bp->pdev->addr.bus,
+			bp->pdev->addr.devid, bp->pdev->addr.function);
+
+		rte_free(bp->hwrm_cmd_resp_addr);
+
+		bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0);
+		if (bp->hwrm_cmd_resp_addr == NULL) {
+			rc = -ENOMEM;
+			goto error;
+		}
+		bp->hwrm_cmd_resp_dma_addr =
+			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		bp->max_resp_len = max_resp_len;
+	}
+
+error:
+	rte_spinlock_unlock(&bp->hwrm_lock);
+	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;
+}
+
+/*
+ * HWRM utility functions
+ */
+
+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->max_req_len = HWRM_MAX_REQ_LEN;
+	bp->max_resp_len = HWRM_MAX_RESP_LEN;
+	bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
+	if (bp->hwrm_cmd_resp_addr == NULL)
+		return -ENOMEM;
+	bp->hwrm_cmd_resp_dma_addr =
+		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+	rte_spinlock_init(&bp->hwrm_lock);
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
new file mode 100644
index 0000000..e35e8c0
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -0,0 +1,53 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+#include "bnxt.h"
+
+#define HWRM_SEQ_ID_INVALID -1U
+
+int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+
+int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
+
+int bnxt_hwrm_ver_get(struct bnxt *bp);
+
+void bnxt_free_hwrm_resources(struct bnxt *bp);
+int bnxt_alloc_hwrm_resources(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..1667927
--- /dev/null
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -0,0 +1,954 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_EXTERNAL_H_
+#define _HSI_STRUCT_DEF_EXTERNAL_H_
+
+/* HW Resource Manager Specification 1.2.0 */
+#define HWRM_VERSION_MAJOR	1
+#define HWRM_VERSION_MINOR	2
+#define HWRM_VERSION_UPDATE	0
+
+/*
+ * Following is the signature for HWRM message field that indicates not
+ * applicable (All F's). Need to cast it the size of the field if needed.
+ */
+#define HWRM_MAX_REQ_LEN	(128)  /* hwrm_func_buf_rgtr */
+#define HWRM_MAX_RESP_LEN	(176)  /* hwrm_func_qstats */
+#define HWRM_RESP_VALID_KEY	1 /* valid key for HWRM response */
+
+/*
+ * Request types
+ */
+#define HWRM_VER_GET                                      (UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS                                   (UINT32_C(0x15))
+#define HWRM_QUEUE_QPORTCFG                               (UINT32_C(0x30))
+
+/*
+ * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
+ * inside the chip. The HWRM is implemented in firmware, and runs on embedded
+ * processors inside the chip. This firmware is vital part of the chip's
+ * hardware. The chip can not be used by driver without it.
+ */
+
+/* Input (16 bytes) */
+struct input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+} __attribute__((packed));
+
+/* Output (8 bytes) */
+struct output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+} __attribute__((packed));
+
+/* hwrm_func_qcaps */
+/*
+ * Description: This command returns capabilities of a function. The input FID
+ * value is used to indicate what function is being queried. This allows a
+ * physical function driver to query virtual functions that are children of the
+ * physical function. The output FID value is needed to configure Rings and
+ * MSI-X vectors so their DMA operations appear correctly on the PCI bus.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_func_qcaps_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Function ID of the function that is being queried. 0xFF... (All Fs)
+	 * if the query is for the requesting function.
+	 */
+	uint16_t fid;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (80 bytes) */
+struct hwrm_func_qcaps_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * FID value. This value is used to identify operations on the PCI bus
+	 * as belonging to a particular PCI function.
+	 */
+	uint16_t fid;
+
+	/*
+	 * Port ID of port that this function is associated with. Valid only for
+	 * the PF. 0xFF... (All Fs) if this function is not associated with any
+	 * port. 0xFF... (All Fs) if this function is called from a VF.
+	 */
+	uint16_t port_id;
+
+	/* If 1, then Push mode is supported on this function. */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED   UINT32_C(0x1)
+	/*
+	 * If 1, then the global MSI-X auto-masking is enabled for the device.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING \
+								UINT32_C(0x2)
+	/*
+	 * If 1, then the Precision Time Protocol (PTP) processing is supported
+	 * on this function. The HWRM should enable PTP on only a single
+	 * Physical Function (PF) per port.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED         UINT32_C(0x4)
+	uint32_t flags;
+
+	/*
+	 * This value is current MAC address configured for this function. A
+	 * value of 00-00-00-00-00-00 indicates no MAC address is currently
+	 * configured.
+	 */
+	uint8_t perm_mac_address[6];
+
+	/*
+	 * The maximum number of RSS/COS contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_rsscos_ctx;
+
+	/*
+	 * The maximum number of completion rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_cmpl_rings;
+
+	/*
+	 * The maximum number of transmit rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_tx_rings;
+
+	/*
+	 * The maximum number of receive rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_rx_rings;
+
+	/*
+	 * The maximum number of L2 contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_l2_ctxs;
+
+	/* The maximum number of VNICs that can be allocated to the function. */
+	uint16_t max_vnics;
+
+	/*
+	 * The identifier for the first VF enabled on a PF. This is valid only
+	 * on the PF with SR-IOV enabled. 0xFF... (All Fs) if this command is
+	 * called on a PF with SR-IOV disabled or on a VF.
+	 */
+	uint16_t first_vf_id;
+
+	/*
+	 * The maximum number of VFs that can be allocated to the function. This
+	 * is valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if this
+	 * command is called on a PF with SR-IOV disabled or on a VF.
+	 */
+	uint16_t max_vfs;
+
+	/*
+	 * The maximum number of statistic contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_stat_ctx;
+
+	/*
+	 * The maximum number of Encapsulation records that can be offloaded by
+	 * this function.
+	 */
+	uint32_t max_encap_records;
+
+	/*
+	 * The maximum number of decapsulation records that can be offloaded by
+	 * this function.
+	 */
+	uint32_t max_decap_records;
+
+	/*
+	 * The maximum number of Exact Match (EM) flows that can be offloaded by
+	 * this function on the TX side.
+	 */
+	uint32_t max_tx_em_flows;
+
+	/*
+	 * The maximum number of Wildcard Match (WM) flows that can be offloaded
+	 * by this function on the TX side.
+	 */
+	uint32_t max_tx_wm_flows;
+
+	/*
+	 * The maximum number of Exact Match (EM) flows that can be offloaded by
+	 * this function on the RX side.
+	 */
+	uint32_t max_rx_em_flows;
+
+	/*
+	 * The maximum number of Wildcard Match (WM) flows that can be offloaded
+	 * by this function on the RX side.
+	 */
+	uint32_t max_rx_wm_flows;
+
+	/*
+	 * The maximum number of multicast filters that can be supported by this
+	 * function on the RX side.
+	 */
+	uint32_t max_mcast_filters;
+
+	/*
+	 * The maximum value of flow_id that can be supported in completion
+	 * records.
+	 */
+	uint32_t max_flow_id;
+
+	/*
+	 * The maximum number of HW ring groups that can be supported on this
+	 * function.
+	 */
+	uint32_t max_hw_ring_grps;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ver_get */
+/*
+ * Description: This function is called by a driver to determine the HWRM
+ * interface version supported by the HWRM firmware, the version of HWRM
+ * firmware implementation, the name of HWRM firmware, the versions of other
+ * embedded firmwares, and the names of other embedded firmwares, etc. Any
+ * interface or firmware version with major = 0, minor = 0, and update = 0 shall
+ * be considered an invalid version.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ver_get_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This field represents the major version of HWRM interface
+	 * specification supported by the driver HWRM implementation. The
+	 * interface major version is intended to change only when non backward
+	 * compatible changes are made to the HWRM interface specification.
+	 */
+	uint8_t hwrm_intf_maj;
+
+	/*
+	 * This field represents the minor version of HWRM interface
+	 * specification supported by the driver HWRM implementation. A change
+	 * in interface minor version is used to reflect significant backward
+	 * compatible modification to HWRM interface specification. This can be
+	 * due to addition or removal of functionality. HWRM interface
+	 * specifications with the same major version but different minor
+	 * versions are compatible.
+	 */
+	uint8_t hwrm_intf_min;
+
+	/*
+	 * This field represents the update version of HWRM interface
+	 * specification supported by the driver HWRM implementation. The
+	 * interface update version is used to reflect minor changes or bug
+	 * fixes to a released HWRM interface specification.
+	 */
+	uint8_t hwrm_intf_upd;
+
+	uint8_t unused_0[5];
+} __attribute__((packed));
+
+/* Output (128 bytes) */
+struct hwrm_ver_get_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This field represents the major version of HWRM interface
+	 * specification supported by the HWRM implementation. The interface
+	 * major version is intended to change only when non backward compatible
+	 * changes are made to the HWRM interface specification. A HWRM
+	 * implementation that is compliant with this specification shall
+	 * provide value of 1 in this field.
+	 */
+	uint8_t hwrm_intf_maj;
+
+	/*
+	 * This field represents the minor version of HWRM interface
+	 * specification supported by the HWRM implementation. A change in
+	 * interface minor version is used to reflect significant backward
+	 * compatible modification to HWRM interface specification. This can be
+	 * due to addition or removal of functionality. HWRM interface
+	 * specifications with the same major version but different minor
+	 * versions are compatible. A HWRM implementation that is compliant with
+	 * this specification shall provide value of 0 in this field.
+	 */
+	uint8_t hwrm_intf_min;
+
+	/*
+	 * This field represents the update version of HWRM interface
+	 * specification supported by the HWRM implementation. The interface
+	 * update version is used to reflect minor changes or bug fixes to a
+	 * released HWRM interface specification. A HWRM implementation that is
+	 * compliant with this specification shall provide value of 1 in this
+	 * field.
+	 */
+	uint8_t hwrm_intf_upd;
+
+	uint8_t hwrm_intf_rsvd;
+
+	/*
+	 * This field represents the major version of HWRM firmware. A change in
+	 * firmware major version represents a major firmware release.
+	 */
+	uint8_t hwrm_fw_maj;
+
+	/*
+	 * This field represents the minor version of HWRM firmware. A change in
+	 * firmware minor version represents significant firmware functionality
+	 * changes.
+	 */
+	uint8_t hwrm_fw_min;
+
+	/*
+	 * This field represents the build version of HWRM firmware. A change in
+	 * firmware build version represents bug fixes to a released firmware.
+	 */
+	uint8_t hwrm_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version of the HWRM firmware.
+	 */
+	uint8_t hwrm_fw_rsvd;
+
+	/*
+	 * This field represents the major version of mgmt firmware. A change in
+	 * major version represents a major release.
+	 */
+	uint8_t mgmt_fw_maj;
+
+	/*
+	 * This field represents the minor version of mgmt firmware. A change in
+	 * minor version represents significant functionality changes.
+	 */
+	uint8_t mgmt_fw_min;
+
+	/*
+	 * This field represents the build version of mgmt firmware. A change in
+	 * update version represents bug fixes.
+	 */
+	uint8_t mgmt_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t mgmt_fw_rsvd;
+
+	/*
+	 * This field represents the major version of network control firmware.
+	 * A change in major version represents a major release.
+	 */
+	uint8_t netctrl_fw_maj;
+
+	/*
+	 * This field represents the minor version of network control firmware.
+	 * A change in minor version represents significant functionality
+	 * changes.
+	 */
+	uint8_t netctrl_fw_min;
+
+	/*
+	 * This field represents the build version of network control firmware.
+	 * A change in update version represents bug fixes.
+	 */
+	uint8_t netctrl_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t netctrl_fw_rsvd;
+
+	/*
+	 * This field is reserved for future use. The responder should set it to
+	 * 0. The requester should ignore this field.
+	 */
+	uint32_t reserved1;
+
+	/*
+	 * This field represents the major version of RoCE firmware. A change in
+	 * major version represents a major release.
+	 */
+	uint8_t roce_fw_maj;
+
+	/*
+	 * This field represents the minor version of RoCE firmware. A change in
+	 * minor version represents significant functionality changes.
+	 */
+	uint8_t roce_fw_min;
+
+	/*
+	 * This field represents the build version of RoCE firmware. A change in
+	 * update version represents bug fixes.
+	 */
+	uint8_t roce_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t roce_fw_rsvd;
+
+	/*
+	 * This field represents the name of HWRM FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char hwrm_fw_name[16];
+
+	/*
+	 * This field represents the name of mgmt FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char mgmt_fw_name[16];
+
+	/*
+	 * This field represents the name of network control firmware (ASCII
+	 * chars without NULL at the end).
+	 */
+	char netctrl_fw_name[16];
+
+	/*
+	 * This field is reserved for future use. The responder should set it to
+	 * 0. The requester should ignore this field.
+	 */
+	uint32_t reserved2[4];
+
+	/*
+	 * This field represents the name of RoCE FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char roce_fw_name[16];
+
+	/* This field returns the chip number. */
+	uint16_t chip_num;
+
+	/* This field returns the revision of chip. */
+	uint8_t chip_rev;
+
+	/* This field returns the chip metal number. */
+	uint8_t chip_metal;
+
+	/* This field returns the bond id of the chip. */
+	uint8_t chip_bond_id;
+
+	/*
+	 * This value indicates the type of platform used for chip
+	 * implementation.
+	 */
+	/* ASIC */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_ASIC \
+							(UINT32_C(0x0) << 0)
+	/* FPGA platform of the chip. */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA \
+							(UINT32_C(0x1) << 0)
+	/* Palladium platform of the chip. */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM \
+							(UINT32_C(0x2) << 0)
+	uint8_t chip_platform_type;
+
+	/*
+	 * This field returns the maximum value of request window that is
+	 * supported by the HWRM. The request window is mapped into device
+	 * address space using MMIO.
+	 */
+	uint16_t max_req_win_len;
+
+	/*
+	 * This field returns the maximum value of response buffer in bytes. If
+	 * a request specifies the response buffer length that is greater than
+	 * this value, then the HWRM should fail it. The value of this field
+	 * shall be 4KB or more.
+	 */
+	uint16_t max_resp_len;
+
+	/*
+	 * This field returns the default request timeout value in milliseconds.
+	 */
+	uint16_t def_req_timeout;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_queue_qportcfg */
+/*
+ * Description: This function is called by a driver to query queue configuration
+ * of a port. # The HWRM shall at least advertise one queue with lossy service
+ * profile. # The driver shall use this command to query queue ids before
+ * configuring or using any queues. # If a service profile is not set for a
+ * queue, then the driver shall not use that queue without configuring a service
+ * profile for it. # If the driver is not allowed to configure service profiles,
+ * then the driver shall only use queues for which service profiles are pre-
+ * configured.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_queue_qportcfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Enumeration denoting the RX, TX type of the resource. This
+	 * enumeration is used for resources that are similar for both TX and RX
+	 * paths of the chip.
+	 */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH \
+							UINT32_C(0x1)
+		/* tx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX \
+							(UINT32_C(0x0) << 0)
+		/* rx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX \
+							(UINT32_C(0x1) << 0)
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+					HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+	uint32_t flags;
+
+	/*
+	 * Port ID of port for which the queue configuration is being queried.
+	 * This field is only required when sent by IPC.
+	 */
+	uint16_t port_id;
+
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output (32 bytes) */
+struct hwrm_queue_qportcfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* The maximum number of queues that can be configured. */
+	uint8_t max_configurable_queues;
+
+	/* The maximum number of lossless queues that can be configured. */
+	uint8_t max_configurable_lossless_queues;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed. If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure queues using
+	 * hwrm_queue_cfg.
+	 */
+	uint8_t queue_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure queue buffers
+	 * using hwrm_queue_buffers_cfg.
+	 */
+	uint8_t queue_buffers_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure PFC using
+	 * hwrm_queue_pfcenable_cfg.
+	 */
+	uint8_t queue_pfcenable_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure Priority to CoS
+	 * mapping using hwrm_queue_pri2cos_cfg.
+	 */
+	uint8_t queue_pri2cos_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure CoS Bandwidth
+	 * configuration using hwrm_queue_cos2bw_cfg.
+	 */
+	uint8_t queue_cos2bw_cfg_allowed;
+
+	/* ID of CoS Queue 0. FF - Invalid id */
+	uint8_t queue_id0;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id0_service_profile;
+
+	/* ID of CoS Queue 1. FF - Invalid id */
+	uint8_t queue_id1;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id1_service_profile;
+
+	/* ID of CoS Queue 2. FF - Invalid id */
+	uint8_t queue_id2;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id2_service_profile;
+
+	/* ID of CoS Queue 3. FF - Invalid id */
+	uint8_t queue_id3;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id3_service_profile;
+
+	/* ID of CoS Queue 4. FF - Invalid id */
+	uint8_t queue_id4;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id4_service_profile;
+
+	/* ID of CoS Queue 5. FF - Invalid id */
+	uint8_t queue_id5;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id5_service_profile;
+
+	/* ID of CoS Queue 6. FF - Invalid id */
+	uint8_t queue_id6_service_profile;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id6;
+
+	/* ID of CoS Queue 7. FF - Invalid id */
+	uint8_t queue_id7;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id7_service_profile;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 03/40] bnxt: add driver register/unregister support
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 02/40] bnxt: add HWRM init code Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 04/40] bnxt: add dev infos get operation Stephen Hurd
                                   ` (37 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Move init() cleanup into uninit() function
Fix .dev_private_size
Add require hwrm calls:
	bnxt_hwrm_func_driver_register()
	bnxt_hwrm_func_driver_unregister()

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   1 +
 drivers/net/bnxt/bnxt_ethdev.c         |  48 ++++--
 drivers/net/bnxt/bnxt_hwrm.c           |  50 ++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 277 ++++++++++++++++++++++++++++++++-
 5 files changed, 359 insertions(+), 20 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 0f816ed..ebddeab 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -91,6 +91,7 @@ struct bnxt {
 	struct rte_pci_device		*pdev;
 
 	uint32_t		flags;
+#define BNXT_FLAG_REGISTERED	(1<<0)
 #define BNXT_FLAG_VF		(1<<1)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a74cc6c..07519df 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -52,20 +52,12 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
-static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
-{
-	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-
-	rte_free(eth_dev->data->mac_addrs);
-	bnxt_free_hwrm_resources(bp);
-}
-
 /*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
-	.dev_close = bnxt_dev_close_op,
+0
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -123,7 +115,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 			eth_dev->pci_dev->addr.function < 4) {
 		RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
 			eth_dev->pci_dev->addr.function);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error;
 	}
 
 	rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
@@ -148,11 +141,11 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"hwrm resource allocation failure rc: %x\n", rc);
-		goto error;
+		goto error_free;
 	}
 	rc = bnxt_hwrm_ver_get(bp);
 	if (rc)
-		goto error;
+		goto error_free;
 	bnxt_hwrm_queue_qportcfg(bp);
 
 	/* Get the MAX capabilities for this function */
@@ -177,17 +170,38 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
 
-	return -EPERM;
+	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);
+	eth_dev->driver->eth_dev_uninit(eth_dev);
 error:
 	return rc;
 }
 
 static int
-bnxt_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused) {
-	return 0;
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
+	struct bnxt *bp = eth_dev->data->dev_private;
+	int rc;
+
+	if (eth_dev->data->mac_addrs)
+		rte_free(eth_dev->data->mac_addrs);
+	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
+	bnxt_free_hwrm_resources(bp);
+	return rc;
 }
 
 static struct eth_driver bnxt_rte_pmd = {
@@ -198,7 +212,7 @@ static struct eth_driver bnxt_rte_pmd = {
 		    },
 	.eth_dev_init = bnxt_dev_init,
 	.eth_dev_uninit = bnxt_dev_uninit,
-	.dev_private_size = 32 /* this must be non-zero apparently */,
+	.dev_private_size = sizeof(struct bnxt),
 };
 
 static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 5b66721..398f0f5 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -36,6 +36,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memzone.h>
+#include <rte_version.h>
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
@@ -178,6 +179,34 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	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;
+
+	if (bp->flags & BNXT_FLAG_REGISTERED)
+		return 0;
+
+	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
+	req.flags = flags;
+	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER;
+	req.ver_maj = RTE_VER_YEAR;
+	req.ver_min = RTE_VER_MONTH;
+	req.ver_upd = RTE_VER_MINOR;
+
+	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;
+
+	bp->flags |= BNXT_FLAG_REGISTERED;
+
+	return rc;
+}
+
 int bnxt_hwrm_ver_get(struct bnxt *bp)
 {
 	int rc = 0;
@@ -264,6 +293,27 @@ error:
 	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;
+
+	if (!(bp->flags & BNXT_FLAG_REGISTERED))
+		return 0;
+
+	HWRM_PREP(req, FUNC_DRV_UNRGTR, -1, resp);
+	req.flags = flags;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	bp->flags &= ~BNXT_FLAG_REGISTERED;
+
+	return rc;
+}
+
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index e35e8c0..6f2e445 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,7 +41,10 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
+				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 1667927..be3ed0f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -50,9 +50,11 @@
 /*
  * Request types
  */
-#define HWRM_VER_GET                                      (UINT32_C(0x0))
-#define HWRM_FUNC_QCAPS                                   (UINT32_C(0x15))
-#define HWRM_QUEUE_QPORTCFG                               (UINT32_C(0x30))
+#define HWRM_VER_GET		(UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
+#define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
+#define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
+#define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
  * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
@@ -951,4 +953,273 @@ struct hwrm_queue_qportcfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_func_drv_rgtr */
+/*
+ * Description: This command is used by the function driver to register its
+ * information with the HWRM. A function driver shall implement this command. A
+ * function driver shall use this command during the driver initialization right
+ * after the HWRM version discovery and default ring resources allocation.
+ */
+
+/* Input (80 bytes) */
+struct hwrm_func_drv_rgtr_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the function driver is requesting all requests
+	 * from its children VF drivers to be forwarded to itself. This flag can
+	 * only be set by the PF driver. If a VF driver sets this flag, it
+	 * should be ignored by the HWRM.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_ALL_MODE        UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the function is requesting none of the requests
+	 * from its children VF drivers to be forwarded to itself. This flag can
+	 * only be set by the PF driver. If a VF driver sets this flag, it
+	 * should be ignored by the HWRM.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE       UINT32_C(0x2)
+	uint32_t flags;
+
+	/* This bit must be '1' for the os_type field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE           UINT32_C(0x1)
+	/* This bit must be '1' for the ver field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER               UINT32_C(0x2)
+	/* This bit must be '1' for the timestamp field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_TIMESTAMP         UINT32_C(0x4)
+	/* This bit must be '1' for the vf_req_fwd field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD        UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the async_event_fwd field to be configured.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD \
+								UINT32_C(0x10)
+	uint32_t enables;
+
+	/* This value indicates the type of OS. */
+		/* Unknown */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* Other OS not listed below. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER \
+							(UINT32_C(0x1) << 0)
+		/* MSDOS OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS \
+							(UINT32_C(0xe) << 0)
+		/* Windows OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS \
+							(UINT32_C(0x12) << 0)
+		/* Solaris OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS \
+							(UINT32_C(0x1d) << 0)
+		/* Linux OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX \
+							(UINT32_C(0x24) << 0)
+		/* FreeBSD OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD \
+							(UINT32_C(0x2a) << 0)
+		/* VMware ESXi OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI \
+							(UINT32_C(0x68) << 0)
+		/* Microsoft Windows 8 64-bit OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864 \
+							(UINT32_C(0x73) << 0)
+		/* Microsoft Windows Server 2012 R2 OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2 \
+							(UINT32_C(0x74) << 0)
+	uint16_t os_type;
+
+	/* This is the major version of the driver. */
+	uint8_t ver_maj;
+
+	/* This is the minor version of the driver. */
+	uint8_t ver_min;
+
+	/* This is the update version of the driver. */
+	uint8_t ver_upd;
+
+	uint8_t unused_0;
+	uint16_t unused_1;
+
+	/*
+	 * This is a 32-bit timestamp provided by the driver for keep alive. The
+	 * timestamp is in multiples of 1ms.
+	 */
+	uint32_t timestamp;
+
+	uint32_t unused_2;
+
+	/*
+	 * This is a 256-bit bit mask provided by the PF driver for letting the
+	 * HWRM know what commands issued by the VF driver to the HWRM should be
+	 * forwarded to the PF driver. Nth bit refers to the Nth req_type.
+	 * Setting Nth bit to 1 indicates that requests from the VF driver with
+	 * req_type equal to N shall be forwarded to the parent PF driver. This
+	 * field is not valid for the VF driver.
+	 */
+	uint32_t vf_req_fwd[8];
+
+	/*
+	 * This is a 256-bit bit mask provided by the function driver (PF or VF
+	 * driver) to indicate the list of asynchronous event completions to be
+	 * forwarded. Nth bit refers to the Nth event_id. Setting Nth bit to 1
+	 * by the function driver shall result in the HWRM forwarding
+	 * asynchronous event completion with event_id equal to N. If all bits
+	 * are set to 0 (value of 0), then the HWRM shall not forward any
+	 * asynchronous event completion to this function driver.
+	 */
+	uint32_t async_event_fwd[8];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_drv_rgtr_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_func_drv_unrgtr */
+/*
+ * Description: This command is used by the function driver to un register with
+ * the HWRM. A function driver shall implement this command. A function driver
+ * shall use this command during the driver unloading.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_func_drv_unrgtr_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the function driver is notifying the HWRM to
+	 * prepare for the shutdown.
+	 */
+	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN \
+							UINT32_C(0x1)
+	uint32_t flags;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_func_drv_unrgtr_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 04/40] bnxt: add dev infos get operation
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 02/40] bnxt: add HWRM init code Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 03/40] bnxt: add driver register/unregister support Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 05/40] bnxt: add dev configure operation Stephen Hurd
                                   ` (36 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Gets device info from the bp structure filled in the init() function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  3 ++
 drivers/net/bnxt/bnxt_ethdev.c | 96 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index ebddeab..9ba2433 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,6 +42,9 @@
 #include <rte_lcore.h>
 #include <rte_spinlock.h>
 
+#define BNXT_MAX_MTU		9000
+#define VLAN_TAG_SIZE		4
+
 struct bnxt_vf_info {
 	uint16_t		fw_fid;
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 07519df..d55b9e9 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -53,11 +53,105 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 };
 
 /*
+ * 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;
+}
+
+/*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
-0
+	.dev_infos_get = bnxt_dev_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 05/40] bnxt: add dev configure operation
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (2 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 04/40] bnxt: add dev infos get operation Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 06/40] bnxt: add vnic functions and structs Stephen Hurd
                                   ` (35 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

This adds the bnxt_hwrm_port_phy_cfg() HWRM call, and copies required
information into the new struct bnxt_link_info.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  32 +++
 drivers/net/bnxt/bnxt_ethdev.c         |  24 ++
 drivers/net/bnxt/bnxt_hwrm.c           | 232 +++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 470 +++++++++++++++++++++++++++++++++
 5 files changed, 758 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 9ba2433..f1a620f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -81,6 +81,29 @@ struct bnxt_pf_info {
 	struct bnxt_vf_info	*vf;
 };
 
+/* 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;
@@ -99,6 +122,14 @@ struct bnxt {
 #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;
+
 #define MAX_NUM_MAC_ADDR	32
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
 
@@ -109,6 +140,7 @@ struct bnxt {
 	uint16_t			max_req_len;
 	uint16_t			max_resp_len;
 
+	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
 	struct bnxt_pf_info		pf;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d55b9e9..1852035 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -146,12 +146,36 @@ found:
 	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;
+
+	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;
+	rc = bnxt_set_hwrm_link_config(bp, true);
+	return rc;
+}
+
 /*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
+	.dev_configure = bnxt_dev_configure_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 398f0f5..73d92c5 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -83,7 +83,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 		/* Sanity check on the resp->resp_len */
 		rte_rmb();
 		if (resp->resp_len && resp->resp_len <=
-		    bp->max_resp_len) {
+				bp->max_resp_len) {
 			/* Last byte of resp contains the valid key */
 			valid = (uint8_t *)resp + resp->resp_len - 1;
 			if (*valid == HWRM_RESP_VALID_KEY)
@@ -314,6 +314,61 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)
 	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;
+}
+
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
@@ -372,3 +427,178 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 
 	return 0;
 }
+
+static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
+{
+	uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+	if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+		return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+	switch (conf_link_speed) {
+	case ETH_LINK_SPEED_10M_HD:
+	case ETH_LINK_SPEED_100M_HD:
+		return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF;
+	}
+	return hw_link_duplex;
+}
+
+static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
+{
+	uint16_t eth_link_speed = 0;
+
+	if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+		return ETH_LINK_SPEED_AUTONEG;
+
+	switch (conf_link_speed & ~ETH_LINK_SPEED_FIXED) {
+	case ETH_LINK_SPEED_100M:
+	case ETH_LINK_SPEED_100M_HD:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB;
+		break;
+	case ETH_LINK_SPEED_1G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+		break;
+	case ETH_LINK_SPEED_2_5G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+		break;
+	case ETH_LINK_SPEED_10G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+		break;
+	case ETH_LINK_SPEED_20G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+		break;
+	case ETH_LINK_SPEED_25G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+		break;
+	case ETH_LINK_SPEED_40G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+		break;
+	case ETH_LINK_SPEED_50G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+		break;
+	default:
+		RTE_LOG(ERR, PMD,
+			"Unsupported link speed %d; default to AUTO\n",
+			conf_link_speed);
+		break;
+	}
+	return eth_link_speed;
+}
+
+#define BNXT_SUPPORTED_SPEEDS (ETH_LINK_SPEED_100M | ETH_LINK_SPEED_100M_HD | \
+		ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G | \
+		ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G | ETH_LINK_SPEED_25G | \
+		ETH_LINK_SPEED_40G | ETH_LINK_SPEED_50G)
+
+static int bnxt_valid_link_speed(uint32_t link_speed, uint8_t port_id)
+{
+	uint32_t one_speed;
+
+	if (link_speed == ETH_LINK_SPEED_AUTONEG)
+		return 0;
+
+	if (link_speed & ETH_LINK_SPEED_FIXED) {
+		one_speed = link_speed & ~ETH_LINK_SPEED_FIXED;
+
+		if (one_speed & (one_speed - 1)) {
+			RTE_LOG(ERR, PMD,
+				"Invalid advertised speeds (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+		if ((one_speed & BNXT_SUPPORTED_SPEEDS) != one_speed) {
+			RTE_LOG(ERR, PMD,
+				"Unsupported advertised speed (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+	} else {
+		if (!(link_speed & BNXT_SUPPORTED_SPEEDS)) {
+			RTE_LOG(ERR, PMD,
+				"Unsupported advertised speeds (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static uint16_t bnxt_parse_eth_link_speed_mask(uint32_t link_speed)
+{
+	uint16_t ret = 0;
+
+	if (link_speed == ETH_LINK_SPEED_AUTONEG)
+		link_speed = BNXT_SUPPORTED_SPEEDS;
+
+	if (link_speed & ETH_LINK_SPEED_100M)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+	if (link_speed & ETH_LINK_SPEED_100M_HD)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+	if (link_speed & ETH_LINK_SPEED_1G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+	if (link_speed & ETH_LINK_SPEED_2_5G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+	if (link_speed & ETH_LINK_SPEED_10G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+	if (link_speed & ETH_LINK_SPEED_20G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+	if (link_speed & ETH_LINK_SPEED_25G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+	if (link_speed & ETH_LINK_SPEED_40G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+	if (link_speed & ETH_LINK_SPEED_50G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+	return ret;
+}
+
+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;
+
+	rc = bnxt_valid_link_speed(dev_conf->link_speeds,
+			bp->eth_dev->data->port_id);
+	if (rc)
+		goto error;
+
+	memset(&link_req, 0, sizeof(link_req));
+	speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
+	link_req.link_up = link_up;
+	if (speed == 0) {
+		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;
+		link_req.auto_link_speed_mask =
+			bnxt_parse_eth_link_speed_mask(dev_conf->link_speeds);
+		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_speeds);
+	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);
+	}
+
+error:
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6f2e445..eef3be6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -52,5 +52,6 @@ int bnxt_hwrm_ver_get(struct bnxt *bp);
 
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
 
 #endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index be3ed0f..e36774e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -54,6 +54,7 @@
 #define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
+#define HWRM_PORT_PHY_CFG                                 (UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
@@ -345,6 +346,475 @@ struct hwrm_func_qcaps_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_port_phy_cfg */
+/*
+ * Description: This command configures the PHY device for the port. It allows
+ * setting of the most generic settings for the PHY. The HWRM shall complete
+ * this command as soon as PHY settings are configured. They may not be applied
+ * when the command response is provided. A VF driver shall not be allowed to
+ * configure PHY using this command. In a network partition mode, a PF driver
+ * shall not be allowed to configure PHY using this command.
+ */
+
+/* Input (56 bytes) */
+struct hwrm_port_phy_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is set to '1', the PHY for the port shall be reset. #
+	 * If this bit is set to 1, then the HWRM shall reset the PHY after
+	 * applying PHY configuration changes specified in this command. # In
+	 * order to guarantee that PHY configuration changes specified in this
+	 * command take effect, the HWRM client should set this flag to 1. # If
+	 * this bit is not set to 1, then the HWRM may reset the PHY depending
+	 * on the current PHY configuration and settings specified in this
+	 * command.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY            UINT32_C(0x1)
+	/*
+	 * When this bit is set to '1', the link shall be forced to be taken
+	 * down. # When this bit is set to '1", all other command input settings
+	 * related to the link speed shall be ignored. Once the link state is
+	 * forced down, it can be explicitly cleared from that state by setting
+	 * this flag to '0'. # If this flag is set to '0', then the link shall
+	 * be cleared from forced down state if the link is in forced down
+	 * state. There may be conditions (e.g. out-of-band or sideband
+	 * configuration changes for the link) outside the scope of the HWRM
+	 * implementation that may clear forced down link state.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN      UINT32_C(0x2)
+	/*
+	 * When this bit is set to '1', the link shall be forced to the
+	 * force_link_speed value. When this bit is set to '1', the HWRM client
+	 * should not enable any of the auto negotiation related fields
+	 * represented by auto_XXX fields in this command. When this bit is set
+	 * to '1' and the HWRM client has enabled a auto_XXX field in this
+	 * command, then the HWRM shall ignore the enabled auto_XXX field. When
+	 * this bit is set to zero, the link shall be allowed to autoneg.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE                UINT32_C(0x4)
+	/*
+	 * When this bit is set to '1', the auto-negotiation process shall be
+	 * restarted on the link.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG      UINT32_C(0x8)
+	/*
+	 * When this bit is set to '1', Energy Efficient Ethernet (EEE) is
+	 * requested to be enabled on this link. If EEE is not supported on this
+	 * port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+	/*
+	 * When this bit is set to '1', Energy Efficient Ethernet (EEE) is
+	 * requested to be disabled on this link. If EEE is not supported on
+	 * this port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	/*
+	 * When this bit is set to '1' and EEE is enabled on this link, then TX
+	 * LPI is requested to be enabled on the link. If EEE is not supported
+	 * on this port, then this flag shall be ignored by the HWRM. If EEE is
+	 * disabled on this port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI	UINT32_C(0x40)
+	uint32_t flags;
+
+	/* This bit must be '1' for the auto_mode field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE          UINT32_C(0x1)
+	/* This bit must be '1' for the auto_duplex field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX        UINT32_C(0x2)
+	/* This bit must be '1' for the auto_pause field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE         UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the auto_link_speed field to be configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED    UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the auto_link_speed_mask field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK \
+								UINT32_C(0x10)
+	/* This bit must be '1' for the wirespeed field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_WIRESPEED	UINT32_C(0x20)
+	/* This bit must be '1' for the lpbk field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_LPBK		UINT32_C(0x40)
+	/* This bit must be '1' for the preemphasis field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_PREEMPHASIS	UINT32_C(0x80)
+	/* This bit must be '1' for the force_pause field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the eee_link_speed_mask field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_EEE_LINK_SPEED_MASK \
+								UINT32_C(0x200)
+	/* This bit must be '1' for the tx_lpi_timer field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_TX_LPI_TIMER	UINT32_C(0x400)
+	uint32_t enables;
+
+	/* Port ID of port that is to be configured. */
+	uint16_t port_id;
+
+	/*
+	 * This is the speed that will be used if the force bit is '1'. If
+	 * unsupported speed is selected, an error will be generated.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t force_link_speed;
+
+	/*
+	 * This value is used to identify what autoneg mode is used when the
+	 * link speed is not being forced.
+	 */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE	(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK \
+							(UINT32_C(0x4) << 0)
+	uint8_t auto_mode;
+
+	/*
+	 * This is the duplex setting that will be used if the autoneg_mode is
+	 * "one_speed" or "one_or_below".
+	 */
+		/* Half Duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF \
+							(UINT32_C(0x0) << 0)
+		/* Full duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL \
+							(UINT32_C(0x1) << 0)
+		/* Both Half and Full dupex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH \
+							(UINT32_C(0x2) << 0)
+	uint8_t auto_duplex;
+
+	/*
+	 * This value is used to configure the pause that will be used for
+	 * autonegotiation. Add text on the usage of auto_pause and force_pause.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX              UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX              UINT32_C(0x2)
+	/*
+	 * When set to 1, the advertisement of pause is enabled. # When the
+	 * auto_mode is not set to none and this flag is set to 1, then the
+	 * auto_pause bits on this port are being advertised and autoneg pause
+	 * results are being interpreted. # When the auto_mode is not set to
+	 * none and this flag is set to 0, the pause is forced as indicated in
+	 * force_pause, and also advertised as auto_pause bits, but the autoneg
+	 * results are not interpreted since the pause configuration is being
+	 * forced. # When the auto_mode is set to none and this flag is set to
+	 * 1, auto_pause bits should be ignored and should be set to 0.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE   UINT32_C(0x4)
+	uint8_t auto_pause;
+
+	uint8_t unused_0;
+
+	/*
+	 * This is the speed that will be used if the autoneg_mode is
+	 * "one_speed" or "one_or_below". If an unsupported speed is selected,
+	 * an error will be generated.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t auto_link_speed;
+
+	/*
+	 * This is a mask of link speeds that will be used if autoneg_mode is
+	 * "mask". If unsupported speed is enabled an error will be generated.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB \
+							UINT32_C(0x2000)
+	uint16_t auto_link_speed_mask;
+
+	/* This value controls the wirespeed feature. */
+		/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_OFF	(UINT32_C(0x0) << 0)
+		/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_ON	(UINT32_C(0x1) << 0)
+	uint8_t wirespeed;
+
+	/* This value controls the loopback setting for the PHY. */
+		/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_NONE	(UINT32_C(0x0) << 0)
+		/*
+		 * The HW will be configured with local loopback such that host
+		 * data is sent back to the host without modification.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL	(UINT32_C(0x1) << 0)
+		/*
+		 * The HW will be configured with remote loopback such that port
+		 * logic will send packets back out the transmitter that are
+		 * received.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE	(UINT32_C(0x2) << 0)
+	uint8_t lpbk;
+
+	/*
+	 * This value is used to configure the pause that will be used for force
+	 * mode.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX             UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX             UINT32_C(0x2)
+	uint8_t force_pause;
+
+	uint8_t unused_1;
+
+	/*
+	 * This value controls the pre-emphasis to be used for the link. Driver
+	 * should not set this value (use enable.preemphasis = 0) unless driver
+	 * is sure of setting. Normally HWRM FW will determine proper pre-
+	 * emphasis.
+	 */
+	uint32_t preemphasis;
+
+	/*
+	 * Setting for link speed mask that is used to advertise speeds during
+	 * autonegotiation when EEE is enabled. This field is valid only when
+	 * EEE is enabled. The speeds specified in this field shall be a subset
+	 * of speeds specified in auto_link_speed_mask. If EEE is enabled,then
+	 * at least one speed shall be provided in this mask.
+	 */
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD1  UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_100MB  UINT32_C(0x2)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD2  UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_1GB    UINT32_C(0x8)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD3 \
+								UINT32_C(0x10)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD4 \
+								UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_10GB \
+								UINT32_C(0x40)
+	uint16_t eee_link_speed_mask;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * Reuested setting of TX LPI timer in microseconds. This field is valid
+	 * only when EEE is enabled and TX LPI is enabled.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK \
+							UINT32_C(0xffffff)
+	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT           0
+	uint32_t tx_lpi_timer;
+
+	uint32_t unused_4;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_port_phy_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 06/40] bnxt: add vnic functions and structs
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (3 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 05/40] bnxt: add dev configure operation Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 07/40] bnxt: declare ring structs and free() func Stephen Hurd
                                   ` (34 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Add functions to allocate, initialize, and free vnics.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |  14 ++
 drivers/net/bnxt/bnxt_vnic.c           | 277 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_vnic.h           |  80 ++++++++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |   5 +-
 5 files changed, 376 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/bnxt/bnxt_vnic.c
 create mode 100644 drivers/net/bnxt/bnxt_vnic.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index bb2be76..f77ecb5 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 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_vnic.c
 
 #
 # Export include files
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index f1a620f..846972e 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,6 +45,13 @@
 #define BNXT_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
+enum bnxt_hw_context {
+	HW_CONTEXT_NONE     = 0,
+	HW_CONTEXT_IS_RSS   = 1,
+	HW_CONTEXT_IS_COS   = 2,
+	HW_CONTEXT_IS_LB    = 3,
+};
+
 struct bnxt_vf_info {
 	uint16_t		fw_fid;
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
@@ -130,6 +137,13 @@ struct bnxt {
 	unsigned		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
 
+	struct bnxt_vnic_info	*vnic_info;
+	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_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];
+
 #define MAX_NUM_MAC_ADDR	32
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
 
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
new file mode 100644
index 0000000..c04c4c7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -0,0 +1,277 @@
+/*-
+ *   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 = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->fw_rss_cos_lb_ctx = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->ctx_is_rss_cos_lb = HW_CONTEXT_NONE;
+
+		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
+			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
+
+		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 = (uint16_t)HWRM_NA_SIGNATURE;
+			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;
+
+	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);
+	}
+
+	return 0;
+}
+
+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 != (uint16_t)HWRM_NA_SIGNATURE) {
+			RTE_LOG(ERR, PMD, "VNIC is not freed yet!\n");
+			/* TODO Call HWRM to free VNIC */
+		}
+	}
+
+	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
index e36774e..3c032e0 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -43,8 +43,11 @@
  * Following is the signature for HWRM message field that indicates not
  * applicable (All F's). Need to cast it the size of the field if needed.
  */
+#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
 #define HWRM_MAX_REQ_LEN	(128)  /* hwrm_func_buf_rgtr */
 #define HWRM_MAX_RESP_LEN	(176)  /* hwrm_func_qstats */
+#define HW_HASH_INDEX_SIZE      0x80    /* 7 bit indirection table index. */
+#define HW_HASH_KEY_SIZE        40
 #define HWRM_RESP_VALID_KEY	1 /* valid key for HWRM response */
 
 /*
@@ -54,7 +57,7 @@
 #define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
-#define HWRM_PORT_PHY_CFG                                 (UINT32_C(0x20))
+#define HWRM_PORT_PHY_CFG	(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 07/40] bnxt: declare ring structs and free() func
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (4 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 06/40] bnxt: add vnic functions and structs Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 08/40] bnxt: add completion ring support Stephen Hurd
                                   ` (33 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Declare ring structures and a ring free() function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile    |  1 +
 drivers/net/bnxt/bnxt_ring.c | 51 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_ring.h | 92 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_ring.c
 create mode 100644 drivers/net/bnxt/bnxt_ring.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index f77ecb5..0754dd6 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 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_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
new file mode 100644
index 0000000..0434b07
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -0,0 +1,51 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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;
+	}
+}
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
new file mode 100644
index 0000000..f44025c
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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;
+void bnxt_free_ring(struct bnxt_ring_struct *ring);
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 08/40] bnxt: add completion ring support
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (5 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 07/40] bnxt: declare ring structs and free() func Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
                                   ` (32 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Structures, macros, and functions for working with completion rings
in the driver.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   6 +
 drivers/net/bnxt/bnxt_cpr.c            | 139 +++++++++++++++++++
 drivers/net/bnxt/bnxt_cpr.h            |  88 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c           |  18 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 239 ++++++++++++++++++++++++++++++++-
 7 files changed, 487 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_cpr.c
 create mode 100644 drivers/net/bnxt/bnxt_cpr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0754dd6..e239c96 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -48,6 +48,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 # all source are stored in SRCS-y
 #
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
 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
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 846972e..4e0b514 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,6 +42,9 @@
 #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_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
@@ -137,6 +140,9 @@ struct bnxt {
 	unsigned		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
 
+	/* Default completion ring */
+	struct bnxt_cp_ring_info	def_cp_ring;
+
 	struct bnxt_vnic_info	*vnic_info;
 	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_list;
 
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
new file mode 100644
index 0000000..ff82335
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -0,0 +1,139 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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"
+#include "bnxt_ring.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..878c7c9
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -0,0 +1,88 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+#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_ring_struct;
+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)
+
+
+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_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 73d92c5..f104a3f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -135,6 +135,24 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_qcaps(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index eef3be6..b792313 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,6 +41,8 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
+
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 3c032e0..9efb68b 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -53,12 +53,143 @@
 /*
  * Request types
  */
-#define HWRM_VER_GET		(UINT32_C(0x0))
-#define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
-#define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
-#define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
-#define HWRM_PORT_PHY_CFG	(UINT32_C(0x20))
-#define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
+#define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS			(UINT32_C(0x15))
+#define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
+#define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
+#define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
+#define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#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 HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
+
+/* Return Codes */
+#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
+#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
+
+/* HWRM Forwarded Request (16 bytes) */
+struct hwrm_fwd_req_cmpl {
+	/* Length of forwarded request in bytes. */
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define HWRM_FWD_REQ_CMPL_TYPE_MASK		UINT32_C(0x3f)
+	#define HWRM_FWD_REQ_CMPL_TYPE_SFT		0
+		/* Forwarded HWRM Request */
+	#define HWRM_FWD_REQ_CMPL_TYPE_HWRM_FWD_REQ	(UINT32_C(0x22) << 0)
+	/* Length of forwarded request in bytes. */
+	#define HWRM_FWD_REQ_CMPL_REQ_LEN_MASK		UINT32_C(0xffc0)
+	#define HWRM_FWD_REQ_CMPL_REQ_LEN_SFT		6
+	uint16_t req_len_type;
+
+	/*
+	 * Source ID of this request. Typically used in forwarding requests and
+	 * responses. 0x0 - 0xFFF8 - Used for function ids 0xFFF8 - 0xFFFE -
+	 * Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t source_id;
+
+	uint32_t unused_0;
+
+	/* Address of forwarded request. */
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define HWRM_FWD_REQ_CMPL_V			UINT32_C(0x1)
+	/* Address of forwarded request. */
+	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_MASK	UINT32_C(0xfffffffe)
+	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
+	uint64_t req_buf_addr_v;
+} __attribute__((packed));
+
+/* HWRM Asynchronous Event Completion Record (16 bytes) */
+struct hwrm_async_event_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_MASK		UINT32_C(0x3f)
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_SFT		0
+		/* HWRM Asynchronous Event Information */
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT \
+							(UINT32_C(0x2e) << 0)
+	uint16_t type;
+
+	/* Identifiers of events. */
+		/* Link status changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE \
+							(UINT32_C(0x0) << 0)
+		/* Link MTU changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE \
+							(UINT32_C(0x1) << 0)
+		/* Link speed changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE \
+							(UINT32_C(0x2) << 0)
+		/* DCB Configuration changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE \
+							(UINT32_C(0x3) << 0)
+		/* Port connection not allowed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+							(UINT32_C(0x4) << 0)
+		/* Link speed configuration was not allowed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+							(UINT32_C(0x5) << 0)
+		/* Function driver unloaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD \
+							(UINT32_C(0x10) << 0)
+		/* Function driver loaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD \
+							(UINT32_C(0x11) << 0)
+		/* PF driver unloaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD \
+							(UINT32_C(0x20) << 0)
+		/* PF driver loaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD \
+							(UINT32_C(0x21) << 0)
+		/* VF Function Level Reset (FLR) */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	(UINT32_C(0x30) << 0)
+		/* VF MAC Address Change */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE \
+							(UINT32_C(0x31) << 0)
+		/* PF-VF communication channel status change. */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+							(UINT32_C(0x32) << 0)
+		/* HWRM Error */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR \
+							(UINT32_C(0xff) << 0)
+	uint16_t event_id;
+
+	/* Event specific data */
+	uint32_t event_data2;
+
+	/* opaque is 7 b */
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define HWRM_ASYNC_EVENT_CMPL_V				UINT32_C(0x1)
+	/* opaque is 7 b */
+	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK		UINT32_C(0xfe)
+	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT		1
+	uint8_t opaque_v;
+
+	/* 8-lsb timestamp from POR (100-msec resolution) */
+	uint8_t timestamp_lo;
+
+	/* 16-lsb timestamp from POR (100-msec resolution) */
+	uint16_t timestamp_hi;
+
+	/* Event specific data */
+	uint32_t event_data1;
+} __attribute__((packed));
 
 /*
  * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
@@ -122,6 +253,102 @@ struct output {
 	uint16_t resp_len;
 } __attribute__((packed));
 
+/* hwrm_exec_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to execute the request and forward the
+ * response of the encapsulated request to the location specified in the
+ * original request that is encapsulated. The target id of this command shall be
+ * set to 0xFFFF (HWRM). The response location in this command shall be used to
+ * acknowledge the receipt of the encapsulated request and forwarding of the
+ * response.
+ */
+
+/* Input (128 bytes) */
+struct hwrm_exec_fwd_resp_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This is an encapsulated request. This request should be executed by
+	 * the HWRM and the response should be provided in the response buffer
+	 * inside the encapsulated request.
+	 */
+	uint32_t encap_request[26];
+
+	/*
+	 * This value indicates the target id of the response to the
+	 * encapsulated request. 0x0 - 0xFFF8 - Used for function ids 0xFFF8 -
+	 * 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t encap_resp_target_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_exec_fwd_resp_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_func_qcaps */
 /*
  * Description: This command returns capabilities of a function. The input FID
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 09/40] bnxt: add L2 filter alloc/init/free
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (6 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 08/40] bnxt: add completion ring support Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
                                   ` (31 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Add the L2 filter structure and the alloc/init/free functions for
dealing with them.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   3 +
 drivers/net/bnxt/bnxt_filter.c         | 175 ++++++++++++
 drivers/net/bnxt/bnxt_filter.h         |  74 +++++
 drivers/net/bnxt/bnxt_hwrm.c           |  21 ++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 505 +++++++++++++++++++++++++++++++++
 7 files changed, 782 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_filter.c
 create mode 100644 drivers/net/bnxt/bnxt_filter.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index e239c96..ec1164e 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_vnic.c
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4e0b514..54ddd24 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -146,6 +146,9 @@ struct bnxt {
 	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];
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
new file mode 100644
index 0000000..f03a1dc
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -0,0 +1,175 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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..06fe134
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -0,0 +1,74 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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
index f104a3f..82139ca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -39,6 +39,7 @@
 #include <rte_version.h>
 
 #include "bnxt.h"
+#include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -135,6 +136,26 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd)
 {
 	int rc;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b792313..c48ba3f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,6 +41,9 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_clear_filter(struct bnxt *bp,
+			   struct bnxt_filter_info *filter);
+
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 9efb68b..bfa8a7c 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -253,6 +253,511 @@ struct output {
 	uint16_t resp_len;
 } __attribute__((packed));
 
+/* hwrm_cfa_l2_filter_alloc */
+/*
+ * Description: An L2 filter is a filter resource that is used to identify a
+ * vnic or ring for a packet based on layer 2 fields. Layer 2 fields for
+ * encapsulated packets include both outer L2 header and/or inner l2 header of
+ * encapsulated packet. The L2 filter resource covers the following OS specific
+ * L2 filters. Linux/FreeBSD (per function): # Broadcast enable/disable # List
+ * of individual multicast filters # All multicast enable/disable filter #
+ * Unicast filters # Promiscuous mode VMware: # Broadcast enable/disable (per
+ * physical function) # All multicast enable/disable (per function) # Unicast
+ * filters per ring or vnic # Promiscuous mode per PF Windows: # Broadcast
+ * enable/disable (per physical function) # List of individual multicast filters
+ * (Driver needs to advertise the maximum number of filters supported) # All
+ * multicast enable/disable per physical function # Unicast filters per vnic #
+ * Promiscuous mode per PF Implementation notes on the use of VNIC in this
+ * command: # By default, these filters belong to default vnic for the function.
+ * # Once these filters are set up, only destination VNIC can be modified. # If
+ * the destination VNIC is not specified in this command, then the HWRM shall
+ * only create an l2 context id. HWRM Implementation notes for multicast
+ * filters: # The hwrm_filter_alloc command can be used to set up multicast
+ * filters (perfect match or partial match). Each individual function driver can
+ * set up multicast filters independently. # The HWRM needs to keep track of
+ * multicast filters set up by function drivers and maintain multicast group
+ * replication records to enable a subset of functions to receive traffic for a
+ * specific multicast address. # When a specific multicast filter cannot be set,
+ * the HWRM shall return an error. In this error case, the driver should fall
+ * back to using one general filter (rather than specific) for all multicast
+ * traffic. # When the SR-IOV is enabled, the HWRM needs to additionally track
+ * source knockout per multicast group record. Examples of setting unicast
+ * filters: For a unicast MAC based filter, one can use a combination of the
+ * fields and masks provided in this command to set up the filter. Below are
+ * some examples: # MAC + no VLAN filter: This filter is used to identify
+ * traffic that does not contain any VLAN tags and matches destination (or
+ * source) MAC address. This filter can be set up by setting only l2_addr field
+ * to be a valid field. All other fields are not valid. The following value is
+ * set for l2_addr. l2_addr = MAC # MAC + Any VLAN filter: This filter is used
+ * to identify traffic that carries single VLAN tag and matches (destination or
+ * source) MAC address. This filter can be set up by setting only l2_addr and
+ * l2_ovlan_mask fields to be valid fields. All other fields are not valid. The
+ * following values are set for those two valid fields. l2_addr = MAC,
+ * l2_ovlan_mask = 0xFFFF # MAC + no VLAN or VLAN ID=0: This filter is used to
+ * identify untagged traffic that does not contain any VLAN tags or a VLAN tag
+ * with VLAN ID = 0 and matches destination (or source) MAC address. This filter
+ * can be set up by setting only l2_addr and l2_ovlan fields to be valid fields.
+ * All other fields are not valid. The following value are set for l2_addr and
+ * l2_ovlan. l2_addr = MAC, l2_ovlan = 0x0 # MAC + no VLAN or any VLAN: This
+ * filter is used to identify traffic that contains zero or 1 VLAN tag and
+ * matches destination (or source) MAC address. This filter can be set up by
+ * setting only l2_addr, l2_ovlan, and l2_mask fields to be valid fields. All
+ * other fields are not valid. The following value are set for l2_addr,
+ * l2_ovlan, and l2_mask fields. l2_addr = MAC, l2_ovlan = 0x0, l2_ovlan_mask =
+ * 0xFFFF # MAC + VLAN ID filter: This filter can be set up by setting only
+ * l2_addr, l2_ovlan, and l2_ovlan_mask fields to be valid fields. All other
+ * fields are not valid. The following values are set for those three valid
+ * fields. l2_addr = MAC, l2_ovlan = VLAN ID, l2_ovlan_mask = 0xF000
+ */
+
+/* Input (96 bytes) */
+struct hwrm_cfa_l2_filter_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Enumeration denoting the RX, TX type of the resource. This
+	 * enumeration is used for resources that are similar for both TX and RX
+	 * paths of the chip.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH \
+							UINT32_C(0x1)
+		/* tx path */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_TX \
+							(UINT32_C(0x0) << 0)
+		/* rx path */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX \
+							(UINT32_C(0x1) << 0)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_LAST \
+				HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX
+	/*
+	 * Setting of this flag indicates the applicability to the loopback
+	 * path.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK \
+							UINT32_C(0x2)
+	/*
+	 * Setting of this flag indicates drop action. If this flag is not set,
+	 * then it should be considered accept action.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP \
+							UINT32_C(0x4)
+	/*
+	 * If this flag is set, all t_l2_* fields are invalid and they should
+	 * not be specified. If this flag is set, then l2_* fields refer to
+	 * fields of outermost L2 header.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST \
+							UINT32_C(0x8)
+	uint32_t flags;
+
+	/* This bit must be '1' for the l2_addr field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR \
+							UINT32_C(0x1)
+	/* This bit must be '1' for the l2_addr_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK \
+							UINT32_C(0x2)
+	/* This bit must be '1' for the l2_ovlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN \
+							UINT32_C(0x4)
+	/* This bit must be '1' for the l2_ovlan_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK \
+							UINT32_C(0x8)
+	/* This bit must be '1' for the l2_ivlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN \
+							UINT32_C(0x10)
+	/* This bit must be '1' for the l2_ivlan_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK \
+							UINT32_C(0x20)
+	/* This bit must be '1' for the t_l2_addr field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR \
+							UINT32_C(0x40)
+	/*
+	 * This bit must be '1' for the t_l2_addr_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR_MASK \
+							UINT32_C(0x80)
+	/* This bit must be '1' for the t_l2_ovlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN \
+							UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the t_l2_ovlan_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN_MASK \
+							UINT32_C(0x200)
+	/* This bit must be '1' for the t_l2_ivlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN \
+							UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the t_l2_ivlan_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN_MASK \
+							UINT32_C(0x800)
+	/* This bit must be '1' for the src_type field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE \
+							UINT32_C(0x1000)
+	/* This bit must be '1' for the src_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID \
+							UINT32_C(0x2000)
+	/* This bit must be '1' for the tunnel_type field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+							UINT32_C(0x4000)
+	/* This bit must be '1' for the dst_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID \
+							UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the mirror_vnic_id field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+							UINT32_C(0x10000)
+	uint32_t enables;
+
+	/*
+	 * This value sets the match value for the L2 MAC address. Destination
+	 * MAC address for RX path. Source MAC address for TX path.
+	 */
+	uint8_t l2_addr[6];
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+
+	/*
+	 * This value sets the mask value for the L2 address. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint8_t l2_addr_mask[6];
+
+	/* This value sets VLAN ID value for outer VLAN. */
+	uint16_t l2_ovlan;
+
+	/*
+	 * This value sets the mask value for the ovlan id. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint16_t l2_ovlan_mask;
+
+	/* This value sets VLAN ID value for inner VLAN. */
+	uint16_t l2_ivlan;
+
+	/*
+	 * This value sets the mask value for the ivlan id. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint16_t l2_ivlan_mask;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This value sets the match value for the tunnel L2 MAC address.
+	 * Destination MAC address for RX path. Source MAC address for TX path.
+	 */
+	uint8_t t_l2_addr[6];
+
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/*
+	 * This value sets the mask value for the tunnel L2 address. A value of
+	 * 0 will mask the corresponding bit from compare.
+	 */
+	uint8_t t_l2_addr_mask[6];
+
+	/* This value sets VLAN ID value for tunnel outer VLAN. */
+	uint16_t t_l2_ovlan;
+
+	/*
+	 * This value sets the mask value for the tunnel ovlan id. A value of 0
+	 * will mask the corresponding bit from compare.
+	 */
+	uint16_t t_l2_ovlan_mask;
+
+	/* This value sets VLAN ID value for tunnel inner VLAN. */
+	uint16_t t_l2_ivlan;
+
+	/*
+	 * This value sets the mask value for the tunnel ivlan id. A value of 0
+	 * will mask the corresponding bit from compare.
+	 */
+	uint16_t t_l2_ivlan_mask;
+
+	/* This value identifies the type of source of the packet. */
+		/* Network port */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_NPORT \
+							(UINT32_C(0x0) << 0)
+		/* Physical function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF \
+							(UINT32_C(0x1) << 0)
+		/* Virtual function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF \
+							(UINT32_C(0x2) << 0)
+		/* Virtual NIC of a function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC \
+							(UINT32_C(0x3) << 0)
+		/* Embedded processor for CFA management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG \
+							(UINT32_C(0x4) << 0)
+		/* Embedded processor for OOB management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE \
+							(UINT32_C(0x5) << 0)
+		/* Embedded processor for RoCE */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO \
+							(UINT32_C(0x6) << 0)
+		/* Embedded processor for network proxy functions */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG \
+							(UINT32_C(0x7) << 0)
+	uint8_t src_type;
+
+	uint8_t unused_6;
+	/*
+	 * This value is the id of the source. For a network port, it represents
+	 * port_id. For a physical function, it represents fid. For a virtual
+	 * function, it represents vf_id. For a vnic, it represents vnic_id. For
+	 * embedded processors, this id is not valid. Notes: 1. The function ID
+	 * is implied if it src_id is not provided for a src_type that is either
+	 */
+	uint32_t src_id;
+
+	/* Tunnel Type. */
+		/* Non-tunnel */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+							(UINT32_C(0x0) << 0)
+		/* Virtual eXtensible Local Area Network (VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Network Virtualization Generic Routing Encapsulation (NVGRE)
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Generic Routing Encapsulation (GRE) inside Ethernet payload
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+							(UINT32_C(0x3) << 0)
+		/* IP in IP */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+							(UINT32_C(0x4) << 0)
+		/* Generic Network Virtualization Encapsulation (Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+							(UINT32_C(0x5) << 0)
+		/* Multi-Protocol Lable Switching (MPLS) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+							(UINT32_C(0x6) << 0)
+		/* Stateless Transport Tunnel (STT) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+							(UINT32_C(0x7) << 0)
+		/*
+		 * Generic Routing Encapsulation (GRE) inside IP datagram
+		 * payload
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+							(UINT32_C(0x8) << 0)
+		/* Any tunneled traffic */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+							(UINT32_C(0xff) << 0)
+	uint8_t tunnel_type;
+
+	uint8_t unused_7;
+
+	/*
+	 * If set, this value shall represent the Logical VNIC ID of the
+	 * destination VNIC for the RX path and network port id of the
+	 * destination port for the TX path.
+	 */
+	uint16_t dst_id;
+
+	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
+	uint16_t mirror_vnic_id;
+
+	/*
+	 * This hint is provided to help in placing the filter in the filter
+	 * table.
+	 */
+		/* No preference */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+							(UINT32_C(0x0) << 0)
+		/* Above the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+							(UINT32_C(0x1) << 0)
+		/* Below the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+							(UINT32_C(0x2) << 0)
+		/* As high as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX \
+							(UINT32_C(0x3) << 0)
+		/* As low as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN \
+							(UINT32_C(0x4) << 0)
+	uint8_t pri_hint;
+
+	uint8_t unused_8;
+	uint32_t unused_9;
+
+	/*
+	 * This is the ID of the filter that goes along with the pri_hint. This
+	 * field is valid only for the following values. 1 - Above the given
+	 * filter 2 - Below the given filter
+	 */
+	uint64_t l2_filter_id_hint;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+struct hwrm_cfa_l2_filter_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This value identifies a set of CFA data structures used for an L2
+	 * context.
+	 */
+	uint64_t l2_filter_id;
+
+	/*
+	 * This is the ID of the flow associated with this filter. This value
+	 * shall be used to match and associate the flow identifier returned in
+	 * completion records. A value of 0xFFFFFFFF shall indicate no flow id.
+	 */
+	uint32_t flow_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_filter_free */
+/*
+ * Description: Free a L2 filter. The HWRM shall free all associated filter
+ * resources with the L2 filter.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_cfa_l2_filter_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This value identifies a set of CFA data structures used for an L2
+	 * context.
+	 */
+	uint64_t l2_filter_id;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_cfa_l2_filter_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_exec_fwd_resp */
 /*
  * Description: This command is used to send an encapsulated request to the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 10/40] bnxt: add Tx queue operations (nonfunctional)
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (7 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
                                   ` (30 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Add code to create/destroy TX queues.  This still requires TX ring support
to be completed in a future commit.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile      |   1 +
 drivers/net/bnxt/bnxt_ethdev.c |   3 +
 drivers/net/bnxt/bnxt_txq.c    | 125 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_txq.h    |  75 +++++++++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_txq.c
 create mode 100644 drivers/net/bnxt/bnxt_txq.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index ec1164e..0759df0 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -53,6 +53,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1852035..d8dbc10 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -41,6 +41,7 @@
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -176,6 +177,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_op,
+	.tx_queue_setup = bnxt_tx_queue_setup_op,
+	.tx_queue_release = bnxt_tx_queue_release_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
new file mode 100644
index 0000000..cb3dd8e
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -0,0 +1,125 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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 __rte_unused)
+{
+	/* TODO: Requires interaction with TX ring */
+}
+
+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;
+
+	if (txq) {
+		/* TODO: Free ring and stats here */
+		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;
+
+	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;
+
+	/* TODO: Initialize ring structure */
+
+	txq->queue_id = queue_idx;
+	txq->port_id = eth_dev->data->port_id;
+
+	/* TODO: Allocate TX ring hardware descriptors */
+
+	/* TODO: Initialize the ring */
+
+	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..5d9ccac
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.h
@@ -0,0 +1,75 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+struct bnxt_tx_ring_info;
+struct bnxt_cp_ring_info;
+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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 11/40] bnxt: add Rx queue create/destroy operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (8 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 12/40] bnxt: statistics operations Stephen Hurd
                                   ` (29 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Initial create/destroy queue code.  Requires RX ring support to be
functional.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   2 +
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +
 drivers/net/bnxt/bnxt_rxq.c            | 286 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxq.h            |  74 +++++++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 121 ++++++++++++++
 6 files changed, 487 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_rxq.c
 create mode 100644 drivers/net/bnxt/bnxt_rxq.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0759df0..7320fac 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -53,6 +53,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 54ddd24..38b590b 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -143,6 +143,8 @@ struct bnxt {
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	def_cp_ring;
 
+	unsigned		nr_vnics;
+
 	struct bnxt_vnic_info	*vnic_info;
 	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_list;
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d8dbc10..df39fae 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -41,6 +41,7 @@
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
 #include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
@@ -177,6 +178,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_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,
 };
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
new file mode 100644
index 0000000..4ba5d75
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -0,0 +1,286 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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_RSS:
+		case ETH_MQ_RX_VMDQ_ONLY:
+			{
+				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;
+			}
+		default:
+			RTE_LOG(ERR, PMD, "Unsupported mq_mod %d\n",
+				dev_conf->rxmode.mq_mode);
+			rc = -EINVAL;
+			goto err_out;
+		}
+		/* 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");
+				rc = -ENOMEM;
+				goto err_out;
+			}
+			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 */
+	/* Init default VNIC for RSS or DCB only */
+	vnic = bnxt_alloc_vnic(bp);
+	if (!vnic) {
+		RTE_LOG(ERR, PMD, "VNIC alloc failed\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	/* 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");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+	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 __rte_unused)
+{
+	/* TODO: Requires interaction with TX ring */
+}
+
+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;
+
+	if (rxq) {
+		bnxt_rx_queue_release_mbufs(rxq);
+
+		/* TODO: Free ring and stats here */
+
+		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;
+
+	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) {
+		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;
+
+	/* TODO: Initialize ring structure */
+
+	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);
+
+	eth_dev->data->rx_queues[queue_idx] = rxq;
+	/* TODO: Allocate RX ring hardware descriptors */
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
new file mode 100644
index 0000000..9554329
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -0,0 +1,74 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+struct bnxt;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
+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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index bfa8a7c..c5ff9ff 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1946,6 +1946,127 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+
+/* Input (48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over source and
+	 * destination IPv4 addresses of IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination ports of
+	 * TCP/IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination ports of
+	 * UDP/IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over source and
+	 * destination IPv4 addresses of IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6		UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv6 addresses and source/destination ports of
+	 * TCP/IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv6 addresses and source/destination ports of
+	 * UDP/IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6	UINT32_C(0x20)
+	uint32_t hash_type;
+
+	uint32_t unused_0;
+
+	/* This is the address for rss ring group table */
+	uint64_t ring_grp_tbl_addr;
+
+	/* This is the address for rss hash key table */
+	uint64_t hash_key_tbl_addr;
+
+	/* Index to the rss indirection table. */
+	uint16_t rss_ctx_idx;
+
+	uint16_t unused_1[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_rss_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* Output (32 bytes) */
 struct hwrm_queue_qportcfg_output {
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 12/40] bnxt: statistics operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (9 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 13/40] bnxt: initial Tx ring code Stephen Hurd
                                   ` (28 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Add get and clear staitstics operations and the asociated HWRM calls.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   5 +-
 drivers/net/bnxt/bnxt_cpr.c            |   5 +-
 drivers/net/bnxt/bnxt_cpr.h            |   2 -
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +
 drivers/net/bnxt/bnxt_hwrm.c           |  49 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   8 +-
 drivers/net/bnxt/bnxt_rxq.c            |   1 +
 drivers/net/bnxt/bnxt_stats.c          | 142 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h          |  44 ++++++++++
 drivers/net/bnxt/bnxt_txq.c            |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 107 +++++++++++++++++++++++++
 12 files changed, 358 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_stats.c
 create mode 100644 drivers/net/bnxt/bnxt_stats.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 7320fac..de9ce76 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 38b590b..96f162e 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,9 +42,6 @@
 #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_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
@@ -141,7 +138,7 @@ struct bnxt {
 	struct bnxt_tx_queue **tx_queues;
 
 	/* Default completion ring */
-	struct bnxt_cp_ring_info	def_cp_ring;
+	struct bnxt_cp_ring_info	*def_cp_ring;
 
 	unsigned		nr_vnics;
 
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index ff82335..34e45ef 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -35,6 +35,7 @@
 #include "bnxt_cpr.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
 
 /*
  * Async event handling
@@ -118,7 +119,7 @@ reject:
 /* 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_cp_ring_info *cpr = bp->def_cp_ring;
 	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
 
 	bnxt_free_ring(ring);
@@ -127,7 +128,7 @@ void bnxt_free_def_cp_ring(struct bnxt *bp)
 /* 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_cp_ring_info *cpr = bp->def_cp_ring;
 	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
 
 	ring->bd = (void *)cpr->cp_desc_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 878c7c9..e6333fc 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -34,8 +34,6 @@
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_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)))
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index df39fae..786318c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -42,6 +42,7 @@
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_stats.h"
 #include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
@@ -178,6 +179,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_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,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 82139ca..50d8b89 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -39,8 +39,11 @@
 #include <rte_version.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
 #define HWRM_CMD_TIMEOUT		2000
@@ -436,10 +439,56 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 	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)HWRM_NA_SIGNATURE)
+		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;
+}
+
 /*
  * 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;
+}
+
 void bnxt_free_hwrm_resources(struct bnxt *bp)
 {
 	/* Release memzone */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index c48ba3f..0861417 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -37,10 +37,11 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
-#include "bnxt.h"
-
 #define HWRM_SEQ_ID_INVALID -1U
 
+struct bnxt;
+struct bnxt_filter_info;
+struct bnxt_cp_ring_info;
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 
@@ -53,8 +54,11 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+int bnxt_clear_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_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 4ba5d75..b284e20 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
new file mode 100644
index 0000000..e09956d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -0,0 +1,142 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.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;
+
+	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);
+	}
+
+	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);
+	}
+}
+
+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);
+}
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
index cb3dd8e..a3648c2 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index c5ff9ff..989f533 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -34,6 +34,35 @@
 #ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
 #define _HSI_STRUCT_DEF_EXTERNAL_H_
 
+/*
+ * per-context HW statistics -- chip view
+ */
+
+typedef 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;
+
 /* HW Resource Manager Specification 1.2.0 */
 #define HWRM_VERSION_MAJOR	1
 #define HWRM_VERSION_MINOR	2
@@ -63,6 +92,7 @@
 #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 HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
 /* Return Codes */
@@ -1946,6 +1976,83 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_clr_stats */
+/* Description: This command clears statistics of a context. */
+
+/* Input (24 bytes) */
+struct hwrm_stat_ctx_clr_stats_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* ID of the statistics context that is being queried. */
+	uint32_t stat_ctx_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 13/40] bnxt: initial Tx ring code
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (10 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 12/40] bnxt: statistics operations Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 14/40] bnxt: initial Rx " Stephen Hurd
                                   ` (27 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Initial implementation of rx_pkt_burst
Add code to allocate rings to bnxt_ring.c

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt_cpr.h            |   4 +-
 drivers/net/bnxt/bnxt_ethdev.c         |   5 +-
 drivers/net/bnxt/bnxt_ring.c           | 140 +++++++++
 drivers/net/bnxt/bnxt_ring.h           |   8 +
 drivers/net/bnxt/bnxt_txq.c            |  42 ++-
 drivers/net/bnxt/bnxt_txr.c            | 314 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_txr.h            |  71 +++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 512 +++++++++++++++++++++++++++++++++
 9 files changed, 1086 insertions(+), 11 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_txr.c
 create mode 100644 drivers/net/bnxt/bnxt_txr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index de9ce76..009ddad 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ring.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.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_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index e6333fc..f104281 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -51,11 +51,11 @@
 
 #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)))
+				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)))
+				RING_CMP(cpr->cp_ring_struct, raw_cons)))
 
 struct bnxt_ring_struct;
 struct bnxt_cp_ring_info {
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 786318c..61e856a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -44,6 +44,7 @@
 #include "bnxt_rxq.h"
 #include "bnxt_stats.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -259,10 +260,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error;
 	}
 	eth_dev->dev_ops = &bnxt_dev_ops;
-	/*
-	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
+	/* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
-	 */
 
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0434b07..bb20806 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,8 +31,14 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_memzone.h>
+
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_ring.h"
+#include "bnxt_txr.h"
+
+#include "hsi_struct_def_dpdk.h"
 
 /*
  * Generic ring handling
@@ -49,3 +55,137 @@ void bnxt_free_ring(struct bnxt_ring_struct *ring)
 		*ring->vmem = NULL;
 	}
 }
+
+/*
+ * 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;
+	/* TODO: RX 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_stats64)) : 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;
+	/* TODO: RX ring */
+	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;
+	/* TODO: RX ring */
+	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 = HWRM_NA_SIGNATURE;
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index f44025c..dfa0401 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -87,6 +87,14 @@ struct bnxt_ring_grp_info {
 };
 
 struct bnxt;
+struct bnxt_tx_ring_info;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
 void bnxt_free_ring(struct bnxt_ring_struct *ring);
+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);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
index a3648c2..7aba199 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -39,6 +39,7 @@
 #include "bnxt_cpr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 
 /*
  * TX Queues
@@ -55,9 +56,20 @@ void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
 		cpr->hw_stats = NULL;
 }
 
-static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq __rte_unused)
+static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq)
 {
-	/* TODO: Requires interaction with TX ring */
+	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)
@@ -76,7 +88,15 @@ void bnxt_tx_queue_release_op(void *tx_queue)
 	struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
 
 	if (txq) {
-		/* TODO: Free ring and stats here */
+		/* Free TX ring hardware descriptors */
+		bnxt_tx_queue_release_mbufs(txq);
+		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+
+		/* Free TX completion ring hardware descriptors */
+		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+
+		bnxt_free_txq_stats(txq);
+
 		rte_free(txq);
 	}
 }
@@ -112,14 +132,24 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	txq->nb_tx_desc = nb_desc;
 	txq->tx_free_thresh = tx_conf->tx_free_thresh;
 
-	/* TODO: Initialize ring structure */
+	bnxt_init_tx_ring_struct(txq);
 
 	txq->queue_id = queue_idx;
 	txq->port_id = eth_dev->data->port_id;
 
-	/* TODO: Allocate TX ring hardware descriptors */
+	/* Allocate TX ring hardware descriptors */
+	if (bnxt_alloc_rings(bp, queue_idx, txq->tx_ring, NULL, txq->cp_ring,
+			"bnxt_tx_ring")) {
+		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for tx_ring failed!");
+		bnxt_tx_queue_release_op(txq);
+		return -ENOMEM;
+	}
 
-	/* TODO: Initialize the ring */
+	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_txr.c b/drivers/net/bnxt/bnxt_txr.c
new file mode 100644
index 0000000..2314410
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -0,0 +1,314 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.h"
+#include "bnxt_ring.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];
+
+		if (!txq)
+			continue;
+
+		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+		/* TODO: free() txq->tx_ring and txq->tx_ring->tx_ring_struct */
+		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+		/* TODO: free() txq->cp_ring and txq->cp_ring->cp_ring_struct */
+
+		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;
+
+	/* TODO: These need to be allocated */
+	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;
+
+	/* TODO: These need to be allocated */
+	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 = rte_cpu_to_le_32(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 = rte_cpu_to_le_32(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..1797a3d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -0,0 +1,71 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 989f533..ff02a29 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -99,6 +99,518 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
 #define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
 
+/* Short TX BD (16 bytes) */
+struct tx_bd_short {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	/* This value identifies the type of buffer descriptor. */
+	#define TX_BD_SHORT_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_BD_SHORT_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 16B long and is used for normal L2
+		 * packet transmission.
+		 */
+	#define TX_BD_SHORT_TYPE_TX_BD_SHORT		(UINT32_C(0x0) << 0)
+	/*
+	 * If set to 1, the packet ends with the data in the buffer pointed to
+	 * by this descriptor. This flag must be valid on every BD.
+	 */
+	#define TX_BD_SHORT_FLAGS_PACKET_END		UINT32_C(0x40)
+	/*
+	 * If set to 1, the device will not generate a completion for this
+	 * transmit packet unless there is an error in it's processing. If this
+	 * bit is set to 0, then the packet will be completed normally. This bit
+	 * must be valid only on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_NO_CMPL		UINT32_C(0x80)
+	/*
+	 * This value indicates how many 16B BD locations are consumed in the
+	 * ring by this packet. A value of 1 indicates that this BD is the only
+	 * BD (and that the it is a short BD). A value of 3 indicates either 3
+	 * short BDs or 1 long BD and one short BD in the packet. A value of 0
+	 * indicates that there are 32 BD locations in the packet (the maximum).
+	 * This field is valid only on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_BD_CNT_MASK		UINT32_C(0x1f00)
+	#define TX_BD_SHORT_FLAGS_BD_CNT_SFT		8
+	/*
+	 * This value is a hint for the length of the entire packet. It is used
+	 * by the chip to optimize internal processing. The packet will be
+	 * dropped if the hint is too short. This field is valid only on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_LHINT_MASK		UINT32_C(0x6000)
+	#define TX_BD_SHORT_FLAGS_LHINT_SFT		13
+		/* indicates packet length < 512B */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT512		(UINT32_C(0x0) << 13)
+		/* indicates 512 <= packet length < 1KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT1K		(UINT32_C(0x1) << 13)
+		/* indicates 1KB <= packet length < 2KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT2K		(UINT32_C(0x2) << 13)
+		/* indicates packet length >= 2KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_GTE2K		(UINT32_C(0x3) << 13)
+	#define TX_BD_SHORT_FLAGS_LHINT_LAST	TX_BD_SHORT_FLAGS_LHINT_GTE2K
+	/*
+	 * If set to 1, the device immediately updates the Send Consumer Index
+	 * after the buffer associated with this descriptor has been transferred
+	 * via DMA to NIC memory from host memory. An interrupt may or may not
+	 * be generated according to the state of the interrupt avoidance
+	 * mechanisms. If this bit is set to 0, then the Consumer Index is only
+	 * updated as soon as one of the host interrupt coalescing conditions
+	 * has been met. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_COAL_NOW		UINT32_C(0x8000)
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_BD_SHORT_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the host physical buffer this BD describes in
+	 * bytes. This field must be valid on all BDs of a packet.
+	 */
+	uint16_t len;
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with the
+	 * transmit BD. This field must be valid on the first BD of a packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address for the portion of the packet
+	 * described by this TX BD. This value must be valid on all BDs of a
+	 * packet.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
+/* Long TX BD (32 bytes split to 2 16-byte struct) */
+struct tx_bd_long {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	/* This value identifies the type of buffer descriptor. */
+	#define TX_BD_LONG_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_BD_LONG_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 32B long and is used for normal L2
+		 * packet transmission.
+		 */
+	#define TX_BD_LONG_TYPE_TX_BD_LONG		(UINT32_C(0x10) << 0)
+	/*
+	 * If set to 1, the packet ends with the data in the buffer pointed to
+	 * by this descriptor. This flag must be valid on every BD.
+	 */
+	#define TX_BD_LONG_FLAGS_PACKET_END		UINT32_C(0x40)
+	/*
+	 * If set to 1, the device will not generate a completion for this
+	 * transmit packet unless there is an error in it's processing. If this
+	 * bit is set to 0, then the packet will be completed normally. This bit
+	 * must be valid only on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_NO_CMPL		UINT32_C(0x80)
+	/*
+	 * This value indicates how many 16B BD locations are consumed in the
+	 * ring by this packet. A value of 1 indicates that this BD is the only
+	 * BD (and that the it is a short BD). A value of 3 indicates either 3
+	 * short BDs or 1 long BD and one short BD in the packet. A value of 0
+	 * indicates that there are 32 BD locations in the packet (the maximum).
+	 * This field is valid only on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_BD_CNT_MASK		UINT32_C(0x1f00)
+	#define TX_BD_LONG_FLAGS_BD_CNT_SFT		8
+	/*
+	 * This value is a hint for the length of the entire packet. It is used
+	 * by the chip to optimize internal processing. The packet will be
+	 * dropped if the hint is too short. This field is valid only on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_LHINT_MASK		UINT32_C(0x6000)
+	#define TX_BD_LONG_FLAGS_LHINT_SFT		13
+		/* indicates packet length < 512B */
+	#define TX_BD_LONG_FLAGS_LHINT_LT512		(UINT32_C(0x0) << 13)
+		/* indicates 512 <= packet length < 1KB */
+	#define TX_BD_LONG_FLAGS_LHINT_LT1K		(UINT32_C(0x1) << 13)
+		/* indicates 1KB <= packet length < 2KB */
+	#define TX_BD_LONG_FLAGS_LHINT_LT2K		(UINT32_C(0x2) << 13)
+		/* indicates packet length >= 2KB */
+	#define TX_BD_LONG_FLAGS_LHINT_GTE2K		(UINT32_C(0x3) << 13)
+	#define TX_BD_LONG_FLAGS_LHINT_LAST	TX_BD_LONG_FLAGS_LHINT_GTE2K
+	/*
+	 * If set to 1, the device immediately updates the Send Consumer Index
+	 * after the buffer associated with this descriptor has been transferred
+	 * via DMA to NIC memory from host memory. An interrupt may or may not
+	 * be generated according to the state of the interrupt avoidance
+	 * mechanisms. If this bit is set to 0, then the Consumer Index is only
+	 * updated as soon as one of the host interrupt coalescing conditions
+	 * has been met. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_COAL_NOW		UINT32_C(0x8000)
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	#define TX_BD_LONG_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_BD_LONG_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the host physical buffer this BD describes in
+	 * bytes. This field must be valid on all BDs of a packet.
+	 */
+	uint16_t len;
+
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with the
+	 * transmit BD. This field must be valid on the first BD of a packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address for the portion of the packet
+	 * described by this TX BD. This value must be valid on all BDs of a
+	 * packet.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
+/* last 16 bytes of Long TX BD */
+
+struct tx_bd_long_hi {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Their value on other BDs of the packet will be ignored.
+	 */
+	/*
+	 * If set to 1, the controller replaces the TCP/UPD checksum fields of
+	 * normal TCP/UPD checksum, or the inner TCP/UDP checksum field of the
+	 * encapsulated TCP/UDP packets with the hardware calculated TCP/UDP
+	 * checksum for the packet associated with this descriptor. This bit
+	 * must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM	UINT32_C(0x1)
+	/*
+	 * If set to 1, the controller replaces the IP checksum of the normal
+	 * packets, or the inner IP checksum of the encapsulated packets with
+	 * the hardware calculated IP checksum for the packet associated with
+	 * this descriptor. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_IP_CHKSUM		UINT32_C(0x2)
+	/*
+	 * If set to 1, the controller will not append an Ethernet CRC to the
+	 * end of the frame. This bit must be valid on the first BD of a packet.
+	 * Packet must be 64B or longer when this flag is set. It is not useful
+	 * to use this bit with any form of TX offload such as CSO or LSO. The
+	 * intent is that the packet from the host already has a valid Ethernet
+	 * CRC on the packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_NOCRC			UINT32_C(0x4)
+	/*
+	 * If set to 1, the device will record the time at which the packet was
+	 * actually transmitted at the TX MAC. This bit must be valid on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_STAMP			UINT32_C(0x8)
+	/*
+	 * If set to 1, The controller replaces the tunnel IP checksum field
+	 * with hardware calculated IP checksum for the IP header of the packet
+	 * associated with this descriptor. In case of VXLAN, the controller
+	 * also replaces the outer header UDP checksum with hardware calculated
+	 * UDP checksum for the packet associated with this descriptor.
+	 */
+	#define TX_BD_LONG_LFLAGS_T_IP_CHKSUM		UINT32_C(0x10)
+	/*
+	 * If set to 1, the device will treat this packet with LSO(Large Send
+	 * Offload) processing for both normal or encapsulated packets, which is
+	 * a form of TCP segmentation. When this bit is 1, the hdr_size and mss
+	 * fields must be valid. The driver doesn't need to set t_ip_chksum,
+	 * ip_chksum, and tcp_udp_chksum flags since the controller will replace
+	 * the appropriate checksum fields for segmented packets. When this bit
+	 * is 1, the hdr_size and mss fields must be valid.
+	 */
+	#define TX_BD_LONG_LFLAGS_LSO			UINT32_C(0x20)
+	/*
+	 * If set to zero when LSO is '1', then the IPID will be treated as a
+	 * 16b number and will be wrapped if it exceeds a value of 0xffff. If
+	 * set to one when LSO is '1', then the IPID will be treated as a 15b
+	 * number and will be wrapped if it exceeds a value 0f 0x7fff.
+	 */
+	#define TX_BD_LONG_LFLAGS_IPID_FMT		UINT32_C(0x40)
+	/*
+	 * If set to zero when LSO is '1', then the IPID of the tunnel IP header
+	 * will not be modified during LSO operations. If set to one when LSO is
+	 * '1', then the IPID of the tunnel IP header will be incremented for
+	 * each subsequent segment of an LSO operation.
+	 */
+	#define TX_BD_LONG_LFLAGS_T_IPID		UINT32_C(0x80)
+	/*
+	 * If set to '1', then the RoCE ICRC will be appended to the packet.
+	 * Packet must be a valid RoCE format packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_ROCE_CRC		UINT32_C(0x100)
+	/*
+	 * If set to '1', then the FCoE CRC will be appended to the packet.
+	 * Packet must be a valid FCoE format packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_FCOE_CRC		UINT32_C(0x200)
+	uint16_t lflags;
+
+	/*
+	 * When LSO is '1', this field must contain the offset of the TCP
+	 * payload from the beginning of the packet in as 16b words. In case of
+	 * encapsulated/tunneling packet, this field contains the offset of the
+	 * inner TCP payload from beginning of the packet as 16-bit words. This
+	 * value must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_HDR_SIZE_MASK		UINT32_C(0x1ff)
+	#define TX_BD_LONG_HDR_SIZE_SFT			0
+	uint16_t hdr_size;
+
+	/*
+	 * This is the MSS value that will be used to do the LSO processing. The
+	 * value is the length in bytes of the TCP payload for each segment
+	 * generated by the LSO operation. This value must be valid on the first
+	 * BD of a packet.
+	 */
+	#define TX_BD_LONG_MSS_MASK			UINT32_C(0x7fff)
+	#define TX_BD_LONG_MSS_SFT			0
+	uint32_t mss;
+
+	uint16_t unused_2;
+
+	/*
+	 * This value selects a CFA action to perform on the packet. Set this
+	 * value to zero if no CFA action is desired. This value must be valid
+	 * on the first BD of a packet.
+	 */
+	uint16_t cfa_action;
+
+	/*
+	 * This value is action meta-data that defines CFA edit operations that
+	 * are done in addition to any action editing.
+	 */
+	/* When key=1, This is the VLAN tag VID value. */
+	#define TX_BD_LONG_CFA_META_VLAN_VID_MASK	UINT32_C(0xfff)
+	#define TX_BD_LONG_CFA_META_VLAN_VID_SFT	0
+	/* When key=1, This is the VLAN tag DE value. */
+	#define TX_BD_LONG_CFA_META_VLAN_DE		UINT32_C(0x1000)
+	/* When key=1, This is the VLAN tag PRI value. */
+	#define TX_BD_LONG_CFA_META_VLAN_PRI_MASK	UINT32_C(0xe000)
+	#define TX_BD_LONG_CFA_META_VLAN_PRI_SFT	13
+	/* When key=1, This is the VLAN tag TPID select value. */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_MASK	UINT32_C(0x70000)
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_SFT	16
+		/* 0x88a8 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8	(UINT32_C(0x0) << 16)
+		/* 0x8100 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100	(UINT32_C(0x1) << 16)
+		/* 0x9100 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100	(UINT32_C(0x2) << 16)
+		/* 0x9200 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200	(UINT32_C(0x3) << 16)
+		/* 0x9300 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300	(UINT32_C(0x4) << 16)
+		/* Value programmed in CFA VLANTPID register. */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG	(UINT32_C(0x5) << 16)
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_LAST \
+					TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG
+	/* When key=1, This is the VLAN tag TPID select value. */
+	#define TX_BD_LONG_CFA_META_VLAN_RESERVED_MASK	UINT32_C(0xff80000)
+	#define TX_BD_LONG_CFA_META_VLAN_RESERVED_SFT	19
+	/*
+	 * This field identifies the type of edit to be performed on the packet.
+	 * This value must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_CFA_META_KEY_MASK		UINT32_C(0xf0000000)
+	#define TX_BD_LONG_CFA_META_KEY_SFT		28
+		/* No editing */
+	#define TX_BD_LONG_CFA_META_KEY_NONE		(UINT32_C(0x0) << 28)
+		/*
+		 * - meta[17:16] - TPID select value (0 = 0x8100). - meta[15:12]
+		 * - PRI/DE value. - meta[11:0] - VID value.
+		 */
+	#define TX_BD_LONG_CFA_META_KEY_VLAN_TAG	(UINT32_C(0x1) << 28)
+	#define TX_BD_LONG_CFA_META_KEY_LAST	TX_BD_LONG_CFA_META_KEY_VLAN_TAG
+	uint32_t cfa_meta;
+} __attribute__((packed));
+
+/* Completion Ring Structures */
+/* Note: This structure is used by the HWRM to communicate HWRM Error. */
+/* Base Completion Record (16 bytes) */
+struct cmpl_base {
+	/* unused is 10 b */
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define CMPL_BASE_TYPE_MASK			UINT32_C(0x3f)
+	#define CMPL_BASE_TYPE_SFT			0
+		/* TX L2 completion: Completion of TX packet. Length = 16B */
+	#define CMPL_BASE_TYPE_TX_L2			(UINT32_C(0x0) << 0)
+		/*
+		 * RX L2 completion: Completion of and L2 RX packet.
+		 * Length = 32B
+		*/
+	#define CMPL_BASE_TYPE_RX_L2			(UINT32_C(0x11) << 0)
+		/*
+		 * RX Aggregation Buffer completion : Completion of an L2
+		 * aggregation buffer in support of TPA, HDS, or Jumbo packet
+		 * completion. Length = 16B
+		 */
+	#define CMPL_BASE_TYPE_RX_AGG			(UINT32_C(0x12) << 0)
+		/*
+		 * RX L2 TPA Start Completion: Completion at the beginning of a
+		 * TPA operation. Length = 32B
+		 */
+	#define CMPL_BASE_TYPE_RX_TPA_START		(UINT32_C(0x13) << 0)
+		/*
+		 * RX L2 TPA End Completion: Completion at the end of a TPA
+		 * operation. Length = 32B
+		 */
+	#define CMPL_BASE_TYPE_RX_TPA_END		(UINT32_C(0x15) << 0)
+		/*
+		 * Statistics Ejection Completion: Completion of statistics data
+		 * ejection buffer. Length = 16B
+		 */
+	#define CMPL_BASE_TYPE_STAT_EJECT		(UINT32_C(0x1a) << 0)
+		/* HWRM Command Completion: Completion of an HWRM command. */
+	#define CMPL_BASE_TYPE_HWRM_DONE		(UINT32_C(0x20) << 0)
+		/* Forwarded HWRM Request */
+	#define CMPL_BASE_TYPE_HWRM_FWD_REQ		(UINT32_C(0x22) << 0)
+		/* Forwarded HWRM Response */
+	#define CMPL_BASE_TYPE_HWRM_FWD_RESP		(UINT32_C(0x24) << 0)
+		/* HWRM Asynchronous Event Information */
+	#define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT		(UINT32_C(0x2e) << 0)
+		/* CQ Notification */
+	#define CMPL_BASE_TYPE_CQ_NOTIFICATION		(UINT32_C(0x30) << 0)
+		/* SRQ Threshold Event */
+	#define CMPL_BASE_TYPE_SRQ_EVENT		(UINT32_C(0x32) << 0)
+		/* DBQ Threshold Event */
+	#define CMPL_BASE_TYPE_DBQ_EVENT		(UINT32_C(0x34) << 0)
+		/* QP Async Notification */
+	#define CMPL_BASE_TYPE_QP_EVENT			(UINT32_C(0x38) << 0)
+		/* Function Async Notification */
+	#define CMPL_BASE_TYPE_FUNC_EVENT		(UINT32_C(0x3a) << 0)
+	uint16_t type;
+
+	uint16_t info1;
+	uint32_t info2;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define CMPL_BASE_V				UINT32_C(0x1)
+	/* info3 is 31 b */
+	#define CMPL_BASE_INFO3_MASK			UINT32_C(0xfffffffe)
+	#define CMPL_BASE_INFO3_SFT			1
+	uint32_t info3_v;
+
+	uint32_t info4;
+} __attribute__((packed));
+
+/* TX Completion Record (16 bytes) */
+struct tx_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define TX_CMPL_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_CMPL_TYPE_SFT			0
+		/* TX L2 completion: Completion of TX packet. Length = 16B */
+	#define TX_CMPL_TYPE_TX_L2			(UINT32_C(0x0) << 0)
+	/*
+	 * When this bit is '1', it indicates a packet that has an error of some
+	 * type. Type of error is indicated in error_flags.
+	 */
+	#define TX_CMPL_FLAGS_ERROR			UINT32_C(0x40)
+	/*
+	 * When this bit is '1', it indicates that the packet completed was
+	 * transmitted using the push acceleration data provided by the driver.
+	 * When this bit is '0', it indicates that the packet had not push
+	 * acceleration data written or was executed as a normal packet even
+	 * though push data was provided.
+	 */
+	#define TX_CMPL_FLAGS_PUSH			UINT32_C(0x80)
+	#define TX_CMPL_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_CMPL_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	uint16_t unused_0;
+
+	/*
+	 * This is a copy of the opaque field from the first TX BD of this
+	 * transmitted packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define TX_CMPL_V				UINT32_C(0x1)
+	/*
+	 * This error indicates that there was some sort of problem with the BDs
+	 * for the packet.
+	 */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_SFT		1
+		/* No error */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_NO_ERROR	(UINT32_C(0x0) << 1)
+		/* Bad Format: BDs were not formatted correctly. */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT	(UINT32_C(0x2) << 1)
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_LAST \
+					TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT
+	/*
+	 * When this bit is '1', it indicates that the length of the packet was
+	 * zero. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_ZERO_LENGTH_PKT		UINT32_C(0x10)
+	/*
+	 * When this bit is '1', it indicates that the packet was longer than
+	 * the programmed limit in TDI. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_EXCESSIVE_BD_LENGTH	UINT32_C(0x20)
+	/*
+	 * When this bit is '1', it indicates that one or more of the BDs
+	 * associated with this packet generated a PCI error. This probably
+	 * means the address was not valid.
+	 */
+	#define TX_CMPL_ERRORS_DMA_ERROR		UINT32_C(0x40)
+	/*
+	 * When this bit is '1', it indicates that the packet was longer than
+	 * indicated by the hint. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_HINT_TOO_SHORT		UINT32_C(0x80)
+	/*
+	 * When this bit is '1', it indicates that the packet was dropped due to
+	 * Poison TLP error on one or more of the TLPs in the PXP completion.
+	 */
+	#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 errors_v;
+
+	uint16_t unused_1;
+	uint32_t unused_2;
+} __attribute__((packed)) tx_cmpl_t, *ptx_cmpl_t;
+
 /* HWRM Forwarded Request (16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	/* Length of forwarded request in bytes. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 14/40] bnxt: initial Rx ring code
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (11 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 13/40] bnxt: initial Tx ring code Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 15/40] bnxt: alloc/free ring information Stephen Hurd
                                   ` (26 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Initial implementation of rx_pkt_burst
Add code to allocate rings to bnxt_ring.c

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +-
 drivers/net/bnxt/bnxt_ring.c           |  20 +-
 drivers/net/bnxt/bnxt_rxq.c            |  34 ++-
 drivers/net/bnxt/bnxt_rxr.c            | 338 +++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxr.h            |  62 +++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 474 +++++++++++++++++++++++++++++++++
 7 files changed, 915 insertions(+), 17 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_rxr.c
 create mode 100644 drivers/net/bnxt/bnxt_rxr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 009ddad..b31e33b 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxr.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 61e856a..e1b3e3a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -42,6 +42,7 @@
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_stats.h"
 #include "bnxt_txq.h"
 #include "bnxt_txr.h"
@@ -260,7 +261,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error;
 	}
 	eth_dev->dev_ops = &bnxt_dev_ops;
-	/* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
+	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
 	rc = bnxt_alloc_hwrm_resources(bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index bb20806..69837bf 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -36,6 +36,7 @@
 #include "bnxt.h"
 #include "bnxt_cpr.h"
 #include "bnxt_ring.h"
+#include "bnxt_rxr.h"
 #include "bnxt_txr.h"
 
 #include "hsi_struct_def_dpdk.h"
@@ -77,9 +78,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			    const char *suffix)
 {
 	struct bnxt_ring_struct *cp_ring = cp_ring_info->cp_ring_struct;
+	struct bnxt_ring_struct *rx_ring;
 	struct bnxt_ring_struct *tx_ring;
-	/* TODO: RX 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];
@@ -96,10 +96,9 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 						tx_ring_struct->vmem_size) : 0;
 
 	int rx_vmem_start = tx_vmem_start + tx_vmem_len;
-	/* TODO: RX ring */
-	int rx_vmem_len = /*
-	    rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
-					rx_ring_struct->vmem_size) : */ 0;
+	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 *
@@ -111,10 +110,9 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 				   sizeof(struct tx_bd_long)) : 0;
 
 	int rx_ring_start = tx_ring_start + tx_ring_len;
-	/* TODO: RX ring */
-	int rx_ring_len = /* rx_ring_info ?
+	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;
+				   sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
 
@@ -152,9 +150,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		}
 	}
 
-/*
 	if (rx_ring_info) {
-		rx_ring = &rx_ring_info->rx_ring_struct;
+		rx_ring = rx_ring_info->rx_ring_struct;
 
 		rx_ring->bd = ((char *)mz->addr + rx_ring_start);
 		rx_ring_info->rx_desc_ring =
@@ -171,7 +168,6 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			    (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;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index b284e20..90a116b 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -41,6 +41,7 @@
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -215,7 +216,20 @@ err_out:
 
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 {
-	/* TODO: Requires interaction with TX ring */
+	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)
@@ -236,7 +250,13 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 	if (rxq) {
 		bnxt_rx_queue_release_mbufs(rxq);
 
-		/* TODO: Free ring and stats here */
+		/* Free RX ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+
+		/* Free RX completion ring hardware descriptors */
+		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+
+		bnxt_free_rxq_stats(rxq);
 
 		rte_free(rxq);
 	}
@@ -273,7 +293,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	rxq->nb_rx_desc = nb_desc;
 	rxq->rx_free_thresh = rx_conf->rx_free_thresh;
 
-	/* TODO: Initialize ring structure */
+	bnxt_init_rx_ring_struct(rxq);
 
 	rxq->queue_id = queue_idx;
 	rxq->port_id = eth_dev->data->port_id;
@@ -281,7 +301,13 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 				0 : ETHER_CRC_LEN);
 
 	eth_dev->data->rx_queues[queue_idx] = rxq;
-	/* TODO: Allocate RX ring hardware descriptors */
+	/* Allocate RX ring hardware descriptors */
+	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
+			"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_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
new file mode 100644
index 0000000..eed88c6
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -0,0 +1,338 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.h"
+#include "bnxt_ring.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 = rte_cpu_to_le_64(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 = cons_bd->addr;
+}
+
+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];
+
+		if (!rxq)
+			continue;
+
+		/* TODO: free() rxq->rx_ring and rxq->rx_ring->rx_ring_struct */
+		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* TODO: free() rxq->cp_ring and rxq->cp_ring->cp_ring_struct */
+		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+
+		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 +
+			       (2 * 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;
+
+	/* TODO: These need to be allocated */
+	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);
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
new file mode 100644
index 0000000..e9bae3f
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -0,0 +1,62 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_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_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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index ff02a29..fd9eb62 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -446,6 +446,79 @@ struct tx_bd_long_hi {
 	uint32_t cfa_meta;
 } __attribute__((packed));
 
+/* RX Producer Packet BD (16 bytes) */
+struct rx_prod_pkt_bd {
+	/* This value identifies the type of buffer descriptor. */
+	#define RX_PROD_PKT_BD_TYPE_MASK		UINT32_C(0x3f)
+	#define RX_PROD_PKT_BD_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 16B long and is an RX Producer (ie.
+		 * empty) buffer descriptor.
+		 */
+	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT		(UINT32_C(0x4) << 0)
+	/*
+	 * If set to 1, the packet will be placed at the address plus 2B. The 2
+	 * Bytes of padding will be written as zero.
+	 */
+	/*
+	 * This is intended to be used when the host buffer is cache-line
+	 * aligned to produce packets that are easy to parse in host memory
+	 * while still allowing writes to be cache line aligned.
+	 */
+	#define RX_PROD_PKT_BD_FLAGS_SOP_PAD		UINT32_C(0x40)
+	/*
+	 * If set to 1, the packet write will be padded out to the nearest
+	 * cache-line with zero value padding.
+	 */
+	/*
+	 * If receive buffers start/end on cache-line boundaries, this feature
+	 * will ensure that all data writes on the PCI bus start/end on cache
+	 * line boundaries.
+	 */
+	#define RX_PROD_PKT_BD_FLAGS_EOP_PAD		UINT32_C(0x80)
+	/*
+	 * This value is the number of additional buffers in the ring that
+	 * describe the buffer space to be consumed for the this packet. If the
+	 * value is zero, then the packet must fit within the space described by
+	 * this BD. If this value is 1 or more, it indicates how many additional
+	 * "buffer" BDs are in the ring immediately following this BD to be used
+	 * for the same network packet. Even if the packet to be placed does not
+	 * need all the additional buffers, they will be consumed anyway.
+	 */
+	#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 flags_type;
+
+	/*
+	 * This is the length in Bytes of the host physical buffer where data
+	 * for the packet may be placed in host memory.
+	 */
+	/*
+	 * While this is a Byte resolution value, it is often advantageous to
+	 * ensure that the buffers provided end on a host cache line.
+	 */
+	uint16_t len;
+
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with this
+	 * receive buffer set.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address where data for the packet may by
+	 * placed in host memory.
+	 */
+	/*
+	 * While this is a Byte resolution value, it is often advantageous to
+	 * ensure that the buffers provide start on a host cache line.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
 /* Base Completion Record (16 bytes) */
@@ -611,6 +684,407 @@ struct tx_cmpl {
 	uint32_t unused_2;
 } __attribute__((packed)) tx_cmpl_t, *ptx_cmpl_t;
 
+/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_pkt_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define RX_PKT_CMPL_TYPE_MASK			UINT32_C(0x3f)
+	#define RX_PKT_CMPL_TYPE_SFT			0
+		/*
+		 * RX L2 completion: Completion of and L2 RX packet.
+		 * Length = 32B
+		 */
+	#define RX_PKT_CMPL_TYPE_RX_L2			(UINT32_C(0x11) << 0)
+	/*
+	 * When this bit is '1', it indicates a packet that has an error of some
+	 * type. Type of error is indicated in error_flags.
+	 */
+	#define RX_PKT_CMPL_FLAGS_ERROR			UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_SFT		7
+		/* Normal: Packet was placed using normal algorithm. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_NORMAL	(UINT32_C(0x0) << 7)
+		/* Jumbo: Packet was placed using jumbo algorithm. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_JUMBO	(UINT32_C(0x1) << 7)
+		/*
+		 * Header/Data Separation: Packet was placed using Header/Data
+		 * separation algorithm. The separation location is indicated by
+		 * the itype field.
+		 */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_HDS		(UINT32_C(0x2) << 7)
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_LAST \
+						RX_PKT_CMPL_FLAGS_PLACEMENT_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_PKT_CMPL_FLAGS_RSS_VALID		UINT32_C(0x400)
+	/*
+	 * This value indicates what the inner packet determined for the packet
+	 * was.
+	 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_MASK		UINT32_C(0xf000)
+	#define RX_PKT_CMPL_FLAGS_ITYPE_SFT		12
+		/* Not Known: Indicates that the packet type was not known. */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_NOT_KNOWN	(UINT32_C(0x0) << 12)
+		/*
+		 * IP Packet: Indicates that the packet was an IP packet, but
+		 * further classification was not possible.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_IP		(UINT32_C(0x1) << 12)
+		/*
+		 * TCP Packet: Indicates that the packet was IP and TCP. This
+		 * indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_TCP		(UINT32_C(0x2) << 12)
+		/*
+		 * UDP Packet: Indicates that the packet was IP and UDP. This
+		 * indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_UDP		(UINT32_C(0x3) << 12)
+		/*
+		 * FCoE Packet: Indicates that the packet was recognized as a
+		 * FCoE. This also indicates that the payload_offset field is
+		 * valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_FCOE		(UINT32_C(0x4) << 12)
+		/*
+		 * RoCE Packet: Indicates that the packet was recognized as a
+		 * RoCE. This also indicates that the payload_offset field is
+		 * valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_ROCE		(UINT32_C(0x5) << 12)
+		/*
+		 * ICMP Packet: Indicates that the packet was recognized as
+		 * ICMP. This indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_ICMP		(UINT32_C(0x7) << 12)
+		/*
+		 * PtP packet wo/timestamp: Indicates that the packet was
+		 * recognized as a PtP packet.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_WO_TIMESTAMP \
+							(UINT32_C(0x8) << 12)
+		/*
+		 * PtP packet w/timestamp: Indicates that the packet was
+		 * recognized as a PtP packet and that a timestamp was taken for
+		 * the packet.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP	(UINT32_C(0x9) << 12)
+	#define RX_PKT_CMPL_FLAGS_ITYPE_LAST \
+					RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP
+	#define RX_PKT_CMPL_FLAGS_MASK			UINT32_C(0xffc0)
+	#define RX_PKT_CMPL_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the data for the packet stored in the buffer(s)
+	 * identified by the opaque value. This includes the packet BD and any
+	 * associated buffer BDs. This does not include the the length of any
+	 * data places in aggregation BDs.
+	 */
+	uint16_t len;
+
+	/*
+	 * This is a copy of the opaque field from the RX BD this completion
+	 * corresponds to.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define RX_PKT_CMPL_V1				UINT32_C(0x1)
+	/*
+	 * This value is the number of aggregation buffers that follow this
+	 * entry in the completion ring that are a part of this packet. If the
+	 * value is zero, then the packet is completely contained in the buffer
+	 * space provided for the packet in the RX ring.
+	 */
+	#define RX_PKT_CMPL_AGG_BUFS_MASK		UINT32_C(0x3e)
+	#define RX_PKT_CMPL_AGG_BUFS_SFT		1
+	uint8_t agg_bufs_v1;
+
+	/*
+	 * This is the RSS hash type for the packet. The value is packed
+	 * {tuple_extrac_op[1:0],rss_profile_id[4:0],tuple_extrac_op[2]}.
+	 */
+	uint8_t rss_hash_type;
+
+	/*
+	 * This value indicates the offset from the beginning of the packet
+	 * where the inner payload starts. This value is valid for TCP, UDP,
+	 * FCoE, and RoCE packets.
+	 */
+	uint8_t payload_offset;
+
+	uint8_t unused_1;
+
+	/*
+	 * This value is the RSS hash value calculated for the packet based on
+	 * the mode bits and key value in the VNIC.
+	 */
+	uint32_t rss_hash;
+} __attribute__((packed));
+
+/* last 16 bytes of RX Packet Completion Record */
+struct rx_pkt_cmpl_hi {
+	/*
+	 * This indicates that the ip checksum was calculated for the inner
+	 * packet and that the ip_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_IP_CS_CALC		UINT32_C(0x1)
+	/*
+	 * This indicates that the TCP, UDP or ICMP checksum was calculated for
+	 * the inner packet and that the l4_cs_error field indicates if there
+	 * was an error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_L4_CS_CALC		UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the tunnel
+	 * header and that the t_ip_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC		UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the tunnel
+	 * packet and that the t_l4_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC		UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK	UINT32_C(0xf0)
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT	4
+		/* No metadata informtaion. Value is zero. */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_NONE	(UINT32_C(0x0) << 4)
+		/*
+		 * The metadata field contains the VLAN tag and TPID value. -
+		 * metadata[11:0] contains the vlan VID value. - metadata[12]
+		 * contains the vlan DE value. - metadata[15:13] contains the
+		 * vlan PRI value. - metadata[31:16] contains the vlan TPID
+		 * value.
+		 */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST \
+					RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN
+	/*
+	 * This field indicates the IP type for the inner-most IP header. A
+	 * value of '0' indicates IPv4. A value of '1' indicates IPv6. This
+	 * value is only valid if itype indicates a packet with an IP header.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_IP_TYPE		UINT32_C(0x100)
+	uint32_t flags2;
+
+	/*
+	 * This is data from the CFA block as indicated by the meta_format
+	 * field.
+	 */
+	/* When meta_format=1, this value is the VLAN VID. */
+	#define RX_PKT_CMPL_METADATA_VID_MASK		UINT32_C(0xfff)
+	#define RX_PKT_CMPL_METADATA_VID_SFT		0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_PKT_CMPL_METADATA_DE			UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_PKT_CMPL_METADATA_PRI_MASK		UINT32_C(0xe000)
+	#define RX_PKT_CMPL_METADATA_PRI_SFT		13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_PKT_CMPL_METADATA_TPID_MASK		UINT32_C(0xffff0000)
+	#define RX_PKT_CMPL_METADATA_TPID_SFT		16
+	uint32_t metadata;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define RX_PKT_CMPL_V2				UINT32_C(0x1)
+	/*
+	 * This error indicates that there was some sort of problem with the BDs
+	 * for the packet that was found after part of the packet was already
+	 * placed. The packet should be treated as invalid.
+	 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+		/* No buffer error */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NO_BUFFER \
+							(UINT32_C(0x0) << 1)
+		/*
+		 * Did Not Fit: Packet did not fit into packet buffer provided.
+		 * For regular placement, this means the packet did not fit in
+		 * the buffer provided. For HDS and jumbo placement, this means
+		 * that the packet could not be placed into 7 physical buffers
+		 * or less.
+		 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_DID_NOT_FIT \
+							(UINT32_C(0x1) << 1)
+		/*
+		 * Not On Chip: All BDs needed for the packet were not on-chip
+		 * when the packet arrived.
+		 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+							(UINT32_C(0x2) << 1)
+		/* Bad Format: BDs were not formatted correctly. */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT \
+							(UINT32_C(0x3) << 1)
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT
+	/* This indicates that there was an error in the IP header checksum. */
+	#define RX_PKT_CMPL_ERRORS_IP_CS_ERROR		UINT32_C(0x10)
+	/*
+	 * This indicates that there was an error in the TCP, UDP or ICMP
+	 * checksum.
+	 */
+	#define RX_PKT_CMPL_ERRORS_L4_CS_ERROR		UINT32_C(0x20)
+	/*
+	 * This indicates that there was an error in the tunnel IP header
+	 * checksum.
+	 */
+	#define RX_PKT_CMPL_ERRORS_T_IP_CS_ERROR	UINT32_C(0x40)
+	/* This indicates that there was an error in the tunnel UDP checksum. */
+	#define RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR	UINT32_C(0x80)
+	/*
+	 * This indicates that there was a CRC error on either an FCoE or RoCE
+	 * packet. The itype indicates the packet type.
+	 */
+	#define RX_PKT_CMPL_ERRORS_CRC_ERROR		UINT32_C(0x100)
+	/*
+	 * This indicates that there was an error in the tunnel portion of the
+	 * packet when this field is non-zero.
+	 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_MASK	UINT32_C(0xe00)
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_SFT	9
+		/*
+		 * No additional error occurred on the tunnel portion of the
+		 * packet of the packet does not have a tunnel.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_NO_ERROR	(UINT32_C(0x0) << 9)
+		/*
+		 * Indicates that IP header version does not match expectation
+		 * from L2 Ethertype for IPv4 and IPv6 in the tunnel header.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_VERSION \
+							(UINT32_C(0x1) << 9)
+		/*
+		 * Indicates that header length is out of range in the tunnel
+		 * header. Valid for IPv4.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_HDR_LEN \
+							(UINT32_C(0x2) << 9)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the PPPoE header length for a tunnel PPPoE packet.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_TUNNEL_TOTAL_ERROR \
+							(UINT32_C(0x3) << 9)
+		/*
+		 * Indicates that physical packet is shorter than that claimed
+		 * by the tunnel l3 header length. Valid for IPv4, or IPv6
+		 * tunnel packet packets.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_IP_TOTAL_ERROR \
+							(UINT32_C(0x4) << 9)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the tunnel UDP header length for a tunnel UDP
+		 * packet that is not fragmented.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_UDP_TOTAL_ERROR \
+							(UINT32_C(0x5) << 9)
+		/*
+		 * indicates that the IPv4 TTL or IPv6 hop limit check have
+		 * failed (e.g. TTL = 0) in the tunnel header. Valid for IPv4,
+		 * and IPv6.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL \
+							(UINT32_C(0x6) << 9)
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL
+	/*
+	 * This indicates that there was an error in the inner portion of the
+	 * packet when this field is non-zero.
+	 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_MASK	UINT32_C(0xf000)
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_SFT	12
+		/*
+		 * No additional error occurred on the tunnel portion of the
+		 * packet of the packet does not have a tunnel.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_NO_ERROR	(UINT32_C(0x0) << 12)
+		/*
+		 * Indicates that IP header version does not match expectation
+		 * from L2 Ethertype for IPv4 and IPv6 or that option other than
+		 * VFT was parsed on FCoE packet.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_VERSION \
+							(UINT32_C(0x1) << 12)
+		/*
+		 * indicates that header length is out of range. Valid for IPv4
+		 * and RoCE
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_HDR_LEN \
+							(UINT32_C(0x2) << 12)
+		/*
+		 * indicates that the IPv4 TTL or IPv6 hop limit check have
+		 * failed (e.g. TTL = 0). Valid for IPv4, and IPv6
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_TTL	(UINT32_C(0x3) << 12)
+		/*
+		 * Indicates that physical packet is shorter than that claimed
+		 * by the l3 header length. Valid for IPv4, IPv6 packet or RoCE
+		 * packets.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_IP_TOTAL_ERROR \
+							(UINT32_C(0x4) << 12)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the UDP header length for a UDP packet that is not
+		 * fragmented.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_UDP_TOTAL_ERROR \
+							(UINT32_C(0x5) << 12)
+		/*
+		 * Indicates that TCP header length > IP payload. Valid for TCP
+		 * packets only.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN \
+							(UINT32_C(0x6) << 12)
+		/* Indicates that TCP header length < 5. Valid for TCP. */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL \
+							(UINT32_C(0x7) << 12)
+		/*
+		 * Indicates that TCP option headers result in a TCP header size
+		 * that does not match data offset in TCP header. Valid for TCP.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
+							(UINT32_C(0x8) << 12)
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN
+	#define RX_PKT_CMPL_ERRORS_MASK			UINT32_C(0xfffe)
+	#define RX_PKT_CMPL_ERRORS_SFT			1
+	uint16_t errors_v2;
+
+	/*
+	 * This field identifies the CFA action rule that was used for this
+	 * packet.
+	 */
+	uint16_t cfa_code;
+
+	/*
+	 * This value holds the reordering sequence number for the packet. If
+	 * the reordering sequence is not valid, then this value is zero. The
+	 * reordering domain for the packet is in the bottom 8 to 10b of the
+	 * rss_hash value. The bottom 20b of this value contain the ordering
+	 * domain value for the packet.
+	 */
+	#define RX_PKT_CMPL_REORDER_MASK		UINT32_C(0xffffff)
+	#define RX_PKT_CMPL_REORDER_SFT			0
+	uint32_t reorder;
+} __attribute__((packed));
+
 /* HWRM Forwarded Request (16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	/* Length of forwarded request in bytes. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 15/40] bnxt: alloc/free ring information
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (12 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 14/40] bnxt: initial Rx " Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 16/40] bnxt: add HWRM function reset command Stephen Hurd
                                   ` (25 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Perform allocation and free()ing of ring information structures for
TX, RX, and completion rings.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_cpr.c | 28 +++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_cpr.h |  2 +-
 drivers/net/bnxt/bnxt_rxq.c | 17 ++++++++++++-----
 drivers/net/bnxt/bnxt_rxr.c | 42 ++++++++++++++++++++++++++++++++++--------
 drivers/net/bnxt/bnxt_rxr.h |  2 +-
 drivers/net/bnxt/bnxt_txq.c | 23 ++++++++++++++++-------
 drivers/net/bnxt/bnxt_txr.c | 43 ++++++++++++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_txr.h |  2 +-
 8 files changed, 122 insertions(+), 37 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 34e45ef..27c557f 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_malloc.h>
+
 #include "bnxt.h"
 #include "bnxt_cpr.h"
 #include "bnxt_hwrm.h"
@@ -120,21 +122,37 @@ reject:
 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);
+	bnxt_free_ring(cpr->cp_ring_struct);
+	rte_free(cpr->cp_ring_struct);
+	rte_free(cpr);
 }
 
 /* For the default completion ring only */
-void bnxt_init_def_ring_struct(struct bnxt *bp)
+int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id)
 {
-	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
+	struct bnxt_cp_ring_info *cpr;
+	struct bnxt_ring_struct *ring;
 
+	cpr = rte_zmalloc_socket("bnxt_cp_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	bp->def_cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_cp_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index f104281..3e25a75 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -79,7 +79,7 @@ struct bnxt_cp_ring_info {
 
 struct bnxt;
 void bnxt_free_def_cp_ring(struct bnxt *bp);
-void bnxt_init_def_ring_struct(struct bnxt *bp);
+int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id);
 void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp);
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp);
 
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 90a116b..2fe4de8 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -271,10 +271,12 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	struct bnxt_rx_queue *rxq;
+	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
 		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
 	if (eth_dev->data->rx_queues) {
@@ -286,14 +288,17 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 				 RTE_CACHE_LINE_SIZE, socket_id);
 	if (!rxq) {
 		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 	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);
+	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
+	if (rc)
+		goto out;
 
 	rxq->queue_id = queue_idx;
 	rxq->port_id = eth_dev->data->port_id;
@@ -306,8 +311,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 			"bnxt_rx_ring")) {
 		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
 		bnxt_rx_queue_release_op(rxq);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 
-	return 0;
+out:
+	return rc;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index eed88c6..5a6f2fe 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -252,17 +252,20 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 		if (!rxq)
 			continue;
 
-		/* TODO: free() rxq->rx_ring and rxq->rx_ring->rx_ring_struct */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
-		/* TODO: free() rxq->cp_ring and rxq->cp_ring->cp_ring_struct */
+		rte_free(rxq->rx_ring->rx_ring_struct);
+		rte_free(rxq->rx_ring);
+
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+		rte_free(rxq->cp_ring->cp_ring_struct);
+		rte_free(rxq->cp_ring);
 
 		rte_free(rxq);
 		bp->rx_queues[i] = NULL;
 	}
 }
 
-void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
+int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 {
 	struct bnxt *bp = rxq->bp;
 	struct bnxt_cp_ring_info *cpr;
@@ -274,8 +277,19 @@ void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
 			       (2 * 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;
+	rxr = rte_zmalloc_socket("bnxt_rx_ring",
+				 sizeof(struct bnxt_rx_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!rxr)
+		return -ENOMEM;
+	rxq->rx_ring = rxr;
+
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring_struct),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	rxr->rx_ring_struct = ring;
 	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc);
 	ring->ring_mask = ring->ring_size - 1;
 	ring->bd = (void *)rxr->rx_desc_ring;
@@ -283,14 +297,27 @@ void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
 	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;
+	cpr = rte_zmalloc_socket("bnxt_rx_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	rxq->cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring_struct),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
 
 static void bnxt_init_rxbds(struct bnxt_ring_struct *ring, uint32_t type,
@@ -317,7 +344,6 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 
 	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
 
-	/* TODO: These need to be allocated */
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
 	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e9bae3f..7ba8f7b 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -56,7 +56,7 @@ struct bnxt_rx_ring_info {
 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_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);
 int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
index 7aba199..beda5fe 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -109,10 +109,12 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	struct bnxt_tx_queue *txq;
+	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {
 		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
 	if (eth_dev->data->tx_queues) {
@@ -124,15 +126,18 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	}
 	txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
 				 RTE_CACHE_LINE_SIZE, socket_id);
-	if (txq == NULL) {
+	if (!txq) {
 		RTE_LOG(ERR, PMD, "bnxt_tx_queue allocation failed!");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 	txq->bp = bp;
 	txq->nb_tx_desc = nb_desc;
 	txq->tx_free_thresh = tx_conf->tx_free_thresh;
 
-	bnxt_init_tx_ring_struct(txq);
+	rc = bnxt_init_tx_ring_struct(txq, socket_id);
+	if (rc)
+		goto out;
 
 	txq->queue_id = queue_idx;
 	txq->port_id = eth_dev->data->port_id;
@@ -142,15 +147,19 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 			"bnxt_tx_ring")) {
 		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for tx_ring failed!");
 		bnxt_tx_queue_release_op(txq);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 
 	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;
+		rc = -ENOMEM;
+		goto out;
 	}
 
 	eth_dev->data->tx_queues[queue_idx] = txq;
-	return 0;
+
+out:
+	return rc;
 }
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 2314410..218b945 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -59,9 +59,12 @@ void bnxt_free_tx_rings(struct bnxt *bp)
 			continue;
 
 		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
-		/* TODO: free() txq->tx_ring and txq->tx_ring->tx_ring_struct */
+		rte_free(txq->tx_ring->tx_ring_struct);
+		rte_free(txq->tx_ring);
+
 		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
-		/* TODO: free() txq->cp_ring and txq->cp_ring->cp_ring_struct */
+		rte_free(txq->cp_ring->cp_ring_struct);
+		rte_free(txq->cp_ring);
 
 		rte_free(txq);
 		bp->tx_queues[i] = NULL;
@@ -79,15 +82,25 @@ int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq)
 	return 0;
 }
 
-void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq)
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id)
 {
 	struct bnxt_cp_ring_info *cpr;
 	struct bnxt_tx_ring_info *txr;
 	struct bnxt_ring_struct *ring;
 
-	/* TODO: These need to be allocated */
-	txr = txq->tx_ring;
-	ring = txr->tx_ring_struct;
+	txr = rte_zmalloc_socket("bnxt_tx_ring",
+				 sizeof(struct bnxt_tx_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!txr)
+		return -ENOMEM;
+	txq->tx_ring = txr;
+
+	ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	txr->tx_ring_struct = ring;
 	ring->ring_size = rte_align32pow2(txq->nb_tx_desc + 1);
 	ring->ring_mask = ring->ring_size - 1;
 	ring->bd = (void *)txr->tx_desc_ring;
@@ -95,15 +108,27 @@ void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq)
 	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_tx_bd);
 	ring->vmem = (void **)&txr->tx_buf_ring;
 
-	/* TODO: These need to be allocated */
-	cpr = txq->cp_ring;
-	ring = cpr->cp_ring_struct;
+	cpr = rte_zmalloc_socket("bnxt_tx_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	txq->cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
 
 static inline uint32_t bnxt_tx_avail(struct bnxt_tx_ring_info *txr)
diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h
index 1797a3d..56d0b08 100644
--- a/drivers/net/bnxt/bnxt_txr.h
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -64,7 +64,7 @@ struct bnxt_sw_tx_bd {
 
 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);
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id);
 uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			       uint16_t nb_pkts);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 16/40] bnxt: add HWRM function reset command
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (13 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 15/40] bnxt: alloc/free ring information Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
                                   ` (24 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Add bnxt_hwrm_func_reset() function and supporting structs and macros.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  17 +++++
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 129 +++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 50d8b89..922c92a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -221,6 +221,23 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	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_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 0861417..4fa94aa 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -50,6 +50,7 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index fd9eb62..9c82d13 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -83,6 +83,7 @@ typedef struct ctx_hw_stats64 {
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_RESET			(UINT32_C(0x11))
 #define HWRM_FUNC_QCAPS			(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
@@ -2097,6 +2098,134 @@ struct hwrm_func_qcaps_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_func_reset */
+/*
+ * Description: This command resets a hardware function (PCIe function) and
+ * frees any resources used by the function. This command shall be initiated by
+ * the driver after an FLR has occurred to prepare the function for re-use. This
+ * command may also be initiated by a driver prior to doing it's own
+ * configuration. This command puts the function into the reset state. In the
+ * reset state, global and port related features of the chip are not available.
+ */
+/*
+ * Note: This command will reset a function that has already been disabled or
+ * idled. The command returns all the resources owned by the function so a new
+ * driver may allocate and configure resources normally.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_func_reset_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_FUNC_RESET_INPUT_ENABLES_VF_ID_VALID \
+							UINT32_C(0x1)
+	uint32_t enables;
+
+	/*
+	 * The ID of the VF that this PF is trying to reset. Only the parent PF
+	 * shall be allowed to reset a child VF. A parent PF driver shall use
+	 * this field only when a specific child VF is requested to be reset.
+	 */
+	uint16_t vf_id;
+
+	/* This value indicates the level of a function reset. */
+		/*
+		 * Reset the caller function and its children VFs (if any). If
+		 * no children functions exist, then reset the caller function
+		 * only.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETALL \
+							(UINT32_C(0x0) << 0)
+		/* Reset the caller function only */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETME \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Reset all children VFs of the caller function driver if the
+		 * caller is a PF driver. It is an error to specify this level
+		 * by a VF driver. It is an error to specify this level by a PF
+		 * driver with no children VFs.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Reset a specific VF of the caller function driver if the
+		 * caller is the parent PF driver. It is an error to specify
+		 * this level by a VF driver. It is an error to specify this
+		 * level by a PF driver that is not the parent of the VF that is
+		 * being requested to reset.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETVF \
+							(UINT32_C(0x3) << 0)
+	uint8_t func_reset_level;
+
+	uint8_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_func_reset_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_port_phy_cfg */
 /*
  * Description: This command configures the PHY device for the port. It allows
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 17/40] bnxt: add HWRM vnic alloc function
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (14 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 16/40] bnxt: add HWRM function reset command Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 18/40] bnxt: add HWRM vnic free function Stephen Hurd
                                   ` (23 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

This requires a group info array in struct bnxt, so add that, save
the max size from the func_qcap response, and alloc/free in init/uninit

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  2 +
 drivers/net/bnxt/bnxt_hwrm.c           | 33 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 99 ++++++++++++++++++++++++++++++++++
 4 files changed, 136 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 96f162e..d258e2b 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -140,6 +140,8 @@ struct bnxt {
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
 
+	uint32_t		max_ring_grps;
+	struct bnxt_ring_grp_info	*grp_info;
 	unsigned		nr_vnics;
 
 	struct bnxt_vnic_info	*vnic_info;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 922c92a..ecd4718 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -43,7 +43,9 @@
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
 #define HWRM_CMD_TIMEOUT		2000
@@ -191,6 +193,7 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
+	bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps);
 	if (BNXT_PF(bp)) {
 		struct bnxt_pf_info *pf = &bp->pf;
 
@@ -477,6 +480,36 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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 == (uint16_t)HWRM_NA_SIGNATURE) {
+			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 = (uint16_t)HWRM_NA_SIGNATURE;
+	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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 4fa94aa..62dc801 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,8 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 9c82d13..ba0e054 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -89,6 +89,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #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))
@@ -3168,6 +3169,104 @@ struct hwrm_stat_ctx_clr_stats_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_alloc */
+/*
+ * Description: This VNIC is a resource in the RX side of the chip that is used
+ * to represent a virtual host "interface". # At the time of VNIC allocation or
+ * configuration, the function can specify whether it wants the requested VNIC
+ * to be the default VNIC for the function or not. # If a function requests
+ * allocation of a VNIC for the first time and a VNIC is successfully allocated
+ * by the HWRM, then the HWRM shall make the allocated VNIC as the default VNIC
+ * for that function. # The default VNIC shall be used for the default action
+ * for a partition or function. # For each VNIC allocated on a function, a
+ * mapping on the RX side to map the allocated VNIC to source virtual interface
+ * shall be performed by the HWRM. This should be hidden to the function driver
+ * requesting the VNIC allocation. This enables broadcast/multicast replication
+ * with source knockout. # If multicast replication with source knockout is
+ * enabled, then the internal VNIC to SVIF mapping data structures shall be
+ * programmed at the time of VNIC allocation.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_vnic_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', this VNIC is requested to be the default VNIC
+	 * for this function.
+	 */
+	#define HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT                UINT32_C(0x1)
+	uint32_t flags;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* Logical vnic ID */
+	uint32_t vnic_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 18/40] bnxt: add HWRM vnic free function
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (15 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:25                 ` [PATCH 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
                                   ` (22 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Frees a vnic allocated by vnic_alloc.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 21 +++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 82 ++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index ecd4718..d716b67 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -510,6 +510,27 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 62dc801..887ad2d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,7 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+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_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index ba0e054..93d50fb 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -90,6 +90,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
+#define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #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))
@@ -3267,6 +3268,87 @@ struct hwrm_vnic_alloc_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_free */
+/*
+ * Description: Free a VNIC resource. Idle any resources associated with the
+ * VNIC as well as the VNIC. Reset and release all resources associated with the
+ * VNIC.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_vnic_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Logical vnic ID */
+	uint32_t vnic_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 19/40] bnxt: add HWRM vnic cfg function
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (16 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 18/40] bnxt: add HWRM vnic free function Stephen Hurd
@ 2016-05-06 19:25                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
                                   ` (21 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:25 UTC (permalink / raw)
  To: dev

Configurs a vnic allocaed by vnic_alloc function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  34 ++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 155 +++++++++++++++++++++++++++++++++
 3 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d716b67..2a18cf3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -510,6 +510,40 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 887ad2d..b5cf090 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,8 +59,9 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
-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_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_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 93d50fb..b74f9f9 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -91,6 +91,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
+#define HWRM_VNIC_CFG			(UINT32_C(0x42))
 #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))
@@ -3268,6 +3269,160 @@ struct hwrm_vnic_alloc_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_cfg */
+/* Description: Configure the RX VNIC structure. */
+
+/* Input (40 bytes) */
+struct hwrm_vnic_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the VNIC is requested to be the default VNIC
+	 * for the function.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC is being configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled on this
+	 * VNIC.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC is being configured to buffer receive
+	 * packets in the hardware until the host posts new receive buffers. If
+	 * set to '0', then bd_stall is being configured to be disabled on this
+	 * VNIC.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE		UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC is being configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is not
+	 * configured to be operating in dual VNIC mode.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	/*
+	 * When this flag is set to '1', the VNIC is requested to be configured
+	 * to receive only RoCE traffic. If this flag is set to '0', then this
+	 * flag shall be ignored by the HWRM. If roce_dual_vnic_mode flag is set
+	 * to '1', then the HWRM client shall not set this flag to '1'.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	uint32_t flags;
+
+	/* This bit must be '1' for the dflt_ring_grp field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP	UINT32_C(0x1)
+	/* This bit must be '1' for the rss_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE		UINT32_C(0x2)
+	/* This bit must be '1' for the cos_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE		UINT32_C(0x4)
+	/* This bit must be '1' for the lb_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE		UINT32_C(0x8)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_MRU			UINT32_C(0x10)
+	uint32_t enables;
+
+	/* Logical vnic ID */
+	uint16_t vnic_id;
+
+	/*
+	 * Default Completion ring for the VNIC. This ring will be chosen if
+	 * packet does not match any RSS rules and if there is no COS rule.
+	 */
+	uint16_t dflt_ring_grp;
+
+	/*
+	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if there is no
+	 * RSS rule.
+	 */
+	uint16_t rss_rule;
+
+	/*
+	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if there is no
+	 * COS rule.
+	 */
+	uint16_t cos_rule;
+
+	/*
+	 * RSS ID for load balancing rule/table structure. 0xFF... (All Fs) if
+	 * there is no LB rule.
+	 */
+	uint16_t lb_rule;
+
+	/*
+	 * The maximum receive unit of the vnic. Each vnic is associated with a
+	 * function. The vnic mru value overwrites the mru setting of the
+	 * associated function. The HWRM shall make sure that vnic mru does not
+	 * exceed the mru of the port the function is associated with.
+	 */
+	uint16_t mru;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_free */
 /*
  * Description: Free a VNIC resource. Idle any resources associated with the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (17 preceding siblings ...)
  2016-05-06 19:25                 ` [PATCH 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
                                   ` (20 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

More HWRM calls.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  38 ++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 153 +++++++++++++++++++++++++++++++++
 3 files changed, 193 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 2a18cf3..4609862 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -544,6 +544,44 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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_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_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b5cf090..b7f6b20 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -61,6 +61,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp);
 
 int bnxt_hwrm_vnic_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_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index b74f9f9..34f66c5 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -92,6 +92,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
+#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))
@@ -3625,6 +3627,157 @@ struct hwrm_vnic_rss_cfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* Input (16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* rss_cos_lb_ctx_id is 16 b */
+	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;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_free */
+/* Description: This function can be used to free COS/Load Balance context. */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_rss_cos_lb_ctx_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint16_t rss_cos_lb_ctx_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* Output (32 bytes) */
 struct hwrm_queue_qportcfg_output {
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 21/40] bnxt: add HWRM vnic RSS config function
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (18 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
                                   ` (19 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Used to enable RSS configuration

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 24 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  2 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  1 +
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 4609862..6e37315 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -603,6 +603,30 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b7f6b20..7c12c6d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -64,6 +64,8 @@ int bnxt_hwrm_vnic_cfg(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_ctx_free(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_rss_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic);
 
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 34f66c5..5b8895c 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -92,6 +92,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
+#define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
 #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))
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 22/40] bnxt: add L2 Rx mask set/clear functions
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (19 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
                                   ` (18 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Allows setting and clearing L2 context RX masks per vnic

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  45 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 135 +++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6e37315..44c6e80 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -141,6 +141,51 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 7c12c6d..915cf2a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -42,6 +42,9 @@
 struct bnxt;
 struct bnxt_filter_info;
 struct bnxt_cp_ring_info;
+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_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 5b8895c..89a1d6f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1781,6 +1781,141 @@ struct hwrm_cfa_l2_filter_free_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_cfa_l2_set_rx_mask */
+/* Description: This command will set rx mask of the function. */
+
+/* Input (40 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* VNIC ID */
+	uint32_t vnic_id;
+
+	/* Reserved for future use. */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_RESERVED	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the function is requested to accept multi-cast
+	 * packets specified by the multicast addr table.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the function is requested to accept all multi-
+	 * cast packets.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the function is requested to accept broadcast
+	 * packets.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the function is requested to be put in the
+	 * promiscuous mode. The HWRM should accept any function to set up
+	 * promiscuous mode. The HWRM shall follow the semantics below for the
+	 * promiscuous mode support. # When partitioning is not enabled on a
+	 * port (i.e. single PF on the port), then the PF shall be allowed to be
+	 * in the promiscuous mode. When the PF is in the promiscuous mode, then
+	 * it shall receive all host bound traffic on that port. # When
+	 * partitioning is enabled on a port (i.e. multiple PFs per port) and a
+	 * PF on that port is in the promiscuous mode, then the PF receives all
+	 * traffic within that partition as identified by a unique identifier
+	 * for the PF (e.g. S-Tag). If a unique outer VLAN for the PF is
+	 * specified, then the setting of promiscuous mode on that PF shall
+	 * result in the PF receiving all host bound traffic with matching outer
+	 * VLAN. # A VF shall can be set in the promiscuous mode. In the
+	 * promiscuous mode, the VF does not receive any traffic unless a unique
+	 * outer VLAN for the VF is specified. If a unique outer VLAN for the VF
+	 * is specified, then the setting of promiscuous mode on that VF shall
+	 * result in the VF receiving all host bound traffic with the matching
+	 * outer VLAN. # The HWRM shall allow the setting of promiscuous mode on
+	 * a function independently from the promiscuous mode settings on other
+	 * functions.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS	UINT32_C(0x10)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be set up to
+	 * cover multicast/broadcast filters for the outermost Layer 2
+	 * destination MAC address field.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST	UINT32_C(0x20)
+	uint32_t mask;
+
+	/* This is the address for mcast address tbl. */
+	uint64_t mc_tbl_addr;
+
+	/*
+	 * This value indicates how many entries in mc_tbl are valid. Each entry
+	 * is 6 bytes.
+	 */
+	uint32_t num_mc_entries;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_exec_fwd_resp */
 /*
  * Description: This command is used to send an encapsulated request to the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 23/40] bnxt: add HWRM stats context allocation
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (20 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
                                   ` (17 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add HWRM code to allocate a statistics context and a helper function
to allocate one for evert completion ring.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 52 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  3 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 89 ++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 44c6e80..2993aef 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -525,6 +525,31 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	return rc;
 }
 
+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_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0, i, j;
@@ -701,6 +726,33 @@ int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
 	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 */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 915cf2a..b4cc3b6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,8 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
+			     struct bnxt_cp_ring_info *cpr, unsigned idx);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
@@ -70,6 +72,7 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 89a1d6f..de3eb0e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -99,6 +99,7 @@ typedef struct ctx_hw_stats64 {
 #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 HWRM_STAT_CTX_ALLOC		(UINT32_C(0xb0))
 #define HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
@@ -3232,6 +3233,94 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a stat
+ * context.
+ */
+
+/* Input (32 bytes) */
+struct hwrm_stat_ctx_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This is the address for statistic block. */
+	uint64_t stats_dma_addr;
+
+	/*
+	 * The statistic block update period in ms. e.g. 250ms, 500ms, 750ms,
+	 * 1000ms.
+	 */
+	uint32_t update_period_ms;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_stat_ctx_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This is the statistics context ID value. */
+	uint32_t stat_ctx_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_clr_stats */
 /* Description: This command clears statistics of a context. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 24/40] bnxt: add HWRM ring alloc/free functions
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (21 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 25/40] bnxt: add ring group " Stephen Hurd
                                   ` (16 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add HWRM calls to allocate and free TX/RX/CMPL rings along with
the associated structs and definitions.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 108 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   7 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 305 +++++++++++++++++++++++++++++++++
 3 files changed, 420 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 2993aef..6a92089 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -504,6 +504,114 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 	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_POLL;
+		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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b4cc3b6..40accbc 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -58,6 +58,13 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
+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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned idx);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index de3eb0e..16ac528 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -93,6 +93,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
 #define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
+#define HWRM_RING_ALLOC			(UINT32_C(0x50))
+#define HWRM_RING_FREE			(UINT32_C(0x51))
 #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))
@@ -3233,6 +3235,309 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_ring_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a ring.
+ */
+
+/* Input (80 bytes) */
+struct hwrm_ring_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This bit must be '1' for the Reserved1 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED1		UINT32_C(0x1)
+	/* This bit must be '1' for the Reserved2 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED2		UINT32_C(0x2)
+	/* This bit must be '1' for the Reserved3 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED3		UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the stat_ctx_id_valid field to be
+	 * configured.
+	 */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID	UINT32_C(0x8)
+	/* This bit must be '1' for the Reserved4 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED4		UINT32_C(0x10)
+	/* This bit must be '1' for the max_bw_valid field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_MAX_BW_VALID	UINT32_C(0x20)
+	uint32_t enables;
+
+	/* Ring Type. */
+		/* Completion Ring (CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	(UINT32_C(0x0) << 0)
+		/* TX Ring (TR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	(UINT32_C(0x1) << 0)
+		/* RX Ring (RR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	(UINT32_C(0x2) << 0)
+	uint8_t ring_type;
+
+	uint8_t unused_0;
+	uint16_t unused_1;
+
+	/* This value is a pointer to the page table for the Ring. */
+	uint64_t page_tbl_addr;
+
+	/* First Byte Offset of the first entry in the first page. */
+	uint32_t fbo;
+
+	/*
+	 * Actual page size in 2^page_size. The supported range is increments in
+	 * powers of 2 from 16 bytes to 1GB. - 4 = 16 B Page size is 16 B. - 12
+	 * = 4 KB Page size is 4 KB. - 13 = 8 KB Page size is 8 KB. - 16 = 64 KB
+	 * Page size is 64 KB. - 22 = 2 MB Page size is 2 MB. - 23 = 4 MB Page
+	 * size is 4 MB. - 31 = 1 GB Page size is 1 GB.
+	 */
+	uint8_t page_size;
+
+	/*
+	 * This value indicates the depth of page table. For this version of the
+	 * specification, value other than 0 or 1 shall be considered as an
+	 * invalid value. When the page_tbl_depth = 0, then it is treated as a
+	 * special case with the following. 1. FBO and page size fields are not
+	 * valid. 2. page_tbl_addr is the physical address of the first element
+	 * of the ring.
+	 */
+	uint8_t page_tbl_depth;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * Number of 16B units in the ring. Minimum size for a ring is 16 16B
+	 * entries.
+	 */
+	uint32_t length;
+
+	/*
+	 * Logical ring number for the ring to be allocated. This value
+	 * determines the position in the doorbell area where the update to the
+	 * ring will be made. For completion rings, this value is also the MSI-X
+	 * vector number for the function the completion ring is associated
+	 * with.
+	 */
+	uint16_t logical_id;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This value
+	 * indicates what completion ring the TX ring is associated with.
+	 */
+	uint16_t cmpl_ring_id;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This value
+	 * indicates what CoS queue the TX ring is associated with.
+	 */
+	uint16_t queue_id;
+
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved1;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint16_t reserved2;
+
+	uint8_t unused_6;
+	uint8_t unused_7;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved3;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This input
+	 * indicates what statistics context this ring should be associated
+	 * with.
+	 */
+	uint32_t stat_ctx_id;
+
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved4;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. Maximum BW
+	 * allocated to this TX ring in Mbps. The HWRM will translate this value
+	 * into byte counter and time interval used for this ring inside the
+	 * device.
+	 */
+	uint32_t max_bw;
+
+	/*
+	 * This field is used only when ring_type is a Completion ring. This
+	 * value indicates what interrupt mode should be used on this completion
+	 * ring. Note: In the legacy interrupt mode, no more than 16 completion
+	 * rings are allowed.
+	 */
+		/* Legacy INTA */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY	(UINT32_C(0x0) << 0)
+		/* Reserved */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	(UINT32_C(0x1) << 0)
+		/* MSI-X */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	(UINT32_C(0x2) << 0)
+		/* No Interrupt - Polled mode */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	(UINT32_C(0x3) << 0)
+	uint8_t int_mode;
+
+	uint8_t unused_8[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_ring_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* Physical number of ring allocated. */
+	uint16_t ring_id;
+
+	/* Logical number of ring allocated. */
+	uint16_t logical_ring_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ring_free */
+/*
+ * Description: This command is used to free a ring and associated resources.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_ring_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Ring Type. */
+		/* Completion Ring (CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	(UINT32_C(0x0) << 0)
+		/* TX Ring (TR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	(UINT32_C(0x1) << 0)
+		/* RX Ring (RR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	(UINT32_C(0x2) << 0)
+	uint8_t ring_type;
+
+	uint8_t unused_0;
+
+	/* Physical number of ring allocated. */
+	uint16_t ring_id;
+
+	uint32_t unused_1;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_alloc */
 /*
  * Description: This command allocates and does basic preparation for a stat
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 25/40] bnxt: add ring group alloc/free functions
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (22 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 26/40] bnxt: add HWRM stat context free function Stephen Hurd
                                   ` (15 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add HWRM ring group add/free functions and associated structs and
definitions.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  84 +++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   4 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 185 +++++++++++++++++++++++++++++++++
 3 files changed, 273 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6a92089..027a2e8 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -612,6 +612,47 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 	return 0;
 }
 
+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_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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
 	int rc = 0;
@@ -861,6 +902,49 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 	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;
+}
+
 void bnxt_free_hwrm_resources(struct bnxt *bp)
 {
 	/* Release memzone */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 40accbc..b65d692 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -64,6 +64,8 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 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_ring_grp_alloc(struct bnxt *bp, unsigned idx);
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx);
 
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
@@ -81,6 +83,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 16ac528..12a28ba 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -95,6 +95,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
 #define HWRM_RING_ALLOC			(UINT32_C(0x50))
 #define HWRM_RING_FREE			(UINT32_C(0x51))
+#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))
@@ -3538,6 +3540,189 @@ struct hwrm_ring_free_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_ring_grp_alloc */
+/*
+ * Description: This API allocates and does basic preparation for a ring group.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ring_grp_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This value identifies the CR associated with the ring group. */
+	uint16_t cr;
+
+	/* This value identifies the main RR associated with the ring group. */
+	uint16_t rr;
+
+	/*
+	 * This value identifies the aggregation RR associated with the ring
+	 * group. If this value is 0xFF... (All Fs), then no Aggregation ring
+	 * will be set.
+	 */
+	uint16_t ar;
+
+	/*
+	 * This value identifies the statistics context associated with the ring
+	 * group.
+	 */
+	uint16_t sc;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_grp_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This is the ring group ID value. Use this value to program the
+	 * default ring group for the VNIC or as table entries in an RSS/COS
+	 * context.
+	 */
+	uint32_t ring_group_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ring_grp_free */
+/*
+ * Description: This API frees a ring group and associated resources. # If a
+ * ring in the ring group is reset or free, then the associated rings in the
+ * ring group shall also be reset/free using hwrm_ring_free. # A function driver
+ * shall always use hwrm_ring_grp_free after freeing all rings in a group. # As
+ * a part of executing this command, the HWRM shall reset all associated ring
+ * group resources.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ring_grp_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This is the ring group ID value. */
+	uint32_t ring_group_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_grp_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_alloc */
 /*
  * Description: This command allocates and does basic preparation for a stat
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 26/40] bnxt: add HWRM stat context free function
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (23 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 25/40] bnxt: add ring group " Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 27/40] bnxt: add struct forward decl Stephen Hurd
                                   ` (14 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add function and associated structures and definitions as well as
some convenienct functions for manipulating the state of the entire
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 219 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  10 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  81 ++++++++++++
 3 files changed, 310 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 027a2e8..b5bc473 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -43,8 +43,10 @@
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 #include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -206,6 +208,49 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 	return 0;
 }
 
+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_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd)
 {
 	int rc;
@@ -699,6 +744,28 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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 = HWRM_NA_SIGNATURE;
+	bp->grp_info[idx].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+	return rc;
+}
+
 int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0, i, j;
@@ -875,6 +942,28 @@ int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
 	return 0;
 }
 
+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 != HWRM_NA_SIGNATURE) {
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, idx);
+			if (rc)
+				return rc;
+		}
+	}
+	return 0;
+}
+
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 {
 	unsigned i;
@@ -925,6 +1014,84 @@ int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 	return rc;
 }
 
+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_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 {
 	uint16_t i;
@@ -972,6 +1139,58 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 	return 0;
 }
 
+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;
+}
+
+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;
+}
+
+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_eth_link_duplex(uint32_t conf_link_speed)
 {
 	uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b65d692..b7a3f24 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -47,6 +47,9 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp,
 int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
+int bnxt_hwrm_set_filter(struct bnxt *bp,
+			 struct bnxt_vnic_info *vnic,
+			 struct bnxt_filter_info *filter);
 
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 
@@ -70,6 +73,8 @@ int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx);
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned idx);
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
+			    struct bnxt_cp_ring_info *cpr, unsigned idx);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
@@ -83,8 +88,13 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_stat_ctxs(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_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);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 12a28ba..6644c8e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -104,6 +104,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_CFA_L2_FILTER_CFG		(UINT32_C(0x92))
 #define HWRM_CFA_L2_SET_RX_MASK		(UINT32_C(0x93))
 #define HWRM_STAT_CTX_ALLOC		(UINT32_C(0xb0))
+#define HWRM_STAT_CTX_FREE		(UINT32_C(0xb1))
 #define HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
@@ -3888,6 +3889,86 @@ struct hwrm_stat_ctx_clr_stats_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_free */
+/* Description: This command is used to free a stat context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* ID of the statistics context that is being queried. */
+	uint32_t stat_ctx_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_stat_ctx_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This is the statistics context ID value. */
+	uint32_t stat_ctx_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_alloc */
 /*
  * Description: This VNIC is a resource in the RX side of the chip that is used
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 27/40] bnxt: add struct forward decl
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (24 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 26/40] bnxt: add HWRM stat context free function Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 28/40] bnxt: add ring allocation and group init Stephen Hurd
                                   ` (13 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add missing forward declaration of struct bnxt_ring_struct to avoid
requiring additional headers for the function declaation.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b7a3f24..8ad91d3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -42,6 +42,7 @@
 struct bnxt;
 struct bnxt_filter_info;
 struct bnxt_cp_ring_info;
+struct bnxt_ring_struct;
 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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 28/40] bnxt: add ring allocation and group init
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (25 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 27/40] bnxt: add struct forward decl Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
                                   ` (12 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add a function to initialize ring groups, and a function to
allocate the rings via HWRM.

This should be the last functionality needed to add start/stop
device operations.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ring.c | 119 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_ring.h |   2 +
 2 files changed, 121 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 69837bf..8852e28 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -35,8 +35,11 @@
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
+#include "bnxt_rxq.h"
 #include "bnxt_rxr.h"
+#include "bnxt_txq.h"
 #include "bnxt_txr.h"
 
 #include "hsi_struct_def_dpdk.h"
@@ -58,6 +61,19 @@ void bnxt_free_ring(struct bnxt_ring_struct *ring)
 }
 
 /*
+ * Ring groups
+ */
+
+void bnxt_init_ring_grps(struct bnxt *bp)
+{
+	unsigned i;
+
+	for (i = 0; i < bp->max_ring_grps; i++)
+		memset(&bp->grp_info[i], (uint8_t)HWRM_NA_SIGNATURE,
+		       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.
@@ -185,3 +201,106 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	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, HWRM_NA_SIGNATURE);
+		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, HWRM_NA_SIGNATURE);
+		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, HWRM_NA_SIGNATURE);
+		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
index dfa0401..4e7c6db 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -91,10 +91,12 @@ 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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 29/40] bnxt: work around HWRM error when creating rings
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (26 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 28/40] bnxt: add ring allocation and group init Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
                                   ` (11 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Some HWRM versions will stop responding if we request poll mode interrupt.
As a workaround, request an MSI interrupt even though we never enable it.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index b5bc473..897e766 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -581,7 +581,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
 		req.ring_type = ring_type;
-		req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_POLL;
+		/*
+		 * TODO: Some HWRM versions crash with
+		 * HWRM_RING_ALLOC_INPUT_INT_MODE_POLL
+		 */
+		req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
 		req.length = rte_cpu_to_le_32(ring->ring_size);
 		break;
 	default:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 30/40] bnxt: add HWRM port phy qcfg call and wrapper
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (27 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 31/40] bnxt: add start/stop/link update operations Stephen Hurd
                                   ` (10 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add HWRM port pgy qcfg HWRM command and bnxt_get_hwrm_link_config()
wrapper which parses the link state.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 120 +++++
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 790 +++++++++++++++++++++++++++++++++
 3 files changed, 911 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 897e766..1a1f108 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -521,6 +521,43 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 	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_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
@@ -1326,6 +1363,89 @@ static uint16_t bnxt_parse_eth_link_speed_mask(uint32_t link_speed)
 	return ret;
 }
 
+static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
+{
+	uint32_t eth_link_speed = ETH_SPEED_NUM_NONE;
+
+	switch (hw_link_speed) {
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
+		eth_link_speed = ETH_SPEED_NUM_100M;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
+		eth_link_speed = ETH_SPEED_NUM_1G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB:
+		eth_link_speed = ETH_SPEED_NUM_2_5G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
+		eth_link_speed = ETH_SPEED_NUM_10G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
+		eth_link_speed = ETH_SPEED_NUM_20G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
+		eth_link_speed = ETH_SPEED_NUM_25G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
+		eth_link_speed = ETH_SPEED_NUM_40G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
+		eth_link_speed = ETH_SPEED_NUM_50G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
+	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_hw_link_duplex(uint16_t hw_link_duplex)
+{
+	uint16_t eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+
+	switch (hw_link_duplex) {
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH:
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL:
+		eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF:
+		eth_link_duplex = ETH_LINK_HALF_DUPLEX;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "HWRM link duplex %d not defined\n",
+			hw_link_duplex);
+		break;
+	}
+	return eth_link_duplex;
+}
+
+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_10M;
+	link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
+	link->link_status = link_info->link_up;
+	link->link_autoneg = link_info->auto_mode == \
+		HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE ? \
+		ETH_LINK_SPEED_FIXED : ETH_LINK_SPEED_AUTONEG;
+exit:
+	return rc;
+}
+
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 8ad91d3..2bcb4da 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -98,6 +98,7 @@ int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 void bnxt_free_all_hwrm_resources(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 6644c8e..8656b92 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -88,6 +88,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
+#define HWRM_PORT_PHY_QCFG		(UINT32_C(0x27))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
@@ -2842,6 +2843,795 @@ struct hwrm_port_phy_cfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_port_phy_qcfg */
+/* Description: This command queries the PHY configuration for the port. */
+/* Input (24 bytes) */
+
+struct hwrm_port_phy_qcfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Port ID of port that is to be queried. */
+	uint16_t port_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (96 bytes) */
+struct hwrm_port_phy_qcfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This value indicates the current link status. */
+		/* There is no link or cable detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK	(UINT32_C(0x0) << 0)
+		/* There is no link, but a cable has been detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	(UINT32_C(0x1) << 0)
+		/* There is a link. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	(UINT32_C(0x2) << 0)
+	uint8_t link;
+
+	uint8_t unused_0;
+
+	/* This value indicates the current link speed of the connection. */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t link_speed;
+
+	/* This value is indicates the duplex of the current connection. */
+		/* Half Duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	(UINT32_C(0x0) << 0)
+		/* Full duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	(UINT32_C(0x1) << 0)
+	uint8_t duplex;
+
+	/*
+	 * This value is used to indicate the current pause configuration. When
+	 * autoneg is enabled, this value represents the autoneg results of
+	 * pause configuration.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX	UINT32_C(0x2)
+	uint8_t pause;
+
+	/*
+	 * The supported speeds for the port. This is a bit mask. For each speed
+	 * that is supported, the corrresponding bit will be set to '1'.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB \
+							UINT32_C(0x2000)
+	uint16_t support_speeds;
+
+	/*
+	 * Current setting of forced link speed. When the link speed is not
+	 * being forced, this value shall be set to 0.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t force_link_speed;
+
+	/* Current setting of auto negotiation mode. */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK \
+							(UINT32_C(0x4) << 0)
+	uint8_t auto_mode;
+
+	/*
+	 * Current setting of pause autonegotiation. Move autoneg_pause flag
+	 * here.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+	/*
+	 * When set to 1, the advertisement of pause is enabled. # When the
+	 * auto_mode is not set to none and this flag is set to 1, then the
+	 * auto_pause bits on this port are being advertised and autoneg pause
+	 * results are being interpreted. # When the auto_mode is not set to
+	 * none and this flag is set to 0, the pause is forced as indicated in
+	 * force_pause, and also advertised as auto_pause bits, but the autoneg
+	 * results are not interpreted since the pause configuration is being
+	 * forced. # When the auto_mode is set to none and this flag is set to
+	 * 1, auto_pause bits should be ignored and should be set to 0.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE \
+							UINT32_C(0x4)
+	uint8_t auto_pause;
+
+	/*
+	 * Current setting for auto_link_speed. This field is only valid when
+	 * auto_mode is set to "one_speed" or "one_or_below".
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t auto_link_speed;
+
+	/*
+	 * Current setting for auto_link_speed_mask that is used to advertise
+	 * speeds during autonegotiation. This field is only valid when
+	 * auto_mode is set to "mask". The speeds specified in this field shall
+	 * be a subset of supported speeds on this port.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MB \
+							UINT32_C(0x2000)
+	uint16_t auto_link_speed_mask;
+
+	/* Current setting for wirespeed. */
+		/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_OFF	(UINT32_C(0x0) << 0)
+		/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_ON	(UINT32_C(0x1) << 0)
+	uint8_t wirespeed;
+
+	/* Current setting for loopback. */
+		/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	(UINT32_C(0x0) << 0)
+		/*
+		 * The HW will be configured with local loopback such that host
+		 * data is sent back to the host without modification.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL	(UINT32_C(0x1) << 0)
+		/*
+		 * The HW will be configured with remote loopback such that port
+		 * logic will send packets back out the transmitter that are
+		 * received.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE	(UINT32_C(0x2) << 0)
+	uint8_t lpbk;
+
+	/*
+	 * Current setting of forced pause. When the pause configuration is not
+	 * being forced, then this value shall be set to 0.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX \
+							UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX \
+							UINT32_C(0x2)
+	uint8_t force_pause;
+
+	/*
+	 * This value indicates the current status of the optics module on this
+	 * port.
+	 */
+		/* Module is inserted and accepted */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Module is rejected and transmit side Laser is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX \
+							(UINT32_C(0x1) << 0)
+		/* Module mismatch warning. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG \
+							(UINT32_C(0x2) << 0)
+		/* Module is rejected and powered down. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN \
+							(UINT32_C(0x3) << 0)
+		/* Module is not inserted. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+							(UINT32_C(0x4) << 0)
+		/* Module status is not applicable. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+							(UINT32_C(0xff) << 0)
+	uint8_t module_status;
+
+	/* Current setting for preemphasis. */
+	uint32_t preemphasis;
+
+	/* This field represents the major version of the PHY. */
+	uint8_t phy_maj;
+
+	/* This field represents the minor version of the PHY. */
+	uint8_t phy_min;
+
+	/* This field represents the build version of the PHY. */
+	uint8_t phy_bld;
+
+	/* This value represents a PHY type. */
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* BASE-CR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR \
+							(UINT32_C(0x1) << 0)
+		/* BASE-KR4 (Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4 \
+							(UINT32_C(0x2) << 0)
+		/* BASE-LR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR \
+							(UINT32_C(0x3) << 0)
+		/* BASE-SR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR \
+							(UINT32_C(0x4) << 0)
+		/* BASE-KR2 (Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2 \
+							(UINT32_C(0x5) << 0)
+		/* BASE-KX */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX \
+							(UINT32_C(0x6) << 0)
+		/* BASE-KR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR \
+							(UINT32_C(0x7) << 0)
+		/* BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET \
+							(UINT32_C(0x8) << 0)
+		/* EEE capable BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE \
+							(UINT32_C(0x9) << 0)
+		/* SGMII connected external PHY */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY \
+							(UINT32_C(0xa) << 0)
+	uint8_t phy_type;
+
+	/* This value represents a media type. */
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* Twisted Pair */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	(UINT32_C(0x1) << 0)
+		/* Direct Attached Copper */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC \
+							(UINT32_C(0x2) << 0)
+		/* Fiber */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE \
+							(UINT32_C(0x3) << 0)
+	uint8_t media_type;
+
+	/* This value represents a transceiver type. */
+		/* PHY and MAC are in the same package */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_INTERNAL \
+							(UINT32_C(0x1) << 0)
+		/* PHY and MAC are in different packages */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+							(UINT32_C(0x2) << 0)
+	uint8_t xcvr_pkg_type;
+
+	/*
+	 * This field represents flags related to EEE configuration. These EEE
+	 * configuration flags are valid only when the auto_mode is not set to
+	 * none (in other words autonegotiation is enabled).
+	 */
+	/* This field represents PHY address. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK	UINT32_C(0x1f)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_SFT	0
+	/*
+	 * When set to 1, Energy Efficient Ethernet (EEE) mode is enabled.
+	 * Speeds for autoneg with EEE mode enabled are based on
+	 * eee_link_speed_mask.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED \
+							UINT32_C(0x20)
+	/*
+	 * This flag is valid only when eee_enabled is set to 1. # If
+	 * eee_enabled is set to 0, then EEE mode is disabled and this flag
+	 * shall be ignored. # If eee_enabled is set to 1 and this flag is set
+	 * to 1, then Energy Efficient Ethernet (EEE) mode is enabled and in
+	 * use. # If eee_enabled is set to 1 and this flag is set to 0, then
+	 * Energy Efficient Ethernet (EEE) mode is enabled but is currently not
+	 * in use.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE \
+							UINT32_C(0x40)
+	/*
+	 * This flag is valid only when eee_enabled is set to 1. # If
+	 * eee_enabled is set to 0, then EEE mode is disabled and this flag
+	 * shall be ignored. # If eee_enabled is set to 1 and this flag is set
+	 * to 1, then Energy Efficient Ethernet (EEE) mode is enabled and TX LPI
+	 * is enabled. # If eee_enabled is set to 1 and this flag is set to 0,
+	 * then Energy Efficient Ethernet (EEE) mode is enabled but TX LPI is
+	 * disabled.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI \
+							UINT32_C(0x80)
+	/*
+	 * This field represents flags related to EEE configuration. These EEE
+	 * configuration flags are valid only when the auto_mode is not set to
+	 * none (in other words autonegotiation is enabled).
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK \
+							UINT32_C(0xe0)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT	5
+	uint8_t eee_config_phy_addr;
+
+	/* Reserved field, set to 0 */
+	/*
+	 * When set to 1, the parallel detection is used to determine the speed
+	 * of the link partner. Parallel detection is used when a
+	 * autonegotiation capable device is connected to a link parter that is
+	 * not capable of autonegotiation.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PARALLEL_DETECT \
+							UINT32_C(0x1)
+	/* Reserved field, set to 0 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_RESERVED_MASK	UINT32_C(0xfe)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_RESERVED_SFT	1
+	uint8_t parallel_detect;
+
+	/*
+	 * The advertised speeds for the port by the link partner. Each
+	 * advertised speed will be set to '1'.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MB \
+							UINT32_C(0x2000)
+	uint16_t link_partner_adv_speeds;
+
+	/*
+	 * The advertised autoneg for the port by the link partner. This field
+	 * is deprecated and should be set to 0.
+	 */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS\
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK\
+							(UINT32_C(0x4) << 0)
+	uint8_t link_partner_adv_auto_mode;
+
+	/* The advertised pause settings on the port by the link partner. */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX \
+							UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX \
+							UINT32_C(0x2)
+	uint8_t link_partner_adv_pause;
+
+	/*
+	 * Current setting for link speed mask that is used to advertise speeds
+	 * during autonegotiation when EEE is enabled. This field is valid only
+	 * when eee_enabled flags is set to 1. The speeds specified in this
+	 * field shall be a subset of speeds specified in auto_link_speed_mask.
+	 */
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+							UINT32_C(0x10)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	uint16_t adv_eee_link_speed_mask;
+
+	/*
+	 * Current setting for link speed mask that is advertised by the link
+	 * partner when EEE is enabled. This field is valid only when
+	 * eee_enabled flags is set to 1.
+	 */
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+							UINT32_C(0x10)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	uint16_t link_partner_adv_eee_link_speed_mask;
+
+	/* This value represents transceiver identifier type. */
+	/*
+	 * Current setting of TX LPI timer in microseconds. This field is valid
+	 * only when_eee_enabled flag is set to 1 and tx_lpi_enabled is set to
+	 * 1.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_MASK \
+							UINT32_C(0xffffff)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_SFT         0
+	/* This value represents transceiver identifier type. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_MASK \
+							UINT32_C(0xff000000)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFT \
+							24
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 24)
+		/* SFP/SFP+/SFP28 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFP \
+							(UINT32_C(0x3) << 24)
+		/* QSFP */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP \
+							(UINT32_C(0xc) << 24)
+		/* QSFP+ */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS \
+							(UINT32_C(0xd) << 24)
+		/* QSFP28 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \
+							(UINT32_C(0x11) << 24)
+	uint32_t xcvr_identifier_type_tx_lpi_timer;
+
+	uint32_t unused_1;
+
+	/*
+	 * Up to 16 bytes of null padded ASCII string representing PHY vendor.
+	 * If the string is set to null, then the vendor name is not available.
+	 */
+	char phy_vendor_name[16];
+
+	/*
+	 * Up to 16 bytes of null padded ASCII string that identifies vendor
+	 * specific part number of the PHY. If the string is set to null, then
+	 * the vendor specific part number is not available.
+	 */
+	char phy_vendor_partnumber[16];
+
+	uint32_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 31/40] bnxt: add start/stop/link update operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (28 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
                                   ` (9 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

BNXT driver will now minimally pass traffic with testpmd.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 267 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e1b3e3a..a91e1c2 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -40,12 +40,17 @@
 #include <rte_cycles.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
 #include "bnxt_hwrm.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 DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -57,6 +62,175 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
+/***********************/
+
+/*
+ * 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 */
+	rc = bnxt_init_def_ring_struct(bp, SOCKET_ID_ANY);
+	if (rc)
+		goto alloc_mem_err;
+
+	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;
+	}
+
+	/* 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
  */
@@ -174,6 +348,85 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 	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_alloc_mem(bp);
+	if (rc)
+		goto error;
+
+	rc = bnxt_init_nic(bp);
+	if (rc)
+		goto error;
+
+	return 0;
+
+error:
+	bnxt_shutdown_nic(bp);
+	bnxt_free_tx_mbufs(bp);
+	bnxt_free_rx_mbufs(bp);
+	bnxt_free_mem(bp);
+	return rc;
+}
+
+/* Unload the driver, release resources */
+static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->eth_dev->data->dev_started) {
+		/* TBD: STOP HW queues DMA */
+		eth_dev->data->dev_link.link_status = 0;
+	}
+	bnxt_shutdown_nic(bp);
+}
+
+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_100M;
+			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;
+}
+
 /*
  * Initialization
  */
@@ -181,12 +434,15 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 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,
 	.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,
+	.link_update = bnxt_link_update_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -296,6 +552,15 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	else
 		memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+	bp->grp_info = rte_zmalloc("bnxt_grp_info",
+				sizeof(*bp->grp_info) * bp->max_ring_grps, 0);
+	if (!bp->grp_info) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc %lu bytes needed to store group info table\n",
+			sizeof(*bp->grp_info) * bp->max_ring_grps);
+		rc = -ENOMEM;
+		goto error_free;
+	}
 
 	rc = bnxt_hwrm_func_driver_register(bp, 0,
 					    bp->pf.vf_req_fwd);
@@ -326,6 +591,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 
 	if (eth_dev->data->mac_addrs)
 		rte_free(eth_dev->data->mac_addrs);
+	if (bp->grp_info)
+		rte_free(bp->grp_info);
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
 	return rc;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 32/40] bnxt: add promiscuous enable/disable operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (29 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 31/40] bnxt: add start/stop/link update operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 33/40] bnxt: add all multicast " Stephen Hurd
                                   ` (8 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Enables and diables promiscuous mode.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a91e1c2..f5de4c4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -427,6 +427,34 @@ out:
 	return rc;
 }
 
+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);
+}
+
 /*
  * Initialization
  */
@@ -443,6 +471,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.tx_queue_setup = bnxt_tx_queue_setup_op,
 	.tx_queue_release = bnxt_tx_queue_release_op,
 	.link_update = bnxt_link_update_op,
+	.promiscuous_enable = bnxt_promiscuous_enable_op,
+	.promiscuous_disable = bnxt_promiscuous_disable_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 33/40] bnxt: add all multicast enable/disable operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (30 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 34/40] bnxt: add device close operation Stephen Hurd
                                   ` (7 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Enables/disables all multicast traffic.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index f5de4c4..97ef0b4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -455,6 +455,34 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	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);
+}
+
 /*
  * Initialization
  */
@@ -473,6 +501,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 34/40] bnxt: add device close operation
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (31 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 33/40] bnxt: add all multicast " Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
                                   ` (6 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Frees all resources except the hwrm ones, which are required to notify
the HWRM that the driver is unloaded (these are freed in uninit()).

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 97ef0b4..edb7427 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -390,6 +390,16 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	bnxt_shutdown_nic(bp);
 }
 
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	bnxt_free_tx_mbufs(bp);
+	bnxt_free_rx_mbufs(bp);
+	bnxt_free_mem(bp);
+	rte_free(eth_dev->data->mac_addrs);
+}
+
 static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
 			       int wait_to_complete)
 {
@@ -492,6 +502,7 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_configure = bnxt_dev_configure_op,
 	.dev_start = bnxt_dev_start_op,
 	.dev_stop = bnxt_dev_stop_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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 35/40] bnxt: add MAC address add/remove operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (32 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 34/40] bnxt: add device close operation Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 36/40] bnxt: add dev set link up/down operations Stephen Hurd
                                   ` (5 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add/remove MAC addresses

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 69 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index edb7427..7056f98 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -400,6 +400,73 @@ static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
 	rte_free(eth_dev->data->mac_addrs);
 }
 
+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_link_update_op(struct rte_eth_dev *eth_dev,
 			       int wait_to_complete)
 {
@@ -514,6 +581,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.promiscuous_disable = bnxt_promiscuous_disable_op,
 	.allmulticast_enable = bnxt_allmulticast_enable_op,
 	.allmulticast_disable = bnxt_allmulticast_disable_op,
+	.mac_addr_add = bnxt_mac_addr_add_op,
+	.mac_addr_remove = bnxt_mac_addr_remove_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 36/40] bnxt: add dev set link up/down operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (33 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 37/40] bnxt: add reta update/query operations Stephen Hurd
                                   ` (4 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Sets link to up or down as appropriate.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7056f98..3396079 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -390,6 +390,24 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	bnxt_shutdown_nic(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;
@@ -569,6 +587,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 37/40] bnxt: add reta update/query operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (34 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 36/40] bnxt: add dev set link up/down operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 38/40] bnxt: add RSS device operations Stephen Hurd
                                   ` (3 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Update/query reta operations

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 3396079..2503112 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -578,6 +578,60 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	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;
+}
+
 /*
  * Initialization
  */
@@ -596,6 +650,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
 	.link_update = bnxt_link_update_op,
 	.promiscuous_enable = bnxt_promiscuous_enable_op,
 	.promiscuous_disable = bnxt_promiscuous_disable_op,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 38/40] bnxt: add RSS device operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (35 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 37/40] bnxt: add reta update/query operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 39/40] bnxt: add flow control operations Stephen Hurd
                                   ` (2 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add rss_hash_update and rss_hash_conf_get

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 117 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 2503112..d14fcae 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -62,6 +62,14 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.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)
+
 /***********************/
 
 /*
@@ -632,6 +640,113 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
 	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;
+	}
+	if (rss_conf->rss_hf & ETH_RSS_IPV4)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_IPV6)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+
+	/* 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;
+	uint32_t hash_types;
+
+	/* 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);
+		}
+
+		hash_types = vnic->hash_type;
+		rss_conf->rss_hf = 0;
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_IPV4;
+			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_IPV6;
+			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+		}
+		if (hash_types) {
+			RTE_LOG(ERR, PMD,
+				"Unknwon RSS config from firmware (%08x), RSS disabled",
+				vnic->hash_type);
+			return -ENOTSUP;
+		}
+	} else {
+		rss_conf->rss_hf = 0;
+	}
+	return 0;
+}
+
 /*
  * Initialization
  */
@@ -652,6 +767,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 39/40] bnxt: add flow control operations
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (36 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 38/40] bnxt: add RSS device operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-06 19:26                 ` [PATCH 40/40] bnxt: cleanup null pointer checks Stephen Hurd
  2016-05-11  4:53                 ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Panu Matilainen
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Add flow_ctrl_get and flow_ctrl_set device operations.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 83 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d14fcae..93dac7a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -747,6 +747,87 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
+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));
+	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
  */
@@ -776,6 +857,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.allmulticast_disable = bnxt_allmulticast_disable_op,
 	.mac_addr_add = bnxt_mac_addr_add_op,
 	.mac_addr_remove = bnxt_mac_addr_remove_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)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH 40/40] bnxt: cleanup null pointer checks
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (37 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 39/40] bnxt: add flow control operations Stephen Hurd
@ 2016-05-06 19:26                 ` Stephen Hurd
  2016-05-11  4:53                 ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Panu Matilainen
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-06 19:26 UTC (permalink / raw)
  To: dev

Prefer !ptr to ptr == NULL

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 10 +++++-----
 drivers/net/bnxt/bnxt_filter.c |  2 +-
 drivers/net/bnxt/bnxt_hwrm.c   |  6 +++---
 drivers/net/bnxt/bnxt_ring.c   |  2 +-
 drivers/net/bnxt/bnxt_vnic.c   |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 93dac7a..2f1a85a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -535,7 +535,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -549,7 +549,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -563,7 +563,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -577,7 +577,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -955,7 +955,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	}
 	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) {
+	if (!eth_dev->data->mac_addrs) {
 		RTE_LOG(ERR, PMD,
 			"Failed to alloc %u bytes needed to store MAC addr tbl",
 			ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR);
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index f03a1dc..d2576f7 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -165,7 +165,7 @@ int bnxt_alloc_filter_mem(struct bnxt *bp)
 	filter_mem = rte_zmalloc("bnxt_filter_info",
 				 max_filters * sizeof(struct bnxt_filter_info),
 				 0);
-	if (filter_mem == NULL) {
+	if (!filter_mem) {
 		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d filters",
 			max_filters);
 		return -ENOMEM;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1a1f108..8994c47 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -431,7 +431,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		rte_free(bp->hwrm_cmd_resp_addr);
 
 		bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0);
-		if (bp->hwrm_cmd_resp_addr == NULL) {
+		if (!bp->hwrm_cmd_resp_addr) {
 			rc = -ENOMEM;
 			goto error;
 		}
@@ -1171,7 +1171,7 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 	bp->max_req_len = HWRM_MAX_REQ_LEN;
 	bp->max_resp_len = HWRM_MAX_RESP_LEN;
 	bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
-	if (bp->hwrm_cmd_resp_addr == NULL)
+	if (!bp->hwrm_cmd_resp_addr)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
 		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
@@ -1211,7 +1211,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	struct bnxt_vnic_info *vnic;
 	unsigned i;
 
-	if (bp->vnic_info == NULL)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 8852e28..91f6371 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -143,7 +143,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
 					 RTE_MEMZONE_SIZE_HINT_ONLY);
-		if (mz == NULL)
+		if (!mz)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index c04c4c7..e957c0d 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -267,7 +267,7 @@ int bnxt_alloc_vnic_mem(struct bnxt *bp)
 	/* 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) {
+	if (!vnic_mem) {
 		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d VNICs",
 			max_vnics);
 		return -ENOMEM;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-06 19:25               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
                                   ` (38 preceding siblings ...)
  2016-05-06 19:26                 ` [PATCH 40/40] bnxt: cleanup null pointer checks Stephen Hurd
@ 2016-05-11  4:53                 ` Panu Matilainen
  2016-05-11 20:59                   ` Stephen Hurd
  39 siblings, 1 reply; 142+ messages in thread
From: Panu Matilainen @ 2016-05-11  4:53 UTC (permalink / raw)
  To: Stephen Hurd, dev

On 05/06/2016 10:25 PM, Stephen Hurd wrote:
> Initial skeleton simply fails init.
> Add nic guide and tie into build system.
>
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> ---
[...]
> diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
> new file mode 100644
> index 0000000..89b4a27
> --- /dev/null
> +++ b/drivers/net/bnxt/Makefile
> @@ -0,0 +1,63 @@
> +#   BSD LICENSE
> +#
> +#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
> +#   Copyright(c) 2014 6WIND S.A.
> +#   Copyright(c) Broadcom Limited.
> +#   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 += $(WERROR_FLAGS)
> +
> +EXPORT_MAP := rte_pmd_bnxt_version.map
> +
> +#
> +# all source are stored in SRCS-y
> +#
> +SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.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

librte_malloc got merged into librte_eal almost a year ago so it no 
longer exists at all [*], but still this keeps getting copy-pasted to 
new drivers, qede had this too :)

[*] See commits 2f9d47013e4d and aace9d0bcf58

	- Panu -

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-11  4:53                 ` [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                     ` [PATCH v2 " Stephen Hurd
  0 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-11 20:59 UTC (permalink / raw)
  To: Panu Matilainen; +Cc: dev

On Tue, May 10, 2016 at 9:53 PM, Panu Matilainen <pmatilai@redhat.com>
wrote:

> On 05/06/2016 10:25 PM, Stephen Hurd wrote:
>
>> +DEPDIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += lib/librte_malloc
>>
>
> librte_malloc got merged into librte_eal almost a year ago so it no longer
> exists at all [*], but still this keeps getting copy-pasted to new drivers,
> qede had this too :)
>

Thanks, will update.  This driver was originally developed for DPDK 1.8, so
the removal must have gotten lost in the updates.

-- Stephen Hurd

^ permalink raw reply	[flat|nested] 142+ messages in thread

* [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-11 20:59                   ` Stephen Hurd
@ 2016-05-13 22:45                     ` Stephen Hurd
  2016-05-13 22:45                       ` [PATCH v2 02/40] bnxt: add HWRM init code Stephen Hurd
                                         ` (39 more replies)
  0 siblings, 40 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Initial skeleton simply fails init.
Add nic guide and tie into build system.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
---
 MAINTAINERS                                     |   5 ++
 config/common_base                              |   5 ++
 doc/guides/nics/bnxt.rst                        |  49 +++++++++++
 drivers/net/Makefile                            |   1 +
 drivers/net/bnxt/Makefile                       |  63 ++++++++++++++
 drivers/net/bnxt/bnxt_ethdev.c                  | 104 ++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map       |   4 +
 lib/librte_eal/common/include/rte_pci_dev_ids.h |  40 +++++++--
 mk/rte.app.mk                                   |   1 +
 9 files changed, 267 insertions(+), 5 deletions(-)
 create mode 100644 doc/guides/nics/bnxt.rst
 create mode 100644 drivers/net/bnxt/Makefile
 create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map

diff --git a/MAINTAINERS b/MAINTAINERS
index ba4053a..c69b529 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -403,6 +403,11 @@ M: Declan Doherty <declan.doherty@intel.com>
 F: drivers/crypto/null/
 F: doc/guides/cryptodevs/null.rst
 
+Broadcom BNXT PMD
+M: Stephen Hurd <stephen.hurd@broadcom.com>
+F: drivers/net/bnxt/
+F: doc/guides/nics/bnxt.rst
+
 
 Packet processing
 -----------------
diff --git a/config/common_base b/config/common_base
index 3535c6e..08a19e1 100644
--- a/config/common_base
+++ b/config/common_base
@@ -245,6 +245,11 @@ CONFIG_RTE_LIBRTE_NFP_PMD=n
 CONFIG_RTE_LIBRTE_NFP_DEBUG=n
 
 #
+# Compile burst-oriented Broadcom BNXT PMD driver
+#
+CONFIG_RTE_LIBRTE_BNXT_PMD=y
+
+#
 # Compile software PMD backed by SZEDATA2 device
 #
 CONFIG_RTE_LIBRTE_PMD_SZEDATA2=n
diff --git a/doc/guides/nics/bnxt.rst b/doc/guides/nics/bnxt.rst
new file mode 100644
index 0000000..2669e98
--- /dev/null
+++ b/doc/guides/nics/bnxt.rst
@@ -0,0 +1,49 @@
+..  BSD LICENSE
+    Copyright 2016 Broadcom Limited
+
+    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 Limited 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.
+
+bnxt poll mode driver library
+=============================
+
+The bnxt poll mode library (**librte_pmd_bnxt**) implements support for
+**Broadcom NetXtreme® C-Series**.  These adapters support Standards-
+compliant 10/25/50Gbps 30MPPS full-duplex throughput.
+
+Information about this family of adapters can be found in the
+`NetXtreme® Brand section <https://www.broadcom.com/products/ethernet-communication-and-switching?technology%5B%5D=88>`_
+of the `Broadcom web site <http://www.broadcom.com/>`_.
+
+Limitations
+-----------
+
+With the current driver, allocated mbufs must be large enough to hold
+the entire received frame.  If the mbufs are not large enough, the
+packets will be dropped.  This is most limiting when jumbo frames are
+used.
+
+SR-IOV is not supported.
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 6ba7658..3832706 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -45,6 +45,7 @@ DIRS-$(CONFIG_RTE_LIBRTE_MLX4_PMD) += mlx4
 DIRS-$(CONFIG_RTE_LIBRTE_MLX5_PMD) += mlx5
 DIRS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD) += mpipe
 DIRS-$(CONFIG_RTE_LIBRTE_NFP_PMD) += nfp
+DIRS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_NULL) += null
 DIRS-$(CONFIG_RTE_LIBRTE_PMD_PCAP) += pcap
 DIRS-$(CONFIG_RTE_LIBRTE_QEDE_PMD) += qede
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
new file mode 100644
index 0000000..f6333fd
--- /dev/null
+++ b/drivers/net/bnxt/Makefile
@@ -0,0 +1,63 @@
+#   BSD LICENSE
+#
+#   Copyright(c) 2010-2014 Intel Corporation. All rights reserved.
+#   Copyright(c) 2014 6WIND S.A.
+#   Copyright(c) Broadcom Limited.
+#   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 += $(WERROR_FLAGS)
+
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
+#
+# all source are stored in SRCS-y
+#
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.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_eal
+
+include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
new file mode 100644
index 0000000..d6c0d51
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -0,0 +1,104 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+#define DRV_MODULE_NAME		"bnxt"
+static const char bnxt_version[] =
+	"Broadcom Cumulus driver " DRV_MODULE_NAME "\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},
+};
+
+/*
+ * Initialization
+ */
+
+static int
+bnxt_dev_init(struct rte_eth_dev *eth_dev)
+{
+	static int version_printed;
+
+	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);
+	return -EPERM;
+}
+
+static int
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused) {
+	return 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 = 32 /* this must be non-zero apparently */,
+};
+
+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/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
new file mode 100644
index 0000000..349c6e1
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -0,0 +1,4 @@
+DPDK_16.04 {
+
+	local: *;
+};
diff --git a/lib/librte_eal/common/include/rte_pci_dev_ids.h b/lib/librte_eal/common/include/rte_pci_dev_ids.h
index cf7b548..af26e11 100644
--- a/lib/librte_eal/common/include/rte_pci_dev_ids.h
+++ b/lib/librte_eal/common/include/rte_pci_dev_ids.h
@@ -63,11 +63,12 @@
  * This file contains a list of the PCI device IDs recognised by DPDK, which
  * can be used to fill out an array of structures describing the devices.
  *
- * Currently four families of devices are recognised: those supported by the
- * IGB driver, by EM driver, those supported by the IXGBE driver, and by virtio
- * driver which is a para virtualization driver running in guest virtual machine.
- * The inclusion of these in an array built using this file depends on the
- * definition of
+ * Currently five families of devices are recognised: those supported by the
+ * IGB driver, by EM driver, those supported by the IXGBE driver, those
+ * supported by the BNXT driver, and by virtio driver which is a para
+ * virtualization driver running in guest virtual machine. The inclusion of
+ * these in an array built using this file depends on the definition of
+ * RTE_PCI_DEV_ID_DECL_BNXT
  * RTE_PCI_DEV_ID_DECL_EM
  * RTE_PCI_DEV_ID_DECL_IGB
  * RTE_PCI_DEV_ID_DECL_IGBVF
@@ -152,6 +153,10 @@
 #define RTE_PCI_DEV_ID_DECL_BNX2XVF(vend, dev)
 #endif
 
+#ifndef RTE_PCI_DEV_ID_DECL_BNXT
+#define RTE_PCI_DEV_ID_DECL_BNXT(vend, dev)
+#endif
+
 #ifndef PCI_VENDOR_ID_INTEL
 /** Vendor ID used by Intel devices */
 #define PCI_VENDOR_ID_INTEL 0x8086
@@ -686,6 +691,30 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57811_MF)
 RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #endif
 
+/****************** Broadcom bnxt devices ******************/
+
+#define BROADCOM_DEV_ID_57301                  0x16c8
+#define BROADCOM_DEV_ID_57302                  0x16c9
+#define BROADCOM_DEV_ID_57304_PF               0x16ca
+#define BROADCOM_DEV_ID_57304_VF               0x16cb
+#define BROADCOM_DEV_ID_57304_MF               0x16cc
+#define BROADCOM_DEV_ID_57402                  0x16d0
+#define BROADCOM_DEV_ID_57404                  0x16d1
+#define BROADCOM_DEV_ID_57406_PF               0x16d2
+#define BROADCOM_DEV_ID_57406_VF               0x16d3
+#define BROADCOM_DEV_ID_57406_MF               0x16d4
+
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57301)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57302)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57304_MF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57402)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57404)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_PF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_VF)
+RTE_PCI_DEV_ID_DECL_BNXT(PCI_VENDOR_ID_BROADCOM, BROADCOM_DEV_ID_57406_MF)
+
 /*
  * Undef all RTE_PCI_DEV_ID_DECL_* here.
  */
@@ -702,3 +731,4 @@ RTE_PCI_DEV_ID_DECL_BNX2X(PCI_VENDOR_ID_BROADCOM, BNX2X_DEV_ID_57840_MF)
 #undef RTE_PCI_DEV_ID_DECL_VMXNET3
 #undef RTE_PCI_DEV_ID_DECL_FM10K
 #undef RTE_PCI_DEV_ID_DECL_FM10KVF
+#undef RTE_PCI_DEV_ID_DECL_BNXT
diff --git a/mk/rte.app.mk b/mk/rte.app.mk
index 7f364d3..9eefbdc 100644
--- a/mk/rte.app.mk
+++ b/mk/rte.app.mk
@@ -143,6 +143,7 @@ _LDLIBS-$(CONFIG_RTE_LIBRTE_ENA_PMD)        += -lrte_pmd_ena
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX4_PMD)       += -lrte_pmd_mlx4
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MLX5_PMD)       += -lrte_pmd_mlx5
 _LDLIBS-$(CONFIG_RTE_LIBRTE_NFP_PMD)        += -lrte_pmd_nfp
+_LDLIBS-$(CONFIG_RTE_LIBRTE_BNXT_PMD)       += -lrte_pmd_bnxt
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_SZEDATA2)   += -lrte_pmd_szedata2
 _LDLIBS-$(CONFIG_RTE_LIBRTE_MPIPE_PMD)      += -lrte_pmd_mpipe
 _LDLIBS-$(CONFIG_RTE_LIBRTE_PMD_RING)       += -lrte_pmd_ring
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 02/40] bnxt: add HWRM init code
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 15:05                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 03/40] bnxt: add driver register/unregister support Stephen Hurd
                                         ` (38 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Start adding HWRM support.
Initial commit just performs necessary HWRM queries for init, then
fails as before.

Thee used HWRM calls so far:
bnxt_hwrm_func_qcaps:
	Queries device capabilities.

bnxt_hwrm_ver_get:
	Gets the firmware version and interface specifications.
	Returns an error if the firmware on the device is not
	supported by the driver and ensures the response space
	is large enough for the largest possible response.

bnxt_hwrm_queue_qportcfg:
	Required to get the default queue ID.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: David Christensen <david.christensen@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                | 114 ++++
 drivers/net/bnxt/bnxt_ethdev.c         | 113 ++++
 drivers/net/bnxt/bnxt_hwrm.c           | 324 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  53 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 954 +++++++++++++++++++++++++++++++++
 6 files changed, 1559 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt.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/hsi_struct_def_dpdk.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index f6333fd..9965597 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -49,6 +49,7 @@ 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
 
 #
 # Export include files
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
new file mode 100644
index 0000000..0f816ed
--- /dev/null
+++ b/drivers/net/bnxt/bnxt.h
@@ -0,0 +1,114 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+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;
+};
+
+#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_VF		(1<<1)
+#define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
+#define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
+
+#define MAX_NUM_MAC_ADDR	32
+	uint8_t			mac_addr[ETHER_ADDR_LEN];
+
+	uint16_t			hwrm_cmd_seq;
+	void				*hwrm_cmd_resp_addr;
+	phys_addr_t			hwrm_cmd_resp_dma_addr;
+	rte_spinlock_t			hwrm_lock;
+	uint16_t			max_req_len;
+	uint16_t			max_resp_len;
+
+	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
+
+	struct bnxt_pf_info		pf;
+	struct bnxt_vf_info		vf;
+};
+
+#endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d6c0d51..a74cc6c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -39,6 +39,9 @@
 #include <rte_malloc.h>
 #include <rte_cycles.h>
 
+#include "bnxt.h"
+#include "bnxt_hwrm.h"
+
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
 	"Broadcom Cumulus driver " DRV_MODULE_NAME "\n";
@@ -49,14 +52,69 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	rte_free(eth_dev->data->mac_addrs);
+	bnxt_free_hwrm_resources(bp);
+}
+
 /*
  * Initialization
  */
 
+static struct eth_dev_ops bnxt_dev_ops = {
+	.dev_close = bnxt_dev_close_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);
@@ -69,7 +127,62 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	}
 
 	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(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
 	return -EPERM;
+
+error_free:
+	bnxt_dev_close_op(eth_dev);
+error:
+	return rc;
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
new file mode 100644
index 0000000..5b66721
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -0,0 +1,324 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_hwrm.h"
+#include "hsi_struct_def_dpdk.h"
+
+#define HWRM_CMD_TIMEOUT		2000
+
+/*
+ * 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_locked(struct bnxt *bp, void *msg,
+					uint32_t msg_len)
+{
+	unsigned i;
+	struct input *req = msg;
+	struct output *resp = bp->hwrm_cmd_resp_addr;
+	uint32_t *data = msg;
+	uint8_t *bar;
+	uint8_t *valid;
+
+	/* 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++;
+	}
+
+	/* Zero the rest of the request space */
+	for (; i < bp->max_req_len; i += 4) {
+		bar = (uint8_t *)bp->bar0 + i;
+		*(volatile uint32_t *)bar = 0;
+	}
+
+	/* Ring channel doorbell */
+	bar = (uint8_t *)bp->bar0 + 0x100;
+	*(volatile uint32_t *)bar = 1;
+
+	/* Poll for the valid bit */
+	for (i = 0; i < HWRM_CMD_TIMEOUT; i++) {
+		/* Sanity check on the resp->resp_len */
+		rte_rmb();
+		if (resp->resp_len && resp->resp_len <=
+		    bp->max_resp_len) {
+			/* 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;
+	}
+	return 0;
+
+err_ret:
+	return -1;
+}
+
+static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
+{
+	int rc;
+
+	rte_spinlock_lock(&bp->hwrm_lock);
+	rc = bnxt_hwrm_send_message_locked(bp, msg, msg_len);
+	rte_spinlock_unlock(&bp->hwrm_lock);
+	return rc;
+}
+
+#define HWRM_PREP(req, type, cr, resp) \
+	memset(bp->hwrm_cmd_resp_addr, 0, bp->max_resp_len); \
+	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_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_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;
+	uint16_t max_resp_len;
+	char type[RTE_MEMZONE_NAMESIZE];
+
+	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;
+
+	/*
+	 * Hold the lock since we may be adjusting the response pointers.
+	 */
+	rte_spinlock_lock(&bp->hwrm_lock);
+	rc = bnxt_hwrm_send_message_locked(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 (resp->hwrm_intf_maj != HWRM_VERSION_MAJOR) {
+		RTE_LOG(ERR, PMD, "Unsupported firmware API version\n");
+		rc = -EINVAL;
+		goto error;
+	}
+
+	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");
+		}
+	}
+
+	if (bp->max_req_len > resp->max_req_win_len) {
+		RTE_LOG(ERR, PMD, "Unsupported request length\n");
+		rc = -EINVAL;
+	}
+	bp->max_req_len = resp->max_req_win_len;
+	max_resp_len = resp->max_resp_len;
+	if (bp->max_resp_len != max_resp_len) {
+		sprintf(type, "bnxt_hwrm_%04x:%02x:%02x:%02x",
+			bp->pdev->addr.domain, bp->pdev->addr.bus,
+			bp->pdev->addr.devid, bp->pdev->addr.function);
+
+		rte_free(bp->hwrm_cmd_resp_addr);
+
+		bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0);
+		if (bp->hwrm_cmd_resp_addr == NULL) {
+			rc = -ENOMEM;
+			goto error;
+		}
+		bp->hwrm_cmd_resp_dma_addr =
+			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		bp->max_resp_len = max_resp_len;
+	}
+
+error:
+	rte_spinlock_unlock(&bp->hwrm_lock);
+	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;
+}
+
+/*
+ * HWRM utility functions
+ */
+
+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->max_req_len = HWRM_MAX_REQ_LEN;
+	bp->max_resp_len = HWRM_MAX_RESP_LEN;
+	bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
+	if (bp->hwrm_cmd_resp_addr == NULL)
+		return -ENOMEM;
+	bp->hwrm_cmd_resp_dma_addr =
+		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+	rte_spinlock_init(&bp->hwrm_lock);
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
new file mode 100644
index 0000000..e35e8c0
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -0,0 +1,53 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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>
+
+#include "bnxt.h"
+
+#define HWRM_SEQ_ID_INVALID -1U
+
+int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+
+int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
+
+int bnxt_hwrm_ver_get(struct bnxt *bp);
+
+void bnxt_free_hwrm_resources(struct bnxt *bp);
+int bnxt_alloc_hwrm_resources(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..1667927
--- /dev/null
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -0,0 +1,954 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_EXTERNAL_H_
+#define _HSI_STRUCT_DEF_EXTERNAL_H_
+
+/* HW Resource Manager Specification 1.2.0 */
+#define HWRM_VERSION_MAJOR	1
+#define HWRM_VERSION_MINOR	2
+#define HWRM_VERSION_UPDATE	0
+
+/*
+ * Following is the signature for HWRM message field that indicates not
+ * applicable (All F's). Need to cast it the size of the field if needed.
+ */
+#define HWRM_MAX_REQ_LEN	(128)  /* hwrm_func_buf_rgtr */
+#define HWRM_MAX_RESP_LEN	(176)  /* hwrm_func_qstats */
+#define HWRM_RESP_VALID_KEY	1 /* valid key for HWRM response */
+
+/*
+ * Request types
+ */
+#define HWRM_VER_GET                                      (UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS                                   (UINT32_C(0x15))
+#define HWRM_QUEUE_QPORTCFG                               (UINT32_C(0x30))
+
+/*
+ * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
+ * inside the chip. The HWRM is implemented in firmware, and runs on embedded
+ * processors inside the chip. This firmware is vital part of the chip's
+ * hardware. The chip can not be used by driver without it.
+ */
+
+/* Input (16 bytes) */
+struct input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+} __attribute__((packed));
+
+/* Output (8 bytes) */
+struct output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+} __attribute__((packed));
+
+/* hwrm_func_qcaps */
+/*
+ * Description: This command returns capabilities of a function. The input FID
+ * value is used to indicate what function is being queried. This allows a
+ * physical function driver to query virtual functions that are children of the
+ * physical function. The output FID value is needed to configure Rings and
+ * MSI-X vectors so their DMA operations appear correctly on the PCI bus.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_func_qcaps_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Function ID of the function that is being queried. 0xFF... (All Fs)
+	 * if the query is for the requesting function.
+	 */
+	uint16_t fid;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (80 bytes) */
+struct hwrm_func_qcaps_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * FID value. This value is used to identify operations on the PCI bus
+	 * as belonging to a particular PCI function.
+	 */
+	uint16_t fid;
+
+	/*
+	 * Port ID of port that this function is associated with. Valid only for
+	 * the PF. 0xFF... (All Fs) if this function is not associated with any
+	 * port. 0xFF... (All Fs) if this function is called from a VF.
+	 */
+	uint16_t port_id;
+
+	/* If 1, then Push mode is supported on this function. */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED   UINT32_C(0x1)
+	/*
+	 * If 1, then the global MSI-X auto-masking is enabled for the device.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING \
+								UINT32_C(0x2)
+	/*
+	 * If 1, then the Precision Time Protocol (PTP) processing is supported
+	 * on this function. The HWRM should enable PTP on only a single
+	 * Physical Function (PF) per port.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED         UINT32_C(0x4)
+	uint32_t flags;
+
+	/*
+	 * This value is current MAC address configured for this function. A
+	 * value of 00-00-00-00-00-00 indicates no MAC address is currently
+	 * configured.
+	 */
+	uint8_t perm_mac_address[6];
+
+	/*
+	 * The maximum number of RSS/COS contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_rsscos_ctx;
+
+	/*
+	 * The maximum number of completion rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_cmpl_rings;
+
+	/*
+	 * The maximum number of transmit rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_tx_rings;
+
+	/*
+	 * The maximum number of receive rings that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_rx_rings;
+
+	/*
+	 * The maximum number of L2 contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_l2_ctxs;
+
+	/* The maximum number of VNICs that can be allocated to the function. */
+	uint16_t max_vnics;
+
+	/*
+	 * The identifier for the first VF enabled on a PF. This is valid only
+	 * on the PF with SR-IOV enabled. 0xFF... (All Fs) if this command is
+	 * called on a PF with SR-IOV disabled or on a VF.
+	 */
+	uint16_t first_vf_id;
+
+	/*
+	 * The maximum number of VFs that can be allocated to the function. This
+	 * is valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if this
+	 * command is called on a PF with SR-IOV disabled or on a VF.
+	 */
+	uint16_t max_vfs;
+
+	/*
+	 * The maximum number of statistic contexts that can be allocated to the
+	 * function.
+	 */
+	uint16_t max_stat_ctx;
+
+	/*
+	 * The maximum number of Encapsulation records that can be offloaded by
+	 * this function.
+	 */
+	uint32_t max_encap_records;
+
+	/*
+	 * The maximum number of decapsulation records that can be offloaded by
+	 * this function.
+	 */
+	uint32_t max_decap_records;
+
+	/*
+	 * The maximum number of Exact Match (EM) flows that can be offloaded by
+	 * this function on the TX side.
+	 */
+	uint32_t max_tx_em_flows;
+
+	/*
+	 * The maximum number of Wildcard Match (WM) flows that can be offloaded
+	 * by this function on the TX side.
+	 */
+	uint32_t max_tx_wm_flows;
+
+	/*
+	 * The maximum number of Exact Match (EM) flows that can be offloaded by
+	 * this function on the RX side.
+	 */
+	uint32_t max_rx_em_flows;
+
+	/*
+	 * The maximum number of Wildcard Match (WM) flows that can be offloaded
+	 * by this function on the RX side.
+	 */
+	uint32_t max_rx_wm_flows;
+
+	/*
+	 * The maximum number of multicast filters that can be supported by this
+	 * function on the RX side.
+	 */
+	uint32_t max_mcast_filters;
+
+	/*
+	 * The maximum value of flow_id that can be supported in completion
+	 * records.
+	 */
+	uint32_t max_flow_id;
+
+	/*
+	 * The maximum number of HW ring groups that can be supported on this
+	 * function.
+	 */
+	uint32_t max_hw_ring_grps;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ver_get */
+/*
+ * Description: This function is called by a driver to determine the HWRM
+ * interface version supported by the HWRM firmware, the version of HWRM
+ * firmware implementation, the name of HWRM firmware, the versions of other
+ * embedded firmwares, and the names of other embedded firmwares, etc. Any
+ * interface or firmware version with major = 0, minor = 0, and update = 0 shall
+ * be considered an invalid version.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ver_get_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This field represents the major version of HWRM interface
+	 * specification supported by the driver HWRM implementation. The
+	 * interface major version is intended to change only when non backward
+	 * compatible changes are made to the HWRM interface specification.
+	 */
+	uint8_t hwrm_intf_maj;
+
+	/*
+	 * This field represents the minor version of HWRM interface
+	 * specification supported by the driver HWRM implementation. A change
+	 * in interface minor version is used to reflect significant backward
+	 * compatible modification to HWRM interface specification. This can be
+	 * due to addition or removal of functionality. HWRM interface
+	 * specifications with the same major version but different minor
+	 * versions are compatible.
+	 */
+	uint8_t hwrm_intf_min;
+
+	/*
+	 * This field represents the update version of HWRM interface
+	 * specification supported by the driver HWRM implementation. The
+	 * interface update version is used to reflect minor changes or bug
+	 * fixes to a released HWRM interface specification.
+	 */
+	uint8_t hwrm_intf_upd;
+
+	uint8_t unused_0[5];
+} __attribute__((packed));
+
+/* Output (128 bytes) */
+struct hwrm_ver_get_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This field represents the major version of HWRM interface
+	 * specification supported by the HWRM implementation. The interface
+	 * major version is intended to change only when non backward compatible
+	 * changes are made to the HWRM interface specification. A HWRM
+	 * implementation that is compliant with this specification shall
+	 * provide value of 1 in this field.
+	 */
+	uint8_t hwrm_intf_maj;
+
+	/*
+	 * This field represents the minor version of HWRM interface
+	 * specification supported by the HWRM implementation. A change in
+	 * interface minor version is used to reflect significant backward
+	 * compatible modification to HWRM interface specification. This can be
+	 * due to addition or removal of functionality. HWRM interface
+	 * specifications with the same major version but different minor
+	 * versions are compatible. A HWRM implementation that is compliant with
+	 * this specification shall provide value of 0 in this field.
+	 */
+	uint8_t hwrm_intf_min;
+
+	/*
+	 * This field represents the update version of HWRM interface
+	 * specification supported by the HWRM implementation. The interface
+	 * update version is used to reflect minor changes or bug fixes to a
+	 * released HWRM interface specification. A HWRM implementation that is
+	 * compliant with this specification shall provide value of 1 in this
+	 * field.
+	 */
+	uint8_t hwrm_intf_upd;
+
+	uint8_t hwrm_intf_rsvd;
+
+	/*
+	 * This field represents the major version of HWRM firmware. A change in
+	 * firmware major version represents a major firmware release.
+	 */
+	uint8_t hwrm_fw_maj;
+
+	/*
+	 * This field represents the minor version of HWRM firmware. A change in
+	 * firmware minor version represents significant firmware functionality
+	 * changes.
+	 */
+	uint8_t hwrm_fw_min;
+
+	/*
+	 * This field represents the build version of HWRM firmware. A change in
+	 * firmware build version represents bug fixes to a released firmware.
+	 */
+	uint8_t hwrm_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version of the HWRM firmware.
+	 */
+	uint8_t hwrm_fw_rsvd;
+
+	/*
+	 * This field represents the major version of mgmt firmware. A change in
+	 * major version represents a major release.
+	 */
+	uint8_t mgmt_fw_maj;
+
+	/*
+	 * This field represents the minor version of mgmt firmware. A change in
+	 * minor version represents significant functionality changes.
+	 */
+	uint8_t mgmt_fw_min;
+
+	/*
+	 * This field represents the build version of mgmt firmware. A change in
+	 * update version represents bug fixes.
+	 */
+	uint8_t mgmt_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t mgmt_fw_rsvd;
+
+	/*
+	 * This field represents the major version of network control firmware.
+	 * A change in major version represents a major release.
+	 */
+	uint8_t netctrl_fw_maj;
+
+	/*
+	 * This field represents the minor version of network control firmware.
+	 * A change in minor version represents significant functionality
+	 * changes.
+	 */
+	uint8_t netctrl_fw_min;
+
+	/*
+	 * This field represents the build version of network control firmware.
+	 * A change in update version represents bug fixes.
+	 */
+	uint8_t netctrl_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t netctrl_fw_rsvd;
+
+	/*
+	 * This field is reserved for future use. The responder should set it to
+	 * 0. The requester should ignore this field.
+	 */
+	uint32_t reserved1;
+
+	/*
+	 * This field represents the major version of RoCE firmware. A change in
+	 * major version represents a major release.
+	 */
+	uint8_t roce_fw_maj;
+
+	/*
+	 * This field represents the minor version of RoCE firmware. A change in
+	 * minor version represents significant functionality changes.
+	 */
+	uint8_t roce_fw_min;
+
+	/*
+	 * This field represents the build version of RoCE firmware. A change in
+	 * update version represents bug fixes.
+	 */
+	uint8_t roce_fw_bld;
+
+	/*
+	 * This field is a reserved field. This field can be used to represent
+	 * firmware branches or customer specific releases tied to a specific
+	 * (major,minor,update) version
+	 */
+	uint8_t roce_fw_rsvd;
+
+	/*
+	 * This field represents the name of HWRM FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char hwrm_fw_name[16];
+
+	/*
+	 * This field represents the name of mgmt FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char mgmt_fw_name[16];
+
+	/*
+	 * This field represents the name of network control firmware (ASCII
+	 * chars without NULL at the end).
+	 */
+	char netctrl_fw_name[16];
+
+	/*
+	 * This field is reserved for future use. The responder should set it to
+	 * 0. The requester should ignore this field.
+	 */
+	uint32_t reserved2[4];
+
+	/*
+	 * This field represents the name of RoCE FW (ASCII chars without NULL
+	 * at the end).
+	 */
+	char roce_fw_name[16];
+
+	/* This field returns the chip number. */
+	uint16_t chip_num;
+
+	/* This field returns the revision of chip. */
+	uint8_t chip_rev;
+
+	/* This field returns the chip metal number. */
+	uint8_t chip_metal;
+
+	/* This field returns the bond id of the chip. */
+	uint8_t chip_bond_id;
+
+	/*
+	 * This value indicates the type of platform used for chip
+	 * implementation.
+	 */
+	/* ASIC */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_ASIC \
+							(UINT32_C(0x0) << 0)
+	/* FPGA platform of the chip. */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA \
+							(UINT32_C(0x1) << 0)
+	/* Palladium platform of the chip. */
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM \
+							(UINT32_C(0x2) << 0)
+	uint8_t chip_platform_type;
+
+	/*
+	 * This field returns the maximum value of request window that is
+	 * supported by the HWRM. The request window is mapped into device
+	 * address space using MMIO.
+	 */
+	uint16_t max_req_win_len;
+
+	/*
+	 * This field returns the maximum value of response buffer in bytes. If
+	 * a request specifies the response buffer length that is greater than
+	 * this value, then the HWRM should fail it. The value of this field
+	 * shall be 4KB or more.
+	 */
+	uint16_t max_resp_len;
+
+	/*
+	 * This field returns the default request timeout value in milliseconds.
+	 */
+	uint16_t def_req_timeout;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_queue_qportcfg */
+/*
+ * Description: This function is called by a driver to query queue configuration
+ * of a port. # The HWRM shall at least advertise one queue with lossy service
+ * profile. # The driver shall use this command to query queue ids before
+ * configuring or using any queues. # If a service profile is not set for a
+ * queue, then the driver shall not use that queue without configuring a service
+ * profile for it. # If the driver is not allowed to configure service profiles,
+ * then the driver shall only use queues for which service profiles are pre-
+ * configured.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_queue_qportcfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Enumeration denoting the RX, TX type of the resource. This
+	 * enumeration is used for resources that are similar for both TX and RX
+	 * paths of the chip.
+	 */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH \
+							UINT32_C(0x1)
+		/* tx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX \
+							(UINT32_C(0x0) << 0)
+		/* rx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX \
+							(UINT32_C(0x1) << 0)
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+					HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+	uint32_t flags;
+
+	/*
+	 * Port ID of port for which the queue configuration is being queried.
+	 * This field is only required when sent by IPC.
+	 */
+	uint16_t port_id;
+
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output (32 bytes) */
+struct hwrm_queue_qportcfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* The maximum number of queues that can be configured. */
+	uint8_t max_configurable_queues;
+
+	/* The maximum number of lossless queues that can be configured. */
+	uint8_t max_configurable_lossless_queues;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed. If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure queues using
+	 * hwrm_queue_cfg.
+	 */
+	uint8_t queue_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure queue buffers
+	 * using hwrm_queue_buffers_cfg.
+	 */
+	uint8_t queue_buffers_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure PFC using
+	 * hwrm_queue_pfcenable_cfg.
+	 */
+	uint8_t queue_pfcenable_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure Priority to CoS
+	 * mapping using hwrm_queue_pri2cos_cfg.
+	 */
+	uint8_t queue_pri2cos_cfg_allowed;
+
+	/*
+	 * 0 - Not allowed. Non-zero - Allowed If this value is non-zero, then
+	 * the HWRM shall allow the host SW driver to configure CoS Bandwidth
+	 * configuration using hwrm_queue_cos2bw_cfg.
+	 */
+	uint8_t queue_cos2bw_cfg_allowed;
+
+	/* ID of CoS Queue 0. FF - Invalid id */
+	uint8_t queue_id0;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id0_service_profile;
+
+	/* ID of CoS Queue 1. FF - Invalid id */
+	uint8_t queue_id1;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id1_service_profile;
+
+	/* ID of CoS Queue 2. FF - Invalid id */
+	uint8_t queue_id2;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id2_service_profile;
+
+	/* ID of CoS Queue 3. FF - Invalid id */
+	uint8_t queue_id3;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id3_service_profile;
+
+	/* ID of CoS Queue 4. FF - Invalid id */
+	uint8_t queue_id4;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id4_service_profile;
+
+	/* ID of CoS Queue 5. FF - Invalid id */
+	uint8_t queue_id5;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id5_service_profile;
+
+	/* ID of CoS Queue 6. FF - Invalid id */
+	uint8_t queue_id6_service_profile;
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id6;
+
+	/* ID of CoS Queue 7. FF - Invalid id */
+	uint8_t queue_id7;
+
+	/* This value is applicable to CoS queues only. */
+		/* Lossy (best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+							(UINT32_C(0x0) << 0)
+		/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Set to 0xFF... (All Fs) if there is no service profile
+		 * specified
+		 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+							(UINT32_C(0xff) << 0)
+	uint8_t queue_id7_service_profile;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 03/40] bnxt: add driver register/unregister support
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
  2016-05-13 22:45                       ` [PATCH v2 02/40] bnxt: add HWRM init code Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 15:11                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 04/40] bnxt: add dev infos get operation Stephen Hurd
                                         ` (37 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Move init() cleanup into uninit() function
Fix .dev_private_size
Add require hwrm calls:
	bnxt_hwrm_func_driver_register()
	bnxt_hwrm_func_driver_unregister()

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   1 +
 drivers/net/bnxt/bnxt_ethdev.c         |  48 ++++--
 drivers/net/bnxt/bnxt_hwrm.c           |  50 ++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 277 ++++++++++++++++++++++++++++++++-
 5 files changed, 359 insertions(+), 20 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 0f816ed..ebddeab 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -91,6 +91,7 @@ struct bnxt {
 	struct rte_pci_device		*pdev;
 
 	uint32_t		flags;
+#define BNXT_FLAG_REGISTERED	(1<<0)
 #define BNXT_FLAG_VF		(1<<1)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a74cc6c..07519df 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -52,20 +52,12 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
-static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
-{
-	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-
-	rte_free(eth_dev->data->mac_addrs);
-	bnxt_free_hwrm_resources(bp);
-}
-
 /*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
-	.dev_close = bnxt_dev_close_op,
+0
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -123,7 +115,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 			eth_dev->pci_dev->addr.function < 4) {
 		RTE_LOG(ERR, PMD, "Function not enabled %x:\n",
 			eth_dev->pci_dev->addr.function);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto error;
 	}
 
 	rte_eth_copy_pci_info(eth_dev, eth_dev->pci_dev);
@@ -148,11 +141,11 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"hwrm resource allocation failure rc: %x\n", rc);
-		goto error;
+		goto error_free;
 	}
 	rc = bnxt_hwrm_ver_get(bp);
 	if (rc)
-		goto error;
+		goto error_free;
 	bnxt_hwrm_queue_qportcfg(bp);
 
 	/* Get the MAX capabilities for this function */
@@ -177,17 +170,38 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
 
-	return -EPERM;
+	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);
+	eth_dev->driver->eth_dev_uninit(eth_dev);
 error:
 	return rc;
 }
 
 static int
-bnxt_dev_uninit(struct rte_eth_dev *eth_dev __rte_unused) {
-	return 0;
+bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
+	struct bnxt *bp = eth_dev->data->dev_private;
+	int rc;
+
+	if (eth_dev->data->mac_addrs)
+		rte_free(eth_dev->data->mac_addrs);
+	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
+	bnxt_free_hwrm_resources(bp);
+	return rc;
 }
 
 static struct eth_driver bnxt_rte_pmd = {
@@ -198,7 +212,7 @@ static struct eth_driver bnxt_rte_pmd = {
 		    },
 	.eth_dev_init = bnxt_dev_init,
 	.eth_dev_uninit = bnxt_dev_uninit,
-	.dev_private_size = 32 /* this must be non-zero apparently */,
+	.dev_private_size = sizeof(struct bnxt),
 };
 
 static int bnxt_rte_pmd_init(const char *name, const char *params __rte_unused)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 5b66721..398f0f5 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -36,6 +36,7 @@
 #include <rte_cycles.h>
 #include <rte_malloc.h>
 #include <rte_memzone.h>
+#include <rte_version.h>
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
@@ -178,6 +179,34 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	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;
+
+	if (bp->flags & BNXT_FLAG_REGISTERED)
+		return 0;
+
+	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
+	req.flags = flags;
+	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER;
+	req.ver_maj = RTE_VER_YEAR;
+	req.ver_min = RTE_VER_MONTH;
+	req.ver_upd = RTE_VER_MINOR;
+
+	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;
+
+	bp->flags |= BNXT_FLAG_REGISTERED;
+
+	return rc;
+}
+
 int bnxt_hwrm_ver_get(struct bnxt *bp)
 {
 	int rc = 0;
@@ -264,6 +293,27 @@ error:
 	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;
+
+	if (!(bp->flags & BNXT_FLAG_REGISTERED))
+		return 0;
+
+	HWRM_PREP(req, FUNC_DRV_UNRGTR, -1, resp);
+	req.flags = flags;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	bp->flags &= ~BNXT_FLAG_REGISTERED;
+
+	return rc;
+}
+
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index e35e8c0..6f2e445 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,7 +41,10 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
+				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 1667927..be3ed0f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -50,9 +50,11 @@
 /*
  * Request types
  */
-#define HWRM_VER_GET                                      (UINT32_C(0x0))
-#define HWRM_FUNC_QCAPS                                   (UINT32_C(0x15))
-#define HWRM_QUEUE_QPORTCFG                               (UINT32_C(0x30))
+#define HWRM_VER_GET		(UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
+#define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
+#define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
+#define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
  * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
@@ -951,4 +953,273 @@ struct hwrm_queue_qportcfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_func_drv_rgtr */
+/*
+ * Description: This command is used by the function driver to register its
+ * information with the HWRM. A function driver shall implement this command. A
+ * function driver shall use this command during the driver initialization right
+ * after the HWRM version discovery and default ring resources allocation.
+ */
+
+/* Input (80 bytes) */
+struct hwrm_func_drv_rgtr_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the function driver is requesting all requests
+	 * from its children VF drivers to be forwarded to itself. This flag can
+	 * only be set by the PF driver. If a VF driver sets this flag, it
+	 * should be ignored by the HWRM.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_ALL_MODE        UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the function is requesting none of the requests
+	 * from its children VF drivers to be forwarded to itself. This flag can
+	 * only be set by the PF driver. If a VF driver sets this flag, it
+	 * should be ignored by the HWRM.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_FLAGS_FWD_NONE_MODE       UINT32_C(0x2)
+	uint32_t flags;
+
+	/* This bit must be '1' for the os_type field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_OS_TYPE           UINT32_C(0x1)
+	/* This bit must be '1' for the ver field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER               UINT32_C(0x2)
+	/* This bit must be '1' for the timestamp field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_TIMESTAMP         UINT32_C(0x4)
+	/* This bit must be '1' for the vf_req_fwd field to be configured. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_REQ_FWD        UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the async_event_fwd field to be configured.
+	 */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD \
+								UINT32_C(0x10)
+	uint32_t enables;
+
+	/* This value indicates the type of OS. */
+		/* Unknown */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* Other OS not listed below. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER \
+							(UINT32_C(0x1) << 0)
+		/* MSDOS OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS \
+							(UINT32_C(0xe) << 0)
+		/* Windows OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS \
+							(UINT32_C(0x12) << 0)
+		/* Solaris OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS \
+							(UINT32_C(0x1d) << 0)
+		/* Linux OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX \
+							(UINT32_C(0x24) << 0)
+		/* FreeBSD OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD \
+							(UINT32_C(0x2a) << 0)
+		/* VMware ESXi OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI \
+							(UINT32_C(0x68) << 0)
+		/* Microsoft Windows 8 64-bit OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864 \
+							(UINT32_C(0x73) << 0)
+		/* Microsoft Windows Server 2012 R2 OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2 \
+							(UINT32_C(0x74) << 0)
+	uint16_t os_type;
+
+	/* This is the major version of the driver. */
+	uint8_t ver_maj;
+
+	/* This is the minor version of the driver. */
+	uint8_t ver_min;
+
+	/* This is the update version of the driver. */
+	uint8_t ver_upd;
+
+	uint8_t unused_0;
+	uint16_t unused_1;
+
+	/*
+	 * This is a 32-bit timestamp provided by the driver for keep alive. The
+	 * timestamp is in multiples of 1ms.
+	 */
+	uint32_t timestamp;
+
+	uint32_t unused_2;
+
+	/*
+	 * This is a 256-bit bit mask provided by the PF driver for letting the
+	 * HWRM know what commands issued by the VF driver to the HWRM should be
+	 * forwarded to the PF driver. Nth bit refers to the Nth req_type.
+	 * Setting Nth bit to 1 indicates that requests from the VF driver with
+	 * req_type equal to N shall be forwarded to the parent PF driver. This
+	 * field is not valid for the VF driver.
+	 */
+	uint32_t vf_req_fwd[8];
+
+	/*
+	 * This is a 256-bit bit mask provided by the function driver (PF or VF
+	 * driver) to indicate the list of asynchronous event completions to be
+	 * forwarded. Nth bit refers to the Nth event_id. Setting Nth bit to 1
+	 * by the function driver shall result in the HWRM forwarding
+	 * asynchronous event completion with event_id equal to N. If all bits
+	 * are set to 0 (value of 0), then the HWRM shall not forward any
+	 * asynchronous event completion to this function driver.
+	 */
+	uint32_t async_event_fwd[8];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_drv_rgtr_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_func_drv_unrgtr */
+/*
+ * Description: This command is used by the function driver to un register with
+ * the HWRM. A function driver shall implement this command. A function driver
+ * shall use this command during the driver unloading.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_func_drv_unrgtr_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the function driver is notifying the HWRM to
+	 * prepare for the shutdown.
+	 */
+	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN \
+							UINT32_C(0x1)
+	uint32_t flags;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_func_drv_unrgtr_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 #endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 04/40] bnxt: add dev infos get operation
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
  2016-05-13 22:45                       ` [PATCH v2 02/40] bnxt: add HWRM init code Stephen Hurd
  2016-05-13 22:45                       ` [PATCH v2 03/40] bnxt: add driver register/unregister support Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-13 22:45                       ` [PATCH v2 05/40] bnxt: add dev configure operation Stephen Hurd
                                         ` (36 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Gets device info from the bp structure filled in the init() function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  3 ++
 drivers/net/bnxt/bnxt_ethdev.c | 96 +++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index ebddeab..9ba2433 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,6 +42,9 @@
 #include <rte_lcore.h>
 #include <rte_spinlock.h>
 
+#define BNXT_MAX_MTU		9000
+#define VLAN_TAG_SIZE		4
+
 struct bnxt_vf_info {
 	uint16_t		fw_fid;
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 07519df..d55b9e9 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -53,11 +53,105 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 };
 
 /*
+ * 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;
+}
+
+/*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
-0
+	.dev_infos_get = bnxt_dev_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 05/40] bnxt: add dev configure operation
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (2 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 04/40] bnxt: add dev infos get operation Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 15:25                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 06/40] bnxt: add vnic functions and structs Stephen Hurd
                                         ` (35 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

This adds the bnxt_hwrm_port_phy_cfg() HWRM call, and copies required
information into the new struct bnxt_link_info.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  32 +++
 drivers/net/bnxt/bnxt_ethdev.c         |  24 ++
 drivers/net/bnxt/bnxt_hwrm.c           | 232 +++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 470 +++++++++++++++++++++++++++++++++
 5 files changed, 758 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 9ba2433..f1a620f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -81,6 +81,29 @@ struct bnxt_pf_info {
 	struct bnxt_vf_info	*vf;
 };
 
+/* 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;
@@ -99,6 +122,14 @@ struct bnxt {
 #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;
+
 #define MAX_NUM_MAC_ADDR	32
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
 
@@ -109,6 +140,7 @@ struct bnxt {
 	uint16_t			max_req_len;
 	uint16_t			max_resp_len;
 
+	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
 	struct bnxt_pf_info		pf;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d55b9e9..1852035 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -146,12 +146,36 @@ found:
 	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;
+
+	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;
+	rc = bnxt_set_hwrm_link_config(bp, true);
+	return rc;
+}
+
 /*
  * Initialization
  */
 
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
+	.dev_configure = bnxt_dev_configure_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 398f0f5..73d92c5 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -83,7 +83,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 		/* Sanity check on the resp->resp_len */
 		rte_rmb();
 		if (resp->resp_len && resp->resp_len <=
-		    bp->max_resp_len) {
+				bp->max_resp_len) {
 			/* Last byte of resp contains the valid key */
 			valid = (uint8_t *)resp + resp->resp_len - 1;
 			if (*valid == HWRM_RESP_VALID_KEY)
@@ -314,6 +314,61 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags)
 	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;
+}
+
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
@@ -372,3 +427,178 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 
 	return 0;
 }
+
+static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
+{
+	uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+	if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+		return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
+
+	switch (conf_link_speed) {
+	case ETH_LINK_SPEED_10M_HD:
+	case ETH_LINK_SPEED_100M_HD:
+		return HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF;
+	}
+	return hw_link_duplex;
+}
+
+static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed)
+{
+	uint16_t eth_link_speed = 0;
+
+	if ((conf_link_speed & ETH_LINK_SPEED_FIXED) == ETH_LINK_SPEED_AUTONEG)
+		return ETH_LINK_SPEED_AUTONEG;
+
+	switch (conf_link_speed & ~ETH_LINK_SPEED_FIXED) {
+	case ETH_LINK_SPEED_100M:
+	case ETH_LINK_SPEED_100M_HD:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB;
+		break;
+	case ETH_LINK_SPEED_1G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+		break;
+	case ETH_LINK_SPEED_2_5G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+		break;
+	case ETH_LINK_SPEED_10G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+		break;
+	case ETH_LINK_SPEED_20G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+		break;
+	case ETH_LINK_SPEED_25G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+		break;
+	case ETH_LINK_SPEED_40G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+		break;
+	case ETH_LINK_SPEED_50G:
+		eth_link_speed =
+			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+		break;
+	default:
+		RTE_LOG(ERR, PMD,
+			"Unsupported link speed %d; default to AUTO\n",
+			conf_link_speed);
+		break;
+	}
+	return eth_link_speed;
+}
+
+#define BNXT_SUPPORTED_SPEEDS (ETH_LINK_SPEED_100M | ETH_LINK_SPEED_100M_HD | \
+		ETH_LINK_SPEED_1G | ETH_LINK_SPEED_2_5G | \
+		ETH_LINK_SPEED_10G | ETH_LINK_SPEED_20G | ETH_LINK_SPEED_25G | \
+		ETH_LINK_SPEED_40G | ETH_LINK_SPEED_50G)
+
+static int bnxt_valid_link_speed(uint32_t link_speed, uint8_t port_id)
+{
+	uint32_t one_speed;
+
+	if (link_speed == ETH_LINK_SPEED_AUTONEG)
+		return 0;
+
+	if (link_speed & ETH_LINK_SPEED_FIXED) {
+		one_speed = link_speed & ~ETH_LINK_SPEED_FIXED;
+
+		if (one_speed & (one_speed - 1)) {
+			RTE_LOG(ERR, PMD,
+				"Invalid advertised speeds (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+		if ((one_speed & BNXT_SUPPORTED_SPEEDS) != one_speed) {
+			RTE_LOG(ERR, PMD,
+				"Unsupported advertised speed (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+	} else {
+		if (!(link_speed & BNXT_SUPPORTED_SPEEDS)) {
+			RTE_LOG(ERR, PMD,
+				"Unsupported advertised speeds (%u) for port %u\n",
+				link_speed, port_id);
+			return -EINVAL;
+		}
+	}
+	return 0;
+}
+
+static uint16_t bnxt_parse_eth_link_speed_mask(uint32_t link_speed)
+{
+	uint16_t ret = 0;
+
+	if (link_speed == ETH_LINK_SPEED_AUTONEG)
+		link_speed = BNXT_SUPPORTED_SPEEDS;
+
+	if (link_speed & ETH_LINK_SPEED_100M)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+	if (link_speed & ETH_LINK_SPEED_100M_HD)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB;
+	if (link_speed & ETH_LINK_SPEED_1G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB;
+	if (link_speed & ETH_LINK_SPEED_2_5G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB;
+	if (link_speed & ETH_LINK_SPEED_10G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB;
+	if (link_speed & ETH_LINK_SPEED_20G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB;
+	if (link_speed & ETH_LINK_SPEED_25G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB;
+	if (link_speed & ETH_LINK_SPEED_40G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB;
+	if (link_speed & ETH_LINK_SPEED_50G)
+		ret |= HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB;
+	return ret;
+}
+
+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;
+
+	rc = bnxt_valid_link_speed(dev_conf->link_speeds,
+			bp->eth_dev->data->port_id);
+	if (rc)
+		goto error;
+
+	memset(&link_req, 0, sizeof(link_req));
+	speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds);
+	link_req.link_up = link_up;
+	if (speed == 0) {
+		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;
+		link_req.auto_link_speed_mask =
+			bnxt_parse_eth_link_speed_mask(dev_conf->link_speeds);
+		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_speeds);
+	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);
+	}
+
+error:
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6f2e445..eef3be6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -52,5 +52,6 @@ int bnxt_hwrm_ver_get(struct bnxt *bp);
 
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
+int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
 
 #endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index be3ed0f..e36774e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -54,6 +54,7 @@
 #define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
+#define HWRM_PORT_PHY_CFG                                 (UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
@@ -345,6 +346,475 @@ struct hwrm_func_qcaps_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_port_phy_cfg */
+/*
+ * Description: This command configures the PHY device for the port. It allows
+ * setting of the most generic settings for the PHY. The HWRM shall complete
+ * this command as soon as PHY settings are configured. They may not be applied
+ * when the command response is provided. A VF driver shall not be allowed to
+ * configure PHY using this command. In a network partition mode, a PF driver
+ * shall not be allowed to configure PHY using this command.
+ */
+
+/* Input (56 bytes) */
+struct hwrm_port_phy_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is set to '1', the PHY for the port shall be reset. #
+	 * If this bit is set to 1, then the HWRM shall reset the PHY after
+	 * applying PHY configuration changes specified in this command. # In
+	 * order to guarantee that PHY configuration changes specified in this
+	 * command take effect, the HWRM client should set this flag to 1. # If
+	 * this bit is not set to 1, then the HWRM may reset the PHY depending
+	 * on the current PHY configuration and settings specified in this
+	 * command.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY            UINT32_C(0x1)
+	/*
+	 * When this bit is set to '1', the link shall be forced to be taken
+	 * down. # When this bit is set to '1", all other command input settings
+	 * related to the link speed shall be ignored. Once the link state is
+	 * forced down, it can be explicitly cleared from that state by setting
+	 * this flag to '0'. # If this flag is set to '0', then the link shall
+	 * be cleared from forced down state if the link is in forced down
+	 * state. There may be conditions (e.g. out-of-band or sideband
+	 * configuration changes for the link) outside the scope of the HWRM
+	 * implementation that may clear forced down link state.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN      UINT32_C(0x2)
+	/*
+	 * When this bit is set to '1', the link shall be forced to the
+	 * force_link_speed value. When this bit is set to '1', the HWRM client
+	 * should not enable any of the auto negotiation related fields
+	 * represented by auto_XXX fields in this command. When this bit is set
+	 * to '1' and the HWRM client has enabled a auto_XXX field in this
+	 * command, then the HWRM shall ignore the enabled auto_XXX field. When
+	 * this bit is set to zero, the link shall be allowed to autoneg.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE                UINT32_C(0x4)
+	/*
+	 * When this bit is set to '1', the auto-negotiation process shall be
+	 * restarted on the link.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG      UINT32_C(0x8)
+	/*
+	 * When this bit is set to '1', Energy Efficient Ethernet (EEE) is
+	 * requested to be enabled on this link. If EEE is not supported on this
+	 * port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+	/*
+	 * When this bit is set to '1', Energy Efficient Ethernet (EEE) is
+	 * requested to be disabled on this link. If EEE is not supported on
+	 * this port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	/*
+	 * When this bit is set to '1' and EEE is enabled on this link, then TX
+	 * LPI is requested to be enabled on the link. If EEE is not supported
+	 * on this port, then this flag shall be ignored by the HWRM. If EEE is
+	 * disabled on this port, then this flag shall be ignored by the HWRM.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI	UINT32_C(0x40)
+	uint32_t flags;
+
+	/* This bit must be '1' for the auto_mode field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE          UINT32_C(0x1)
+	/* This bit must be '1' for the auto_duplex field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX        UINT32_C(0x2)
+	/* This bit must be '1' for the auto_pause field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE         UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the auto_link_speed field to be configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED    UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the auto_link_speed_mask field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED_MASK \
+								UINT32_C(0x10)
+	/* This bit must be '1' for the wirespeed field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_WIRESPEED	UINT32_C(0x20)
+	/* This bit must be '1' for the lpbk field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_LPBK		UINT32_C(0x40)
+	/* This bit must be '1' for the preemphasis field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_PREEMPHASIS	UINT32_C(0x80)
+	/* This bit must be '1' for the force_pause field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the eee_link_speed_mask field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_EEE_LINK_SPEED_MASK \
+								UINT32_C(0x200)
+	/* This bit must be '1' for the tx_lpi_timer field to be configured. */
+	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_TX_LPI_TIMER	UINT32_C(0x400)
+	uint32_t enables;
+
+	/* Port ID of port that is to be configured. */
+	uint16_t port_id;
+
+	/*
+	 * This is the speed that will be used if the force bit is '1'. If
+	 * unsupported speed is selected, an error will be generated.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t force_link_speed;
+
+	/*
+	 * This value is used to identify what autoneg mode is used when the
+	 * link speed is not being forced.
+	 */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE	(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK \
+							(UINT32_C(0x4) << 0)
+	uint8_t auto_mode;
+
+	/*
+	 * This is the duplex setting that will be used if the autoneg_mode is
+	 * "one_speed" or "one_or_below".
+	 */
+		/* Half Duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF \
+							(UINT32_C(0x0) << 0)
+		/* Full duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL \
+							(UINT32_C(0x1) << 0)
+		/* Both Half and Full dupex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH \
+							(UINT32_C(0x2) << 0)
+	uint8_t auto_duplex;
+
+	/*
+	 * This value is used to configure the pause that will be used for
+	 * autonegotiation. Add text on the usage of auto_pause and force_pause.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX              UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX              UINT32_C(0x2)
+	/*
+	 * When set to 1, the advertisement of pause is enabled. # When the
+	 * auto_mode is not set to none and this flag is set to 1, then the
+	 * auto_pause bits on this port are being advertised and autoneg pause
+	 * results are being interpreted. # When the auto_mode is not set to
+	 * none and this flag is set to 0, the pause is forced as indicated in
+	 * force_pause, and also advertised as auto_pause bits, but the autoneg
+	 * results are not interpreted since the pause configuration is being
+	 * forced. # When the auto_mode is set to none and this flag is set to
+	 * 1, auto_pause bits should be ignored and should be set to 0.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE   UINT32_C(0x4)
+	uint8_t auto_pause;
+
+	uint8_t unused_0;
+
+	/*
+	 * This is the speed that will be used if the autoneg_mode is
+	 * "one_speed" or "one_or_below". If an unsupported speed is selected,
+	 * an error will be generated.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t auto_link_speed;
+
+	/*
+	 * This is a mask of link speeds that will be used if autoneg_mode is
+	 * "mask". If unsupported speed is enabled an error will be generated.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_MASK_10MB \
+							UINT32_C(0x2000)
+	uint16_t auto_link_speed_mask;
+
+	/* This value controls the wirespeed feature. */
+		/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_OFF	(UINT32_C(0x0) << 0)
+		/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIRESPEED_ON	(UINT32_C(0x1) << 0)
+	uint8_t wirespeed;
+
+	/* This value controls the loopback setting for the PHY. */
+		/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_NONE	(UINT32_C(0x0) << 0)
+		/*
+		 * The HW will be configured with local loopback such that host
+		 * data is sent back to the host without modification.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL	(UINT32_C(0x1) << 0)
+		/*
+		 * The HW will be configured with remote loopback such that port
+		 * logic will send packets back out the transmitter that are
+		 * received.
+		 */
+	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE	(UINT32_C(0x2) << 0)
+	uint8_t lpbk;
+
+	/*
+	 * This value is used to configure the pause that will be used for force
+	 * mode.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX             UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX             UINT32_C(0x2)
+	uint8_t force_pause;
+
+	uint8_t unused_1;
+
+	/*
+	 * This value controls the pre-emphasis to be used for the link. Driver
+	 * should not set this value (use enable.preemphasis = 0) unless driver
+	 * is sure of setting. Normally HWRM FW will determine proper pre-
+	 * emphasis.
+	 */
+	uint32_t preemphasis;
+
+	/*
+	 * Setting for link speed mask that is used to advertise speeds during
+	 * autonegotiation when EEE is enabled. This field is valid only when
+	 * EEE is enabled. The speeds specified in this field shall be a subset
+	 * of speeds specified in auto_link_speed_mask. If EEE is enabled,then
+	 * at least one speed shall be provided in this mask.
+	 */
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD1  UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_100MB  UINT32_C(0x2)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD2  UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_1GB    UINT32_C(0x8)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD3 \
+								UINT32_C(0x10)
+	/* Reserved */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD4 \
+								UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_10GB \
+								UINT32_C(0x40)
+	uint16_t eee_link_speed_mask;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * Reuested setting of TX LPI timer in microseconds. This field is valid
+	 * only when EEE is enabled and TX LPI is enabled.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK \
+							UINT32_C(0xffffff)
+	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT           0
+	uint32_t tx_lpi_timer;
+
+	uint32_t unused_4;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_port_phy_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 06/40] bnxt: add vnic functions and structs
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (3 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 05/40] bnxt: add dev configure operation Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 16:14                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 07/40] bnxt: declare ring structs and free() func Stephen Hurd
                                         ` (34 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Add functions to allocate, initialize, and free vnics.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |  14 ++
 drivers/net/bnxt/bnxt_vnic.c           | 277 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_vnic.h           |  80 ++++++++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |   5 +-
 5 files changed, 376 insertions(+), 1 deletion(-)
 create mode 100644 drivers/net/bnxt/bnxt_vnic.c
 create mode 100644 drivers/net/bnxt/bnxt_vnic.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 9965597..c57afaa 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 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_vnic.c
 
 #
 # Export include files
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index f1a620f..846972e 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,6 +45,13 @@
 #define BNXT_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
+enum bnxt_hw_context {
+	HW_CONTEXT_NONE     = 0,
+	HW_CONTEXT_IS_RSS   = 1,
+	HW_CONTEXT_IS_COS   = 2,
+	HW_CONTEXT_IS_LB    = 3,
+};
+
 struct bnxt_vf_info {
 	uint16_t		fw_fid;
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
@@ -130,6 +137,13 @@ struct bnxt {
 	unsigned		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
 
+	struct bnxt_vnic_info	*vnic_info;
+	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_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];
+
 #define MAX_NUM_MAC_ADDR	32
 	uint8_t			mac_addr[ETHER_ADDR_LEN];
 
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
new file mode 100644
index 0000000..c04c4c7
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -0,0 +1,277 @@
+/*-
+ *   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 = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->fw_rss_cos_lb_ctx = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->ctx_is_rss_cos_lb = HW_CONTEXT_NONE;
+
+		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
+			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
+
+		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 = (uint16_t)HWRM_NA_SIGNATURE;
+			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;
+
+	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);
+	}
+
+	return 0;
+}
+
+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 != (uint16_t)HWRM_NA_SIGNATURE) {
+			RTE_LOG(ERR, PMD, "VNIC is not freed yet!\n");
+			/* TODO Call HWRM to free VNIC */
+		}
+	}
+
+	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
index e36774e..3c032e0 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -43,8 +43,11 @@
  * Following is the signature for HWRM message field that indicates not
  * applicable (All F's). Need to cast it the size of the field if needed.
  */
+#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
 #define HWRM_MAX_REQ_LEN	(128)  /* hwrm_func_buf_rgtr */
 #define HWRM_MAX_RESP_LEN	(176)  /* hwrm_func_qstats */
+#define HW_HASH_INDEX_SIZE      0x80    /* 7 bit indirection table index. */
+#define HW_HASH_KEY_SIZE        40
 #define HWRM_RESP_VALID_KEY	1 /* valid key for HWRM response */
 
 /*
@@ -54,7 +57,7 @@
 #define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
-#define HWRM_PORT_PHY_CFG                                 (UINT32_C(0x20))
+#define HWRM_PORT_PHY_CFG	(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
 
 /*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 07/40] bnxt: declare ring structs and free() func
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (4 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 06/40] bnxt: add vnic functions and structs Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 16:37                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 08/40] bnxt: add completion ring support Stephen Hurd
                                         ` (33 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Declare ring structures and a ring free() function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile    |  1 +
 drivers/net/bnxt/bnxt_ring.c | 51 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_ring.h | 92 ++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_ring.c
 create mode 100644 drivers/net/bnxt/bnxt_ring.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index c57afaa..757ea62 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 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_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
new file mode 100644
index 0000000..0434b07
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -0,0 +1,51 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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;
+	}
+}
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
new file mode 100644
index 0000000..f44025c
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -0,0 +1,92 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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;
+void bnxt_free_ring(struct bnxt_ring_struct *ring);
+
+#endif
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 08/40] bnxt: add completion ring support
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (5 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 07/40] bnxt: declare ring structs and free() func Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 17:33                         ` Bruce Richardson
  2016-05-26  9:38                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
                                         ` (32 subsequent siblings)
  39 siblings, 2 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Structures, macros, and functions for working with completion rings
in the driver.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   6 +
 drivers/net/bnxt/bnxt_cpr.c            | 139 +++++++++++++++++++
 drivers/net/bnxt/bnxt_cpr.h            |  88 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c           |  18 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 239 ++++++++++++++++++++++++++++++++-
 7 files changed, 487 insertions(+), 6 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_cpr.c
 create mode 100644 drivers/net/bnxt/bnxt_cpr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 757ea62..afd1690 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -48,6 +48,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 # all source are stored in SRCS-y
 #
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
 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
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 846972e..4e0b514 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,6 +42,9 @@
 #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_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
@@ -137,6 +140,9 @@ struct bnxt {
 	unsigned		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
 
+	/* Default completion ring */
+	struct bnxt_cp_ring_info	def_cp_ring;
+
 	struct bnxt_vnic_info	*vnic_info;
 	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_list;
 
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
new file mode 100644
index 0000000..ff82335
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -0,0 +1,139 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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"
+#include "bnxt_ring.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..878c7c9
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -0,0 +1,88 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+#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_ring_struct;
+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)
+
+
+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_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 73d92c5..f104a3f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -135,6 +135,24 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_qcaps(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index eef3be6..b792313 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,6 +41,8 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
+
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 3c032e0..9efb68b 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -53,12 +53,143 @@
 /*
  * Request types
  */
-#define HWRM_VER_GET		(UINT32_C(0x0))
-#define HWRM_FUNC_QCAPS		(UINT32_C(0x15))
-#define HWRM_FUNC_DRV_UNRGTR	(UINT32_C(0x1a))
-#define HWRM_FUNC_DRV_RGTR	(UINT32_C(0x1d))
-#define HWRM_PORT_PHY_CFG	(UINT32_C(0x20))
-#define HWRM_QUEUE_QPORTCFG	(UINT32_C(0x30))
+#define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_QCAPS			(UINT32_C(0x15))
+#define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
+#define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
+#define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
+#define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#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 HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
+
+/* Return Codes */
+#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
+#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
+
+/* HWRM Forwarded Request (16 bytes) */
+struct hwrm_fwd_req_cmpl {
+	/* Length of forwarded request in bytes. */
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define HWRM_FWD_REQ_CMPL_TYPE_MASK		UINT32_C(0x3f)
+	#define HWRM_FWD_REQ_CMPL_TYPE_SFT		0
+		/* Forwarded HWRM Request */
+	#define HWRM_FWD_REQ_CMPL_TYPE_HWRM_FWD_REQ	(UINT32_C(0x22) << 0)
+	/* Length of forwarded request in bytes. */
+	#define HWRM_FWD_REQ_CMPL_REQ_LEN_MASK		UINT32_C(0xffc0)
+	#define HWRM_FWD_REQ_CMPL_REQ_LEN_SFT		6
+	uint16_t req_len_type;
+
+	/*
+	 * Source ID of this request. Typically used in forwarding requests and
+	 * responses. 0x0 - 0xFFF8 - Used for function ids 0xFFF8 - 0xFFFE -
+	 * Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t source_id;
+
+	uint32_t unused_0;
+
+	/* Address of forwarded request. */
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define HWRM_FWD_REQ_CMPL_V			UINT32_C(0x1)
+	/* Address of forwarded request. */
+	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_MASK	UINT32_C(0xfffffffe)
+	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
+	uint64_t req_buf_addr_v;
+} __attribute__((packed));
+
+/* HWRM Asynchronous Event Completion Record (16 bytes) */
+struct hwrm_async_event_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_MASK		UINT32_C(0x3f)
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_SFT		0
+		/* HWRM Asynchronous Event Information */
+	#define HWRM_ASYNC_EVENT_CMPL_TYPE_HWRM_ASYNC_EVENT \
+							(UINT32_C(0x2e) << 0)
+	uint16_t type;
+
+	/* Identifiers of events. */
+		/* Link status changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_STATUS_CHANGE \
+							(UINT32_C(0x0) << 0)
+		/* Link MTU changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE \
+							(UINT32_C(0x1) << 0)
+		/* Link speed changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE \
+							(UINT32_C(0x2) << 0)
+		/* DCB Configuration changed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE \
+							(UINT32_C(0x3) << 0)
+		/* Port connection not allowed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED \
+							(UINT32_C(0x4) << 0)
+		/* Link speed configuration was not allowed */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+							(UINT32_C(0x5) << 0)
+		/* Function driver unloaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD \
+							(UINT32_C(0x10) << 0)
+		/* Function driver loaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD \
+							(UINT32_C(0x11) << 0)
+		/* PF driver unloaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD \
+							(UINT32_C(0x20) << 0)
+		/* PF driver loaded */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD \
+							(UINT32_C(0x21) << 0)
+		/* VF Function Level Reset (FLR) */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	(UINT32_C(0x30) << 0)
+		/* VF MAC Address Change */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE \
+							(UINT32_C(0x31) << 0)
+		/* PF-VF communication channel status change. */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+							(UINT32_C(0x32) << 0)
+		/* HWRM Error */
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_HWRM_ERROR \
+							(UINT32_C(0xff) << 0)
+	uint16_t event_id;
+
+	/* Event specific data */
+	uint32_t event_data2;
+
+	/* opaque is 7 b */
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define HWRM_ASYNC_EVENT_CMPL_V				UINT32_C(0x1)
+	/* opaque is 7 b */
+	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK		UINT32_C(0xfe)
+	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT		1
+	uint8_t opaque_v;
+
+	/* 8-lsb timestamp from POR (100-msec resolution) */
+	uint8_t timestamp_lo;
+
+	/* 16-lsb timestamp from POR (100-msec resolution) */
+	uint16_t timestamp_hi;
+
+	/* Event specific data */
+	uint32_t event_data1;
+} __attribute__((packed));
 
 /*
  * Note: The Hardware Resource Manager (HWRM) manages various hardware resources
@@ -122,6 +253,102 @@ struct output {
 	uint16_t resp_len;
 } __attribute__((packed));
 
+/* hwrm_exec_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to execute the request and forward the
+ * response of the encapsulated request to the location specified in the
+ * original request that is encapsulated. The target id of this command shall be
+ * set to 0xFFFF (HWRM). The response location in this command shall be used to
+ * acknowledge the receipt of the encapsulated request and forwarding of the
+ * response.
+ */
+
+/* Input (128 bytes) */
+struct hwrm_exec_fwd_resp_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This is an encapsulated request. This request should be executed by
+	 * the HWRM and the response should be provided in the response buffer
+	 * inside the encapsulated request.
+	 */
+	uint32_t encap_request[26];
+
+	/*
+	 * This value indicates the target id of the response to the
+	 * encapsulated request. 0x0 - 0xFFF8 - Used for function ids 0xFFF8 -
+	 * 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t encap_resp_target_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_exec_fwd_resp_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_func_qcaps */
 /*
  * Description: This command returns capabilities of a function. The input FID
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (6 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 08/40] bnxt: add completion ring support Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-25 17:51                         ` Bruce Richardson
  2016-05-13 22:45                       ` [PATCH v2 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
                                         ` (31 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Add the L2 filter structure and the alloc/init/free functions for
dealing with them.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   3 +
 drivers/net/bnxt/bnxt_filter.c         | 175 ++++++++++++
 drivers/net/bnxt/bnxt_filter.h         |  74 +++++
 drivers/net/bnxt/bnxt_hwrm.c           |  21 ++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 505 +++++++++++++++++++++++++++++++++
 7 files changed, 782 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_filter.c
 create mode 100644 drivers/net/bnxt/bnxt_filter.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index afd1690..b7834b1 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
 #
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_vnic.c
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4e0b514..54ddd24 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -146,6 +146,9 @@ struct bnxt {
 	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];
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
new file mode 100644
index 0000000..f03a1dc
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -0,0 +1,175 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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..06fe134
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -0,0 +1,74 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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
index f104a3f..82139ca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -39,6 +39,7 @@
 #include <rte_version.h>
 
 #include "bnxt.h"
+#include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -135,6 +136,26 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd)
 {
 	int rc;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b792313..c48ba3f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -41,6 +41,9 @@
 
 #define HWRM_SEQ_ID_INVALID -1U
 
+int bnxt_hwrm_clear_filter(struct bnxt *bp,
+			   struct bnxt_filter_info *filter);
+
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 9efb68b..bfa8a7c 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -253,6 +253,511 @@ struct output {
 	uint16_t resp_len;
 } __attribute__((packed));
 
+/* hwrm_cfa_l2_filter_alloc */
+/*
+ * Description: An L2 filter is a filter resource that is used to identify a
+ * vnic or ring for a packet based on layer 2 fields. Layer 2 fields for
+ * encapsulated packets include both outer L2 header and/or inner l2 header of
+ * encapsulated packet. The L2 filter resource covers the following OS specific
+ * L2 filters. Linux/FreeBSD (per function): # Broadcast enable/disable # List
+ * of individual multicast filters # All multicast enable/disable filter #
+ * Unicast filters # Promiscuous mode VMware: # Broadcast enable/disable (per
+ * physical function) # All multicast enable/disable (per function) # Unicast
+ * filters per ring or vnic # Promiscuous mode per PF Windows: # Broadcast
+ * enable/disable (per physical function) # List of individual multicast filters
+ * (Driver needs to advertise the maximum number of filters supported) # All
+ * multicast enable/disable per physical function # Unicast filters per vnic #
+ * Promiscuous mode per PF Implementation notes on the use of VNIC in this
+ * command: # By default, these filters belong to default vnic for the function.
+ * # Once these filters are set up, only destination VNIC can be modified. # If
+ * the destination VNIC is not specified in this command, then the HWRM shall
+ * only create an l2 context id. HWRM Implementation notes for multicast
+ * filters: # The hwrm_filter_alloc command can be used to set up multicast
+ * filters (perfect match or partial match). Each individual function driver can
+ * set up multicast filters independently. # The HWRM needs to keep track of
+ * multicast filters set up by function drivers and maintain multicast group
+ * replication records to enable a subset of functions to receive traffic for a
+ * specific multicast address. # When a specific multicast filter cannot be set,
+ * the HWRM shall return an error. In this error case, the driver should fall
+ * back to using one general filter (rather than specific) for all multicast
+ * traffic. # When the SR-IOV is enabled, the HWRM needs to additionally track
+ * source knockout per multicast group record. Examples of setting unicast
+ * filters: For a unicast MAC based filter, one can use a combination of the
+ * fields and masks provided in this command to set up the filter. Below are
+ * some examples: # MAC + no VLAN filter: This filter is used to identify
+ * traffic that does not contain any VLAN tags and matches destination (or
+ * source) MAC address. This filter can be set up by setting only l2_addr field
+ * to be a valid field. All other fields are not valid. The following value is
+ * set for l2_addr. l2_addr = MAC # MAC + Any VLAN filter: This filter is used
+ * to identify traffic that carries single VLAN tag and matches (destination or
+ * source) MAC address. This filter can be set up by setting only l2_addr and
+ * l2_ovlan_mask fields to be valid fields. All other fields are not valid. The
+ * following values are set for those two valid fields. l2_addr = MAC,
+ * l2_ovlan_mask = 0xFFFF # MAC + no VLAN or VLAN ID=0: This filter is used to
+ * identify untagged traffic that does not contain any VLAN tags or a VLAN tag
+ * with VLAN ID = 0 and matches destination (or source) MAC address. This filter
+ * can be set up by setting only l2_addr and l2_ovlan fields to be valid fields.
+ * All other fields are not valid. The following value are set for l2_addr and
+ * l2_ovlan. l2_addr = MAC, l2_ovlan = 0x0 # MAC + no VLAN or any VLAN: This
+ * filter is used to identify traffic that contains zero or 1 VLAN tag and
+ * matches destination (or source) MAC address. This filter can be set up by
+ * setting only l2_addr, l2_ovlan, and l2_mask fields to be valid fields. All
+ * other fields are not valid. The following value are set for l2_addr,
+ * l2_ovlan, and l2_mask fields. l2_addr = MAC, l2_ovlan = 0x0, l2_ovlan_mask =
+ * 0xFFFF # MAC + VLAN ID filter: This filter can be set up by setting only
+ * l2_addr, l2_ovlan, and l2_ovlan_mask fields to be valid fields. All other
+ * fields are not valid. The following values are set for those three valid
+ * fields. l2_addr = MAC, l2_ovlan = VLAN ID, l2_ovlan_mask = 0xF000
+ */
+
+/* Input (96 bytes) */
+struct hwrm_cfa_l2_filter_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * Enumeration denoting the RX, TX type of the resource. This
+	 * enumeration is used for resources that are similar for both TX and RX
+	 * paths of the chip.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH \
+							UINT32_C(0x1)
+		/* tx path */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_TX \
+							(UINT32_C(0x0) << 0)
+		/* rx path */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX \
+							(UINT32_C(0x1) << 0)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_LAST \
+				HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX
+	/*
+	 * Setting of this flag indicates the applicability to the loopback
+	 * path.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_LOOPBACK \
+							UINT32_C(0x2)
+	/*
+	 * Setting of this flag indicates drop action. If this flag is not set,
+	 * then it should be considered accept action.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_DROP \
+							UINT32_C(0x4)
+	/*
+	 * If this flag is set, all t_l2_* fields are invalid and they should
+	 * not be specified. If this flag is set, then l2_* fields refer to
+	 * fields of outermost L2 header.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST \
+							UINT32_C(0x8)
+	uint32_t flags;
+
+	/* This bit must be '1' for the l2_addr field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR \
+							UINT32_C(0x1)
+	/* This bit must be '1' for the l2_addr_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR_MASK \
+							UINT32_C(0x2)
+	/* This bit must be '1' for the l2_ovlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN \
+							UINT32_C(0x4)
+	/* This bit must be '1' for the l2_ovlan_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK \
+							UINT32_C(0x8)
+	/* This bit must be '1' for the l2_ivlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN \
+							UINT32_C(0x10)
+	/* This bit must be '1' for the l2_ivlan_mask field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_IVLAN_MASK \
+							UINT32_C(0x20)
+	/* This bit must be '1' for the t_l2_addr field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR \
+							UINT32_C(0x40)
+	/*
+	 * This bit must be '1' for the t_l2_addr_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_ADDR_MASK \
+							UINT32_C(0x80)
+	/* This bit must be '1' for the t_l2_ovlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN \
+							UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the t_l2_ovlan_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_OVLAN_MASK \
+							UINT32_C(0x200)
+	/* This bit must be '1' for the t_l2_ivlan field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN \
+							UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the t_l2_ivlan_mask field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_T_L2_IVLAN_MASK \
+							UINT32_C(0x800)
+	/* This bit must be '1' for the src_type field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE \
+							UINT32_C(0x1000)
+	/* This bit must be '1' for the src_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID \
+							UINT32_C(0x2000)
+	/* This bit must be '1' for the tunnel_type field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_TUNNEL_TYPE \
+							UINT32_C(0x4000)
+	/* This bit must be '1' for the dst_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID \
+							UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the mirror_vnic_id field to be configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID \
+							UINT32_C(0x10000)
+	uint32_t enables;
+
+	/*
+	 * This value sets the match value for the L2 MAC address. Destination
+	 * MAC address for RX path. Source MAC address for TX path.
+	 */
+	uint8_t l2_addr[6];
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+
+	/*
+	 * This value sets the mask value for the L2 address. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint8_t l2_addr_mask[6];
+
+	/* This value sets VLAN ID value for outer VLAN. */
+	uint16_t l2_ovlan;
+
+	/*
+	 * This value sets the mask value for the ovlan id. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint16_t l2_ovlan_mask;
+
+	/* This value sets VLAN ID value for inner VLAN. */
+	uint16_t l2_ivlan;
+
+	/*
+	 * This value sets the mask value for the ivlan id. A value of 0 will
+	 * mask the corresponding bit from compare.
+	 */
+	uint16_t l2_ivlan_mask;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This value sets the match value for the tunnel L2 MAC address.
+	 * Destination MAC address for RX path. Source MAC address for TX path.
+	 */
+	uint8_t t_l2_addr[6];
+
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/*
+	 * This value sets the mask value for the tunnel L2 address. A value of
+	 * 0 will mask the corresponding bit from compare.
+	 */
+	uint8_t t_l2_addr_mask[6];
+
+	/* This value sets VLAN ID value for tunnel outer VLAN. */
+	uint16_t t_l2_ovlan;
+
+	/*
+	 * This value sets the mask value for the tunnel ovlan id. A value of 0
+	 * will mask the corresponding bit from compare.
+	 */
+	uint16_t t_l2_ovlan_mask;
+
+	/* This value sets VLAN ID value for tunnel inner VLAN. */
+	uint16_t t_l2_ivlan;
+
+	/*
+	 * This value sets the mask value for the tunnel ivlan id. A value of 0
+	 * will mask the corresponding bit from compare.
+	 */
+	uint16_t t_l2_ivlan_mask;
+
+	/* This value identifies the type of source of the packet. */
+		/* Network port */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_NPORT \
+							(UINT32_C(0x0) << 0)
+		/* Physical function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF \
+							(UINT32_C(0x1) << 0)
+		/* Virtual function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF \
+							(UINT32_C(0x2) << 0)
+		/* Virtual NIC of a function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC \
+							(UINT32_C(0x3) << 0)
+		/* Embedded processor for CFA management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG \
+							(UINT32_C(0x4) << 0)
+		/* Embedded processor for OOB management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE \
+							(UINT32_C(0x5) << 0)
+		/* Embedded processor for RoCE */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO \
+							(UINT32_C(0x6) << 0)
+		/* Embedded processor for network proxy functions */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG \
+							(UINT32_C(0x7) << 0)
+	uint8_t src_type;
+
+	uint8_t unused_6;
+	/*
+	 * This value is the id of the source. For a network port, it represents
+	 * port_id. For a physical function, it represents fid. For a virtual
+	 * function, it represents vf_id. For a vnic, it represents vnic_id. For
+	 * embedded processors, this id is not valid. Notes: 1. The function ID
+	 * is implied if it src_id is not provided for a src_type that is either
+	 */
+	uint32_t src_id;
+
+	/* Tunnel Type. */
+		/* Non-tunnel */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+							(UINT32_C(0x0) << 0)
+		/* Virtual eXtensible Local Area Network (VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Network Virtualization Generic Routing Encapsulation (NVGRE)
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Generic Routing Encapsulation (GRE) inside Ethernet payload
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE \
+							(UINT32_C(0x3) << 0)
+		/* IP in IP */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP \
+							(UINT32_C(0x4) << 0)
+		/* Generic Network Virtualization Encapsulation (Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+							(UINT32_C(0x5) << 0)
+		/* Multi-Protocol Lable Switching (MPLS) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS \
+							(UINT32_C(0x6) << 0)
+		/* Stateless Transport Tunnel (STT) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT \
+							(UINT32_C(0x7) << 0)
+		/*
+		 * Generic Routing Encapsulation (GRE) inside IP datagram
+		 * payload
+		 */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE \
+							(UINT32_C(0x8) << 0)
+		/* Any tunneled traffic */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+							(UINT32_C(0xff) << 0)
+	uint8_t tunnel_type;
+
+	uint8_t unused_7;
+
+	/*
+	 * If set, this value shall represent the Logical VNIC ID of the
+	 * destination VNIC for the RX path and network port id of the
+	 * destination port for the TX path.
+	 */
+	uint16_t dst_id;
+
+	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
+	uint16_t mirror_vnic_id;
+
+	/*
+	 * This hint is provided to help in placing the filter in the filter
+	 * table.
+	 */
+		/* No preference */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+							(UINT32_C(0x0) << 0)
+		/* Above the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+							(UINT32_C(0x1) << 0)
+		/* Below the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+							(UINT32_C(0x2) << 0)
+		/* As high as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX \
+							(UINT32_C(0x3) << 0)
+		/* As low as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN \
+							(UINT32_C(0x4) << 0)
+	uint8_t pri_hint;
+
+	uint8_t unused_8;
+	uint32_t unused_9;
+
+	/*
+	 * This is the ID of the filter that goes along with the pri_hint. This
+	 * field is valid only for the following values. 1 - Above the given
+	 * filter 2 - Below the given filter
+	 */
+	uint64_t l2_filter_id_hint;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+struct hwrm_cfa_l2_filter_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This value identifies a set of CFA data structures used for an L2
+	 * context.
+	 */
+	uint64_t l2_filter_id;
+
+	/*
+	 * This is the ID of the flow associated with this filter. This value
+	 * shall be used to match and associate the flow identifier returned in
+	 * completion records. A value of 0xFFFFFFFF shall indicate no flow id.
+	 */
+	uint32_t flow_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_cfa_l2_filter_free */
+/*
+ * Description: Free a L2 filter. The HWRM shall free all associated filter
+ * resources with the L2 filter.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_cfa_l2_filter_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * This value identifies a set of CFA data structures used for an L2
+	 * context.
+	 */
+	uint64_t l2_filter_id;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_cfa_l2_filter_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_exec_fwd_resp */
 /*
  * Description: This command is used to send an encapsulated request to the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 10/40] bnxt: add Tx queue operations (nonfunctional)
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (7 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
@ 2016-05-13 22:45                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
                                         ` (30 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:45 UTC (permalink / raw)
  To: dev

Add code to create/destroy TX queues.  This still requires TX ring support
to be completed in a future commit.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile      |   1 +
 drivers/net/bnxt/bnxt_ethdev.c |   3 +
 drivers/net/bnxt/bnxt_txq.c    | 125 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_txq.h    |  75 +++++++++++++++++++++++++
 4 files changed, 204 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_txq.c
 create mode 100644 drivers/net/bnxt/bnxt_txq.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index b7834b1..13a90b9 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -53,6 +53,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1852035..d8dbc10 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -41,6 +41,7 @@
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -176,6 +177,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_op,
+	.tx_queue_setup = bnxt_tx_queue_setup_op,
+	.tx_queue_release = bnxt_tx_queue_release_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
new file mode 100644
index 0000000..cb3dd8e
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -0,0 +1,125 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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 __rte_unused)
+{
+	/* TODO: Requires interaction with TX ring */
+}
+
+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;
+
+	if (txq) {
+		/* TODO: Free ring and stats here */
+		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;
+
+	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;
+
+	/* TODO: Initialize ring structure */
+
+	txq->queue_id = queue_idx;
+	txq->port_id = eth_dev->data->port_id;
+
+	/* TODO: Allocate TX ring hardware descriptors */
+
+	/* TODO: Initialize the ring */
+
+	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..5d9ccac
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txq.h
@@ -0,0 +1,75 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+struct bnxt_tx_ring_info;
+struct bnxt_cp_ring_info;
+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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 11/40] bnxt: add Rx queue create/destroy operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (8 preceding siblings ...)
  2016-05-13 22:45                       ` [PATCH v2 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 12/40] bnxt: statistics operations Stephen Hurd
                                         ` (29 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Initial create/destroy queue code.  Requires RX ring support to be
functional.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   2 +
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +
 drivers/net/bnxt/bnxt_rxq.c            | 286 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxq.h            |  74 +++++++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 121 ++++++++++++++
 6 files changed, 487 insertions(+)
 create mode 100644 drivers/net/bnxt/bnxt_rxq.c
 create mode 100644 drivers/net/bnxt/bnxt_rxq.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 13a90b9..21ed71c 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -53,6 +53,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ethdev.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 54ddd24..38b590b 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -143,6 +143,8 @@ struct bnxt {
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	def_cp_ring;
 
+	unsigned		nr_vnics;
+
 	struct bnxt_vnic_info	*vnic_info;
 	STAILQ_HEAD(, bnxt_vnic_info)	free_vnic_list;
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d8dbc10..df39fae 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -41,6 +41,7 @@
 
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
 #include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
@@ -177,6 +178,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_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,
 };
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
new file mode 100644
index 0000000..4ba5d75
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -0,0 +1,286 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_ring.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_RSS:
+		case ETH_MQ_RX_VMDQ_ONLY:
+			{
+				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;
+			}
+		default:
+			RTE_LOG(ERR, PMD, "Unsupported mq_mod %d\n",
+				dev_conf->rxmode.mq_mode);
+			rc = -EINVAL;
+			goto err_out;
+		}
+		/* 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");
+				rc = -ENOMEM;
+				goto err_out;
+			}
+			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 */
+	/* Init default VNIC for RSS or DCB only */
+	vnic = bnxt_alloc_vnic(bp);
+	if (!vnic) {
+		RTE_LOG(ERR, PMD, "VNIC alloc failed\n");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	/* 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");
+		rc = -ENOMEM;
+		goto err_out;
+	}
+	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
+
+	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 __rte_unused)
+{
+	/* TODO: Requires interaction with TX ring */
+}
+
+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;
+
+	if (rxq) {
+		bnxt_rx_queue_release_mbufs(rxq);
+
+		/* TODO: Free ring and stats here */
+
+		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;
+
+	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) {
+		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;
+
+	/* TODO: Initialize ring structure */
+
+	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);
+
+	eth_dev->data->rx_queues[queue_idx] = rxq;
+	/* TODO: Allocate RX ring hardware descriptors */
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
new file mode 100644
index 0000000..9554329
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -0,0 +1,74 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_
+
+struct bnxt;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
+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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index bfa8a7c..c5ff9ff 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1946,6 +1946,127 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+
+/* Input (48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over source and
+	 * destination IPv4 addresses of IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination ports of
+	 * TCP/IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination ports of
+	 * UDP/IPv4 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over source and
+	 * destination IPv4 addresses of IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6		UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv6 addresses and source/destination ports of
+	 * TCP/IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv6 addresses and source/destination ports of
+	 * UDP/IPv6 packets.
+	 */
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6	UINT32_C(0x20)
+	uint32_t hash_type;
+
+	uint32_t unused_0;
+
+	/* This is the address for rss ring group table */
+	uint64_t ring_grp_tbl_addr;
+
+	/* This is the address for rss hash key table */
+	uint64_t hash_key_tbl_addr;
+
+	/* Index to the rss indirection table. */
+	uint16_t rss_ctx_idx;
+
+	uint16_t unused_1[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_rss_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* Output (32 bytes) */
 struct hwrm_queue_qportcfg_output {
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 12/40] bnxt: statistics operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (9 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26  9:40                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 13/40] bnxt: initial Tx ring code Stephen Hurd
                                         ` (28 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add get and clear staitstics operations and the asociated HWRM calls.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt.h                |   5 +-
 drivers/net/bnxt/bnxt_cpr.c            |   5 +-
 drivers/net/bnxt/bnxt_cpr.h            |   2 -
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +
 drivers/net/bnxt/bnxt_hwrm.c           |  49 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   8 +-
 drivers/net/bnxt/bnxt_rxq.c            |   1 +
 drivers/net/bnxt/bnxt_stats.c          | 142 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h          |  44 ++++++++++
 drivers/net/bnxt/bnxt_txq.c            |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 107 +++++++++++++++++++++++++
 12 files changed, 358 insertions(+), 10 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_stats.c
 create mode 100644 drivers/net/bnxt/bnxt_stats.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 21ed71c..f6a04f8 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
 
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 38b590b..96f162e 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -42,9 +42,6 @@
 #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_MAX_MTU		9000
 #define VLAN_TAG_SIZE		4
 
@@ -141,7 +138,7 @@ struct bnxt {
 	struct bnxt_tx_queue **tx_queues;
 
 	/* Default completion ring */
-	struct bnxt_cp_ring_info	def_cp_ring;
+	struct bnxt_cp_ring_info	*def_cp_ring;
 
 	unsigned		nr_vnics;
 
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index ff82335..34e45ef 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -35,6 +35,7 @@
 #include "bnxt_cpr.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
+#include "hsi_struct_def_dpdk.h"
 
 /*
  * Async event handling
@@ -118,7 +119,7 @@ reject:
 /* 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_cp_ring_info *cpr = bp->def_cp_ring;
 	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
 
 	bnxt_free_ring(ring);
@@ -127,7 +128,7 @@ void bnxt_free_def_cp_ring(struct bnxt *bp)
 /* 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_cp_ring_info *cpr = bp->def_cp_ring;
 	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
 
 	ring->bd = (void *)cpr->cp_desc_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 878c7c9..e6333fc 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -34,8 +34,6 @@
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_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)))
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index df39fae..786318c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -42,6 +42,7 @@
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_stats.h"
 #include "bnxt_txq.h"
 
 #define DRV_MODULE_NAME		"bnxt"
@@ -178,6 +179,8 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_infos_get = bnxt_dev_info_get_op,
 	.dev_configure = bnxt_dev_configure_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,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 82139ca..50d8b89 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -39,8 +39,11 @@
 #include <rte_version.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
+#include "bnxt_rxq.h"
+#include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
 #define HWRM_CMD_TIMEOUT		2000
@@ -436,10 +439,56 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 	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)HWRM_NA_SIGNATURE)
+		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;
+}
+
 /*
  * 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;
+}
+
 void bnxt_free_hwrm_resources(struct bnxt *bp)
 {
 	/* Release memzone */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index c48ba3f..0861417 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -37,10 +37,11 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
-#include "bnxt.h"
-
 #define HWRM_SEQ_ID_INVALID -1U
 
+struct bnxt;
+struct bnxt_filter_info;
+struct bnxt_cp_ring_info;
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 
@@ -53,8 +54,11 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
+int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+int bnxt_clear_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_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 4ba5d75..b284e20 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
new file mode 100644
index 0000000..e09956d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -0,0 +1,142 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.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;
+
+	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);
+	}
+
+	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);
+	}
+}
+
+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);
+}
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
index cb3dd8e..a3648c2 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -36,6 +36,7 @@
 #include <rte_malloc.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index c5ff9ff..989f533 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -34,6 +34,35 @@
 #ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
 #define _HSI_STRUCT_DEF_EXTERNAL_H_
 
+/*
+ * per-context HW statistics -- chip view
+ */
+
+typedef 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;
+
 /* HW Resource Manager Specification 1.2.0 */
 #define HWRM_VERSION_MAJOR	1
 #define HWRM_VERSION_MINOR	2
@@ -63,6 +92,7 @@
 #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 HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
 /* Return Codes */
@@ -1946,6 +1976,83 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_clr_stats */
+/* Description: This command clears statistics of a context. */
+
+/* Input (24 bytes) */
+struct hwrm_stat_ctx_clr_stats_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* ID of the statistics context that is being queried. */
+	uint32_t stat_ctx_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 13/40] bnxt: initial Tx ring code
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (10 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 12/40] bnxt: statistics operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 10:40                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 14/40] bnxt: initial Rx " Stephen Hurd
                                         ` (27 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Initial implementation of rx_pkt_burst
Add code to allocate rings to bnxt_ring.c

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt_cpr.h            |   4 +-
 drivers/net/bnxt/bnxt_ethdev.c         |   5 +-
 drivers/net/bnxt/bnxt_ring.c           | 140 +++++++++
 drivers/net/bnxt/bnxt_ring.h           |   8 +
 drivers/net/bnxt/bnxt_txq.c            |  42 ++-
 drivers/net/bnxt/bnxt_txr.c            | 314 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_txr.h            |  71 +++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 512 +++++++++++++++++++++++++++++++++
 9 files changed, 1086 insertions(+), 11 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_txr.c
 create mode 100644 drivers/net/bnxt/bnxt_txr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index f6a04f8..0785681 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ring.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.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_vnic.c
 
 #
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index e6333fc..f104281 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -51,11 +51,11 @@
 
 #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)))
+				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)))
+				RING_CMP(cpr->cp_ring_struct, raw_cons)))
 
 struct bnxt_ring_struct;
 struct bnxt_cp_ring_info {
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 786318c..61e856a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -44,6 +44,7 @@
 #include "bnxt_rxq.h"
 #include "bnxt_stats.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 
 #define DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -259,10 +260,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error;
 	}
 	eth_dev->dev_ops = &bnxt_dev_ops;
-	/*
-	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
+	/* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
-	 */
 
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0434b07..bb20806 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,8 +31,14 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_memzone.h>
+
 #include "bnxt.h"
+#include "bnxt_cpr.h"
 #include "bnxt_ring.h"
+#include "bnxt_txr.h"
+
+#include "hsi_struct_def_dpdk.h"
 
 /*
  * Generic ring handling
@@ -49,3 +55,137 @@ void bnxt_free_ring(struct bnxt_ring_struct *ring)
 		*ring->vmem = NULL;
 	}
 }
+
+/*
+ * 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;
+	/* TODO: RX 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_stats64)) : 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;
+	/* TODO: RX ring */
+	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;
+	/* TODO: RX ring */
+	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 = HWRM_NA_SIGNATURE;
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index f44025c..dfa0401 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -87,6 +87,14 @@ struct bnxt_ring_grp_info {
 };
 
 struct bnxt;
+struct bnxt_tx_ring_info;
+struct bnxt_rx_ring_info;
+struct bnxt_cp_ring_info;
 void bnxt_free_ring(struct bnxt_ring_struct *ring);
+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);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
index a3648c2..7aba199 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -39,6 +39,7 @@
 #include "bnxt_cpr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 
 /*
  * TX Queues
@@ -55,9 +56,20 @@ void bnxt_free_txq_stats(struct bnxt_tx_queue *txq)
 		cpr->hw_stats = NULL;
 }
 
-static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq __rte_unused)
+static void bnxt_tx_queue_release_mbufs(struct bnxt_tx_queue *txq)
 {
-	/* TODO: Requires interaction with TX ring */
+	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)
@@ -76,7 +88,15 @@ void bnxt_tx_queue_release_op(void *tx_queue)
 	struct bnxt_tx_queue *txq = (struct bnxt_tx_queue *)tx_queue;
 
 	if (txq) {
-		/* TODO: Free ring and stats here */
+		/* Free TX ring hardware descriptors */
+		bnxt_tx_queue_release_mbufs(txq);
+		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+
+		/* Free TX completion ring hardware descriptors */
+		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+
+		bnxt_free_txq_stats(txq);
+
 		rte_free(txq);
 	}
 }
@@ -112,14 +132,24 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	txq->nb_tx_desc = nb_desc;
 	txq->tx_free_thresh = tx_conf->tx_free_thresh;
 
-	/* TODO: Initialize ring structure */
+	bnxt_init_tx_ring_struct(txq);
 
 	txq->queue_id = queue_idx;
 	txq->port_id = eth_dev->data->port_id;
 
-	/* TODO: Allocate TX ring hardware descriptors */
+	/* Allocate TX ring hardware descriptors */
+	if (bnxt_alloc_rings(bp, queue_idx, txq->tx_ring, NULL, txq->cp_ring,
+			"bnxt_tx_ring")) {
+		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for tx_ring failed!");
+		bnxt_tx_queue_release_op(txq);
+		return -ENOMEM;
+	}
 
-	/* TODO: Initialize the ring */
+	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_txr.c b/drivers/net/bnxt/bnxt_txr.c
new file mode 100644
index 0000000..2314410
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -0,0 +1,314 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.h"
+#include "bnxt_ring.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];
+
+		if (!txq)
+			continue;
+
+		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
+		/* TODO: free() txq->tx_ring and txq->tx_ring->tx_ring_struct */
+		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
+		/* TODO: free() txq->cp_ring and txq->cp_ring->cp_ring_struct */
+
+		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;
+
+	/* TODO: These need to be allocated */
+	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;
+
+	/* TODO: These need to be allocated */
+	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 = rte_cpu_to_le_32(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 = rte_cpu_to_le_32(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..1797a3d
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -0,0 +1,71 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 989f533..ff02a29 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -99,6 +99,518 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
 #define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
 
+/* Short TX BD (16 bytes) */
+struct tx_bd_short {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	/* This value identifies the type of buffer descriptor. */
+	#define TX_BD_SHORT_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_BD_SHORT_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 16B long and is used for normal L2
+		 * packet transmission.
+		 */
+	#define TX_BD_SHORT_TYPE_TX_BD_SHORT		(UINT32_C(0x0) << 0)
+	/*
+	 * If set to 1, the packet ends with the data in the buffer pointed to
+	 * by this descriptor. This flag must be valid on every BD.
+	 */
+	#define TX_BD_SHORT_FLAGS_PACKET_END		UINT32_C(0x40)
+	/*
+	 * If set to 1, the device will not generate a completion for this
+	 * transmit packet unless there is an error in it's processing. If this
+	 * bit is set to 0, then the packet will be completed normally. This bit
+	 * must be valid only on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_NO_CMPL		UINT32_C(0x80)
+	/*
+	 * This value indicates how many 16B BD locations are consumed in the
+	 * ring by this packet. A value of 1 indicates that this BD is the only
+	 * BD (and that the it is a short BD). A value of 3 indicates either 3
+	 * short BDs or 1 long BD and one short BD in the packet. A value of 0
+	 * indicates that there are 32 BD locations in the packet (the maximum).
+	 * This field is valid only on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_BD_CNT_MASK		UINT32_C(0x1f00)
+	#define TX_BD_SHORT_FLAGS_BD_CNT_SFT		8
+	/*
+	 * This value is a hint for the length of the entire packet. It is used
+	 * by the chip to optimize internal processing. The packet will be
+	 * dropped if the hint is too short. This field is valid only on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_LHINT_MASK		UINT32_C(0x6000)
+	#define TX_BD_SHORT_FLAGS_LHINT_SFT		13
+		/* indicates packet length < 512B */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT512		(UINT32_C(0x0) << 13)
+		/* indicates 512 <= packet length < 1KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT1K		(UINT32_C(0x1) << 13)
+		/* indicates 1KB <= packet length < 2KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_LT2K		(UINT32_C(0x2) << 13)
+		/* indicates packet length >= 2KB */
+	#define TX_BD_SHORT_FLAGS_LHINT_GTE2K		(UINT32_C(0x3) << 13)
+	#define TX_BD_SHORT_FLAGS_LHINT_LAST	TX_BD_SHORT_FLAGS_LHINT_GTE2K
+	/*
+	 * If set to 1, the device immediately updates the Send Consumer Index
+	 * after the buffer associated with this descriptor has been transferred
+	 * via DMA to NIC memory from host memory. An interrupt may or may not
+	 * be generated according to the state of the interrupt avoidance
+	 * mechanisms. If this bit is set to 0, then the Consumer Index is only
+	 * updated as soon as one of the host interrupt coalescing conditions
+	 * has been met. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_COAL_NOW		UINT32_C(0x8000)
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	#define TX_BD_SHORT_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_BD_SHORT_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the host physical buffer this BD describes in
+	 * bytes. This field must be valid on all BDs of a packet.
+	 */
+	uint16_t len;
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with the
+	 * transmit BD. This field must be valid on the first BD of a packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address for the portion of the packet
+	 * described by this TX BD. This value must be valid on all BDs of a
+	 * packet.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
+/* Long TX BD (32 bytes split to 2 16-byte struct) */
+struct tx_bd_long {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	/* This value identifies the type of buffer descriptor. */
+	#define TX_BD_LONG_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_BD_LONG_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 32B long and is used for normal L2
+		 * packet transmission.
+		 */
+	#define TX_BD_LONG_TYPE_TX_BD_LONG		(UINT32_C(0x10) << 0)
+	/*
+	 * If set to 1, the packet ends with the data in the buffer pointed to
+	 * by this descriptor. This flag must be valid on every BD.
+	 */
+	#define TX_BD_LONG_FLAGS_PACKET_END		UINT32_C(0x40)
+	/*
+	 * If set to 1, the device will not generate a completion for this
+	 * transmit packet unless there is an error in it's processing. If this
+	 * bit is set to 0, then the packet will be completed normally. This bit
+	 * must be valid only on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_NO_CMPL		UINT32_C(0x80)
+	/*
+	 * This value indicates how many 16B BD locations are consumed in the
+	 * ring by this packet. A value of 1 indicates that this BD is the only
+	 * BD (and that the it is a short BD). A value of 3 indicates either 3
+	 * short BDs or 1 long BD and one short BD in the packet. A value of 0
+	 * indicates that there are 32 BD locations in the packet (the maximum).
+	 * This field is valid only on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_BD_CNT_MASK		UINT32_C(0x1f00)
+	#define TX_BD_LONG_FLAGS_BD_CNT_SFT		8
+	/*
+	 * This value is a hint for the length of the entire packet. It is used
+	 * by the chip to optimize internal processing. The packet will be
+	 * dropped if the hint is too short. This field is valid only on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_LHINT_MASK		UINT32_C(0x6000)
+	#define TX_BD_LONG_FLAGS_LHINT_SFT		13
+		/* indicates packet length < 512B */
+	#define TX_BD_LONG_FLAGS_LHINT_LT512		(UINT32_C(0x0) << 13)
+		/* indicates 512 <= packet length < 1KB */
+	#define TX_BD_LONG_FLAGS_LHINT_LT1K		(UINT32_C(0x1) << 13)
+		/* indicates 1KB <= packet length < 2KB */
+	#define TX_BD_LONG_FLAGS_LHINT_LT2K		(UINT32_C(0x2) << 13)
+		/* indicates packet length >= 2KB */
+	#define TX_BD_LONG_FLAGS_LHINT_GTE2K		(UINT32_C(0x3) << 13)
+	#define TX_BD_LONG_FLAGS_LHINT_LAST	TX_BD_LONG_FLAGS_LHINT_GTE2K
+	/*
+	 * If set to 1, the device immediately updates the Send Consumer Index
+	 * after the buffer associated with this descriptor has been transferred
+	 * via DMA to NIC memory from host memory. An interrupt may or may not
+	 * be generated according to the state of the interrupt avoidance
+	 * mechanisms. If this bit is set to 0, then the Consumer Index is only
+	 * updated as soon as one of the host interrupt coalescing conditions
+	 * has been met. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_FLAGS_COAL_NOW		UINT32_C(0x8000)
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Only the packet_end bit must be valid for the remaining BDs of a
+	 * packet.
+	 */
+	#define TX_BD_LONG_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_BD_LONG_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the host physical buffer this BD describes in
+	 * bytes. This field must be valid on all BDs of a packet.
+	 */
+	uint16_t len;
+
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with the
+	 * transmit BD. This field must be valid on the first BD of a packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address for the portion of the packet
+	 * described by this TX BD. This value must be valid on all BDs of a
+	 * packet.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
+/* last 16 bytes of Long TX BD */
+
+struct tx_bd_long_hi {
+	/*
+	 * All bits in this field must be valid on the first BD of a packet.
+	 * Their value on other BDs of the packet will be ignored.
+	 */
+	/*
+	 * If set to 1, the controller replaces the TCP/UPD checksum fields of
+	 * normal TCP/UPD checksum, or the inner TCP/UDP checksum field of the
+	 * encapsulated TCP/UDP packets with the hardware calculated TCP/UDP
+	 * checksum for the packet associated with this descriptor. This bit
+	 * must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_TCP_UDP_CHKSUM	UINT32_C(0x1)
+	/*
+	 * If set to 1, the controller replaces the IP checksum of the normal
+	 * packets, or the inner IP checksum of the encapsulated packets with
+	 * the hardware calculated IP checksum for the packet associated with
+	 * this descriptor. This bit must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_IP_CHKSUM		UINT32_C(0x2)
+	/*
+	 * If set to 1, the controller will not append an Ethernet CRC to the
+	 * end of the frame. This bit must be valid on the first BD of a packet.
+	 * Packet must be 64B or longer when this flag is set. It is not useful
+	 * to use this bit with any form of TX offload such as CSO or LSO. The
+	 * intent is that the packet from the host already has a valid Ethernet
+	 * CRC on the packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_NOCRC			UINT32_C(0x4)
+	/*
+	 * If set to 1, the device will record the time at which the packet was
+	 * actually transmitted at the TX MAC. This bit must be valid on the
+	 * first BD of a packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_STAMP			UINT32_C(0x8)
+	/*
+	 * If set to 1, The controller replaces the tunnel IP checksum field
+	 * with hardware calculated IP checksum for the IP header of the packet
+	 * associated with this descriptor. In case of VXLAN, the controller
+	 * also replaces the outer header UDP checksum with hardware calculated
+	 * UDP checksum for the packet associated with this descriptor.
+	 */
+	#define TX_BD_LONG_LFLAGS_T_IP_CHKSUM		UINT32_C(0x10)
+	/*
+	 * If set to 1, the device will treat this packet with LSO(Large Send
+	 * Offload) processing for both normal or encapsulated packets, which is
+	 * a form of TCP segmentation. When this bit is 1, the hdr_size and mss
+	 * fields must be valid. The driver doesn't need to set t_ip_chksum,
+	 * ip_chksum, and tcp_udp_chksum flags since the controller will replace
+	 * the appropriate checksum fields for segmented packets. When this bit
+	 * is 1, the hdr_size and mss fields must be valid.
+	 */
+	#define TX_BD_LONG_LFLAGS_LSO			UINT32_C(0x20)
+	/*
+	 * If set to zero when LSO is '1', then the IPID will be treated as a
+	 * 16b number and will be wrapped if it exceeds a value of 0xffff. If
+	 * set to one when LSO is '1', then the IPID will be treated as a 15b
+	 * number and will be wrapped if it exceeds a value 0f 0x7fff.
+	 */
+	#define TX_BD_LONG_LFLAGS_IPID_FMT		UINT32_C(0x40)
+	/*
+	 * If set to zero when LSO is '1', then the IPID of the tunnel IP header
+	 * will not be modified during LSO operations. If set to one when LSO is
+	 * '1', then the IPID of the tunnel IP header will be incremented for
+	 * each subsequent segment of an LSO operation.
+	 */
+	#define TX_BD_LONG_LFLAGS_T_IPID		UINT32_C(0x80)
+	/*
+	 * If set to '1', then the RoCE ICRC will be appended to the packet.
+	 * Packet must be a valid RoCE format packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_ROCE_CRC		UINT32_C(0x100)
+	/*
+	 * If set to '1', then the FCoE CRC will be appended to the packet.
+	 * Packet must be a valid FCoE format packet.
+	 */
+	#define TX_BD_LONG_LFLAGS_FCOE_CRC		UINT32_C(0x200)
+	uint16_t lflags;
+
+	/*
+	 * When LSO is '1', this field must contain the offset of the TCP
+	 * payload from the beginning of the packet in as 16b words. In case of
+	 * encapsulated/tunneling packet, this field contains the offset of the
+	 * inner TCP payload from beginning of the packet as 16-bit words. This
+	 * value must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_HDR_SIZE_MASK		UINT32_C(0x1ff)
+	#define TX_BD_LONG_HDR_SIZE_SFT			0
+	uint16_t hdr_size;
+
+	/*
+	 * This is the MSS value that will be used to do the LSO processing. The
+	 * value is the length in bytes of the TCP payload for each segment
+	 * generated by the LSO operation. This value must be valid on the first
+	 * BD of a packet.
+	 */
+	#define TX_BD_LONG_MSS_MASK			UINT32_C(0x7fff)
+	#define TX_BD_LONG_MSS_SFT			0
+	uint32_t mss;
+
+	uint16_t unused_2;
+
+	/*
+	 * This value selects a CFA action to perform on the packet. Set this
+	 * value to zero if no CFA action is desired. This value must be valid
+	 * on the first BD of a packet.
+	 */
+	uint16_t cfa_action;
+
+	/*
+	 * This value is action meta-data that defines CFA edit operations that
+	 * are done in addition to any action editing.
+	 */
+	/* When key=1, This is the VLAN tag VID value. */
+	#define TX_BD_LONG_CFA_META_VLAN_VID_MASK	UINT32_C(0xfff)
+	#define TX_BD_LONG_CFA_META_VLAN_VID_SFT	0
+	/* When key=1, This is the VLAN tag DE value. */
+	#define TX_BD_LONG_CFA_META_VLAN_DE		UINT32_C(0x1000)
+	/* When key=1, This is the VLAN tag PRI value. */
+	#define TX_BD_LONG_CFA_META_VLAN_PRI_MASK	UINT32_C(0xe000)
+	#define TX_BD_LONG_CFA_META_VLAN_PRI_SFT	13
+	/* When key=1, This is the VLAN tag TPID select value. */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_MASK	UINT32_C(0x70000)
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_SFT	16
+		/* 0x88a8 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID88A8	(UINT32_C(0x0) << 16)
+		/* 0x8100 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID8100	(UINT32_C(0x1) << 16)
+		/* 0x9100 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9100	(UINT32_C(0x2) << 16)
+		/* 0x9200 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9200	(UINT32_C(0x3) << 16)
+		/* 0x9300 */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPID9300	(UINT32_C(0x4) << 16)
+		/* Value programmed in CFA VLANTPID register. */
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG	(UINT32_C(0x5) << 16)
+	#define TX_BD_LONG_CFA_META_VLAN_TPID_LAST \
+					TX_BD_LONG_CFA_META_VLAN_TPID_TPIDCFG
+	/* When key=1, This is the VLAN tag TPID select value. */
+	#define TX_BD_LONG_CFA_META_VLAN_RESERVED_MASK	UINT32_C(0xff80000)
+	#define TX_BD_LONG_CFA_META_VLAN_RESERVED_SFT	19
+	/*
+	 * This field identifies the type of edit to be performed on the packet.
+	 * This value must be valid on the first BD of a packet.
+	 */
+	#define TX_BD_LONG_CFA_META_KEY_MASK		UINT32_C(0xf0000000)
+	#define TX_BD_LONG_CFA_META_KEY_SFT		28
+		/* No editing */
+	#define TX_BD_LONG_CFA_META_KEY_NONE		(UINT32_C(0x0) << 28)
+		/*
+		 * - meta[17:16] - TPID select value (0 = 0x8100). - meta[15:12]
+		 * - PRI/DE value. - meta[11:0] - VID value.
+		 */
+	#define TX_BD_LONG_CFA_META_KEY_VLAN_TAG	(UINT32_C(0x1) << 28)
+	#define TX_BD_LONG_CFA_META_KEY_LAST	TX_BD_LONG_CFA_META_KEY_VLAN_TAG
+	uint32_t cfa_meta;
+} __attribute__((packed));
+
+/* Completion Ring Structures */
+/* Note: This structure is used by the HWRM to communicate HWRM Error. */
+/* Base Completion Record (16 bytes) */
+struct cmpl_base {
+	/* unused is 10 b */
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define CMPL_BASE_TYPE_MASK			UINT32_C(0x3f)
+	#define CMPL_BASE_TYPE_SFT			0
+		/* TX L2 completion: Completion of TX packet. Length = 16B */
+	#define CMPL_BASE_TYPE_TX_L2			(UINT32_C(0x0) << 0)
+		/*
+		 * RX L2 completion: Completion of and L2 RX packet.
+		 * Length = 32B
+		*/
+	#define CMPL_BASE_TYPE_RX_L2			(UINT32_C(0x11) << 0)
+		/*
+		 * RX Aggregation Buffer completion : Completion of an L2
+		 * aggregation buffer in support of TPA, HDS, or Jumbo packet
+		 * completion. Length = 16B
+		 */
+	#define CMPL_BASE_TYPE_RX_AGG			(UINT32_C(0x12) << 0)
+		/*
+		 * RX L2 TPA Start Completion: Completion at the beginning of a
+		 * TPA operation. Length = 32B
+		 */
+	#define CMPL_BASE_TYPE_RX_TPA_START		(UINT32_C(0x13) << 0)
+		/*
+		 * RX L2 TPA End Completion: Completion at the end of a TPA
+		 * operation. Length = 32B
+		 */
+	#define CMPL_BASE_TYPE_RX_TPA_END		(UINT32_C(0x15) << 0)
+		/*
+		 * Statistics Ejection Completion: Completion of statistics data
+		 * ejection buffer. Length = 16B
+		 */
+	#define CMPL_BASE_TYPE_STAT_EJECT		(UINT32_C(0x1a) << 0)
+		/* HWRM Command Completion: Completion of an HWRM command. */
+	#define CMPL_BASE_TYPE_HWRM_DONE		(UINT32_C(0x20) << 0)
+		/* Forwarded HWRM Request */
+	#define CMPL_BASE_TYPE_HWRM_FWD_REQ		(UINT32_C(0x22) << 0)
+		/* Forwarded HWRM Response */
+	#define CMPL_BASE_TYPE_HWRM_FWD_RESP		(UINT32_C(0x24) << 0)
+		/* HWRM Asynchronous Event Information */
+	#define CMPL_BASE_TYPE_HWRM_ASYNC_EVENT		(UINT32_C(0x2e) << 0)
+		/* CQ Notification */
+	#define CMPL_BASE_TYPE_CQ_NOTIFICATION		(UINT32_C(0x30) << 0)
+		/* SRQ Threshold Event */
+	#define CMPL_BASE_TYPE_SRQ_EVENT		(UINT32_C(0x32) << 0)
+		/* DBQ Threshold Event */
+	#define CMPL_BASE_TYPE_DBQ_EVENT		(UINT32_C(0x34) << 0)
+		/* QP Async Notification */
+	#define CMPL_BASE_TYPE_QP_EVENT			(UINT32_C(0x38) << 0)
+		/* Function Async Notification */
+	#define CMPL_BASE_TYPE_FUNC_EVENT		(UINT32_C(0x3a) << 0)
+	uint16_t type;
+
+	uint16_t info1;
+	uint32_t info2;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define CMPL_BASE_V				UINT32_C(0x1)
+	/* info3 is 31 b */
+	#define CMPL_BASE_INFO3_MASK			UINT32_C(0xfffffffe)
+	#define CMPL_BASE_INFO3_SFT			1
+	uint32_t info3_v;
+
+	uint32_t info4;
+} __attribute__((packed));
+
+/* TX Completion Record (16 bytes) */
+struct tx_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define TX_CMPL_TYPE_MASK			UINT32_C(0x3f)
+	#define TX_CMPL_TYPE_SFT			0
+		/* TX L2 completion: Completion of TX packet. Length = 16B */
+	#define TX_CMPL_TYPE_TX_L2			(UINT32_C(0x0) << 0)
+	/*
+	 * When this bit is '1', it indicates a packet that has an error of some
+	 * type. Type of error is indicated in error_flags.
+	 */
+	#define TX_CMPL_FLAGS_ERROR			UINT32_C(0x40)
+	/*
+	 * When this bit is '1', it indicates that the packet completed was
+	 * transmitted using the push acceleration data provided by the driver.
+	 * When this bit is '0', it indicates that the packet had not push
+	 * acceleration data written or was executed as a normal packet even
+	 * though push data was provided.
+	 */
+	#define TX_CMPL_FLAGS_PUSH			UINT32_C(0x80)
+	#define TX_CMPL_FLAGS_MASK			UINT32_C(0xffc0)
+	#define TX_CMPL_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	uint16_t unused_0;
+
+	/*
+	 * This is a copy of the opaque field from the first TX BD of this
+	 * transmitted packet.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define TX_CMPL_V				UINT32_C(0x1)
+	/*
+	 * This error indicates that there was some sort of problem with the BDs
+	 * for the packet.
+	 */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_SFT		1
+		/* No error */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_NO_ERROR	(UINT32_C(0x0) << 1)
+		/* Bad Format: BDs were not formatted correctly. */
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT	(UINT32_C(0x2) << 1)
+	#define TX_CMPL_ERRORS_BUFFER_ERROR_LAST \
+					TX_CMPL_ERRORS_BUFFER_ERROR_BAD_FMT
+	/*
+	 * When this bit is '1', it indicates that the length of the packet was
+	 * zero. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_ZERO_LENGTH_PKT		UINT32_C(0x10)
+	/*
+	 * When this bit is '1', it indicates that the packet was longer than
+	 * the programmed limit in TDI. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_EXCESSIVE_BD_LENGTH	UINT32_C(0x20)
+	/*
+	 * When this bit is '1', it indicates that one or more of the BDs
+	 * associated with this packet generated a PCI error. This probably
+	 * means the address was not valid.
+	 */
+	#define TX_CMPL_ERRORS_DMA_ERROR		UINT32_C(0x40)
+	/*
+	 * When this bit is '1', it indicates that the packet was longer than
+	 * indicated by the hint. No packet was transmitted.
+	 */
+	#define TX_CMPL_ERRORS_HINT_TOO_SHORT		UINT32_C(0x80)
+	/*
+	 * When this bit is '1', it indicates that the packet was dropped due to
+	 * Poison TLP error on one or more of the TLPs in the PXP completion.
+	 */
+	#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 errors_v;
+
+	uint16_t unused_1;
+	uint32_t unused_2;
+} __attribute__((packed)) tx_cmpl_t, *ptx_cmpl_t;
+
 /* HWRM Forwarded Request (16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	/* Length of forwarded request in bytes. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 14/40] bnxt: initial Rx ring code
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (11 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 13/40] bnxt: initial Tx ring code Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 10:52                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 15/40] bnxt: alloc/free ring information Stephen Hurd
                                         ` (26 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Initial implementation of rx_pkt_burst
Add code to allocate rings to bnxt_ring.c

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile              |   1 +
 drivers/net/bnxt/bnxt_ethdev.c         |   3 +-
 drivers/net/bnxt/bnxt_ring.c           |  20 +-
 drivers/net/bnxt/bnxt_rxq.c            |  34 ++-
 drivers/net/bnxt/bnxt_rxr.c            | 338 +++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxr.h            |  62 +++++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 474 +++++++++++++++++++++++++++++++++
 7 files changed, 915 insertions(+), 17 deletions(-)
 create mode 100644 drivers/net/bnxt/bnxt_rxr.c
 create mode 100644 drivers/net/bnxt/bnxt_rxr.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0785681..4d35412 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxr.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txr.c
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 61e856a..e1b3e3a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -42,6 +42,7 @@
 #include "bnxt.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_stats.h"
 #include "bnxt_txq.h"
 #include "bnxt_txr.h"
@@ -260,7 +261,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error;
 	}
 	eth_dev->dev_ops = &bnxt_dev_ops;
-	/* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
+	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
 	rc = bnxt_alloc_hwrm_resources(bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index bb20806..69837bf 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -36,6 +36,7 @@
 #include "bnxt.h"
 #include "bnxt_cpr.h"
 #include "bnxt_ring.h"
+#include "bnxt_rxr.h"
 #include "bnxt_txr.h"
 
 #include "hsi_struct_def_dpdk.h"
@@ -77,9 +78,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			    const char *suffix)
 {
 	struct bnxt_ring_struct *cp_ring = cp_ring_info->cp_ring_struct;
+	struct bnxt_ring_struct *rx_ring;
 	struct bnxt_ring_struct *tx_ring;
-	/* TODO: RX 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];
@@ -96,10 +96,9 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 						tx_ring_struct->vmem_size) : 0;
 
 	int rx_vmem_start = tx_vmem_start + tx_vmem_len;
-	/* TODO: RX ring */
-	int rx_vmem_len = /*
-	    rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
-					rx_ring_struct->vmem_size) : */ 0;
+	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 *
@@ -111,10 +110,9 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 				   sizeof(struct tx_bd_long)) : 0;
 
 	int rx_ring_start = tx_ring_start + tx_ring_len;
-	/* TODO: RX ring */
-	int rx_ring_len = /* rx_ring_info ?
+	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;
+				   sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
 
@@ -152,9 +150,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		}
 	}
 
-/*
 	if (rx_ring_info) {
-		rx_ring = &rx_ring_info->rx_ring_struct;
+		rx_ring = rx_ring_info->rx_ring_struct;
 
 		rx_ring->bd = ((char *)mz->addr + rx_ring_start);
 		rx_ring_info->rx_desc_ring =
@@ -171,7 +168,6 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			    (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;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index b284e20..90a116b 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -41,6 +41,7 @@
 #include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -215,7 +216,20 @@ err_out:
 
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 {
-	/* TODO: Requires interaction with TX ring */
+	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)
@@ -236,7 +250,13 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 	if (rxq) {
 		bnxt_rx_queue_release_mbufs(rxq);
 
-		/* TODO: Free ring and stats here */
+		/* Free RX ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+
+		/* Free RX completion ring hardware descriptors */
+		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+
+		bnxt_free_rxq_stats(rxq);
 
 		rte_free(rxq);
 	}
@@ -273,7 +293,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	rxq->nb_rx_desc = nb_desc;
 	rxq->rx_free_thresh = rx_conf->rx_free_thresh;
 
-	/* TODO: Initialize ring structure */
+	bnxt_init_rx_ring_struct(rxq);
 
 	rxq->queue_id = queue_idx;
 	rxq->port_id = eth_dev->data->port_id;
@@ -281,7 +301,13 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 				0 : ETHER_CRC_LEN);
 
 	eth_dev->data->rx_queues[queue_idx] = rxq;
-	/* TODO: Allocate RX ring hardware descriptors */
+	/* Allocate RX ring hardware descriptors */
+	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
+			"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_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
new file mode 100644
index 0000000..eed88c6
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -0,0 +1,338 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_cpr.h"
+#include "bnxt_ring.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 = rte_cpu_to_le_64(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 = cons_bd->addr;
+}
+
+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];
+
+		if (!rxq)
+			continue;
+
+		/* TODO: free() rxq->rx_ring and rxq->rx_ring->rx_ring_struct */
+		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* TODO: free() rxq->cp_ring and rxq->cp_ring->cp_ring_struct */
+		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+
+		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 +
+			       (2 * 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;
+
+	/* TODO: These need to be allocated */
+	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);
+	}
+
+	return 0;
+}
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
new file mode 100644
index 0000000..e9bae3f
--- /dev/null
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -0,0 +1,62 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) Broadcom Limited.
+ *   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_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_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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index ff02a29..fd9eb62 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -446,6 +446,79 @@ struct tx_bd_long_hi {
 	uint32_t cfa_meta;
 } __attribute__((packed));
 
+/* RX Producer Packet BD (16 bytes) */
+struct rx_prod_pkt_bd {
+	/* This value identifies the type of buffer descriptor. */
+	#define RX_PROD_PKT_BD_TYPE_MASK		UINT32_C(0x3f)
+	#define RX_PROD_PKT_BD_TYPE_SFT			0
+		/*
+		 * Indicates that this BD is 16B long and is an RX Producer (ie.
+		 * empty) buffer descriptor.
+		 */
+	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT		(UINT32_C(0x4) << 0)
+	/*
+	 * If set to 1, the packet will be placed at the address plus 2B. The 2
+	 * Bytes of padding will be written as zero.
+	 */
+	/*
+	 * This is intended to be used when the host buffer is cache-line
+	 * aligned to produce packets that are easy to parse in host memory
+	 * while still allowing writes to be cache line aligned.
+	 */
+	#define RX_PROD_PKT_BD_FLAGS_SOP_PAD		UINT32_C(0x40)
+	/*
+	 * If set to 1, the packet write will be padded out to the nearest
+	 * cache-line with zero value padding.
+	 */
+	/*
+	 * If receive buffers start/end on cache-line boundaries, this feature
+	 * will ensure that all data writes on the PCI bus start/end on cache
+	 * line boundaries.
+	 */
+	#define RX_PROD_PKT_BD_FLAGS_EOP_PAD		UINT32_C(0x80)
+	/*
+	 * This value is the number of additional buffers in the ring that
+	 * describe the buffer space to be consumed for the this packet. If the
+	 * value is zero, then the packet must fit within the space described by
+	 * this BD. If this value is 1 or more, it indicates how many additional
+	 * "buffer" BDs are in the ring immediately following this BD to be used
+	 * for the same network packet. Even if the packet to be placed does not
+	 * need all the additional buffers, they will be consumed anyway.
+	 */
+	#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 flags_type;
+
+	/*
+	 * This is the length in Bytes of the host physical buffer where data
+	 * for the packet may be placed in host memory.
+	 */
+	/*
+	 * While this is a Byte resolution value, it is often advantageous to
+	 * ensure that the buffers provided end on a host cache line.
+	 */
+	uint16_t len;
+
+	/*
+	 * The opaque data field is pass through to the completion and can be
+	 * used for any data that the driver wants to associate with this
+	 * receive buffer set.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This is the host physical address where data for the packet may by
+	 * placed in host memory.
+	 */
+	/*
+	 * While this is a Byte resolution value, it is often advantageous to
+	 * ensure that the buffers provide start on a host cache line.
+	 */
+	uint64_t addr;
+} __attribute__((packed));
+
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
 /* Base Completion Record (16 bytes) */
@@ -611,6 +684,407 @@ struct tx_cmpl {
 	uint32_t unused_2;
 } __attribute__((packed)) tx_cmpl_t, *ptx_cmpl_t;
 
+/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_pkt_cmpl {
+	/*
+	 * This field indicates the exact type of the completion. By convention,
+	 * the LSB identifies the length of the record in 16B units. Even values
+	 * indicate 16B records. Odd values indicate 32B records.
+	 */
+	#define RX_PKT_CMPL_TYPE_MASK			UINT32_C(0x3f)
+	#define RX_PKT_CMPL_TYPE_SFT			0
+		/*
+		 * RX L2 completion: Completion of and L2 RX packet.
+		 * Length = 32B
+		 */
+	#define RX_PKT_CMPL_TYPE_RX_L2			(UINT32_C(0x11) << 0)
+	/*
+	 * When this bit is '1', it indicates a packet that has an error of some
+	 * type. Type of error is indicated in error_flags.
+	 */
+	#define RX_PKT_CMPL_FLAGS_ERROR			UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_SFT		7
+		/* Normal: Packet was placed using normal algorithm. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_NORMAL	(UINT32_C(0x0) << 7)
+		/* Jumbo: Packet was placed using jumbo algorithm. */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_JUMBO	(UINT32_C(0x1) << 7)
+		/*
+		 * Header/Data Separation: Packet was placed using Header/Data
+		 * separation algorithm. The separation location is indicated by
+		 * the itype field.
+		 */
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_HDS		(UINT32_C(0x2) << 7)
+	#define RX_PKT_CMPL_FLAGS_PLACEMENT_LAST \
+						RX_PKT_CMPL_FLAGS_PLACEMENT_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_PKT_CMPL_FLAGS_RSS_VALID		UINT32_C(0x400)
+	/*
+	 * This value indicates what the inner packet determined for the packet
+	 * was.
+	 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_MASK		UINT32_C(0xf000)
+	#define RX_PKT_CMPL_FLAGS_ITYPE_SFT		12
+		/* Not Known: Indicates that the packet type was not known. */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_NOT_KNOWN	(UINT32_C(0x0) << 12)
+		/*
+		 * IP Packet: Indicates that the packet was an IP packet, but
+		 * further classification was not possible.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_IP		(UINT32_C(0x1) << 12)
+		/*
+		 * TCP Packet: Indicates that the packet was IP and TCP. This
+		 * indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_TCP		(UINT32_C(0x2) << 12)
+		/*
+		 * UDP Packet: Indicates that the packet was IP and UDP. This
+		 * indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_UDP		(UINT32_C(0x3) << 12)
+		/*
+		 * FCoE Packet: Indicates that the packet was recognized as a
+		 * FCoE. This also indicates that the payload_offset field is
+		 * valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_FCOE		(UINT32_C(0x4) << 12)
+		/*
+		 * RoCE Packet: Indicates that the packet was recognized as a
+		 * RoCE. This also indicates that the payload_offset field is
+		 * valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_ROCE		(UINT32_C(0x5) << 12)
+		/*
+		 * ICMP Packet: Indicates that the packet was recognized as
+		 * ICMP. This indicates that the payload_offset field is valid.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_ICMP		(UINT32_C(0x7) << 12)
+		/*
+		 * PtP packet wo/timestamp: Indicates that the packet was
+		 * recognized as a PtP packet.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_WO_TIMESTAMP \
+							(UINT32_C(0x8) << 12)
+		/*
+		 * PtP packet w/timestamp: Indicates that the packet was
+		 * recognized as a PtP packet and that a timestamp was taken for
+		 * the packet.
+		 */
+	#define RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP	(UINT32_C(0x9) << 12)
+	#define RX_PKT_CMPL_FLAGS_ITYPE_LAST \
+					RX_PKT_CMPL_FLAGS_ITYPE_PTP_W_TIMESTAMP
+	#define RX_PKT_CMPL_FLAGS_MASK			UINT32_C(0xffc0)
+	#define RX_PKT_CMPL_FLAGS_SFT			6
+	uint16_t flags_type;
+
+	/*
+	 * This is the length of the data for the packet stored in the buffer(s)
+	 * identified by the opaque value. This includes the packet BD and any
+	 * associated buffer BDs. This does not include the the length of any
+	 * data places in aggregation BDs.
+	 */
+	uint16_t len;
+
+	/*
+	 * This is a copy of the opaque field from the RX BD this completion
+	 * corresponds to.
+	 */
+	uint32_t opaque;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define RX_PKT_CMPL_V1				UINT32_C(0x1)
+	/*
+	 * This value is the number of aggregation buffers that follow this
+	 * entry in the completion ring that are a part of this packet. If the
+	 * value is zero, then the packet is completely contained in the buffer
+	 * space provided for the packet in the RX ring.
+	 */
+	#define RX_PKT_CMPL_AGG_BUFS_MASK		UINT32_C(0x3e)
+	#define RX_PKT_CMPL_AGG_BUFS_SFT		1
+	uint8_t agg_bufs_v1;
+
+	/*
+	 * This is the RSS hash type for the packet. The value is packed
+	 * {tuple_extrac_op[1:0],rss_profile_id[4:0],tuple_extrac_op[2]}.
+	 */
+	uint8_t rss_hash_type;
+
+	/*
+	 * This value indicates the offset from the beginning of the packet
+	 * where the inner payload starts. This value is valid for TCP, UDP,
+	 * FCoE, and RoCE packets.
+	 */
+	uint8_t payload_offset;
+
+	uint8_t unused_1;
+
+	/*
+	 * This value is the RSS hash value calculated for the packet based on
+	 * the mode bits and key value in the VNIC.
+	 */
+	uint32_t rss_hash;
+} __attribute__((packed));
+
+/* last 16 bytes of RX Packet Completion Record */
+struct rx_pkt_cmpl_hi {
+	/*
+	 * This indicates that the ip checksum was calculated for the inner
+	 * packet and that the ip_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_IP_CS_CALC		UINT32_C(0x1)
+	/*
+	 * This indicates that the TCP, UDP or ICMP checksum was calculated for
+	 * the inner packet and that the l4_cs_error field indicates if there
+	 * was an error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_L4_CS_CALC		UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the tunnel
+	 * header and that the t_ip_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC		UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the tunnel
+	 * packet and that the t_l4_cs_error field indicates if there was an
+	 * error.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_T_L4_CS_CALC		UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_MASK	UINT32_C(0xf0)
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT	4
+		/* No metadata informtaion. Value is zero. */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_NONE	(UINT32_C(0x0) << 4)
+		/*
+		 * The metadata field contains the VLAN tag and TPID value. -
+		 * metadata[11:0] contains the vlan VID value. - metadata[12]
+		 * contains the vlan DE value. - metadata[15:13] contains the
+		 * vlan PRI value. - metadata[31:16] contains the vlan TPID
+		 * value.
+		 */
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
+	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST \
+					RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN
+	/*
+	 * This field indicates the IP type for the inner-most IP header. A
+	 * value of '0' indicates IPv4. A value of '1' indicates IPv6. This
+	 * value is only valid if itype indicates a packet with an IP header.
+	 */
+	#define RX_PKT_CMPL_FLAGS2_IP_TYPE		UINT32_C(0x100)
+	uint32_t flags2;
+
+	/*
+	 * This is data from the CFA block as indicated by the meta_format
+	 * field.
+	 */
+	/* When meta_format=1, this value is the VLAN VID. */
+	#define RX_PKT_CMPL_METADATA_VID_MASK		UINT32_C(0xfff)
+	#define RX_PKT_CMPL_METADATA_VID_SFT		0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_PKT_CMPL_METADATA_DE			UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_PKT_CMPL_METADATA_PRI_MASK		UINT32_C(0xe000)
+	#define RX_PKT_CMPL_METADATA_PRI_SFT		13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_PKT_CMPL_METADATA_TPID_MASK		UINT32_C(0xffff0000)
+	#define RX_PKT_CMPL_METADATA_TPID_SFT		16
+	uint32_t metadata;
+
+	/*
+	 * This value is written by the NIC such that it will be different for
+	 * each pass through the completion queue. The even passes will write 1.
+	 * The odd passes will write 0.
+	 */
+	#define RX_PKT_CMPL_V2				UINT32_C(0x1)
+	/*
+	 * This error indicates that there was some sort of problem with the BDs
+	 * for the packet that was found after part of the packet was already
+	 * placed. The packet should be treated as invalid.
+	 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+		/* No buffer error */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NO_BUFFER \
+							(UINT32_C(0x0) << 1)
+		/*
+		 * Did Not Fit: Packet did not fit into packet buffer provided.
+		 * For regular placement, this means the packet did not fit in
+		 * the buffer provided. For HDS and jumbo placement, this means
+		 * that the packet could not be placed into 7 physical buffers
+		 * or less.
+		 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_DID_NOT_FIT \
+							(UINT32_C(0x1) << 1)
+		/*
+		 * Not On Chip: All BDs needed for the packet were not on-chip
+		 * when the packet arrived.
+		 */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+							(UINT32_C(0x2) << 1)
+		/* Bad Format: BDs were not formatted correctly. */
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT \
+							(UINT32_C(0x3) << 1)
+	#define RX_PKT_CMPL_ERRORS_BUFFER_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_BUFFER_ERROR_BAD_FORMAT
+	/* This indicates that there was an error in the IP header checksum. */
+	#define RX_PKT_CMPL_ERRORS_IP_CS_ERROR		UINT32_C(0x10)
+	/*
+	 * This indicates that there was an error in the TCP, UDP or ICMP
+	 * checksum.
+	 */
+	#define RX_PKT_CMPL_ERRORS_L4_CS_ERROR		UINT32_C(0x20)
+	/*
+	 * This indicates that there was an error in the tunnel IP header
+	 * checksum.
+	 */
+	#define RX_PKT_CMPL_ERRORS_T_IP_CS_ERROR	UINT32_C(0x40)
+	/* This indicates that there was an error in the tunnel UDP checksum. */
+	#define RX_PKT_CMPL_ERRORS_T_L4_CS_ERROR	UINT32_C(0x80)
+	/*
+	 * This indicates that there was a CRC error on either an FCoE or RoCE
+	 * packet. The itype indicates the packet type.
+	 */
+	#define RX_PKT_CMPL_ERRORS_CRC_ERROR		UINT32_C(0x100)
+	/*
+	 * This indicates that there was an error in the tunnel portion of the
+	 * packet when this field is non-zero.
+	 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_MASK	UINT32_C(0xe00)
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_SFT	9
+		/*
+		 * No additional error occurred on the tunnel portion of the
+		 * packet of the packet does not have a tunnel.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_NO_ERROR	(UINT32_C(0x0) << 9)
+		/*
+		 * Indicates that IP header version does not match expectation
+		 * from L2 Ethertype for IPv4 and IPv6 in the tunnel header.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_VERSION \
+							(UINT32_C(0x1) << 9)
+		/*
+		 * Indicates that header length is out of range in the tunnel
+		 * header. Valid for IPv4.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_HDR_LEN \
+							(UINT32_C(0x2) << 9)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the PPPoE header length for a tunnel PPPoE packet.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_TUNNEL_TOTAL_ERROR \
+							(UINT32_C(0x3) << 9)
+		/*
+		 * Indicates that physical packet is shorter than that claimed
+		 * by the tunnel l3 header length. Valid for IPv4, or IPv6
+		 * tunnel packet packets.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_IP_TOTAL_ERROR \
+							(UINT32_C(0x4) << 9)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the tunnel UDP header length for a tunnel UDP
+		 * packet that is not fragmented.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_UDP_TOTAL_ERROR \
+							(UINT32_C(0x5) << 9)
+		/*
+		 * indicates that the IPv4 TTL or IPv6 hop limit check have
+		 * failed (e.g. TTL = 0) in the tunnel header. Valid for IPv4,
+		 * and IPv6.
+		 */
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL \
+							(UINT32_C(0x6) << 9)
+	#define RX_PKT_CMPL_ERRORS_T_PKT_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_T_PKT_ERROR_T_L3_BAD_TTL
+	/*
+	 * This indicates that there was an error in the inner portion of the
+	 * packet when this field is non-zero.
+	 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_MASK	UINT32_C(0xf000)
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_SFT	12
+		/*
+		 * No additional error occurred on the tunnel portion of the
+		 * packet of the packet does not have a tunnel.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_NO_ERROR	(UINT32_C(0x0) << 12)
+		/*
+		 * Indicates that IP header version does not match expectation
+		 * from L2 Ethertype for IPv4 and IPv6 or that option other than
+		 * VFT was parsed on FCoE packet.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_VERSION \
+							(UINT32_C(0x1) << 12)
+		/*
+		 * indicates that header length is out of range. Valid for IPv4
+		 * and RoCE
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_HDR_LEN \
+							(UINT32_C(0x2) << 12)
+		/*
+		 * indicates that the IPv4 TTL or IPv6 hop limit check have
+		 * failed (e.g. TTL = 0). Valid for IPv4, and IPv6
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L3_BAD_TTL	(UINT32_C(0x3) << 12)
+		/*
+		 * Indicates that physical packet is shorter than that claimed
+		 * by the l3 header length. Valid for IPv4, IPv6 packet or RoCE
+		 * packets.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_IP_TOTAL_ERROR \
+							(UINT32_C(0x4) << 12)
+		/*
+		 * Indicates that the physical packet is shorter than that
+		 * claimed by the UDP header length for a UDP packet that is not
+		 * fragmented.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_UDP_TOTAL_ERROR \
+							(UINT32_C(0x5) << 12)
+		/*
+		 * Indicates that TCP header length > IP payload. Valid for TCP
+		 * packets only.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN \
+							(UINT32_C(0x6) << 12)
+		/* Indicates that TCP header length < 5. Valid for TCP. */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_HDR_LEN_TOO_SMALL \
+							(UINT32_C(0x7) << 12)
+		/*
+		 * Indicates that TCP option headers result in a TCP header size
+		 * that does not match data offset in TCP header. Valid for TCP.
+		 */
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
+							(UINT32_C(0x8) << 12)
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST \
+				RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN
+	#define RX_PKT_CMPL_ERRORS_MASK			UINT32_C(0xfffe)
+	#define RX_PKT_CMPL_ERRORS_SFT			1
+	uint16_t errors_v2;
+
+	/*
+	 * This field identifies the CFA action rule that was used for this
+	 * packet.
+	 */
+	uint16_t cfa_code;
+
+	/*
+	 * This value holds the reordering sequence number for the packet. If
+	 * the reordering sequence is not valid, then this value is zero. The
+	 * reordering domain for the packet is in the bottom 8 to 10b of the
+	 * rss_hash value. The bottom 20b of this value contain the ordering
+	 * domain value for the packet.
+	 */
+	#define RX_PKT_CMPL_REORDER_MASK		UINT32_C(0xffffff)
+	#define RX_PKT_CMPL_REORDER_SFT			0
+	uint32_t reorder;
+} __attribute__((packed));
+
 /* HWRM Forwarded Request (16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	/* Length of forwarded request in bytes. */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 15/40] bnxt: alloc/free ring information
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (12 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 14/40] bnxt: initial Rx " Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 10:59                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 16/40] bnxt: add HWRM function reset command Stephen Hurd
                                         ` (25 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Perform allocation and free()ing of ring information structures for
TX, RX, and completion rings.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_cpr.c | 28 +++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_cpr.h |  2 +-
 drivers/net/bnxt/bnxt_rxq.c | 17 ++++++++++++-----
 drivers/net/bnxt/bnxt_rxr.c | 42 ++++++++++++++++++++++++++++++++++--------
 drivers/net/bnxt/bnxt_rxr.h |  2 +-
 drivers/net/bnxt/bnxt_txq.c | 23 ++++++++++++++++-------
 drivers/net/bnxt/bnxt_txr.c | 43 ++++++++++++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_txr.h |  2 +-
 8 files changed, 122 insertions(+), 37 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 34e45ef..27c557f 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_malloc.h>
+
 #include "bnxt.h"
 #include "bnxt_cpr.h"
 #include "bnxt_hwrm.h"
@@ -120,21 +122,37 @@ reject:
 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);
+	bnxt_free_ring(cpr->cp_ring_struct);
+	rte_free(cpr->cp_ring_struct);
+	rte_free(cpr);
 }
 
 /* For the default completion ring only */
-void bnxt_init_def_ring_struct(struct bnxt *bp)
+int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id)
 {
-	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-	struct bnxt_ring_struct *ring = cpr->cp_ring_struct;
+	struct bnxt_cp_ring_info *cpr;
+	struct bnxt_ring_struct *ring;
 
+	cpr = rte_zmalloc_socket("bnxt_cp_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	bp->def_cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_cp_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index f104281..3e25a75 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -79,7 +79,7 @@ struct bnxt_cp_ring_info {
 
 struct bnxt;
 void bnxt_free_def_cp_ring(struct bnxt *bp);
-void bnxt_init_def_ring_struct(struct bnxt *bp);
+int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id);
 void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp);
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp);
 
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 90a116b..2fe4de8 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -271,10 +271,12 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	struct bnxt_rx_queue *rxq;
+	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
 		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
 	if (eth_dev->data->rx_queues) {
@@ -286,14 +288,17 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 				 RTE_CACHE_LINE_SIZE, socket_id);
 	if (!rxq) {
 		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 	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);
+	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
+	if (rc)
+		goto out;
 
 	rxq->queue_id = queue_idx;
 	rxq->port_id = eth_dev->data->port_id;
@@ -306,8 +311,10 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 			"bnxt_rx_ring")) {
 		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
 		bnxt_rx_queue_release_op(rxq);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 
-	return 0;
+out:
+	return rc;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index eed88c6..5a6f2fe 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -252,17 +252,20 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 		if (!rxq)
 			continue;
 
-		/* TODO: free() rxq->rx_ring and rxq->rx_ring->rx_ring_struct */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
-		/* TODO: free() rxq->cp_ring and rxq->cp_ring->cp_ring_struct */
+		rte_free(rxq->rx_ring->rx_ring_struct);
+		rte_free(rxq->rx_ring);
+
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
+		rte_free(rxq->cp_ring->cp_ring_struct);
+		rte_free(rxq->cp_ring);
 
 		rte_free(rxq);
 		bp->rx_queues[i] = NULL;
 	}
 }
 
-void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
+int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 {
 	struct bnxt *bp = rxq->bp;
 	struct bnxt_cp_ring_info *cpr;
@@ -274,8 +277,19 @@ void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
 			       (2 * 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;
+	rxr = rte_zmalloc_socket("bnxt_rx_ring",
+				 sizeof(struct bnxt_rx_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!rxr)
+		return -ENOMEM;
+	rxq->rx_ring = rxr;
+
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring_struct),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	rxr->rx_ring_struct = ring;
 	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc);
 	ring->ring_mask = ring->ring_size - 1;
 	ring->bd = (void *)rxr->rx_desc_ring;
@@ -283,14 +297,27 @@ void bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq)
 	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;
+	cpr = rte_zmalloc_socket("bnxt_rx_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	rxq->cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring_struct),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
 
 static void bnxt_init_rxbds(struct bnxt_ring_struct *ring, uint32_t type,
@@ -317,7 +344,6 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 
 	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
 
-	/* TODO: These need to be allocated */
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
 	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e9bae3f..7ba8f7b 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -56,7 +56,7 @@ struct bnxt_rx_ring_info {
 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_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id);
 int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
index 7aba199..beda5fe 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -109,10 +109,12 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 	struct bnxt_tx_queue *txq;
+	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_TX_DESC_CNT) {
 		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
-		return -EINVAL;
+		rc = -EINVAL;
+		goto out;
 	}
 
 	if (eth_dev->data->tx_queues) {
@@ -124,15 +126,18 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	}
 	txq = rte_zmalloc_socket("bnxt_tx_queue", sizeof(struct bnxt_tx_queue),
 				 RTE_CACHE_LINE_SIZE, socket_id);
-	if (txq == NULL) {
+	if (!txq) {
 		RTE_LOG(ERR, PMD, "bnxt_tx_queue allocation failed!");
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 	txq->bp = bp;
 	txq->nb_tx_desc = nb_desc;
 	txq->tx_free_thresh = tx_conf->tx_free_thresh;
 
-	bnxt_init_tx_ring_struct(txq);
+	rc = bnxt_init_tx_ring_struct(txq, socket_id);
+	if (rc)
+		goto out;
 
 	txq->queue_id = queue_idx;
 	txq->port_id = eth_dev->data->port_id;
@@ -142,15 +147,19 @@ int bnxt_tx_queue_setup_op(struct rte_eth_dev *eth_dev,
 			"bnxt_tx_ring")) {
 		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for tx_ring failed!");
 		bnxt_tx_queue_release_op(txq);
-		return -ENOMEM;
+		rc = -ENOMEM;
+		goto out;
 	}
 
 	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;
+		rc = -ENOMEM;
+		goto out;
 	}
 
 	eth_dev->data->tx_queues[queue_idx] = txq;
-	return 0;
+
+out:
+	return rc;
 }
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 2314410..218b945 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -59,9 +59,12 @@ void bnxt_free_tx_rings(struct bnxt *bp)
 			continue;
 
 		bnxt_free_ring(txq->tx_ring->tx_ring_struct);
-		/* TODO: free() txq->tx_ring and txq->tx_ring->tx_ring_struct */
+		rte_free(txq->tx_ring->tx_ring_struct);
+		rte_free(txq->tx_ring);
+
 		bnxt_free_ring(txq->cp_ring->cp_ring_struct);
-		/* TODO: free() txq->cp_ring and txq->cp_ring->cp_ring_struct */
+		rte_free(txq->cp_ring->cp_ring_struct);
+		rte_free(txq->cp_ring);
 
 		rte_free(txq);
 		bp->tx_queues[i] = NULL;
@@ -79,15 +82,25 @@ int bnxt_init_one_tx_ring(struct bnxt_tx_queue *txq)
 	return 0;
 }
 
-void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq)
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id)
 {
 	struct bnxt_cp_ring_info *cpr;
 	struct bnxt_tx_ring_info *txr;
 	struct bnxt_ring_struct *ring;
 
-	/* TODO: These need to be allocated */
-	txr = txq->tx_ring;
-	ring = txr->tx_ring_struct;
+	txr = rte_zmalloc_socket("bnxt_tx_ring",
+				 sizeof(struct bnxt_tx_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!txr)
+		return -ENOMEM;
+	txq->tx_ring = txr;
+
+	ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	txr->tx_ring_struct = ring;
 	ring->ring_size = rte_align32pow2(txq->nb_tx_desc + 1);
 	ring->ring_mask = ring->ring_size - 1;
 	ring->bd = (void *)txr->tx_desc_ring;
@@ -95,15 +108,27 @@ void bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq)
 	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_tx_bd);
 	ring->vmem = (void **)&txr->tx_buf_ring;
 
-	/* TODO: These need to be allocated */
-	cpr = txq->cp_ring;
-	ring = cpr->cp_ring_struct;
+	cpr = rte_zmalloc_socket("bnxt_tx_ring",
+				 sizeof(struct bnxt_cp_ring_info),
+				 RTE_CACHE_LINE_SIZE, socket_id);
+	if (!cpr)
+		return -ENOMEM;
+	txq->cp_ring = cpr;
+
+	ring = rte_zmalloc_socket("bnxt_tx_ring_struct",
+				  sizeof(struct bnxt_ring_struct),
+				  RTE_CACHE_LINE_SIZE, socket_id);
+	if (!ring)
+		return -ENOMEM;
+	cpr->cp_ring_struct = ring;
 	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;
+
+	return 0;
 }
 
 static inline uint32_t bnxt_tx_avail(struct bnxt_tx_ring_info *txr)
diff --git a/drivers/net/bnxt/bnxt_txr.h b/drivers/net/bnxt/bnxt_txr.h
index 1797a3d..56d0b08 100644
--- a/drivers/net/bnxt/bnxt_txr.h
+++ b/drivers/net/bnxt/bnxt_txr.h
@@ -64,7 +64,7 @@ struct bnxt_sw_tx_bd {
 
 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);
+int bnxt_init_tx_ring_struct(struct bnxt_tx_queue *txq, unsigned int socket_id);
 uint16_t bnxt_xmit_pkts(void *tx_queue, struct rte_mbuf **tx_pkts,
 			       uint16_t nb_pkts);
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 16/40] bnxt: add HWRM function reset command
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (13 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 15/40] bnxt: alloc/free ring information Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
                                         ` (24 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add bnxt_hwrm_func_reset() function and supporting structs and macros.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  17 +++++
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 129 +++++++++++++++++++++++++++++++++
 3 files changed, 147 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 50d8b89..922c92a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -221,6 +221,23 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	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_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 0861417..4fa94aa 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -50,6 +50,7 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 				   uint32_t *vf_req_fwd);
 int bnxt_hwrm_func_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index fd9eb62..9c82d13 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -83,6 +83,7 @@ typedef struct ctx_hw_stats64 {
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_RESET			(UINT32_C(0x11))
 #define HWRM_FUNC_QCAPS			(UINT32_C(0x15))
 #define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
@@ -2097,6 +2098,134 @@ struct hwrm_func_qcaps_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_func_reset */
+/*
+ * Description: This command resets a hardware function (PCIe function) and
+ * frees any resources used by the function. This command shall be initiated by
+ * the driver after an FLR has occurred to prepare the function for re-use. This
+ * command may also be initiated by a driver prior to doing it's own
+ * configuration. This command puts the function into the reset state. In the
+ * reset state, global and port related features of the chip are not available.
+ */
+/*
+ * Note: This command will reset a function that has already been disabled or
+ * idled. The command returns all the resources owned by the function so a new
+ * driver may allocate and configure resources normally.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_func_reset_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_FUNC_RESET_INPUT_ENABLES_VF_ID_VALID \
+							UINT32_C(0x1)
+	uint32_t enables;
+
+	/*
+	 * The ID of the VF that this PF is trying to reset. Only the parent PF
+	 * shall be allowed to reset a child VF. A parent PF driver shall use
+	 * this field only when a specific child VF is requested to be reset.
+	 */
+	uint16_t vf_id;
+
+	/* This value indicates the level of a function reset. */
+		/*
+		 * Reset the caller function and its children VFs (if any). If
+		 * no children functions exist, then reset the caller function
+		 * only.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETALL \
+							(UINT32_C(0x0) << 0)
+		/* Reset the caller function only */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETME \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Reset all children VFs of the caller function driver if the
+		 * caller is a PF driver. It is an error to specify this level
+		 * by a VF driver. It is an error to specify this level by a PF
+		 * driver with no children VFs.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Reset a specific VF of the caller function driver if the
+		 * caller is the parent PF driver. It is an error to specify
+		 * this level by a VF driver. It is an error to specify this
+		 * level by a PF driver that is not the parent of the VF that is
+		 * being requested to reset.
+		 */
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETVF \
+							(UINT32_C(0x3) << 0)
+	uint8_t func_reset_level;
+
+	uint8_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_func_reset_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_port_phy_cfg */
 /*
  * Description: This command configures the PHY device for the port. It allows
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 17/40] bnxt: add HWRM vnic alloc function
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (14 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 16/40] bnxt: add HWRM function reset command Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 18/40] bnxt: add HWRM vnic free function Stephen Hurd
                                         ` (23 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

This requires a group info array in struct bnxt, so add that, save
the max size from the func_qcap response, and alloc/free in init/uninit

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  2 +
 drivers/net/bnxt/bnxt_hwrm.c           | 33 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 99 ++++++++++++++++++++++++++++++++++
 4 files changed, 136 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 96f162e..d258e2b 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -140,6 +140,8 @@ struct bnxt {
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
 
+	uint32_t		max_ring_grps;
+	struct bnxt_ring_grp_info	*grp_info;
 	unsigned		nr_vnics;
 
 	struct bnxt_vnic_info	*vnic_info;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 922c92a..ecd4718 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -43,7 +43,9 @@
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
 #define HWRM_CMD_TIMEOUT		2000
@@ -191,6 +193,7 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
+	bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps);
 	if (BNXT_PF(bp)) {
 		struct bnxt_pf_info *pf = &bp->pf;
 
@@ -477,6 +480,36 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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 == (uint16_t)HWRM_NA_SIGNATURE) {
+			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 = (uint16_t)HWRM_NA_SIGNATURE;
+	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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 4fa94aa..62dc801 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,8 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 9c82d13..ba0e054 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -89,6 +89,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #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))
@@ -3168,6 +3169,104 @@ struct hwrm_stat_ctx_clr_stats_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_alloc */
+/*
+ * Description: This VNIC is a resource in the RX side of the chip that is used
+ * to represent a virtual host "interface". # At the time of VNIC allocation or
+ * configuration, the function can specify whether it wants the requested VNIC
+ * to be the default VNIC for the function or not. # If a function requests
+ * allocation of a VNIC for the first time and a VNIC is successfully allocated
+ * by the HWRM, then the HWRM shall make the allocated VNIC as the default VNIC
+ * for that function. # The default VNIC shall be used for the default action
+ * for a partition or function. # For each VNIC allocated on a function, a
+ * mapping on the RX side to map the allocated VNIC to source virtual interface
+ * shall be performed by the HWRM. This should be hidden to the function driver
+ * requesting the VNIC allocation. This enables broadcast/multicast replication
+ * with source knockout. # If multicast replication with source knockout is
+ * enabled, then the internal VNIC to SVIF mapping data structures shall be
+ * programmed at the time of VNIC allocation.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_vnic_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', this VNIC is requested to be the default VNIC
+	 * for this function.
+	 */
+	#define HWRM_VNIC_ALLOC_INPUT_FLAGS_DEFAULT                UINT32_C(0x1)
+	uint32_t flags;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* Logical vnic ID */
+	uint32_t vnic_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 18/40] bnxt: add HWRM vnic free function
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (15 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
                                         ` (22 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Frees a vnic allocated by vnic_alloc.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 21 +++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 82 ++++++++++++++++++++++++++++++++++
 3 files changed, 104 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index ecd4718..d716b67 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -510,6 +510,27 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 62dc801..887ad2d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,7 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
+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_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index ba0e054..93d50fb 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -90,6 +90,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
+#define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #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))
@@ -3267,6 +3268,87 @@ struct hwrm_vnic_alloc_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_free */
+/*
+ * Description: Free a VNIC resource. Idle any resources associated with the
+ * VNIC as well as the VNIC. Reset and release all resources associated with the
+ * VNIC.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_vnic_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Logical vnic ID */
+	uint32_t vnic_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 19/40] bnxt: add HWRM vnic cfg function
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (16 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 18/40] bnxt: add HWRM vnic free function Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 12:04                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
                                         ` (21 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Configurs a vnic allocaed by vnic_alloc function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  34 ++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 155 +++++++++++++++++++++++++++++++++
 3 files changed, 191 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d716b67..2a18cf3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -510,6 +510,40 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 887ad2d..b5cf090 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,8 +59,9 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
-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_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_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 93d50fb..b74f9f9 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -91,6 +91,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
+#define HWRM_VNIC_CFG			(UINT32_C(0x42))
 #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))
@@ -3268,6 +3269,160 @@ struct hwrm_vnic_alloc_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_vnic_cfg */
+/* Description: Configure the RX VNIC structure. */
+
+/* Input (40 bytes) */
+struct hwrm_vnic_cfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/*
+	 * When this bit is '1', the VNIC is requested to be the default VNIC
+	 * for the function.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC is being configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled on this
+	 * VNIC.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC is being configured to buffer receive
+	 * packets in the hardware until the host posts new receive buffers. If
+	 * set to '0', then bd_stall is being configured to be disabled on this
+	 * VNIC.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE		UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC is being configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is not
+	 * configured to be operating in dual VNIC mode.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	/*
+	 * When this flag is set to '1', the VNIC is requested to be configured
+	 * to receive only RoCE traffic. If this flag is set to '0', then this
+	 * flag shall be ignored by the HWRM. If roce_dual_vnic_mode flag is set
+	 * to '1', then the HWRM client shall not set this flag to '1'.
+	 */
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	uint32_t flags;
+
+	/* This bit must be '1' for the dflt_ring_grp field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_DFLT_RING_GRP	UINT32_C(0x1)
+	/* This bit must be '1' for the rss_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE		UINT32_C(0x2)
+	/* This bit must be '1' for the cos_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE		UINT32_C(0x4)
+	/* This bit must be '1' for the lb_rule field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE		UINT32_C(0x8)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_VNIC_CFG_INPUT_ENABLES_MRU			UINT32_C(0x10)
+	uint32_t enables;
+
+	/* Logical vnic ID */
+	uint16_t vnic_id;
+
+	/*
+	 * Default Completion ring for the VNIC. This ring will be chosen if
+	 * packet does not match any RSS rules and if there is no COS rule.
+	 */
+	uint16_t dflt_ring_grp;
+
+	/*
+	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if there is no
+	 * RSS rule.
+	 */
+	uint16_t rss_rule;
+
+	/*
+	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if there is no
+	 * COS rule.
+	 */
+	uint16_t cos_rule;
+
+	/*
+	 * RSS ID for load balancing rule/table structure. 0xFF... (All Fs) if
+	 * there is no LB rule.
+	 */
+	uint16_t lb_rule;
+
+	/*
+	 * The maximum receive unit of the vnic. Each vnic is associated with a
+	 * function. The vnic mru value overwrites the mru setting of the
+	 * associated function. The HWRM shall make sure that vnic mru does not
+	 * exceed the mru of the port the function is associated with.
+	 */
+	uint16_t mru;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_cfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_free */
 /*
  * Description: Free a VNIC resource. Idle any resources associated with the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (17 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 12:06                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
                                         ` (20 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

More HWRM calls.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  38 ++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 153 +++++++++++++++++++++++++++++++++
 3 files changed, 193 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 2a18cf3..4609862 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -544,6 +544,44 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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_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_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b5cf090..b7f6b20 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -61,6 +61,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp);
 
 int bnxt_hwrm_vnic_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_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index b74f9f9..34f66c5 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -92,6 +92,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
+#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))
@@ -3625,6 +3627,157 @@ struct hwrm_vnic_rss_cfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* Input (16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* rss_cos_lb_ctx_id is 16 b */
+	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;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_free */
+/* Description: This function can be used to free COS/Load Balance context. */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_rss_cos_lb_ctx_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint16_t rss_cos_lb_ctx_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* Output (32 bytes) */
 struct hwrm_queue_qportcfg_output {
 	/*
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (18 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 12:14                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
                                         ` (19 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Used to enable RSS configuration

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 24 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  2 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  1 +
 3 files changed, 27 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 4609862..6e37315 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -603,6 +603,30 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+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;
+}
+
 /*
  * HWRM utility functions
  */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b7f6b20..7c12c6d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -64,6 +64,8 @@ int bnxt_hwrm_vnic_cfg(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_ctx_free(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_rss_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic);
 
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 34f66c5..5b8895c 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -92,6 +92,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
+#define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
 #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))
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 22/40] bnxt: add L2 Rx mask set/clear functions
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (19 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
                                         ` (18 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Allows setting and clearing L2 context RX masks per vnic

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  45 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   3 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 135 +++++++++++++++++++++++++++++++++
 3 files changed, 183 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6e37315..44c6e80 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -141,6 +141,51 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 	}
 
+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_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 7c12c6d..915cf2a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -42,6 +42,9 @@
 struct bnxt;
 struct bnxt_filter_info;
 struct bnxt_cp_ring_info;
+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_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 5b8895c..89a1d6f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1781,6 +1781,141 @@ struct hwrm_cfa_l2_filter_free_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_cfa_l2_set_rx_mask */
+/* Description: This command will set rx mask of the function. */
+
+/* Input (40 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* VNIC ID */
+	uint32_t vnic_id;
+
+	/* Reserved for future use. */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_RESERVED	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the function is requested to accept multi-cast
+	 * packets specified by the multicast addr table.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the function is requested to accept all multi-
+	 * cast packets.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the function is requested to accept broadcast
+	 * packets.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the function is requested to be put in the
+	 * promiscuous mode. The HWRM should accept any function to set up
+	 * promiscuous mode. The HWRM shall follow the semantics below for the
+	 * promiscuous mode support. # When partitioning is not enabled on a
+	 * port (i.e. single PF on the port), then the PF shall be allowed to be
+	 * in the promiscuous mode. When the PF is in the promiscuous mode, then
+	 * it shall receive all host bound traffic on that port. # When
+	 * partitioning is enabled on a port (i.e. multiple PFs per port) and a
+	 * PF on that port is in the promiscuous mode, then the PF receives all
+	 * traffic within that partition as identified by a unique identifier
+	 * for the PF (e.g. S-Tag). If a unique outer VLAN for the PF is
+	 * specified, then the setting of promiscuous mode on that PF shall
+	 * result in the PF receiving all host bound traffic with matching outer
+	 * VLAN. # A VF shall can be set in the promiscuous mode. In the
+	 * promiscuous mode, the VF does not receive any traffic unless a unique
+	 * outer VLAN for the VF is specified. If a unique outer VLAN for the VF
+	 * is specified, then the setting of promiscuous mode on that VF shall
+	 * result in the VF receiving all host bound traffic with the matching
+	 * outer VLAN. # The HWRM shall allow the setting of promiscuous mode on
+	 * a function independently from the promiscuous mode settings on other
+	 * functions.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS	UINT32_C(0x10)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be set up to
+	 * cover multicast/broadcast filters for the outermost Layer 2
+	 * destination MAC address field.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST	UINT32_C(0x20)
+	uint32_t mask;
+
+	/* This is the address for mcast address tbl. */
+	uint64_t mc_tbl_addr;
+
+	/*
+	 * This value indicates how many entries in mc_tbl are valid. Each entry
+	 * is 6 bytes.
+	 */
+	uint32_t num_mc_entries;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_exec_fwd_resp */
 /*
  * Description: This command is used to send an encapsulated request to the
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 23/40] bnxt: add HWRM stats context allocation
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (20 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 12:23                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
                                         ` (17 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add HWRM code to allocate a statistics context and a helper function
to allocate one for evert completion ring.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 52 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  3 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 89 ++++++++++++++++++++++++++++++++++
 3 files changed, 144 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 44c6e80..2993aef 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -525,6 +525,31 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	return rc;
 }
 
+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_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0, i, j;
@@ -701,6 +726,33 @@ int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
 	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 */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 915cf2a..b4cc3b6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -59,6 +59,8 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
+			     struct bnxt_cp_ring_info *cpr, unsigned idx);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
@@ -70,6 +72,7 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 
+int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 89a1d6f..de3eb0e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -99,6 +99,7 @@ typedef struct ctx_hw_stats64 {
 #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 HWRM_STAT_CTX_ALLOC		(UINT32_C(0xb0))
 #define HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
@@ -3232,6 +3233,94 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a stat
+ * context.
+ */
+
+/* Input (32 bytes) */
+struct hwrm_stat_ctx_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This is the address for statistic block. */
+	uint64_t stats_dma_addr;
+
+	/*
+	 * The statistic block update period in ms. e.g. 250ms, 500ms, 750ms,
+	 * 1000ms.
+	 */
+	uint32_t update_period_ms;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_stat_ctx_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This is the statistics context ID value. */
+	uint32_t stat_ctx_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_clr_stats */
 /* Description: This command clears statistics of a context. */
 
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (21 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 12:45                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 25/40] bnxt: add ring group " Stephen Hurd
                                         ` (16 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add HWRM calls to allocate and free TX/RX/CMPL rings along with
the associated structs and definitions.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 108 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   7 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 305 +++++++++++++++++++++++++++++++++
 3 files changed, 420 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 2993aef..6a92089 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -504,6 +504,114 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 	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_POLL;
+		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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b4cc3b6..40accbc 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -58,6 +58,13 @@ int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
+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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned idx);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index de3eb0e..16ac528 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -93,6 +93,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
 #define HWRM_VNIC_CFG			(UINT32_C(0x42))
 #define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
+#define HWRM_RING_ALLOC			(UINT32_C(0x50))
+#define HWRM_RING_FREE			(UINT32_C(0x51))
 #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))
@@ -3233,6 +3235,309 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
+/* hwrm_ring_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a ring.
+ */
+
+/* Input (80 bytes) */
+struct hwrm_ring_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This bit must be '1' for the Reserved1 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED1		UINT32_C(0x1)
+	/* This bit must be '1' for the Reserved2 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED2		UINT32_C(0x2)
+	/* This bit must be '1' for the Reserved3 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED3		UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the stat_ctx_id_valid field to be
+	 * configured.
+	 */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID	UINT32_C(0x8)
+	/* This bit must be '1' for the Reserved4 field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RESERVED4		UINT32_C(0x10)
+	/* This bit must be '1' for the max_bw_valid field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_MAX_BW_VALID	UINT32_C(0x20)
+	uint32_t enables;
+
+	/* Ring Type. */
+		/* Completion Ring (CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	(UINT32_C(0x0) << 0)
+		/* TX Ring (TR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	(UINT32_C(0x1) << 0)
+		/* RX Ring (RR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	(UINT32_C(0x2) << 0)
+	uint8_t ring_type;
+
+	uint8_t unused_0;
+	uint16_t unused_1;
+
+	/* This value is a pointer to the page table for the Ring. */
+	uint64_t page_tbl_addr;
+
+	/* First Byte Offset of the first entry in the first page. */
+	uint32_t fbo;
+
+	/*
+	 * Actual page size in 2^page_size. The supported range is increments in
+	 * powers of 2 from 16 bytes to 1GB. - 4 = 16 B Page size is 16 B. - 12
+	 * = 4 KB Page size is 4 KB. - 13 = 8 KB Page size is 8 KB. - 16 = 64 KB
+	 * Page size is 64 KB. - 22 = 2 MB Page size is 2 MB. - 23 = 4 MB Page
+	 * size is 4 MB. - 31 = 1 GB Page size is 1 GB.
+	 */
+	uint8_t page_size;
+
+	/*
+	 * This value indicates the depth of page table. For this version of the
+	 * specification, value other than 0 or 1 shall be considered as an
+	 * invalid value. When the page_tbl_depth = 0, then it is treated as a
+	 * special case with the following. 1. FBO and page size fields are not
+	 * valid. 2. page_tbl_addr is the physical address of the first element
+	 * of the ring.
+	 */
+	uint8_t page_tbl_depth;
+
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * Number of 16B units in the ring. Minimum size for a ring is 16 16B
+	 * entries.
+	 */
+	uint32_t length;
+
+	/*
+	 * Logical ring number for the ring to be allocated. This value
+	 * determines the position in the doorbell area where the update to the
+	 * ring will be made. For completion rings, this value is also the MSI-X
+	 * vector number for the function the completion ring is associated
+	 * with.
+	 */
+	uint16_t logical_id;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This value
+	 * indicates what completion ring the TX ring is associated with.
+	 */
+	uint16_t cmpl_ring_id;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This value
+	 * indicates what CoS queue the TX ring is associated with.
+	 */
+	uint16_t queue_id;
+
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved1;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint16_t reserved2;
+
+	uint8_t unused_6;
+	uint8_t unused_7;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved3;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. This input
+	 * indicates what statistics context this ring should be associated
+	 * with.
+	 */
+	uint32_t stat_ctx_id;
+
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t reserved4;
+
+	/*
+	 * This field is used only when ring_type is a TX ring. Maximum BW
+	 * allocated to this TX ring in Mbps. The HWRM will translate this value
+	 * into byte counter and time interval used for this ring inside the
+	 * device.
+	 */
+	uint32_t max_bw;
+
+	/*
+	 * This field is used only when ring_type is a Completion ring. This
+	 * value indicates what interrupt mode should be used on this completion
+	 * ring. Note: In the legacy interrupt mode, no more than 16 completion
+	 * rings are allowed.
+	 */
+		/* Legacy INTA */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY	(UINT32_C(0x0) << 0)
+		/* Reserved */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	(UINT32_C(0x1) << 0)
+		/* MSI-X */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	(UINT32_C(0x2) << 0)
+		/* No Interrupt - Polled mode */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	(UINT32_C(0x3) << 0)
+	uint8_t int_mode;
+
+	uint8_t unused_8[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_ring_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* Physical number of ring allocated. */
+	uint16_t ring_id;
+
+	/* Logical number of ring allocated. */
+	uint16_t logical_ring_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ring_free */
+/*
+ * Description: This command is used to free a ring and associated resources.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_ring_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Ring Type. */
+		/* Completion Ring (CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	(UINT32_C(0x0) << 0)
+		/* TX Ring (TR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	(UINT32_C(0x1) << 0)
+		/* RX Ring (RR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	(UINT32_C(0x2) << 0)
+	uint8_t ring_type;
+
+	uint8_t unused_0;
+
+	/* Physical number of ring allocated. */
+	uint16_t ring_id;
+
+	uint32_t unused_1;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_alloc */
 /*
  * Description: This command allocates and does basic preparation for a stat
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 25/40] bnxt: add ring group alloc/free functions
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (22 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 26/40] bnxt: add HWRM stat context free function Stephen Hurd
                                         ` (15 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add HWRM ring group add/free functions and associated structs and
definitions.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  84 +++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   4 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 185 +++++++++++++++++++++++++++++++++
 3 files changed, 273 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6a92089..027a2e8 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -612,6 +612,47 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 	return 0;
 }
 
+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_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_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
 	int rc = 0;
@@ -861,6 +902,49 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 	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;
+}
+
 void bnxt_free_hwrm_resources(struct bnxt *bp)
 {
 	/* Release memzone */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 40accbc..b65d692 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -64,6 +64,8 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 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_ring_grp_alloc(struct bnxt *bp, unsigned idx);
+int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx);
 
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
@@ -81,6 +83,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp);
+int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 16ac528..12a28ba 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -95,6 +95,8 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_VNIC_RSS_CFG		(UINT32_C(0x46))
 #define HWRM_RING_ALLOC			(UINT32_C(0x50))
 #define HWRM_RING_FREE			(UINT32_C(0x51))
+#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))
@@ -3538,6 +3540,189 @@ struct hwrm_ring_free_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_ring_grp_alloc */
+/*
+ * Description: This API allocates and does basic preparation for a ring group.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ring_grp_alloc_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This value identifies the CR associated with the ring group. */
+	uint16_t cr;
+
+	/* This value identifies the main RR associated with the ring group. */
+	uint16_t rr;
+
+	/*
+	 * This value identifies the aggregation RR associated with the ring
+	 * group. If this value is 0xFF... (All Fs), then no Aggregation ring
+	 * will be set.
+	 */
+	uint16_t ar;
+
+	/*
+	 * This value identifies the statistics context associated with the ring
+	 * group.
+	 */
+	uint16_t sc;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_grp_alloc_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/*
+	 * This is the ring group ID value. Use this value to program the
+	 * default ring group for the VNIC or as table entries in an RSS/COS
+	 * context.
+	 */
+	uint32_t ring_group_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
+/* hwrm_ring_grp_free */
+/*
+ * Description: This API frees a ring group and associated resources. # If a
+ * ring in the ring group is reset or free, then the associated rings in the
+ * ring group shall also be reset/free using hwrm_ring_free. # A function driver
+ * shall always use hwrm_ring_grp_free after freeing all rings in a group. # As
+ * a part of executing this command, the HWRM shall reset all associated ring
+ * group resources.
+ */
+
+/* Input (24 bytes) */
+struct hwrm_ring_grp_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* This is the ring group ID value. */
+	uint32_t ring_group_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+struct hwrm_ring_grp_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_alloc */
 /*
  * Description: This command allocates and does basic preparation for a stat
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 26/40] bnxt: add HWRM stat context free function
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (23 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 25/40] bnxt: add ring group " Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 13:15                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 27/40] bnxt: add struct forward decl Stephen Hurd
                                         ` (14 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add function and associated structures and definitions as well as
some convenienct functions for manipulating the state of the entire
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 219 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |  10 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  81 ++++++++++++
 3 files changed, 310 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 027a2e8..b5bc473 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -43,8 +43,10 @@
 #include "bnxt_filter.h"
 #include "bnxt_hwrm.h"
 #include "bnxt_rxq.h"
+#include "bnxt_rxr.h"
 #include "bnxt_ring.h"
 #include "bnxt_txq.h"
+#include "bnxt_txr.h"
 #include "bnxt_vnic.h"
 #include "hsi_struct_def_dpdk.h"
 
@@ -206,6 +208,49 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 	return 0;
 }
 
+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_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd)
 {
 	int rc;
@@ -699,6 +744,28 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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 = HWRM_NA_SIGNATURE;
+	bp->grp_info[idx].fw_stats_ctx = cpr->hw_stats_ctx_id;
+
+	return rc;
+}
+
 int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0, i, j;
@@ -875,6 +942,28 @@ int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp)
 	return 0;
 }
 
+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 != HWRM_NA_SIGNATURE) {
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, idx);
+			if (rc)
+				return rc;
+		}
+	}
+	return 0;
+}
+
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 {
 	unsigned i;
@@ -925,6 +1014,84 @@ int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 	return rc;
 }
 
+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_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 {
 	uint16_t i;
@@ -972,6 +1139,58 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 	return 0;
 }
 
+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;
+}
+
+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;
+}
+
+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_eth_link_duplex(uint32_t conf_link_speed)
 {
 	uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b65d692..b7a3f24 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -47,6 +47,9 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp,
 int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
+int bnxt_hwrm_set_filter(struct bnxt *bp,
+			 struct bnxt_vnic_info *vnic,
+			 struct bnxt_filter_info *filter);
 
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, void *fwd_cmd);
 
@@ -70,6 +73,8 @@ int bnxt_hwrm_ring_grp_free(struct bnxt *bp, unsigned idx);
 int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr);
 int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned idx);
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
+			    struct bnxt_cp_ring_info *cpr, unsigned idx);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
@@ -83,8 +88,13 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
+int bnxt_free_all_hwrm_stat_ctxs(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_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);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_hwrm_resources(struct bnxt *bp);
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up);
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 12a28ba..6644c8e 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -104,6 +104,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_CFA_L2_FILTER_CFG		(UINT32_C(0x92))
 #define HWRM_CFA_L2_SET_RX_MASK		(UINT32_C(0x93))
 #define HWRM_STAT_CTX_ALLOC		(UINT32_C(0xb0))
+#define HWRM_STAT_CTX_FREE		(UINT32_C(0xb1))
 #define HWRM_STAT_CTX_CLR_STATS		(UINT32_C(0xb3))
 #define HWRM_EXEC_FWD_RESP		(UINT32_C(0xd0))
 
@@ -3888,6 +3889,86 @@ struct hwrm_stat_ctx_clr_stats_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_free */
+/* Description: This command is used to free a stat context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_free_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* ID of the statistics context that is being queried. */
+	uint32_t stat_ctx_id;
+
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_stat_ctx_free_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This is the statistics context ID value. */
+	uint32_t stat_ctx_id;
+
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_vnic_alloc */
 /*
  * Description: This VNIC is a resource in the RX side of the chip that is used
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 27/40] bnxt: add struct forward decl
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (24 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 26/40] bnxt: add HWRM stat context free function Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 28/40] bnxt: add ring allocation and group init Stephen Hurd
                                         ` (13 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add missing forward declaration of struct bnxt_ring_struct to avoid
requiring additional headers for the function declaation.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.h | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b7a3f24..8ad91d3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -42,6 +42,7 @@
 struct bnxt;
 struct bnxt_filter_info;
 struct bnxt_cp_ring_info;
+struct bnxt_ring_struct;
 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);
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 28/40] bnxt: add ring allocation and group init
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (25 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 27/40] bnxt: add struct forward decl Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 13:24                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
                                         ` (12 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add a function to initialize ring groups, and a function to
allocate the rings via HWRM.

This should be the last functionality needed to add start/stop
device operations.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ring.c | 119 +++++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_ring.h |   2 +
 2 files changed, 121 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 69837bf..8852e28 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -35,8 +35,11 @@
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
+#include "bnxt_hwrm.h"
 #include "bnxt_ring.h"
+#include "bnxt_rxq.h"
 #include "bnxt_rxr.h"
+#include "bnxt_txq.h"
 #include "bnxt_txr.h"
 
 #include "hsi_struct_def_dpdk.h"
@@ -58,6 +61,19 @@ void bnxt_free_ring(struct bnxt_ring_struct *ring)
 }
 
 /*
+ * Ring groups
+ */
+
+void bnxt_init_ring_grps(struct bnxt *bp)
+{
+	unsigned i;
+
+	for (i = 0; i < bp->max_ring_grps; i++)
+		memset(&bp->grp_info[i], (uint8_t)HWRM_NA_SIGNATURE,
+		       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.
@@ -185,3 +201,106 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	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, HWRM_NA_SIGNATURE);
+		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, HWRM_NA_SIGNATURE);
+		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, HWRM_NA_SIGNATURE);
+		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
index dfa0401..4e7c6db 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -91,10 +91,12 @@ 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
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 29/40] bnxt: work around HWRM error when creating rings
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (26 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 28/40] bnxt: add ring allocation and group init Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 13:25                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
                                         ` (11 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Some HWRM versions will stop responding if we request poll mode interrupt.
As a workaround, request an MSI interrupt even though we never enable it.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index b5bc473..897e766 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -581,7 +581,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
 		req.ring_type = ring_type;
-		req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_POLL;
+		/*
+		 * TODO: Some HWRM versions crash with
+		 * HWRM_RING_ALLOC_INPUT_INT_MODE_POLL
+		 */
+		req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX;
 		req.length = rte_cpu_to_le_32(ring->ring_size);
 		break;
 	default:
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (27 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 13:39                         ` Bruce Richardson
  2016-05-13 22:46                       ` [PATCH v2 31/40] bnxt: add start/stop/link update operations Stephen Hurd
                                         ` (10 subsequent siblings)
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add HWRM port pgy qcfg HWRM command and bnxt_get_hwrm_link_config()
wrapper which parses the link state.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 120 +++++
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 790 +++++++++++++++++++++++++++++++++
 3 files changed, 911 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 897e766..1a1f108 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -521,6 +521,43 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 	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_queue_qportcfg(struct bnxt *bp)
 {
 	int rc = 0;
@@ -1326,6 +1363,89 @@ static uint16_t bnxt_parse_eth_link_speed_mask(uint32_t link_speed)
 	return ret;
 }
 
+static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
+{
+	uint32_t eth_link_speed = ETH_SPEED_NUM_NONE;
+
+	switch (hw_link_speed) {
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
+		eth_link_speed = ETH_SPEED_NUM_100M;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB:
+		eth_link_speed = ETH_SPEED_NUM_1G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB:
+		eth_link_speed = ETH_SPEED_NUM_2_5G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB:
+		eth_link_speed = ETH_SPEED_NUM_10G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB:
+		eth_link_speed = ETH_SPEED_NUM_20G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB:
+		eth_link_speed = ETH_SPEED_NUM_25G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB:
+		eth_link_speed = ETH_SPEED_NUM_40G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB:
+		eth_link_speed = ETH_SPEED_NUM_50G;
+		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
+	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_hw_link_duplex(uint16_t hw_link_duplex)
+{
+	uint16_t eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+
+	switch (hw_link_duplex) {
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH:
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL:
+		eth_link_duplex = ETH_LINK_FULL_DUPLEX;
+		break;
+	case HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF:
+		eth_link_duplex = ETH_LINK_HALF_DUPLEX;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "HWRM link duplex %d not defined\n",
+			hw_link_duplex);
+		break;
+	}
+	return eth_link_duplex;
+}
+
+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_10M;
+	link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
+	link->link_status = link_info->link_up;
+	link->link_autoneg = link_info->auto_mode == \
+		HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE ? \
+		ETH_LINK_SPEED_FIXED : ETH_LINK_SPEED_AUTONEG;
+exit:
+	return rc;
+}
+
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 8ad91d3..2bcb4da 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -98,6 +98,7 @@ int bnxt_clear_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 void bnxt_free_all_hwrm_resources(struct bnxt *bp);
 void bnxt_free_hwrm_resources(struct bnxt *bp);
 int bnxt_alloc_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/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 6644c8e..8656b92 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -88,6 +88,7 @@ typedef struct ctx_hw_stats64 {
 #define HWRM_FUNC_DRV_UNRGTR		(UINT32_C(0x1a))
 #define HWRM_FUNC_DRV_RGTR		(UINT32_C(0x1d))
 #define HWRM_PORT_PHY_CFG		(UINT32_C(0x20))
+#define HWRM_PORT_PHY_QCFG		(UINT32_C(0x27))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
 #define HWRM_VNIC_ALLOC			(UINT32_C(0x40))
 #define HWRM_VNIC_FREE			(UINT32_C(0x41))
@@ -2842,6 +2843,795 @@ struct hwrm_port_phy_cfg_output {
 	uint8_t valid;
 } __attribute__((packed));
 
+/* hwrm_port_phy_qcfg */
+/* Description: This command queries the PHY configuration for the port. */
+/* Input (24 bytes) */
+
+struct hwrm_port_phy_qcfg_input {
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t req_type;
+
+	/*
+	 * This value indicates the what completion ring the request will be
+	 * optionally completed on. If the value is -1, then no CR completion
+	 * will be generated. Any other value must be a valid CR ring_id value
+	 * for this function.
+	 */
+	uint16_t cmpl_ring;
+
+	/* This value indicates the command sequence number. */
+	uint16_t seq_id;
+
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint16_t target_id;
+
+	/*
+	 * This is the host address where the response will be written when the
+	 * request is complete. This area must be 16B aligned and must be
+	 * cleared to zero before the request is made.
+	 */
+	uint64_t resp_addr;
+
+	/* Port ID of port that is to be queried. */
+	uint16_t port_id;
+
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (96 bytes) */
+struct hwrm_port_phy_qcfg_output {
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t error_code;
+
+	/* This field returns the type of original request. */
+	uint16_t req_type;
+
+	/* This field provides original sequence number of the command. */
+	uint16_t seq_id;
+
+	/*
+	 * This field is the length of the response in bytes. The last byte of
+	 * the response is a valid flag that will read as '1' when the command
+	 * has been completely written to memory.
+	 */
+	uint16_t resp_len;
+
+	/* This value indicates the current link status. */
+		/* There is no link or cable detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_NO_LINK	(UINT32_C(0x0) << 0)
+		/* There is no link, but a cable has been detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	(UINT32_C(0x1) << 0)
+		/* There is a link. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	(UINT32_C(0x2) << 0)
+	uint8_t link;
+
+	uint8_t unused_0;
+
+	/* This value indicates the current link speed of the connection. */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t link_speed;
+
+	/* This value is indicates the duplex of the current connection. */
+		/* Half Duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	(UINT32_C(0x0) << 0)
+		/* Full duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	(UINT32_C(0x1) << 0)
+	uint8_t duplex;
+
+	/*
+	 * This value is used to indicate the current pause configuration. When
+	 * autoneg is enabled, this value represents the autoneg results of
+	 * pause configuration.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX	UINT32_C(0x2)
+	uint8_t pause;
+
+	/*
+	 * The supported speeds for the port. This is a bit mask. For each speed
+	 * that is supported, the corrresponding bit will be set to '1'.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB \
+							UINT32_C(0x2000)
+	uint16_t support_speeds;
+
+	/*
+	 * Current setting of forced link speed. When the link speed is not
+	 * being forced, this value shall be set to 0.
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t force_link_speed;
+
+	/* Current setting of auto negotiation mode. */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS \
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK \
+							(UINT32_C(0x4) << 0)
+	uint8_t auto_mode;
+
+	/*
+	 * Current setting of pause autonegotiation. Move autoneg_pause flag
+	 * here.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages has been
+	 * requested. Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+	/*
+	 * When set to 1, the advertisement of pause is enabled. # When the
+	 * auto_mode is not set to none and this flag is set to 1, then the
+	 * auto_pause bits on this port are being advertised and autoneg pause
+	 * results are being interpreted. # When the auto_mode is not set to
+	 * none and this flag is set to 0, the pause is forced as indicated in
+	 * force_pause, and also advertised as auto_pause bits, but the autoneg
+	 * results are not interpreted since the pause configuration is being
+	 * forced. # When the auto_mode is set to none and this flag is set to
+	 * 1, auto_pause bits should be ignored and should be set to 0.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE \
+							UINT32_C(0x4)
+	uint8_t auto_pause;
+
+	/*
+	 * Current setting for auto_link_speed. This field is only valid when
+	 * auto_mode is set to "one_speed" or "one_or_below".
+	 */
+		/* 100Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB \
+							(UINT32_C(0x1) << 0)
+		/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB \
+							(UINT32_C(0xa) << 0)
+		/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB \
+							(UINT32_C(0x14) << 0)
+		/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB \
+							(UINT32_C(0x19) << 0)
+		/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB \
+							(UINT32_C(0x64) << 0)
+		/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB \
+							(UINT32_C(0xc8) << 0)
+		/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB \
+							(UINT32_C(0xfa) << 0)
+		/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB \
+							(UINT32_C(0x190) << 0)
+		/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB \
+							(UINT32_C(0x1f4) << 0)
+		/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB \
+							(UINT32_C(0x3e8) << 0)
+		/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB \
+							(UINT32_C(0xffff) << 0)
+	uint16_t auto_link_speed;
+
+	/*
+	 * Current setting for auto_link_speed_mask that is used to advertise
+	 * speeds during autonegotiation. This field is only valid when
+	 * auto_mode is set to "mask". The speeds specified in this field shall
+	 * be a subset of supported speeds on this port.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MB \
+							UINT32_C(0x2000)
+	uint16_t auto_link_speed_mask;
+
+	/* Current setting for wirespeed. */
+		/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_OFF	(UINT32_C(0x0) << 0)
+		/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIRESPEED_ON	(UINT32_C(0x1) << 0)
+	uint8_t wirespeed;
+
+	/* Current setting for loopback. */
+		/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	(UINT32_C(0x0) << 0)
+		/*
+		 * The HW will be configured with local loopback such that host
+		 * data is sent back to the host without modification.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL	(UINT32_C(0x1) << 0)
+		/*
+		 * The HW will be configured with remote loopback such that port
+		 * logic will send packets back out the transmitter that are
+		 * received.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE	(UINT32_C(0x2) << 0)
+	uint8_t lpbk;
+
+	/*
+	 * Current setting of forced pause. When the pause configuration is not
+	 * being forced, then this value shall be set to 0.
+	 */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX \
+							UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX \
+							UINT32_C(0x2)
+	uint8_t force_pause;
+
+	/*
+	 * This value indicates the current status of the optics module on this
+	 * port.
+	 */
+		/* Module is inserted and accepted */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Module is rejected and transmit side Laser is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX \
+							(UINT32_C(0x1) << 0)
+		/* Module mismatch warning. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG \
+							(UINT32_C(0x2) << 0)
+		/* Module is rejected and powered down. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN \
+							(UINT32_C(0x3) << 0)
+		/* Module is not inserted. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+							(UINT32_C(0x4) << 0)
+		/* Module status is not applicable. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+							(UINT32_C(0xff) << 0)
+	uint8_t module_status;
+
+	/* Current setting for preemphasis. */
+	uint32_t preemphasis;
+
+	/* This field represents the major version of the PHY. */
+	uint8_t phy_maj;
+
+	/* This field represents the minor version of the PHY. */
+	uint8_t phy_min;
+
+	/* This field represents the build version of the PHY. */
+	uint8_t phy_bld;
+
+	/* This value represents a PHY type. */
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* BASE-CR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR \
+							(UINT32_C(0x1) << 0)
+		/* BASE-KR4 (Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4 \
+							(UINT32_C(0x2) << 0)
+		/* BASE-LR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR \
+							(UINT32_C(0x3) << 0)
+		/* BASE-SR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR \
+							(UINT32_C(0x4) << 0)
+		/* BASE-KR2 (Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2 \
+							(UINT32_C(0x5) << 0)
+		/* BASE-KX */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX \
+							(UINT32_C(0x6) << 0)
+		/* BASE-KR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR \
+							(UINT32_C(0x7) << 0)
+		/* BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET \
+							(UINT32_C(0x8) << 0)
+		/* EEE capable BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE \
+							(UINT32_C(0x9) << 0)
+		/* SGMII connected external PHY */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY \
+							(UINT32_C(0xa) << 0)
+	uint8_t phy_type;
+
+	/* This value represents a media type. */
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 0)
+		/* Twisted Pair */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	(UINT32_C(0x1) << 0)
+		/* Direct Attached Copper */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC \
+							(UINT32_C(0x2) << 0)
+		/* Fiber */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE \
+							(UINT32_C(0x3) << 0)
+	uint8_t media_type;
+
+	/* This value represents a transceiver type. */
+		/* PHY and MAC are in the same package */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_INTERNAL \
+							(UINT32_C(0x1) << 0)
+		/* PHY and MAC are in different packages */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+							(UINT32_C(0x2) << 0)
+	uint8_t xcvr_pkg_type;
+
+	/*
+	 * This field represents flags related to EEE configuration. These EEE
+	 * configuration flags are valid only when the auto_mode is not set to
+	 * none (in other words autonegotiation is enabled).
+	 */
+	/* This field represents PHY address. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_MASK	UINT32_C(0x1f)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_ADDR_SFT	0
+	/*
+	 * When set to 1, Energy Efficient Ethernet (EEE) mode is enabled.
+	 * Speeds for autoneg with EEE mode enabled are based on
+	 * eee_link_speed_mask.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED \
+							UINT32_C(0x20)
+	/*
+	 * This flag is valid only when eee_enabled is set to 1. # If
+	 * eee_enabled is set to 0, then EEE mode is disabled and this flag
+	 * shall be ignored. # If eee_enabled is set to 1 and this flag is set
+	 * to 1, then Energy Efficient Ethernet (EEE) mode is enabled and in
+	 * use. # If eee_enabled is set to 1 and this flag is set to 0, then
+	 * Energy Efficient Ethernet (EEE) mode is enabled but is currently not
+	 * in use.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE \
+							UINT32_C(0x40)
+	/*
+	 * This flag is valid only when eee_enabled is set to 1. # If
+	 * eee_enabled is set to 0, then EEE mode is disabled and this flag
+	 * shall be ignored. # If eee_enabled is set to 1 and this flag is set
+	 * to 1, then Energy Efficient Ethernet (EEE) mode is enabled and TX LPI
+	 * is enabled. # If eee_enabled is set to 1 and this flag is set to 0,
+	 * then Energy Efficient Ethernet (EEE) mode is enabled but TX LPI is
+	 * disabled.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI \
+							UINT32_C(0x80)
+	/*
+	 * This field represents flags related to EEE configuration. These EEE
+	 * configuration flags are valid only when the auto_mode is not set to
+	 * none (in other words autonegotiation is enabled).
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK \
+							UINT32_C(0xe0)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT	5
+	uint8_t eee_config_phy_addr;
+
+	/* Reserved field, set to 0 */
+	/*
+	 * When set to 1, the parallel detection is used to determine the speed
+	 * of the link partner. Parallel detection is used when a
+	 * autonegotiation capable device is connected to a link parter that is
+	 * not capable of autonegotiation.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PARALLEL_DETECT \
+							UINT32_C(0x1)
+	/* Reserved field, set to 0 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_RESERVED_MASK	UINT32_C(0xfe)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_RESERVED_SFT	1
+	uint8_t parallel_detect;
+
+	/*
+	 * The advertised speeds for the port by the link partner. Each
+	 * advertised speed will be set to '1'.
+	 */
+	/* 100Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB \
+							UINT32_C(0x2)
+	/* 1Gb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GB \
+							UINT32_C(0x8)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB \
+							UINT32_C(0x10)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2_5GB \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10GB \
+							UINT32_C(0x40)
+	/* 20Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_20GB \
+							UINT32_C(0x80)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_25GB \
+							UINT32_C(0x100)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_40GB \
+							UINT32_C(0x200)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_50GB \
+							UINT32_C(0x400)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100GB \
+							UINT32_C(0x800)
+	/* 10Mb link speed (Half-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MBHD \
+							UINT32_C(0x1000)
+	/* 10Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MB \
+							UINT32_C(0x2000)
+	uint16_t link_partner_adv_speeds;
+
+	/*
+	 * The advertised autoneg for the port by the link partner. This field
+	 * is deprecated and should be set to 0.
+	 */
+		/*
+		 * Disable autoneg or autoneg disabled. No speeds are selected.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
+							(UINT32_C(0x0) << 0)
+		/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS\
+							(UINT32_C(0x1) << 0)
+		/*
+		 * Select only the auto_link_speed speed for autoneg mode. This
+		 * mode has been DEPRECATED. An HWRM client should not use this
+		 * mode.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
+							(UINT32_C(0x2) << 0)
+		/*
+		 * Select the auto_link_speed or any speed below that speed for
+		 * autoneg. This mode has been DEPRECATED. An HWRM client should
+		 * not use this mode.
+		 */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
+							(UINT32_C(0x3) << 0)
+		/*
+		 * Select the speeds based on the corresponding link speed mask
+		 * value that is provided.
+		 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK\
+							(UINT32_C(0x4) << 0)
+	uint8_t link_partner_adv_auto_mode;
+
+	/* The advertised pause settings on the port by the link partner. */
+	/*
+	 * When this bit is '1', Generation of tx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX \
+							UINT32_C(0x1)
+	/*
+	 * When this bit is '1', Reception of rx pause messages is supported.
+	 * Disabled otherwise.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX \
+							UINT32_C(0x2)
+	uint8_t link_partner_adv_pause;
+
+	/*
+	 * Current setting for link speed mask that is used to advertise speeds
+	 * during autonegotiation when EEE is enabled. This field is valid only
+	 * when eee_enabled flags is set to 1. The speeds specified in this
+	 * field shall be a subset of speeds specified in auto_link_speed_mask.
+	 */
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+							UINT32_C(0x10)
+	/* Reserved */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	uint16_t adv_eee_link_speed_mask;
+
+	/*
+	 * Current setting for link speed mask that is advertised by the link
+	 * partner when EEE is enabled. This field is valid only when
+	 * eee_enabled flags is set to 1.
+	 */
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
+							UINT32_C(0x1)
+	/* 100Mb link speed (Full-duplex) */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_100MB \
+							UINT32_C(0x2)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD2 \
+							UINT32_C(0x4)
+	/* 1Gb link speed (Full-duplex) */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_1GB \
+							UINT32_C(0x8)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
+							UINT32_C(0x10)
+	/* Reserved */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
+							UINT32_C(0x20)
+	/* 10Gb link speed */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+							UINT32_C(0x40)
+	uint16_t link_partner_adv_eee_link_speed_mask;
+
+	/* This value represents transceiver identifier type. */
+	/*
+	 * Current setting of TX LPI timer in microseconds. This field is valid
+	 * only when_eee_enabled flag is set to 1 and tx_lpi_enabled is set to
+	 * 1.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_MASK \
+							UINT32_C(0xffffff)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_TX_LPI_TIMER_SFT         0
+	/* This value represents transceiver identifier type. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_MASK \
+							UINT32_C(0xff000000)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFT \
+							24
+		/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_UNKNOWN \
+							(UINT32_C(0x0) << 24)
+		/* SFP/SFP+/SFP28 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFP \
+							(UINT32_C(0x3) << 24)
+		/* QSFP */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP \
+							(UINT32_C(0xc) << 24)
+		/* QSFP+ */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS \
+							(UINT32_C(0xd) << 24)
+		/* QSFP28 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \
+							(UINT32_C(0x11) << 24)
+	uint32_t xcvr_identifier_type_tx_lpi_timer;
+
+	uint32_t unused_1;
+
+	/*
+	 * Up to 16 bytes of null padded ASCII string representing PHY vendor.
+	 * If the string is set to null, then the vendor name is not available.
+	 */
+	char phy_vendor_name[16];
+
+	/*
+	 * Up to 16 bytes of null padded ASCII string that identifies vendor
+	 * specific part number of the PHY. If the string is set to null, then
+	 * the vendor specific part number is not available.
+	 */
+	char phy_vendor_partnumber[16];
+
+	uint32_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+
+	/*
+	 * This field is used in Output records to indicate that the output is
+	 * completely written to RAM. This field should be read as '1' to
+	 * indicate that the output has been completely written. When writing a
+	 * command completion or response to an internal processor, the order of
+	 * writes has to be such that this field is written last.
+	 */
+	uint8_t valid;
+} __attribute__((packed));
+
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 31/40] bnxt: add start/stop/link update operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (28 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
                                         ` (9 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

BNXT driver will now minimally pass traffic with testpmd.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 267 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 267 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e1b3e3a..a91e1c2 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -40,12 +40,17 @@
 #include <rte_cycles.h>
 
 #include "bnxt.h"
+#include "bnxt_cpr.h"
+#include "bnxt_filter.h"
 #include "bnxt_hwrm.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 DRV_MODULE_NAME		"bnxt"
 static const char bnxt_version[] =
@@ -57,6 +62,175 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.device_id = 0},
 };
 
+/***********************/
+
+/*
+ * 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 */
+	rc = bnxt_init_def_ring_struct(bp, SOCKET_ID_ANY);
+	if (rc)
+		goto alloc_mem_err;
+
+	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;
+	}
+
+	/* 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
  */
@@ -174,6 +348,85 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 	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_alloc_mem(bp);
+	if (rc)
+		goto error;
+
+	rc = bnxt_init_nic(bp);
+	if (rc)
+		goto error;
+
+	return 0;
+
+error:
+	bnxt_shutdown_nic(bp);
+	bnxt_free_tx_mbufs(bp);
+	bnxt_free_rx_mbufs(bp);
+	bnxt_free_mem(bp);
+	return rc;
+}
+
+/* Unload the driver, release resources */
+static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->eth_dev->data->dev_started) {
+		/* TBD: STOP HW queues DMA */
+		eth_dev->data->dev_link.link_status = 0;
+	}
+	bnxt_shutdown_nic(bp);
+}
+
+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_100M;
+			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;
+}
+
 /*
  * Initialization
  */
@@ -181,12 +434,15 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev)
 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,
 	.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,
+	.link_update = bnxt_link_update_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -296,6 +552,15 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	else
 		memcpy(bp->mac_addr, bp->vf.mac_addr, sizeof(bp->mac_addr));
 	memcpy(&eth_dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+	bp->grp_info = rte_zmalloc("bnxt_grp_info",
+				sizeof(*bp->grp_info) * bp->max_ring_grps, 0);
+	if (!bp->grp_info) {
+		RTE_LOG(ERR, PMD,
+			"Failed to alloc %lu bytes needed to store group info table\n",
+			sizeof(*bp->grp_info) * bp->max_ring_grps);
+		rc = -ENOMEM;
+		goto error_free;
+	}
 
 	rc = bnxt_hwrm_func_driver_register(bp, 0,
 					    bp->pf.vf_req_fwd);
@@ -326,6 +591,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 
 	if (eth_dev->data->mac_addrs)
 		rte_free(eth_dev->data->mac_addrs);
+	if (bp->grp_info)
+		rte_free(bp->grp_info);
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
 	return rc;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 32/40] bnxt: add promiscuous enable/disable operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (29 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 31/40] bnxt: add start/stop/link update operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 33/40] bnxt: add all multicast " Stephen Hurd
                                         ` (8 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Enables and diables promiscuous mode.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a91e1c2..f5de4c4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -427,6 +427,34 @@ out:
 	return rc;
 }
 
+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);
+}
+
 /*
  * Initialization
  */
@@ -443,6 +471,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.tx_queue_setup = bnxt_tx_queue_setup_op,
 	.tx_queue_release = bnxt_tx_queue_release_op,
 	.link_update = bnxt_link_update_op,
+	.promiscuous_enable = bnxt_promiscuous_enable_op,
+	.promiscuous_disable = bnxt_promiscuous_disable_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 33/40] bnxt: add all multicast enable/disable operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (30 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 34/40] bnxt: add device close operation Stephen Hurd
                                         ` (7 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Enables/disables all multicast traffic.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 30 ++++++++++++++++++++++++++++++
 1 file changed, 30 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index f5de4c4..97ef0b4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -455,6 +455,34 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	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);
+}
+
 /*
  * Initialization
  */
@@ -473,6 +501,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 34/40] bnxt: add device close operation
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (31 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 33/40] bnxt: add all multicast " Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
                                         ` (6 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Frees all resources except the hwrm ones, which are required to notify
the HWRM that the driver is unloaded (these are freed in uninit()).

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 11 +++++++++++
 1 file changed, 11 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 97ef0b4..edb7427 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -390,6 +390,16 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	bnxt_shutdown_nic(bp);
 }
 
+static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	bnxt_free_tx_mbufs(bp);
+	bnxt_free_rx_mbufs(bp);
+	bnxt_free_mem(bp);
+	rte_free(eth_dev->data->mac_addrs);
+}
+
 static int bnxt_link_update_op(struct rte_eth_dev *eth_dev,
 			       int wait_to_complete)
 {
@@ -492,6 +502,7 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.dev_configure = bnxt_dev_configure_op,
 	.dev_start = bnxt_dev_start_op,
 	.dev_stop = bnxt_dev_stop_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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 35/40] bnxt: add MAC address add/remove operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (32 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 34/40] bnxt: add device close operation Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 36/40] bnxt: add dev set link up/down operations Stephen Hurd
                                         ` (5 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add/remove MAC addresses

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 69 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 69 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index edb7427..7056f98 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -400,6 +400,73 @@ static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
 	rte_free(eth_dev->data->mac_addrs);
 }
 
+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_link_update_op(struct rte_eth_dev *eth_dev,
 			       int wait_to_complete)
 {
@@ -514,6 +581,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.promiscuous_disable = bnxt_promiscuous_disable_op,
 	.allmulticast_enable = bnxt_allmulticast_enable_op,
 	.allmulticast_disable = bnxt_allmulticast_disable_op,
+	.mac_addr_add = bnxt_mac_addr_add_op,
+	.mac_addr_remove = bnxt_mac_addr_remove_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 36/40] bnxt: add dev set link up/down operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (33 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 37/40] bnxt: add reta update/query operations Stephen Hurd
                                         ` (4 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Sets link to up or down as appropriate.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7056f98..3396079 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -390,6 +390,24 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 	bnxt_shutdown_nic(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;
@@ -569,6 +587,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 37/40] bnxt: add reta update/query operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (34 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 36/40] bnxt: add dev set link up/down operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 38/40] bnxt: add RSS device operations Stephen Hurd
                                         ` (3 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Update/query reta operations

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 56 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 56 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 3396079..2503112 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -578,6 +578,60 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	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;
+}
+
 /*
  * Initialization
  */
@@ -596,6 +650,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
 	.link_update = bnxt_link_update_op,
 	.promiscuous_enable = bnxt_promiscuous_enable_op,
 	.promiscuous_disable = bnxt_promiscuous_disable_op,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 38/40] bnxt: add RSS device operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (35 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 37/40] bnxt: add reta update/query operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 39/40] bnxt: add flow control operations Stephen Hurd
                                         ` (2 subsequent siblings)
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add rss_hash_update and rss_hash_conf_get

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 117 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 117 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 2503112..d14fcae 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -62,6 +62,14 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
 	{.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)
+
 /***********************/
 
 /*
@@ -632,6 +640,113 @@ static int bnxt_reta_query_op(struct rte_eth_dev *eth_dev,
 	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;
+	}
+	if (rss_conf->rss_hf & ETH_RSS_IPV4)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_TCP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV4_UDP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+	if (rss_conf->rss_hf & ETH_RSS_IPV6)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_TCP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+	if (rss_conf->rss_hf & ETH_RSS_NONFRAG_IPV6_UDP)
+		hash_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+
+	/* 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;
+	uint32_t hash_types;
+
+	/* 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);
+		}
+
+		hash_types = vnic->hash_type;
+		rss_conf->rss_hf = 0;
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_IPV4;
+			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_TCP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV4_UDP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_IPV6;
+			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_TCP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
+		}
+		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
+			rss_conf->rss_hf |= ETH_RSS_NONFRAG_IPV6_UDP;
+			hash_types &=
+				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+		}
+		if (hash_types) {
+			RTE_LOG(ERR, PMD,
+				"Unknwon RSS config from firmware (%08x), RSS disabled",
+				vnic->hash_type);
+			return -ENOTSUP;
+		}
+	} else {
+		rss_conf->rss_hf = 0;
+	}
+	return 0;
+}
+
 /*
  * Initialization
  */
@@ -652,6 +767,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.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,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 39/40] bnxt: add flow control operations
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (36 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 38/40] bnxt: add RSS device operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-13 22:46                       ` [PATCH v2 40/40] bnxt: cleanup null pointer checks Stephen Hurd
  2016-05-25 15:02                       ` [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Bruce Richardson
  39 siblings, 0 replies; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Add flow_ctrl_get and flow_ctrl_set device operations.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 83 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 83 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d14fcae..93dac7a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -747,6 +747,87 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
 	return 0;
 }
 
+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));
+	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
  */
@@ -776,6 +857,8 @@ static struct eth_dev_ops bnxt_dev_ops = {
 	.allmulticast_disable = bnxt_allmulticast_disable_op,
 	.mac_addr_add = bnxt_mac_addr_add_op,
 	.mac_addr_remove = bnxt_mac_addr_remove_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)
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* [PATCH v2 40/40] bnxt: cleanup null pointer checks
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (37 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 39/40] bnxt: add flow control operations Stephen Hurd
@ 2016-05-13 22:46                       ` Stephen Hurd
  2016-05-26 15:20                         ` Bruce Richardson
  2016-05-25 15:02                       ` [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Bruce Richardson
  39 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-13 22:46 UTC (permalink / raw)
  To: dev

Prefer !ptr to ptr == NULL

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 10 +++++-----
 drivers/net/bnxt/bnxt_filter.c |  2 +-
 drivers/net/bnxt/bnxt_hwrm.c   |  6 +++---
 drivers/net/bnxt/bnxt_ring.c   |  2 +-
 drivers/net/bnxt/bnxt_vnic.c   |  2 +-
 5 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 93dac7a..2f1a85a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -535,7 +535,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -549,7 +549,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -563,7 +563,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -577,7 +577,7 @@ 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)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
@@ -955,7 +955,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	}
 	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) {
+	if (!eth_dev->data->mac_addrs) {
 		RTE_LOG(ERR, PMD,
 			"Failed to alloc %u bytes needed to store MAC addr tbl",
 			ETHER_ADDR_LEN * MAX_NUM_MAC_ADDR);
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index f03a1dc..d2576f7 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -165,7 +165,7 @@ int bnxt_alloc_filter_mem(struct bnxt *bp)
 	filter_mem = rte_zmalloc("bnxt_filter_info",
 				 max_filters * sizeof(struct bnxt_filter_info),
 				 0);
-	if (filter_mem == NULL) {
+	if (!filter_mem) {
 		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d filters",
 			max_filters);
 		return -ENOMEM;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1a1f108..8994c47 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -431,7 +431,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		rte_free(bp->hwrm_cmd_resp_addr);
 
 		bp->hwrm_cmd_resp_addr = rte_malloc(type, max_resp_len, 0);
-		if (bp->hwrm_cmd_resp_addr == NULL) {
+		if (!bp->hwrm_cmd_resp_addr) {
 			rc = -ENOMEM;
 			goto error;
 		}
@@ -1171,7 +1171,7 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
 	bp->max_req_len = HWRM_MAX_REQ_LEN;
 	bp->max_resp_len = HWRM_MAX_RESP_LEN;
 	bp->hwrm_cmd_resp_addr = rte_malloc(type, bp->max_resp_len, 0);
-	if (bp->hwrm_cmd_resp_addr == NULL)
+	if (!bp->hwrm_cmd_resp_addr)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
 		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
@@ -1211,7 +1211,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	struct bnxt_vnic_info *vnic;
 	unsigned i;
 
-	if (bp->vnic_info == NULL)
+	if (!bp->vnic_info)
 		return;
 
 	vnic = &bp->vnic_info[0];
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 8852e28..91f6371 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -143,7 +143,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
 					 RTE_MEMZONE_SIZE_HINT_ONLY);
-		if (mz == NULL)
+		if (!mz)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index c04c4c7..e957c0d 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -267,7 +267,7 @@ int bnxt_alloc_vnic_mem(struct bnxt *bp)
 	/* 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) {
+	if (!vnic_mem) {
 		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d VNICs",
 			max_vnics);
 		return -ENOMEM;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-13 22:45                     ` [PATCH v2 " Stephen Hurd
                                         ` (38 preceding siblings ...)
  2016-05-13 22:46                       ` [PATCH v2 40/40] bnxt: cleanup null pointer checks Stephen Hurd
@ 2016-05-25 15:02                       ` Bruce Richardson
  2016-05-25 20:59                         ` Stephen Hurd
  39 siblings, 1 reply; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 15:02 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:50PM -0700, Stephen Hurd wrote:
> Initial skeleton simply fails init.
> Add nic guide and tie into build system.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> ---
>  MAINTAINERS                                     |   5 ++
>  config/common_base                              |   5 ++
>  doc/guides/nics/bnxt.rst                        |  49 +++++++++++
>  drivers/net/Makefile                            |   1 +
>  drivers/net/bnxt/Makefile                       |  63 ++++++++++++++
>  drivers/net/bnxt/bnxt_ethdev.c                  | 104 ++++++++++++++++++++++++
>  drivers/net/bnxt/rte_pmd_bnxt_version.map       |   4 +
>  lib/librte_eal/common/include/rte_pci_dev_ids.h |  40 +++++++--
>  mk/rte.app.mk                                   |   1 +
>  9 files changed, 267 insertions(+), 5 deletions(-)
>  create mode 100644 doc/guides/nics/bnxt.rst
>  create mode 100644 drivers/net/bnxt/Makefile
>  create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
>  create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map
> 
Great to see this patchset split up finer grained, and it getting compiled from
the start. Thanks for the work.

One error that gets flagged by the automated patch checks here is that, although
you add in a new doc for the new driver in this patch, that document is not
included in the overall NIC guides document.

    /home/bruce/next-net/dpdk-next-net/doc/guides/nics/bnxt.rst:: WARNING: document isn't included in any toctree

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 02/40] bnxt: add HWRM init code
  2016-05-13 22:45                       ` [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
  0 siblings, 1 reply; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 15:05 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:51PM -0700, Stephen Hurd wrote:
> Start adding HWRM support.
> Initial commit just performs necessary HWRM queries for init, then
> fails as before.
> 
> Thee used HWRM calls so far:
> bnxt_hwrm_func_qcaps:
> 	Queries device capabilities.
> 
> bnxt_hwrm_ver_get:
> 	Gets the firmware version and interface specifications.
> 	Returns an error if the firmware on the device is not
> 	supported by the driver and ensures the response space
> 	is large enough for the largest possible response.
> 
> bnxt_hwrm_queue_qportcfg:
> 	Required to get the default queue ID.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: David Christensen <david.christensen@broadcom.com>

Can you please clarify in the commit message what HWRM acronym stands for.

Checkpatch also highlights a few minor issues that might be worth addressing.

  CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
  #137: FILE: drivers/net/bnxt/bnxt.h:94:
  +#define BNXT_FLAG_VF           (1<<1)
                                  ^

  WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
  #259: FILE: drivers/net/bnxt/bnxt_ethdev.c:143:
  +       /*
  +       eth_dev->rx_pkt_burst = &bnxt_recv_pkts;

  WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
  #366: FILE: drivers/net/bnxt/bnxt_hwrm.c:56:
  +       unsigned i;

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 03/40] bnxt: add driver register/unregister support
  2016-05-13 22:45                       ` [PATCH v2 03/40] bnxt: add driver register/unregister support Stephen Hurd
@ 2016-05-25 15:11                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 15:11 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:52PM -0700, Stephen Hurd wrote:
> Move init() cleanup into uninit() function
> Fix .dev_private_size
> Add require hwrm calls:
> 	bnxt_hwrm_func_driver_register()
> 	bnxt_hwrm_func_driver_unregister()
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/bnxt.h                |   1 +
>  drivers/net/bnxt/bnxt_ethdev.c         |  48 ++++--
>  drivers/net/bnxt/bnxt_hwrm.c           |  50 ++++++
>  drivers/net/bnxt/bnxt_hwrm.h           |   3 +
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 277 ++++++++++++++++++++++++++++++++-
>  5 files changed, 359 insertions(+), 20 deletions(-)
> 
> diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
> index 0f816ed..ebddeab 100644
> --- a/drivers/net/bnxt/bnxt.h
> +++ b/drivers/net/bnxt/bnxt.h
> @@ -91,6 +91,7 @@ struct bnxt {
>  	struct rte_pci_device		*pdev;
>  
>  	uint32_t		flags;
> +#define BNXT_FLAG_REGISTERED	(1<<0)
>  #define BNXT_FLAG_VF		(1<<1)
>  #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
>  #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
> diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
> index a74cc6c..07519df 100644
> --- a/drivers/net/bnxt/bnxt_ethdev.c
> +++ b/drivers/net/bnxt/bnxt_ethdev.c
> @@ -52,20 +52,12 @@ static struct rte_pci_id bnxt_pci_id_map[] = {
>  	{.device_id = 0},
>  };
>  
> -static void bnxt_dev_close_op(struct rte_eth_dev *eth_dev)
> -{
> -	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
> -
> -	rte_free(eth_dev->data->mac_addrs);
> -	bnxt_free_hwrm_resources(bp);
> -}
> -

It seems strange to remove this code given that it was just added in the previous
commit. Does it need to be added in the first place?

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 05/40] bnxt: add dev configure operation
  2016-05-13 22:45                       ` [PATCH v2 05/40] bnxt: add dev configure operation Stephen Hurd
@ 2016-05-25 15:25                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 15:25 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:54PM -0700, Stephen Hurd wrote:
> This adds the bnxt_hwrm_port_phy_cfg() HWRM call, and copies required
> information into the new struct bnxt_link_info.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/bnxt.h                |  32 +++
>  drivers/net/bnxt/bnxt_ethdev.c         |  24 ++
>  drivers/net/bnxt/bnxt_hwrm.c           | 232 +++++++++++++++-
>  drivers/net/bnxt/bnxt_hwrm.h           |   1 +
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 470 +++++++++++++++++++++++++++++++++
>  5 files changed, 758 insertions(+), 1 deletion(-)
> 

Again, a minor issue: checkpatch flags a couple of instances of "unsigned" instead of 
"unsigned int" in this patch. Maybe just scan the rest of the set with checkpatch
to pick up on other minor niggles like this.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 06/40] bnxt: add vnic functions and structs
  2016-05-13 22:45                       ` [PATCH v2 06/40] bnxt: add vnic functions and structs Stephen Hurd
@ 2016-05-25 16:14                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 16:14 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:55PM -0700, Stephen Hurd wrote:
> Add functions to allocate, initialize, and free vnics.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---

Can you perhaps explain what is meant by vnics in this context. Does this patch
need a doc update to describe this functionality?

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 07/40] bnxt: declare ring structs and free() func
  2016-05-13 22:45                       ` [PATCH v2 07/40] bnxt: declare ring structs and free() func Stephen Hurd
@ 2016-05-25 16:37                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 16:37 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:56PM -0700, Stephen Hurd wrote:
> Declare ring structures and a ring free() function.
> 

Are these rings used for packet RX and TX or something else?

> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/Makefile    |  1 +
>  drivers/net/bnxt/bnxt_ring.c | 51 ++++++++++++++++++++++++
>  drivers/net/bnxt/bnxt_ring.h | 92 ++++++++++++++++++++++++++++++++++++++++++++
>  3 files changed, 144 insertions(+)
>  create mode 100644 drivers/net/bnxt/bnxt_ring.c
>  create mode 100644 drivers/net/bnxt/bnxt_ring.h
> 
> diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
> index c57afaa..757ea62 100644
> --- a/drivers/net/bnxt/Makefile
> +++ b/drivers/net/bnxt/Makefile
> @@ -50,6 +50,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
>  #
>  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_vnic.c
>  
>  #
> diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
> new file mode 100644
> index 0000000..0434b07
> --- /dev/null
> +++ b/drivers/net/bnxt/bnxt_ring.c
> @@ -0,0 +1,51 @@
> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) Broadcom Limited.
> + *   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_ring.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."

I don't believe this is true any more. With recent changes to base memzones on
malloc library, the memzones should be free-able.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 08/40] bnxt: add completion ring support
  2016-05-13 22:45                       ` [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
  1 sibling, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 17:33 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:57PM -0700, Stephen Hurd wrote:
> Structures, macros, and functions for working with completion rings
> in the driver.
> 
Can you add a bit more info in the commit message - and possibly in the docs 
too - about what completion rings are and how they are used. Even a few lines
of further explanation would help those looking to understand the driver.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free
  2016-05-13 22:45                       ` [PATCH v2 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
@ 2016-05-25 17:51                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-25 17:51 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:58PM -0700, Stephen Hurd wrote:
> Add the L2 filter structure and the alloc/init/free functions for
> dealing with them.
> 

The DPDK ethdev API has filtering APIs, but this code is not made accessible
via those APIs. If that link is added via later patches, then that should be
documented in the commit message here.

  
> +/* hwrm_cfa_l2_filter_alloc */
> +/*
> + * Description: An L2 filter is a filter resource that is used to identify a
> + * vnic or ring for a packet based on layer 2 fields. Layer 2 fields for
> + * encapsulated packets include both outer L2 header and/or inner l2 header of
> + * encapsulated packet. The L2 filter resource covers the following OS specific
> + * L2 filters. Linux/FreeBSD (per function): # Broadcast enable/disable # List
> + * of individual multicast filters # All multicast enable/disable filter #
> + * Unicast filters # Promiscuous mode VMware: # Broadcast enable/disable (per
> + * physical function) # All multicast enable/disable (per function) # Unicast
> + * filters per ring or vnic # Promiscuous mode per PF Windows: # Broadcast
> + * enable/disable (per physical function) # List of individual multicast filters
> + * (Driver needs to advertise the maximum number of filters supported) # All
> + * multicast enable/disable per physical function # Unicast filters per vnic #
> + * Promiscuous mode per PF Implementation notes on the use of VNIC in this
> + * command: # By default, these filters belong to default vnic for the function.
> + * # Once these filters are set up, only destination VNIC can be modified. # If
> + * the destination VNIC is not specified in this command, then the HWRM shall
> + * only create an l2 context id. HWRM Implementation notes for multicast
> + * filters: # The hwrm_filter_alloc command can be used to set up multicast
> + * filters (perfect match or partial match). Each individual function driver can
> + * set up multicast filters independently. # The HWRM needs to keep track of
> + * multicast filters set up by function drivers and maintain multicast group
> + * replication records to enable a subset of functions to receive traffic for a
> + * specific multicast address. # When a specific multicast filter cannot be set,
> + * the HWRM shall return an error. In this error case, the driver should fall
> + * back to using one general filter (rather than specific) for all multicast
> + * traffic. # When the SR-IOV is enabled, the HWRM needs to additionally track
> + * source knockout per multicast group record. Examples of setting unicast
> + * filters: For a unicast MAC based filter, one can use a combination of the
> + * fields and masks provided in this command to set up the filter. Below are
> + * some examples: # MAC + no VLAN filter: This filter is used to identify
> + * traffic that does not contain any VLAN tags and matches destination (or
> + * source) MAC address. This filter can be set up by setting only l2_addr field
> + * to be a valid field. All other fields are not valid. The following value is
> + * set for l2_addr. l2_addr = MAC # MAC + Any VLAN filter: This filter is used
> + * to identify traffic that carries single VLAN tag and matches (destination or
> + * source) MAC address. This filter can be set up by setting only l2_addr and
> + * l2_ovlan_mask fields to be valid fields. All other fields are not valid. The
> + * following values are set for those two valid fields. l2_addr = MAC,
> + * l2_ovlan_mask = 0xFFFF # MAC + no VLAN or VLAN ID=0: This filter is used to
> + * identify untagged traffic that does not contain any VLAN tags or a VLAN tag
> + * with VLAN ID = 0 and matches destination (or source) MAC address. This filter
> + * can be set up by setting only l2_addr and l2_ovlan fields to be valid fields.
> + * All other fields are not valid. The following value are set for l2_addr and
> + * l2_ovlan. l2_addr = MAC, l2_ovlan = 0x0 # MAC + no VLAN or any VLAN: This
> + * filter is used to identify traffic that contains zero or 1 VLAN tag and
> + * matches destination (or source) MAC address. This filter can be set up by
> + * setting only l2_addr, l2_ovlan, and l2_mask fields to be valid fields. All
> + * other fields are not valid. The following value are set for l2_addr,
> + * l2_ovlan, and l2_mask fields. l2_addr = MAC, l2_ovlan = 0x0, l2_ovlan_mask =
> + * 0xFFFF # MAC + VLAN ID filter: This filter can be set up by setting only
> + * l2_addr, l2_ovlan, and l2_ovlan_mask fields to be valid fields. All other
> + * fields are not valid. The following values are set for those three valid
> + * fields. l2_addr = MAC, l2_ovlan = VLAN ID, l2_ovlan_mask = 0xF000
> + */
This comment could do with clean-up to improve formatting and readability. I'm
also not sure that an explanation of this size is best placed as a comment on
a function. However, I'm also not sure where this information is best placed as
these filter functions are all internal to the driver, and not part of the common
DPDK NIC APIs.

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-25 15:02                       ` [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
  0 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-25 20:59 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, Ajit Kumar Khaparde

Bruce, is it better at this point to modify the existing patch that adds
bnxt.rst or to create a follow-on patch?

On Wed, May 25, 2016 at 8:02 AM, Bruce Richardson <
bruce.richardson@intel.com> wrote:

> On Fri, May 13, 2016 at 03:45:50PM -0700, Stephen Hurd wrote:
> > Initial skeleton simply fails init.
> > Add nic guide and tie into build system.
> >
> > Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> > ---
> >  MAINTAINERS                                     |   5 ++
> >  config/common_base                              |   5 ++
> >  doc/guides/nics/bnxt.rst                        |  49 +++++++++++
> >  drivers/net/Makefile                            |   1 +
> >  drivers/net/bnxt/Makefile                       |  63 ++++++++++++++
> >  drivers/net/bnxt/bnxt_ethdev.c                  | 104
> ++++++++++++++++++++++++
> >  drivers/net/bnxt/rte_pmd_bnxt_version.map       |   4 +
> >  lib/librte_eal/common/include/rte_pci_dev_ids.h |  40 +++++++--
> >  mk/rte.app.mk                                   |   1 +
> >  9 files changed, 267 insertions(+), 5 deletions(-)
> >  create mode 100644 doc/guides/nics/bnxt.rst
> >  create mode 100644 drivers/net/bnxt/Makefile
> >  create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
> >  create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map
> >
> Great to see this patchset split up finer grained, and it getting compiled
> from
> the start. Thanks for the work.
>
> One error that gets flagged by the automated patch checks here is that,
> although
> you add in a new doc for the new driver in this patch, that document is not
> included in the overall NIC guides document.
>
>     /home/bruce/next-net/dpdk-next-net/doc/guides/nics/bnxt.rst:: WARNING:
> document isn't included in any toctree
>
> Regards,
> /Bruce
>
>


-- 
Stephen Hurd
Principal Engineer - Software Development
Broadcom Corporation
949-926-8039
stephen.hurd@broadcom.com

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 02/40] bnxt: add HWRM init code
  2016-05-25 15:05                         ` Bruce Richardson
@ 2016-05-25 23:35                           ` Stephen Hurd
  2016-05-26  9:01                             ` Bruce Richardson
  0 siblings, 1 reply; 142+ messages in thread
From: Stephen Hurd @ 2016-05-25 23:35 UTC (permalink / raw)
  To: Bruce Richardson; +Cc: dev, Ajit Kumar Khaparde

On Wed, May 25, 2016 at 8:05 AM, Bruce Richardson <
bruce.richardson@intel.com> wrote:

>
> Checkpatch also highlights a few minor issues that might be worth
> addressing.
>
>   CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
>   #137: FILE: drivers/net/bnxt/bnxt.h:94:
>   +#define BNXT_FLAG_VF           (1<<1)
>                                   ^
>
>   WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
>   #259: FILE: drivers/net/bnxt/bnxt_ethdev.c:143:
>   +       /*
>   +       eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
>
>   WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
>   #366: FILE: drivers/net/bnxt/bnxt_hwrm.c:56:
>   +       unsigned i;
>
>
What version of checkpatch.pl should we be using?  These were not found by
the one I had.

-- 
Stephen Hurd

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 02/40] bnxt: add HWRM init code
  2016-05-25 23:35                           ` Stephen Hurd
@ 2016-05-26  9:01                             ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26  9:01 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Ajit Kumar Khaparde

On Wed, May 25, 2016 at 04:35:27PM -0700, Stephen Hurd wrote:
> On Wed, May 25, 2016 at 8:05 AM, Bruce Richardson <
> bruce.richardson@intel.com> wrote:
> 
> >
> > Checkpatch also highlights a few minor issues that might be worth
> > addressing.
> >
> >   CHECK:SPACING: spaces preferred around that '<<' (ctx:VxV)
> >   #137: FILE: drivers/net/bnxt/bnxt.h:94:
> >   +#define BNXT_FLAG_VF           (1<<1)
> >                                   ^
> >
> >   WARNING:BLOCK_COMMENT_STYLE: Block comments use * on subsequent lines
> >   #259: FILE: drivers/net/bnxt/bnxt_ethdev.c:143:
> >   +       /*
> >   +       eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
> >
> >   WARNING:UNSPECIFIED_INT: Prefer 'unsigned int' to bare use of 'unsigned'
> >   #366: FILE: drivers/net/bnxt/bnxt_hwrm.c:56:
> >   +       unsigned i;
> >
> >
> What version of checkpatch.pl should we be using?  These were not found by
> the one I had.
> 
Not to worry, a few checkpatch issues are not that big a problem, I can fix them
on apply if necessary.

I used the latest checkpatch version on linus' tree, since I just did a clone
of that before starting looking at your set. Since I don't pull down the patches
as patch files, but use pwclient git-am to apply them, I don't use the checkpatches.sh
script. The actual command/script I use is:

#! /bin/sh

IGNORE_FLAGS="LINUX_VERSION_CODE,FILE_PATH_CHANGES,\
VOLATILE,PREFER_PACKED,PREFER_ALIGNED,\
PREFER_PRINTF,PREFER_KERNEL_TYPES,\
PARENTHESIS_ALIGNMENT,NETWORKING_BLOCK_COMMENT_STYLE,\
COMPARISON_TO_NULL,SPLIT_STRING,BIT_MACRO,LINE_SPACING"

git show --pretty=email | /usr/src/linux/scripts/checkpatch.pl --max-line-length=90 --show-types --ignore=$IGNORE_FLAGS -

The ignore flags should be pretty much the same as in checkpatches.pl, but there
may be a couple of differences, since I haven't synced them up in some time. I
will attempt do so in the near future, to avoid confusion here.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 01/40] bnxt: new driver for Broadcom NetXtreme-C devices
  2016-05-25 20:59                         ` Stephen Hurd
@ 2016-05-26  9:05                           ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26  9:05 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev, Ajit Kumar Khaparde

On Wed, May 25, 2016 at 01:59:00PM -0700, Stephen Hurd wrote:
> Bruce, is it better at this point to modify the existing patch that adds
> bnxt.rst or to create a follow-on patch?
> 

It's better to modify existing patch to add it. 

However, hold off on doing new versions of the patchset until I've finished
doing a first initial scan of them as-is [you'll see from my emails I'm less
than half way in at this point! :-)].

I'd also like to see if some others can help out with reviewing this patchset.
It is a lot of patches, but since they are logically broken up by functionality,
each one is of more manageable size.

Any volunteers?

/Bruce

> On Wed, May 25, 2016 at 8:02 AM, Bruce Richardson <
> bruce.richardson@intel.com> wrote:
> 
> > On Fri, May 13, 2016 at 03:45:50PM -0700, Stephen Hurd wrote:
> > > Initial skeleton simply fails init.
> > > Add nic guide and tie into build system.
> > >
> > > Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> > > ---
> > >  MAINTAINERS                                     |   5 ++
> > >  config/common_base                              |   5 ++
> > >  doc/guides/nics/bnxt.rst                        |  49 +++++++++++
> > >  drivers/net/Makefile                            |   1 +
> > >  drivers/net/bnxt/Makefile                       |  63 ++++++++++++++
> > >  drivers/net/bnxt/bnxt_ethdev.c                  | 104
> > ++++++++++++++++++++++++
> > >  drivers/net/bnxt/rte_pmd_bnxt_version.map       |   4 +
> > >  lib/librte_eal/common/include/rte_pci_dev_ids.h |  40 +++++++--
> > >  mk/rte.app.mk                                   |   1 +
> > >  9 files changed, 267 insertions(+), 5 deletions(-)
> > >  create mode 100644 doc/guides/nics/bnxt.rst
> > >  create mode 100644 drivers/net/bnxt/Makefile
> > >  create mode 100644 drivers/net/bnxt/bnxt_ethdev.c
> > >  create mode 100644 drivers/net/bnxt/rte_pmd_bnxt_version.map
> > >
> > Great to see this patchset split up finer grained, and it getting compiled
> > from
> > the start. Thanks for the work.
> >
> > One error that gets flagged by the automated patch checks here is that,
> > although
> > you add in a new doc for the new driver in this patch, that document is not
> > included in the overall NIC guides document.
> >
> >     /home/bruce/next-net/dpdk-next-net/doc/guides/nics/bnxt.rst:: WARNING:
> > document isn't included in any toctree
> >
> > Regards,
> > /Bruce
> >
> >
> 
> 
> -- 
> Stephen Hurd
> Principal Engineer - Software Development
> Broadcom Corporation
> 949-926-8039
> stephen.hurd@broadcom.com

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 08/40] bnxt: add completion ring support
  2016-05-13 22:45                       ` [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
  1 sibling, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26  9:38 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:45:57PM -0700, Stephen Hurd wrote:
> Structures, macros, and functions for working with completion rings
> in the driver.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/Makefile              |   1 +
>  drivers/net/bnxt/bnxt.h                |   6 +
>  drivers/net/bnxt/bnxt_cpr.c            | 139 +++++++++++++++++++
>  drivers/net/bnxt/bnxt_cpr.h            |  88 ++++++++++++
>  drivers/net/bnxt/bnxt_hwrm.c           |  18 +++
>  drivers/net/bnxt/bnxt_hwrm.h           |   2 +
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 239 ++++++++++++++++++++++++++++++++-
>  7 files changed, 487 insertions(+), 6 deletions(-)
>  create mode 100644 drivers/net/bnxt/bnxt_cpr.c
>  create mode 100644 drivers/net/bnxt/bnxt_cpr.h
> 
> diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
> index 757ea62..afd1690 100644
> --- a/drivers/net/bnxt/Makefile
> +++ b/drivers/net/bnxt/Makefile
> @@ -48,6 +48,7 @@ EXPORT_MAP := rte_pmd_bnxt_version.map
>  #
>  # all source are stored in SRCS-y
>  #
> +SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_cpr.c
>  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
> diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
> index 846972e..4e0b514 100644
> --- a/drivers/net/bnxt/bnxt.h
> +++ b/drivers/net/bnxt/bnxt.h
> @@ -42,6 +42,9 @@
>  #include <rte_lcore.h>
>  #include <rte_spinlock.h>
>  
> +/* TODO make bnxt.def_cp_ring a pointer to avoid this... */
> +#include "bnxt_cpr.h"
> +

I see this TODO is fixed a couple of patches later. Can we get the fix
included in this patch so that the TODO never appears?

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 12/40] bnxt: statistics operations
  2016-05-13 22:46                       ` [PATCH v2 12/40] bnxt: statistics operations Stephen Hurd
@ 2016-05-26  9:40                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26  9:40 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:01PM -0700, Stephen Hurd wrote:
> Add get and clear staitstics operations and the asociated HWRM calls.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/Makefile              |   1 +
>  drivers/net/bnxt/bnxt.h                |   5 +-
>  drivers/net/bnxt/bnxt_cpr.c            |   5 +-
>  drivers/net/bnxt/bnxt_cpr.h            |   2 -
>  drivers/net/bnxt/bnxt_ethdev.c         |   3 +
>  drivers/net/bnxt/bnxt_hwrm.c           |  49 ++++++++++++
>  drivers/net/bnxt/bnxt_hwrm.h           |   8 +-
>  drivers/net/bnxt/bnxt_rxq.c            |   1 +
>  drivers/net/bnxt/bnxt_stats.c          | 142 +++++++++++++++++++++++++++++++++
>  drivers/net/bnxt/bnxt_stats.h          |  44 ++++++++++
>  drivers/net/bnxt/bnxt_txq.c            |   1 +
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 107 +++++++++++++++++++++++++
>  12 files changed, 358 insertions(+), 10 deletions(-)
>  create mode 100644 drivers/net/bnxt/bnxt_stats.c
>  create mode 100644 drivers/net/bnxt/bnxt_stats.h
> 
> diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
> index 21ed71c..f6a04f8 100644
> --- a/drivers/net/bnxt/Makefile
> +++ b/drivers/net/bnxt/Makefile
> @@ -54,6 +54,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_filter.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_rxq.c
> +SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.c
>  SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_txq.c
>  SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_vnic.c
>  
> diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
> index 38b590b..96f162e 100644
> --- a/drivers/net/bnxt/bnxt.h
> +++ b/drivers/net/bnxt/bnxt.h
> @@ -42,9 +42,6 @@
>  #include <rte_lcore.h>
>  #include <rte_spinlock.h>
>  
> -/* TODO make bnxt.def_cp_ring a pointer to avoid this... */
> -#include "bnxt_cpr.h"
> -

This fix doesn't seem to logically belong in this patch. See if it can be merged
in with the patch where the TODO was first raised.

>  #define BNXT_MAX_MTU		9000
>  #define VLAN_TAG_SIZE		4
>  
> @@ -141,7 +138,7 @@ struct bnxt {
>  	struct bnxt_tx_queue **tx_queues;
>  
>  	/* Default completion ring */
> -	struct bnxt_cp_ring_info	def_cp_ring;
> +	struct bnxt_cp_ring_info	*def_cp_ring;

Even though it's not strictly necessary, it might be nice to put in a dummy
forward definition of the bnxt_cp_ring_info before this structure to show that
it's a structure type that will be used later, but is opaque. i.e. put in a line
with:

"struct bnxt_cp_ring_info;"

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 13/40] bnxt: initial Tx ring code
  2016-05-13 22:46                       ` [PATCH v2 13/40] bnxt: initial Tx ring code Stephen Hurd
@ 2016-05-26 10:40                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 10:40 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:02PM -0700, Stephen Hurd wrote:
> Initial implementation of rx_pkt_burst

typo: s/rx/tx/

> Add code to allocate rings to bnxt_ring.c
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/Makefile              |   1 +
>  drivers/net/bnxt/bnxt_cpr.h            |   4 +-
>  drivers/net/bnxt/bnxt_ethdev.c         |   5 +-
>  drivers/net/bnxt/bnxt_ring.c           | 140 +++++++++
>  drivers/net/bnxt/bnxt_ring.h           |   8 +
>  drivers/net/bnxt/bnxt_txq.c            |  42 ++-
>  drivers/net/bnxt/bnxt_txr.c            | 314 ++++++++++++++++++++
>  drivers/net/bnxt/bnxt_txr.h            |  71 +++++
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 512 +++++++++++++++++++++++++++++++++
>  9 files changed, 1086 insertions(+), 11 deletions(-)
>  create mode 100644 drivers/net/bnxt/bnxt_txr.c
>  create mode 100644 drivers/net/bnxt/bnxt_txr.h
> 
> diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
> index f6a04f8..0785681 100644
> --- a/drivers/net/bnxt/Makefile
> +++ b/drivers/net/bnxt/Makefile
> @@ -56,6 +56,7 @@ SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_ring.c
>  SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_rxq.c
>  SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_stats.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_vnic.c
>  
>  #
> diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
> index e6333fc..f104281 100644
> --- a/drivers/net/bnxt/bnxt_cpr.h
> +++ b/drivers/net/bnxt/bnxt_cpr.h
> @@ -51,11 +51,11 @@
>  
>  #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)))
> +				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)))
> +				RING_CMP(cpr->cp_ring_struct, raw_cons)))
>  
>  struct bnxt_ring_struct;
>  struct bnxt_cp_ring_info {
> diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
> index 786318c..61e856a 100644
> --- a/drivers/net/bnxt/bnxt_ethdev.c
> +++ b/drivers/net/bnxt/bnxt_ethdev.c
> @@ -44,6 +44,7 @@
>  #include "bnxt_rxq.h"
>  #include "bnxt_stats.h"
>  #include "bnxt_txq.h"
> +#include "bnxt_txr.h"
>  
>  #define DRV_MODULE_NAME		"bnxt"
>  static const char bnxt_version[] =
> @@ -259,10 +260,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
>  		goto error;
>  	}
>  	eth_dev->dev_ops = &bnxt_dev_ops;
> -	/*
> -	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
> +	/* eth_dev->rx_pkt_burst = &bnxt_recv_pkts; */
>  	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
> -	 */

When adding these two lines in the earlier patch, I would suggest just adding
them as two separate commented out lines, which will both clear the checkpatch
issue flagged before, as well as simplifying the diff here.

After this patch is applied, does this mean that the tx burst functions call
be successfully called on the NIC?

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 14/40] bnxt: initial Rx ring code
  2016-05-13 22:46                       ` [PATCH v2 14/40] bnxt: initial Rx " Stephen Hurd
@ 2016-05-26 10:52                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 10:52 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:03PM -0700, Stephen Hurd wrote:
> Initial implementation of rx_pkt_burst
> Add code to allocate rings to bnxt_ring.c
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/Makefile              |   1 +
>  drivers/net/bnxt/bnxt_ethdev.c         |   3 +-
>  drivers/net/bnxt/bnxt_ring.c           |  20 +-
>  drivers/net/bnxt/bnxt_rxq.c            |  34 ++-
>  drivers/net/bnxt/bnxt_rxr.c            | 338 +++++++++++++++++++++++
>  drivers/net/bnxt/bnxt_rxr.h            |  62 +++++
>  drivers/net/bnxt/hsi_struct_def_dpdk.h | 474 +++++++++++++++++++++++++++++++++
>  7 files changed, 915 insertions(+), 17 deletions(-)
>  create mode 100644 drivers/net/bnxt/bnxt_rxr.c
>  create mode 100644 drivers/net/bnxt/bnxt_rxr.h
> 
<snip>
> + */
> +
> +static inline struct rte_mbuf *__bnxt_alloc_rx_data(struct rte_mempool *mb)
> +{
> +	struct rte_mbuf *data;
> +
> +	data = __rte_mbuf_raw_alloc(mb);

This function is now deprecated and the version without "__" prefix should
now be used instead. "rte_mbuf_raw_alloc()"

> +	__rte_mbuf_sanity_check(data, 0);

raw_mbuf_raw_alloc already includes a call to sanity_check, so this can be removed.
Perhaps the whole function __bnxt_alloc_rx_data() can be removed as it just
seems to be duplicating rte_mbuf_raw_alloc().

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 15/40] bnxt: alloc/free ring information
  2016-05-13 22:46                       ` [PATCH v2 15/40] bnxt: alloc/free ring information Stephen Hurd
@ 2016-05-26 10:59                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 10:59 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:04PM -0700, Stephen Hurd wrote:
> Perform allocation and free()ing of ring information structures for
> TX, RX, and completion rings.
> 

A bit more detail would be useful here. What are the information structures and
how are they used? We've already had two previous patches each for RX and TX,
which add structures and allocs/frees, so how is this different from them.
Would it make sense to merge in this allocation with other allocation patches?
[Not saying it would, just asking :-)]

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 19/40] bnxt: add HWRM vnic cfg function
  2016-05-13 22:46                       ` [PATCH v2 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
@ 2016-05-26 12:04                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 12:04 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:08PM -0700, Stephen Hurd wrote:
> Configurs a vnic allocaed by vnic_alloc function.
> 
Couple of typos.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions
  2016-05-13 22:46                       ` [PATCH v2 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
@ 2016-05-26 12:06                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 12:06 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:09PM -0700, Stephen Hurd wrote:
> More HWRM calls.
> 

The title should be shortened to something like "add vnic ctx functions" and the
commit message should then explain what the contexts are for, and how things like
RSS apply.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function
  2016-05-13 22:46                       ` [PATCH v2 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
@ 2016-05-26 12:14                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 12:14 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:10PM -0700, Stephen Hurd wrote:
> Used to enable RSS configuration
>
A bit more detail in the commit message would be helpful. Should include details
linking this to the contexts added in the previous commit, where RSS is also
mentioned.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 23/40] bnxt: add HWRM stats context allocation
  2016-05-13 22:46                       ` [PATCH v2 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
@ 2016-05-26 12:23                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 12:23 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:12PM -0700, Stephen Hurd wrote:
> Add HWRM code to allocate a statistics context and a helper function
> to allocate one for evert completion ring.
> 
typo: every

How does this patch related to patch 12, which also concerns stats?

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions
  2016-05-13 22:46                       ` [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
  0 siblings, 1 reply; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 12:45 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:13PM -0700, Stephen Hurd wrote:
> Add HWRM calls to allocate and free TX/RX/CMPL rings along with
> the associated structs and definitions.
> 
What are these RX/TX/CMPL rings used for? I assume they are different from the
RX/TX rings used to send/receive packets, or am I missing something?

Also, I see some compilation errors after applying this patch in the series.
gcc gives errors about "struct bnxt_ring_struct declared inside parameter list".

/Bruce

PS: having "struct" at the end of the name of "struct bnxt_ring_struct" seems
superflous. Since we don't use typedefs in DPDK, the keyword struct will always
appear before the definition, so it shouldn't be needed in the name too.

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 26/40] bnxt: add HWRM stat context free function
  2016-05-13 22:46                       ` [PATCH v2 26/40] bnxt: add HWRM stat context free function Stephen Hurd
@ 2016-05-26 13:15                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 13:15 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:15PM -0700, Stephen Hurd wrote:
> Add function and associated structures and definitions as well as
> some convenienct functions for manipulating the state of the entire
> function.
> 
Again, I think more explanation is needed in the commit message. The commit
title refers to freeing stat contexts, but the patch itself contains functions
working on filters. Either the filter functions belong in a different patch,
or we need more explanation as to why they would belong in this one.

I'd also question if the ordering of the patches should be changed. In other
cases you have a single patch adding allocation and free functions together, but
for these stats contexts there are two patches which are separated in the series.
Logically, if they are not merged, it would be good if they could be at least
sequential commits.

Thanks,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 24/40] bnxt: add HWRM ring alloc/free functions
  2016-05-26 12:45                         ` Bruce Richardson
@ 2016-05-26 13:19                           ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 13:19 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Thu, May 26, 2016 at 01:45:55PM +0100, Bruce Richardson wrote:
> On Fri, May 13, 2016 at 03:46:13PM -0700, Stephen Hurd wrote:
> > Add HWRM calls to allocate and free TX/RX/CMPL rings along with
> > the associated structs and definitions.
> > 
> What are these RX/TX/CMPL rings used for? I assume they are different from the
> RX/TX rings used to send/receive packets, or am I missing something?
> 
> Also, I see some compilation errors after applying this patch in the series.
> gcc gives errors about "struct bnxt_ring_struct declared inside parameter list".
> 
I see a fix for this is made in patch 27, which is good. I just suggest squashing
that patch into this one.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 28/40] bnxt: add ring allocation and group init
  2016-05-13 22:46                       ` [PATCH v2 28/40] bnxt: add ring allocation and group init Stephen Hurd
@ 2016-05-26 13:24                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 13:24 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:17PM -0700, Stephen Hurd wrote:
> Add a function to initialize ring groups, and a function to
> allocate the rings via HWRM.
> 
How does this patch relate to patches 24 and 25, whose titles indicate they
already provide this functionality? [Perhaps some of these patches need to be
squashed so that functionality is not split too much among different patches.]

Regards,
/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 29/40] bnxt: work around HWRM error when creating rings
  2016-05-13 22:46                       ` [PATCH v2 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
@ 2016-05-26 13:25                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 13:25 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:18PM -0700, Stephen Hurd wrote:
> Some HWRM versions will stop responding if we request poll mode interrupt.
> As a workaround, request an MSI interrupt even though we never enable it.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>
> ---
>  drivers/net/bnxt/bnxt_hwrm.c | 6 +++++-
>  1 file changed, 5 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
> index b5bc473..897e766 100644
> --- a/drivers/net/bnxt/bnxt_hwrm.c
> +++ b/drivers/net/bnxt/bnxt_hwrm.c
> @@ -581,7 +581,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
>  		break;
>  	case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
>  		req.ring_type = ring_type;
> -		req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_POLL;
> +		/*
> +		 * TODO: Some HWRM versions crash with

Is this really a TODO? If it's a workaround for an issue, surely it needs to
stay in the code with the appropriate comment [which you have already added].

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper
  2016-05-13 22:46                       ` [PATCH v2 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
@ 2016-05-26 13:39                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 13:39 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:19PM -0700, Stephen Hurd wrote:
> Add HWRM port pgy qcfg HWRM command and bnxt_get_hwrm_link_config()
> wrapper which parses the link state.
> 
For commit messages, there is no need to abbreviate words, since we are not
limited in the number of characters that can be used.

/Bruce

^ permalink raw reply	[flat|nested] 142+ messages in thread

* Re: [PATCH v2 40/40] bnxt: cleanup null pointer checks
  2016-05-13 22:46                       ` [PATCH v2 40/40] bnxt: cleanup null pointer checks Stephen Hurd
@ 2016-05-26 15:20                         ` Bruce Richardson
  0 siblings, 0 replies; 142+ messages in thread
From: Bruce Richardson @ 2016-05-26 15:20 UTC (permalink / raw)
  To: Stephen Hurd; +Cc: dev

On Fri, May 13, 2016 at 03:46:29PM -0700, Stephen Hurd wrote:
> Prefer !ptr to ptr == NULL
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Reviewed-by: Ajit Kumar Khaparde <ajit.khaparde@broadcom.com>

Nak to this particular patch, as it contradicts DPDK coding guidelines which is
to make NULL checks explicit. Ref [1]

/Bruce

[1] http://dpdk.org/doc/guides/contributing/coding_style.html#c-statement-style-and-conventions

^ permalink raw reply	[flat|nested] 142+ messages in thread

end of thread, other threads:[~2016-05-26 15:20 UTC | newest]

Thread overview: 142+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-03-02 21:36 [PATCH] drivers/net/bnxt New driver for Broadcom bnxt Stephen Hurd
2016-03-02 21:44 ` Stephen Hemminger
2016-03-02 21:58 ` Thomas Monjalon
2016-03-03  4:08 ` [PATCH 0/7] drivers/net/bnxt: new Broadcom bnxt driver Stephen Hurd
2016-03-03  4:08   ` [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   ` [PATCH 2/7] lib/librte_eal: Add PCI IDs for Broadcom bnxt Stephen Hurd
2016-03-03  4:08   ` [PATCH 3/7] drivers/net/bnxt new driver " Stephen Hurd
2016-03-03  4:08   ` [PATCH 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
2016-03-03  4:08   ` [PATCH 5/7] build: add bnxt PMD to build Stephen Hurd
2016-03-03  4:08   ` [PATCH 6/7] doc: Add bnxt to overview table Stephen Hurd
2016-03-03  4:08   ` [PATCH 7/7] doc: add guide for new bnxt driver Stephen Hurd
2016-03-04 21:05   ` [PATCH v3 0/7] drivers/net/bnxt: new Broadcom " Stephen Hurd
2016-03-04 21:05   ` [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   ` [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   ` [PATCH v3 3/7] drivers/net/bnxt new driver " Stephen Hurd
2016-03-04 23:02     ` 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               ` [PATCH 01/40] bnxt: new driver for Broadcom NetXtreme-C devices Stephen Hurd
2016-05-06 19:25                 ` [PATCH 02/40] bnxt: add HWRM init code Stephen Hurd
2016-05-06 19:25                 ` [PATCH 03/40] bnxt: add driver register/unregister support Stephen Hurd
2016-05-06 19:25                 ` [PATCH 04/40] bnxt: add dev infos get operation Stephen Hurd
2016-05-06 19:25                 ` [PATCH 05/40] bnxt: add dev configure operation Stephen Hurd
2016-05-06 19:25                 ` [PATCH 06/40] bnxt: add vnic functions and structs Stephen Hurd
2016-05-06 19:25                 ` [PATCH 07/40] bnxt: declare ring structs and free() func Stephen Hurd
2016-05-06 19:25                 ` [PATCH 08/40] bnxt: add completion ring support Stephen Hurd
2016-05-06 19:25                 ` [PATCH 09/40] bnxt: add L2 filter alloc/init/free Stephen Hurd
2016-05-06 19:25                 ` [PATCH 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
2016-05-06 19:25                 ` [PATCH 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
2016-05-06 19:25                 ` [PATCH 12/40] bnxt: statistics operations Stephen Hurd
2016-05-06 19:25                 ` [PATCH 13/40] bnxt: initial Tx ring code Stephen Hurd
2016-05-06 19:25                 ` [PATCH 14/40] bnxt: initial Rx " Stephen Hurd
2016-05-06 19:25                 ` [PATCH 15/40] bnxt: alloc/free ring information Stephen Hurd
2016-05-06 19:25                 ` [PATCH 16/40] bnxt: add HWRM function reset command Stephen Hurd
2016-05-06 19:25                 ` [PATCH 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
2016-05-06 19:25                 ` [PATCH 18/40] bnxt: add HWRM vnic free function Stephen Hurd
2016-05-06 19:25                 ` [PATCH 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
2016-05-06 19:26                 ` [PATCH 20/40] bnxt: add vnic RSS cos lb cTx alloc/free functions Stephen Hurd
2016-05-06 19:26                 ` [PATCH 21/40] bnxt: add HWRM vnic RSS config function Stephen Hurd
2016-05-06 19:26                 ` [PATCH 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
2016-05-06 19:26                 ` [PATCH 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
2016-05-06 19:26                 ` [PATCH 24/40] bnxt: add HWRM ring alloc/free functions Stephen Hurd
2016-05-06 19:26                 ` [PATCH 25/40] bnxt: add ring group " Stephen Hurd
2016-05-06 19:26                 ` [PATCH 26/40] bnxt: add HWRM stat context free function Stephen Hurd
2016-05-06 19:26                 ` [PATCH 27/40] bnxt: add struct forward decl Stephen Hurd
2016-05-06 19:26                 ` [PATCH 28/40] bnxt: add ring allocation and group init Stephen Hurd
2016-05-06 19:26                 ` [PATCH 29/40] bnxt: work around HWRM error when creating rings Stephen Hurd
2016-05-06 19:26                 ` [PATCH 30/40] bnxt: add HWRM port phy qcfg call and wrapper Stephen Hurd
2016-05-06 19:26                 ` [PATCH 31/40] bnxt: add start/stop/link update operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 33/40] bnxt: add all multicast " Stephen Hurd
2016-05-06 19:26                 ` [PATCH 34/40] bnxt: add device close operation Stephen Hurd
2016-05-06 19:26                 ` [PATCH 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 36/40] bnxt: add dev set link up/down operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 37/40] bnxt: add reta update/query operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 38/40] bnxt: add RSS device operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 39/40] bnxt: add flow control operations Stephen Hurd
2016-05-06 19:26                 ` [PATCH 40/40] bnxt: cleanup null pointer checks Stephen Hurd
2016-05-11  4:53                 ` [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                     ` [PATCH v2 " Stephen Hurd
2016-05-13 22:45                       ` [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                       ` [PATCH v2 03/40] bnxt: add driver register/unregister support Stephen Hurd
2016-05-25 15:11                         ` Bruce Richardson
2016-05-13 22:45                       ` [PATCH v2 04/40] bnxt: add dev infos get operation Stephen Hurd
2016-05-13 22:45                       ` [PATCH v2 05/40] bnxt: add dev configure operation Stephen Hurd
2016-05-25 15:25                         ` Bruce Richardson
2016-05-13 22:45                       ` [PATCH v2 06/40] bnxt: add vnic functions and structs Stephen Hurd
2016-05-25 16:14                         ` Bruce Richardson
2016-05-13 22:45                       ` [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                       ` [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                       ` [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                       ` [PATCH v2 10/40] bnxt: add Tx queue operations (nonfunctional) Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 11/40] bnxt: add Rx queue create/destroy operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 12/40] bnxt: statistics operations Stephen Hurd
2016-05-26  9:40                         ` Bruce Richardson
2016-05-13 22:46                       ` [PATCH v2 13/40] bnxt: initial Tx ring code Stephen Hurd
2016-05-26 10:40                         ` Bruce Richardson
2016-05-13 22:46                       ` [PATCH v2 14/40] bnxt: initial Rx " Stephen Hurd
2016-05-26 10:52                         ` Bruce Richardson
2016-05-13 22:46                       ` [PATCH v2 15/40] bnxt: alloc/free ring information Stephen Hurd
2016-05-26 10:59                         ` Bruce Richardson
2016-05-13 22:46                       ` [PATCH v2 16/40] bnxt: add HWRM function reset command Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 17/40] bnxt: add HWRM vnic alloc function Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 18/40] bnxt: add HWRM vnic free function Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 19/40] bnxt: add HWRM vnic cfg function Stephen Hurd
2016-05-26 12:04                         ` Bruce Richardson
2016-05-13 22:46                       ` [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                       ` [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                       ` [PATCH v2 22/40] bnxt: add L2 Rx mask set/clear functions Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 23/40] bnxt: add HWRM stats context allocation Stephen Hurd
2016-05-26 12:23                         ` Bruce Richardson
2016-05-13 22:46                       ` [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                       ` [PATCH v2 25/40] bnxt: add ring group " Stephen Hurd
2016-05-13 22:46                       ` [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                       ` [PATCH v2 27/40] bnxt: add struct forward decl Stephen Hurd
2016-05-13 22:46                       ` [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                       ` [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                       ` [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                       ` [PATCH v2 31/40] bnxt: add start/stop/link update operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 32/40] bnxt: add promiscuous enable/disable operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 33/40] bnxt: add all multicast " Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 34/40] bnxt: add device close operation Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 35/40] bnxt: add MAC address add/remove operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 36/40] bnxt: add dev set link up/down operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 37/40] bnxt: add reta update/query operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 38/40] bnxt: add RSS device operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 39/40] bnxt: add flow control operations Stephen Hurd
2016-05-13 22:46                       ` [PATCH v2 40/40] bnxt: cleanup null pointer checks Stephen Hurd
2016-05-26 15:20                         ` Bruce Richardson
2016-05-25 15:02                       ` [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   ` [PATCH v3 4/7] maintainers: claim drivers/net/bnxt Stephen Hurd
2016-03-04 21:05   ` [PATCH v3 5/7] build: add bnxt PMD to build Stephen Hurd
2016-03-04 21:05   ` [PATCH v3 6/7] doc: Add bnxt to overview table Stephen Hurd
2016-03-04 21:05   ` [PATCH v3 7/7] doc: add guide for new bnxt driver Stephen Hurd

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.