All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/23] bnxt patchset
@ 2017-05-18  1:57 Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 01/23] bnxt: add various hwrm input/output structures Ajit Khaparde
                   ` (23 more replies)
  0 siblings, 24 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patchset amongst other changes adds support few more dev_ops,
updates HWRM to version 1.7.5, switches to polling stats from the
hardware, support for LRO etc..

  bnxt: add various hwrm input/output structures
  bnxt: code reorg to properly allocate resources in PF/VF modes
  bnxt: add tunneling support
  bnxt: support lack of huge pages
  bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en
  bnxt: add support for set VF QOS and MAC anti spoof
  bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs
  bnxt: add support to get and clear VF specific stats
  bnxt: add code to determine the Rx status of VF
  bnxt: add support to add a VF MAC address
  bnxt: add support for xstats get/reset
  bnxt: Add support for VLAN filter and strip dev_ops
  bnxt: add code to configure a default VF VLAN
  bnxt: add support for set_mc_addr_list and mac_addr_set
  bnxt: add support for fw_version_get dev_op
  bnxt: add support to set MTU
  bnxt: add support for LRO
  bnxt: add rxq_info_get and txq_info_get dev_ops
  bnxt: add additonal HWRM debug info to error messages
  bnxt: reorg the query stats code
  bnxt: update to HWRM version 1.7.5
  bnxt: Add support to set VF rxmode
  bnxt: add code to support vlan_pvid_set dev_op

 drivers/net/bnxt/Makefile                 |    4 +
 drivers/net/bnxt/bnxt.h                   |  104 +-
 drivers/net/bnxt/bnxt_cpr.c               |  129 +-
 drivers/net/bnxt/bnxt_cpr.h               |   17 +
 drivers/net/bnxt/bnxt_ethdev.c            |  818 ++-
 drivers/net/bnxt/bnxt_filter.c            |   58 +-
 drivers/net/bnxt/bnxt_filter.h            |    3 +
 drivers/net/bnxt/bnxt_hwrm.c              | 1523 ++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   62 +-
 drivers/net/bnxt/bnxt_irq.c               |   21 +-
 drivers/net/bnxt/bnxt_ring.c              |  159 +-
 drivers/net/bnxt/bnxt_ring.h              |    4 +-
 drivers/net/bnxt/bnxt_rxq.c               |   54 +-
 drivers/net/bnxt/bnxt_rxq.h               |    3 +
 drivers/net/bnxt/bnxt_rxr.c               |  396 +-
 drivers/net/bnxt/bnxt_rxr.h               |   46 +
 drivers/net/bnxt/bnxt_stats.c             |  261 +-
 drivers/net/bnxt/bnxt_stats.h             |   10 +
 drivers/net/bnxt/bnxt_txr.c               |    3 +-
 drivers/net/bnxt/bnxt_vnic.c              |   70 +-
 drivers/net/bnxt/bnxt_vnic.h              |   20 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h    | 8633 ++++++++++++++++++++---------
 drivers/net/bnxt/rte_pmd_bnxt.c           |  701 +++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  322 ++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   22 +
 25 files changed, 10407 insertions(+), 3036 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

-- 
2.10.1 (Apple Git-78)

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

* [PATCH 01/23] bnxt: add various hwrm input/output structures
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 02/23] bnxt: code reorg to properly allocate resources in PF/VF modes Ajit Khaparde
                   ` (22 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds various hwrm API which allows the configuration
and allocation of resources for a PCI function depending on whether
it is a PF or a VF. These structures will be used in subsequent
patches.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 1497 ++++++++++++++++++++++++++++++--
 1 file changed, 1417 insertions(+), 80 deletions(-)

diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index f024837..a091a0b 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -85,20 +85,63 @@ struct ctx_hw_stats64 {
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_BUF_UNRGTR		(UINT32_C(0xe))
+#define HWRM_FUNC_VF_CFG		(UINT32_C(0xf))
+    /* Reserved for future use */
+#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 HWRM_PORT_QSTATS		(UINT32_C(0x23))
+#define HWRM_PORT_LPBK_QSTATS		(UINT32_C(0x24))
 #define HWRM_PORT_PHY_QCFG		(UINT32_C(0x27))
+#define HWRM_PORT_MAC_QCFG		(UINT32_C(0x28))
+#define HWRM_PORT_PHY_QCAPS		(UINT32_C(0x2a))
+#define HWRM_PORT_LED_CFG		(UINT32_C(0x2d))
+#define HWRM_PORT_LED_QCFG		(UINT32_C(0x2e))
+#define HWRM_PORT_LED_QCAPS		(UINT32_C(0x2f))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_QUEUE_QCFG			(UINT32_C(0x31))
+#define HWRM_QUEUE_CFG			(UINT32_C(0x32))
+    /* Reserved for future use */
+#define RESERVED2			(UINT32_C(0x33))
+    /* Reserved for future use */
+#define RESERVED3			(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_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_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_PARAM	(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))
@@ -107,10 +150,46 @@ 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))
+    /* Reserved for future use */
+#define RESERVED4			(UINT32_C(0x94))
+#define HWRM_CFA_TUNNEL_FILTER_ALLOC	(UINT32_C(0x95))
+#define HWRM_CFA_TUNNEL_FILTER_FREE	(UINT32_C(0x96))
+#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_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_CLR_STATS		(UINT32_C(0xb3))
 #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_WOL_FILTER_ALLOC		(UINT32_C(0xf0))
+#define HWRM_WOL_FILTER_FREE		(UINT32_C(0xf1))
+#define HWRM_WOL_FILTER_QCFG		(UINT32_C(0xf2))
+#define HWRM_WOL_REASON_QCFG		(UINT32_C(0xf3))
+#define HWRM_DBG_DUMP			(UINT32_C(0xff14))
+#define HWRM_NVM_VALIDATE_OPTION	(UINT32_C(0xffef))
+#define HWRM_NVM_FLUSH			(UINT32_C(0xfff0))
+#define HWRM_NVM_GET_VARIABLE		(UINT32_C(0xfff1))
+#define HWRM_NVM_SET_VARIABLE		(UINT32_C(0xfff2))
+#define HWRM_NVM_INSTALL_UPDATE		(UINT32_C(0xfff3))
+#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_RAW_DUMP		(UINT32_C(0xfffc))
+#define HWRM_NVM_READ			(UINT32_C(0xfffd))
+#define HWRM_NVM_WRITE			(UINT32_C(0xfffe))
+#define HWRM_NVM_RAW_WRITE_BLK		(UINT32_C(0xffff))
 
 /* Return Codes */
 #define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
@@ -2261,6 +2340,432 @@ struct hwrm_func_qcfg_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_func_cfg */
+/*
+ * Description: This command allows configuration of a PF by the corresponding
+ * PF driver. This command also allows configuration of a child VF by its parent
+ * PF driver. The input FID value is used to indicate what function is being
+ * configured. This allows a PF driver to configure the PF owned by itself or a
+ * virtual function that is a child of the PF. This command allows to reserve
+ * resources for a VF by its parent PF. To reverse the process, the command
+ * should be called with all enables flags cleared for resources. This will free
+ * allocated resources for the VF and return them to the resource pool. If this
+ * command is requested by a VF driver to configure or reserve resources, then
+ * the HWRM shall fail this command. If default MAC address and/or VLAN are
+ * provided in this command, then the HWRM shall set up appropriate MAC/VLAN
+ * filters for the function that is being configured. If source properties
+ * checks are enabled and default MAC address and/or IP address are provided in
+ * this command, then the HWRM shall set appropriate source property checks
+ * based on provided MAC and/or IP addresses. The parent PF driver should not
+ * set MTU/MRU for a VF using this command. This is to allow MTU/MRU setting by
+ * the VF driver. If the MTU or MRU for a VF is set by the PF driver, then the
+ * HWRM should ignore it. A function's MTU/MRU should be set prior to allocating
+ * RX VNICs or TX rings. A PF driver calls hwrm_func_cfg to allocate resources
+ * for itself or its children VFs. All function drivers shall call hwrm_func_cfg
+ * to reserve resources. A request to hwrm_func_cfg may not be fully granted;
+ * that is, a request for resources may be larger than what can be supported by
+ * the device and the HWRM will allocate the best set of resources available,
+ * but that may be less than requested. If all the amounts requested could not
+ * be fulfilled, the HWRM shall allocate what it could and return a status code
+ * of success. A function driver should call hwrm_func_qcfg immediately after
+ * hwrm_func_cfg to determine what resources were assigned to the configured
+ * function. A call by a PF driver to hwrm_func_cfg to allocate resources for
+ * itself shall only allocate resources for the PF driver to use, not for its
+ * children VFs. Likewise, a call to hwrm_func_qcfg shall return the resources
+ * available for the PF driver to use, not what is available to its children
+ * VFs.
+ */
+/* Input	(88 bytes) */
+struct hwrm_func_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF...	(All Fs), then the the configuration is for the
+	 * requesting function.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the function is disabled with source
+	 * MAC address check. This is an anti-spoofing check. If this
+	 * flag is set, then the function shall be configured to
+	 * disallow transmission of frames with the source MAC address
+	 * that is configured for this function.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE	 \
+		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the function is enabled with source MAC
+	 * address check. This is an anti-spoofing check. If this flag
+	 * is set, then the function shall be configured to allow
+	 * transmission of frames with the source MAC address that is
+	 * configured for this function.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE	\
+		UINT32_C(0x2)
+	/* reserved */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_MASK	UINT32_C(0x1fc)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_SFT	2
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is requested to be
+	 * enabled on the function being configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE	\
+		UINT32_C(0x200)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then the standard TX ring mode is requested to be
+	 * disabled on the function being configured. In this extended
+	 * TX ring resource mode, the minimum and maximum bandwidth
+	 * settings are not supported to allow the allocation of TX
+	 * rings to span multiple scheduler nodes.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE	\
+		UINT32_C(0x400)
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MTU	UINT32_C(0x1)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MRU	UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the num_rsscos_ctxs field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS	UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the num_cmpl_rings field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS	UINT32_C(0x8)
+	/* This bit must be '1' for the num_tx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS	UINT32_C(0x10)
+	/* This bit must be '1' for the num_rx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS	UINT32_C(0x20)
+	/* This bit must be '1' for the num_l2_ctxs field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS	UINT32_C(0x40)
+	/* This bit must be '1' for the num_vnics field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS	UINT32_C(0x80)
+	/*
+	 * This bit must be '1' for the num_stat_ctxs field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the dflt_mac_addr field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR	UINT32_C(0x200)
+	/* This bit must be '1' for the dflt_vlan field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN	UINT32_C(0x400)
+	/* This bit must be '1' for the dflt_ip_addr field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_IP_ADDR	UINT32_C(0x800)
+	/* This bit must be '1' for the min_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MIN_BW	UINT32_C(0x1000)
+	/* This bit must be '1' for the max_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW	UINT32_C(0x2000)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR	UINT32_C(0x4000)
+	/*
+	 * This bit must be '1' for the vlan_antispoof_mode field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE	UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the allowed_vlan_pris field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ALLOWED_VLAN_PRIS UINT32_C(0x10000)
+	/* This bit must be '1' for the evb_mode field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE	UINT32_C(0x20000)
+	/*
+	 * This bit must be '1' for the num_mcast_filters field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MCAST_FILTERS UINT32_C(0x40000)
+	/*
+	 * This bit must be '1' for the num_hw_ring_grps field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS UINT32_C(0x80000)
+	uint16_t mtu;
+	/*
+	 * The maximum transmission unit of the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed
+	 * the mtu of the physical port that this function is associated
+	 * with. In addition to configuring mtu per function, it is
+	 * possible to configure mtu per transmit ring. By default, the
+	 * mtu of each transmit ring associated with a function is equal
+	 * to the mtu of the function. The HWRM should make sure that
+	 * the mtu of each transmit ring that is assigned to a function
+	 * has a valid mtu.
+	 */
+	uint16_t mru;
+	/*
+	 * The maximum receive unit of the function. The HWRM should
+	 * make sure that the mru of the function does not exceed the
+	 * mru of the physical port that this function is associated
+	 * with. In addition to configuring mru per function, it is
+	 * possible to configure mru per vnic. By default, the mru of
+	 * each vnic associated with a function is equal to the mru of
+	 * the function. The HWRM should make sure that the mru of each
+	 * vnic that is assigned to a function has a valid mru.
+	 */
+	uint16_t num_rsscos_ctxs;
+	/* The number of RSS/COS contexts requested for the function. */
+	uint16_t num_cmpl_rings;
+	/*
+	 * The number of completion rings requested for the function.
+	 * This does not include the rings allocated to any children
+	 * functions if any.
+	 */
+	uint16_t num_tx_rings;
+	/*
+	 * The number of transmit rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
+	 */
+	uint16_t num_rx_rings;
+	/*
+	 * The number of receive rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
+	 */
+	uint16_t num_l2_ctxs;
+	/* The requested number of L2 contexts for the function. */
+	uint16_t num_vnics;
+	/* The requested number of vnics for the function. */
+	uint16_t num_stat_ctxs;
+	/* The requested number of statistic contexts for the function. */
+	uint16_t num_hw_ring_grps;
+	/*
+	 * The number of HW ring groups that should be reserved for this
+	 * function.
+	 */
+	uint8_t dflt_mac_addr[6];
+	/* The default MAC address for the function being configured. */
+	uint16_t dflt_vlan;
+	/*
+	 * The default VLAN for the function being configured. This
+	 * field's format is same as 802.1Q Tag's Tag Control
+	 * Information	(TCI) format that includes both Priority Code
+	 * Point	(PCP) and VLAN Identifier	(VID).
+	 */
+	uint32_t dflt_ip_addr[4];
+	/*
+	 * The default IP address for the function being configured.
+	 * This address is only used in enabling source property check.
+	 */
+	uint32_t min_bw;
+	/*
+	 * Minimum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK	\
+		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+	uint32_t max_bw;
+	/*
+	 * Maximum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK	\
+		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous
+	 * event completions. If this field is not valid, then the HWRM
+	 * shall use the default completion ring of the function that is
+	 * being configured as the target completion ring for providing
+	 * any asynchronous event completions for that function. If this
+	 * field is valid, then the HWRM shall use the completion ring
+	 * identified by this ID as the target completion ring for
+	 * providing any asynchronous event completions for the function
+	 * that is being configured.
+	 */
+	uint8_t vlan_antispoof_mode;
+	/* VLAN Anti-spoofing mode. */
+	/* No VLAN anti-spoofing checks are enabled */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK	UINT32_C(0x0)
+	/* Validate VLAN against the configured VLAN(s) */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN \
+		UINT32_C(0x1)
+	/* Insert VLAN if it does not exist, otherwise discard */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_IF_VLANDNE \
+		UINT32_C(0x2)
+	/*
+	 * Insert VLAN if it does not exist, override
+	 * VLAN if it exists
+	 */
+	#define \
+	HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN \
+		UINT32_C(0x3)
+	uint8_t allowed_vlan_pris;
+	/*
+	 * This bit field defines VLAN PRIs that are allowed on this
+	 * function. If nth bit is set, then VLAN PRI n is allowed on
+	 * this function.
+	 */
+	uint8_t evb_mode;
+	/*
+	 * The HWRM shall allow a PF driver to change EVB mode for the
+	 * partition it belongs to. The HWRM shall not allow a VF driver
+	 * to change the EVB mode. The HWRM shall take into account the
+	 * switching of EVB mode from one to another and reconfigure
+	 * hardware resources as appropriately. The switching from VEB
+	 * to VEPA mode requires the disabling of the loopback traffic.
+	 * Additionally, source knock outs are handled differently in
+	 * VEB and VEPA modes.
+	 */
+	/* No Edge Virtual Bridging	(EVB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
+	/* Virtual Ethernet Bridge	(VEB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEB	UINT32_C(0x1)
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA	UINT32_C(0x2)
+	uint8_t unused_2;
+	uint16_t num_mcast_filters;
+	/*
+	 * The number of multicast filters that should be reserved for
+	 * this function on the RX side.
+	 */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_func_drv_rgtr */
 /*
  * Description: This command is used by the function driver to register its
@@ -2491,17 +2996,16 @@ struct hwrm_func_drv_unrgtr_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_port_phy_cfg */
+/* hwrm_func_buf_rgtr */
 /*
- * 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.
+ * Description: This command is used by the PF driver to register buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * register buffers for each PF-VF channel. A parent PF may issue this command
+ * per child VF. If VF ID is not valid, then this command is used to register
+ * buffers for all children VFs of the PF.
  */
-/* Input (56 bytes) */
-struct hwrm_port_phy_cfg_input {
+/* Input	(128 bytes) */
+struct hwrm_func_buf_rgtr_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2528,64 +3032,378 @@ struct hwrm_port_phy_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the err_buf_addr field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR	UINT32_C(0x2)
+	uint16_t vf_id;
 	/*
-	 * 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)
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t req_buf_num_pages;
+	/*
+	 * This field represents the number of pages used for request
+	 * buffer(s).
+	 */
+	uint16_t req_buf_page_size;
+	/* This field represents the page size used for request buffer(s). */
+	/* 16 bytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_16B UINT32_C(0x4)
+	/* 4 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4K	UINT32_C(0xc)
+	/* 8 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_8K	UINT32_C(0xd)
+	/* 64 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_64K UINT32_C(0x10)
+	/* 2 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_2M	UINT32_C(0x15)
+	/* 4 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4M	UINT32_C(0x16)
+	/* 1 Gbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_1G	UINT32_C(0x1e)
+	uint16_t req_buf_len;
+	/* The length of the request buffer per VF in bytes. */
+	uint16_t resp_buf_len;
+	/* The length of the response buffer in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint64_t req_buf_page_addr[10];
+	/* This field represents the page address of req buffer. */
+	uint64_t error_buf_addr;
 	/*
-	 * 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.
+	 * This field is used to receive the error reporting from the
+	 * chipset. Only applicable for PFs.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN	UINT32_C(0x2)
+	uint64_t resp_buf_addr;
+	/* This field is used to receive the response forwarded by the HWRM. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_rgtr_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE	UINT32_C(0x4)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * When this bit is set to '1', the auto-negotiation process
-	 * shall be restarted on the link.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG	UINT32_C(0x8)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+} __attribute__((packed));
+
+/* hwrm_func_buf_unrgtr */
+/*
+ * Description: This command is used by the PF driver to unregister buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * unregister buffers for PF-VF communication. A parent PF may issue this
+ * command to unregister buffers for communication between the PF and a specific
+ * VF. If the VF ID is not valid, then this command is used to unregister
+ * buffers used for communications with all children VFs of the PF.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_buf_unrgtr_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	uint16_t cmpl_ring;
 	/*
-	 * 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
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_UNRGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_vf_cfg */
+/*
+ * Description: This command allows configuration of a VF by its driver. If this
+ * function is called by a PF driver, then the HWRM shall fail this command. If
+ * guest VLAN and/or MAC address are provided in this command, then the HWRM
+ * shall set up appropriate MAC/VLAN filters for the VF that is being
+ * configured. A VF driver should set VF MTU/MRU using this command prior to
+ * allocating RX VNICs or TX rings for the corresponding VF.
+ */
+/* Input (32 bytes) */
+
+struct hwrm_func_vf_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_MTU                 UINT32_C(0x1)
+	/* This bit must be '1' for the guest_vlan field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_GUEST_VLAN          UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be configured.
+	 */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR      UINT32_C(0x4)
+	/* This bit must be '1' for the dflt_mac_addr field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR       UINT32_C(0x8)
+	uint16_t mtu;
+	/*
+	 * The maximum transmission unit requested on the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed the mtu
+	 * of the physical port that this function is associated with. In
+	 * addition to requesting mtu per function, it is possible to configure
+	 * mtu per transmit ring. By default, the mtu of each transmit ring
+	 * associated with a function is equal to the mtu of the function. The
+	 * HWRM should make sure that the mtu of each transmit ring that is
+	 * assigned to a function has a valid mtu.
+	 */
+	uint16_t guest_vlan;
+	/*
+	 * The guest VLAN for the function being configured. This field's format
+	 * is same as 802.1Q Tag's Tag Control Information (TCI) format that
+	 * includes both Priority Code Point (PCP) and VLAN Identifier (VID).
+	 */
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous event
+	 * completions. If this field is not valid, then the HWRM shall use the
+	 * default completion ring of the function that is being configured as
+	 * the target completion ring for providing any asynchronous event
+	 * completions for that function. If this field is valid, then the HWRM
+	 * shall use the completion ring identified by this ID as the target
+	 * completion ring for providing any asynchronous event completions for
+	 * the function that is being configured.
+	 */
+	uint8_t dflt_mac_addr[6];
+	/*
+	 * This value is the current MAC address requested by the VF driver to
+	 * be configured on this VF. A value of 00-00-00-00-00-00 indicates no
+	 * MAC address configuration is requested by the VF driver. The parent
+	 * PF driver may reject or overwrite this MAC address.
+	 */
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_vf_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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.
@@ -4366,10 +5184,14 @@ struct hwrm_vnic_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cfg */
-/* Description: This function is used to enable RSS configuration. */
-/* Input (48 bytes) */
-struct hwrm_vnic_rss_cfg_input {
+/* hwrm_vnic_qcfg */
+/*
+ * Description: Query the RX VNIC structure. This function can be used by a PF
+ * driver to query its own VNIC resource or VNIC resource of its child VF. This
+ * function can also be used by a VF driver to query its own VNIC resource.
+ */
+/* Input	(32 bytes) */
+struct hwrm_vnic_qcfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4396,36 +5218,176 @@ struct hwrm_vnic_rss_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t hash_type;
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID	UINT32_C(0x1)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t vf_id;
+	/* ID of Virtual Function whose VNIC resource is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_vnic_qcfg_output {
+	uint16_t error_code;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source and destination IPv4 addresses of IPv4 packets.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4	UINT32_C(0x1)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv4 addresses and source/destination
-	 * ports of TCP/IPv4 packets.
+	 * 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.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4	UINT32_C(0x2)
+	uint16_t dflt_ring_grp;
+	/* Default Completion ring for the VNIC. */
+	uint16_t rss_rule;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv4 addresses and source/destination
-	 * ports of UDP/IPv4 packets.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4	UINT32_C(0x4)
+	uint16_t cos_rule;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source and destination IPv4 addresses of IPv6 packets.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6	UINT32_C(0x8)
+	uint16_t lb_rule;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of TCP/IPv6 packets.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
-	/*
+	uint16_t mru;
+	/* The maximum receive unit of the vnic. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC is the default VNIC for the
+	 * function.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC is configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled
+	 * on this VNIC.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC is configured to buffer
+	 * receive packets in the hardware until the host posts new
+	 * receive buffers. If set to '0', then bd_stall is disabled on
+	 * this VNIC.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC is configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is
+	 * not configured to operate in dual VNIC mode.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	/*
+	 * When this flag is set to '1', the VNIC is configured to
+	 * receive only RoCE traffic. When this flag is set to '0', the
+	 * VNIC is not configured to receive only RoCE traffic. If
+	 * roce_dual_vnic_mode flag and this flag both are set to '1',
+	 * then it is an invalid configuration of the VNIC. The HWRM
+	 * should not allow that type of mis-configuration by HWRM
+	 * clients.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	/*
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. When this bit is set to '1', then the VNIC is enabled
+	 * in a mode where RSS is enabled in the VNIC using a RSS
+	 * context for computing RSS hash but the RSS indirection table
+	 * is not configured.
+	 */
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+/* Input (48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t hash_type;
+	/*
+	 * 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.
@@ -4473,8 +5435,296 @@ struct hwrm_vnic_rss_cfg_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_vnic_plcmodes_cfg */
+/*
+ * Description: This function can be used to set placement mode configuration of
+ * the VNIC.
+ */
+/* Input (40 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to use regular
+	 * placement algorithm. By default, the regular placement algorithm
+	 * shall be enabled on the VNIC.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT \
+		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC shall be configured use the jumbo
+	 * placement algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv4 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv4, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv4, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv4 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv4 packet.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4        UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv6 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv6, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv6, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv6 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv6 packet.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6        UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for FCoE packets at the beginning of FC payload.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_FCOE       UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for RoCE packets at the beginning of RoCE payload (after
+	 * BTH/GRH headers).
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_ROCE       UINT32_C(0x20)
+	uint32_t enables;
+	/*
+	 * This bit must be '1' for the jumbo_thresh_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID \
+		UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the hds_offset_valid field to be configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID \
+		UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the hds_threshold_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID \
+		UINT32_C(0x4)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t jumbo_thresh;
+	/*
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
+	 */
+	uint16_t hds_offset;
+	/*
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
+	 */
+	uint16_t hds_threshold;
+	/*
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_qcfg */
+/*
+ * Description: This function can be used to query placement mode configuration
+ * of the VNIC.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC is configured to use regular placement
+	 * algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_REGULAR_PLACEMENT \
+		UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC is configured to use the jumbo
+	 * placement algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv4 packets.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV4      UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv6 packets.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV6      UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for FCoE packets.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_FCOE     UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for RoCE packets.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_ROCE     UINT32_C(0x20)
+	/*
+	 * When this bit is '1', the VNIC is configured to be the default VNIC
+	 * of the requesting function.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC    UINT32_C(0x40)
+	uint16_t jumbo_thresh;
+	/*
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
+	 */
+	uint16_t hds_offset;
+	/*
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
+	 */
+	uint16_t hds_threshold;
+	/*
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_vnic_rss_cos_lb_ctx_alloc */
-/* Description: This function is used to allocate COS/Load Balance context. */
+/*
+ * Description: This function is used to allocate COS/Load Balance context.
+ */
 /* Input (16 bytes) */
 struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	uint16_t req_type;
@@ -6040,4 +7290,91 @@ struct hwrm_exec_fwd_resp_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_reject_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to reject the request and forward the
+ * error 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_reject_fwd_resp_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t encap_request[26];
+	/*
+	 * This is an encapsulated request. This request should be
+	 * rejected by the HWRM and the error response should be
+	 * provided in the response buffer inside the encapsulated
+	 * request.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_reject_fwd_resp_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 02/23] bnxt: code reorg to properly allocate resources in PF/VF modes
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 01/23] bnxt: add various hwrm input/output structures Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 03/23] bnxt: add tunneling support Ajit Khaparde
                   ` (21 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) Move the function reset to bnxt_dev_init()
2) After a function reset, configure the VFs.  Distribute resources
evenly between all functions (PF and VF) for now. In the future, this
should be controllable.
3) Since PF/VF need to allocate resources from a pool in the hardware,
use func_qcaps and func_qcfg to appropriately query the capabilities
and available resources.
4) If a PF is being initialized and no VFs are allocated, explicitly
call func_cfg to allocate the resources.
5) The bnxt_vf_info and bnxt_pf_info had lot of duplication. Move the
common items to struct bnxt. And only unique items specific to PF remain
in the struct bnxt_pf_info.
6) Once resources are requested from the firmware, update local copy
of resource count in struct bnxt only after sending the func_qcfg to
make sure the allocation request in the firmware went through.
7) Do not initialize the default completion ring in
bnxt_alloc_hwrm_rings().

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  81 +++--
 drivers/net/bnxt/bnxt_cpr.c    | 128 +++++--
 drivers/net/bnxt/bnxt_cpr.h    |  17 +
 drivers/net/bnxt/bnxt_ethdev.c | 187 +++++++---
 drivers/net/bnxt/bnxt_filter.c |  36 +-
 drivers/net/bnxt/bnxt_hwrm.c   | 760 +++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  20 +-
 drivers/net/bnxt/bnxt_irq.c    |  21 +-
 drivers/net/bnxt/bnxt_ring.c   |  17 +-
 drivers/net/bnxt/bnxt_vnic.c   |  47 +--
 drivers/net/bnxt/bnxt_vnic.h   |  11 +-
 11 files changed, 1045 insertions(+), 280 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4418c7f..1522eb4 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -35,6 +35,7 @@
 #define _BNXT_H_
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <sys/queue.h>
 
 #include <rte_ethdev.h>
@@ -54,17 +55,19 @@ enum bnxt_hw_context {
 	HW_CONTEXT_IS_LB    = 3,
 };
 
-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;
-	uint16_t		vlan;
-	struct bnxt_pf_info	*pf;
+struct bnxt_vlan_table_entry {
+	uint16_t		tpid;
+	uint16_t		vid;
+} __attribute__((packed));
+
+struct bnxt_child_vf_info {
+	void			*req_buf;
+	struct bnxt_vlan_table_entry	*vlan_table;
+	STAILQ_HEAD(, bnxt_filter_info)	filter;
+	uint32_t		func_cfg_flags;
+	uint32_t		l2_rx_mask;
+	uint16_t		fid;
+	bool			random_mac;
 };
 
 struct bnxt_pf_info {
@@ -73,22 +76,20 @@ struct bnxt_pf_info {
 #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;
+	uint32_t		func_cfg_flags;
 	void			*vf_req_buf;
 	phys_addr_t		vf_req_buf_dma_addr;
 	uint32_t		vf_req_fwd[8];
-	struct bnxt_vf_info	*vf;
+	uint16_t		total_vnics;
+	struct bnxt_child_vf_info	*vf_info;
+#define BNXT_EVB_MODE_NONE	0
+#define BNXT_EVB_MODE_VEB	1
+#define BNXT_EVB_MODE_VEPA	2
+	uint8_t			evb_mode;
 };
 
 /* Max wait time is 10 * 100ms = 1s */
@@ -174,12 +175,50 @@ struct bnxt {
 	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
+	uint16_t		fw_fid;
+	uint8_t			dflt_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		max_stat_ctx;
+	uint16_t		vlan;
 	struct bnxt_pf_info		pf;
-	struct bnxt_vf_info		vf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint32_t		fw_ver;
+};
+
+/*
+ * Response sent back to the caller after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+	RTE_PMD_BNXT_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_PMD_BNXT_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_PMD_BNXT_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET			0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR	0x02 /* VF requests PF to set MAC addr */
+#define BNXT_VF_SET_VLAN		0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU			0x04 /* VF requests PF to set MTU */
+#define BNXT_VF_SET_MRU			0x05 /* VF requests PF to set MRU */
+/* TODO expose more */
+
+/*
+ * Data sent to the caller when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+	uint16_t vf_id;	/* Virtual Function number */
+	int	retval;	/* return value */
+	void	*msg;	/* pointer to message */
 };
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 3aedcb8..f0b8728 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -65,56 +65,112 @@ void bnxt_handle_async_event(struct bnxt *bp,
 
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
 {
+	struct hwrm_exec_fwd_resp_input *fwreq;
 	struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
 	struct input *fwd_cmd;
-	uint16_t logical_vf_id, error_code;
+	uint16_t fw_vf_id;
+	uint16_t vf_id;
+	uint16_t req_len;
+	int rc;
 
-	/* 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;
+	if (bp->pf.active_vfs <= 0) {
+		RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
+		return;
 	}
 
+	/* Qualify the fwd request */
+	fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+	vf_id = fw_vf_id - bp->pf.first_vf_id;
+
+	req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+		   HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+		HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+	if (req_len > sizeof(fwreq->encap_request))
+		req_len = sizeof(fwreq->encap_request);
+
 	/* 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;
+	fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
+
+	if (fw_vf_id < bp->pf.first_vf_id ||
+	    fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+		RTE_LOG(ERR, PMD,
+		"FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
+			fw_vf_id, bp->pf.first_vf_id,
+			(bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
+			bp->pf.first_vf_id, bp->pf.active_vfs);
 		goto reject;
 	}
 
-	/* Forward */
-	fwd_cmd->target_id = fwd_cmpl->source_id;
-	bnxt_hwrm_exec_fwd_resp(bp, fwd_cmd);
-	return;
+	if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
+		/*
+		 * In older firmware versions, the MAC had to be all zeros for
+		 * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
+		 * zeros if it's being configured and has been ok'd by caller.
+		 */
+		if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
+			struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
+
+			if (vfc->enables &
+			    HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
+				bnxt_hwrm_func_vf_mac(bp, vf_id,
+				(const uint8_t *)"\x00\x00\x00\x00\x00");
+			}
+		}
+		if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
+			struct hwrm_cfa_l2_set_rx_mask_input *srm =
+							(void *)fwd_cmd;
+
+			srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
+			srm->num_vlan_tags = rte_cpu_to_le_32(0);
+			srm->mask &= ~rte_cpu_to_le_32(
+				HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
+		}
+		/* Forward */
+		rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+		if (rc) {
+			RTE_LOG(ERR, PMD,
+				"Failed to send FWD req VF 0x%x, type 0x%x.\n",
+				fw_vf_id - bp->pf.first_vf_id,
+				rte_le_to_cpu_16(fwd_cmd->req_type));
+		}
+		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);
+	rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+	if (rc) {
+		RTE_LOG(ERR, PMD,
+			"Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+			fw_vf_id - bp->pf.first_vf_id,
+			rte_le_to_cpu_16(fwd_cmd->req_type));
+	}
+
+	return;
 }
 
 /* For the default completion ring only */
+int bnxt_alloc_def_cp_ring(struct bnxt *bp)
+{
+	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+	int rc;
+
+	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 = bp->pdev->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;
+	rc = bnxt_hwrm_func_cfg_def_cp(bp);
+
+err_out:
+	return rc;
+}
+
 void bnxt_free_def_cp_ring(struct bnxt *bp)
 {
 	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 83e5376..a6e8785 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -33,6 +33,7 @@
 
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_H_
+#include <stdbool.h>
 
 #include <rte_io.h>
 
@@ -56,6 +57,19 @@
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
 		    ((cpr)->cp_doorbell))
 
+#define B_CP_DB_ARM(cpr)	rte_write32((DB_KEY_CP), ((cpr)->cp_doorbell))
+#define B_CP_DB_DISARM(cpr)	(*(uint32_t *)((cpr)->cp_doorbell) = \
+				 DB_KEY_CP | DB_IRQ_DIS)
+
+#define B_CP_DB_IDX_ARM(cpr, cons)					\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+				(cons)))
+
+#define B_CP_DB_IDX_DISARM(cpr, cons)	do {				\
+		rte_smp_wmb();						\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS |	\
+				(cons));				\
+} while (0)
 #define B_CP_DIS_DB(cpr, raw_cons)					\
 	rte_write32((DB_CP_FLAGS |					\
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
@@ -75,6 +89,8 @@ struct bnxt_cp_ring_info {
 	uint32_t		hw_stats_ctx_id;
 
 	struct bnxt_ring	*cp_ring_struct;
+	uint16_t		cp_cons;
+	bool			v;
 };
 
 #define RX_CMP_L2_ERRORS						\
@@ -82,6 +98,7 @@ struct bnxt_cp_ring_info {
 
 
 struct bnxt;
+int bnxt_alloc_def_cp_ring(struct bnxt *bp);
 void bnxt_free_def_cp_ring(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);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index bb87361..a7f183c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -228,28 +228,31 @@ static int bnxt_init_chip(struct bnxt *bp)
 
 		rc = bnxt_hwrm_vnic_alloc(bp, vnic);
 		if (rc) {
-			RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
-				rc);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d alloc failure rc: %x\n",
+				i, 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);
+				"HWRM vnic %d ctx alloc failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d cfg failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD,
+				"HWRM vnic %d filter failure rc: %x\n",
+				i, rc);
 			goto err_out;
 		}
 		if (vnic->rss_table && vnic->hash_type) {
@@ -269,8 +272,8 @@ static int bnxt_init_chip(struct bnxt *bp)
 			rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
 			if (rc) {
 				RTE_LOG(ERR, PMD,
-					"HWRM vnic set RSS failure rc: %x\n",
-					rc);
+					"HWRM vnic %d set RSS failure rc: %x\n",
+					i, rc);
 				goto err_out;
 			}
 		}
@@ -345,18 +348,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
-	}
+	if (BNXT_PF(bp))
+		dev_info->max_vfs = bp->pdev->max_vfs;
+	dev_info->max_rx_queues = bp->max_rx_rings;
+	dev_info->max_tx_queues = bp->max_tx_rings;
+	dev_info->reta_size = bp->max_rsscos_ctx;
+	max_vnics = bp->max_vnics;
 
 	/* Fast path specifics */
 	dev_info->min_rx_bufsize = 1;
@@ -488,41 +485,18 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	bp->dev_stopped = 0;
-	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);
-
 	bnxt_link_update_op(eth_dev, 0);
 	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;
 }
 
@@ -554,8 +528,6 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
-	bnxt_disable_int(bp);
-	bnxt_free_int(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -669,7 +641,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
 			new.link_speed = ETH_LINK_SPEED_100M;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			RTE_LOG(ERR, PMD,
-				"Failed to retrieve link rc = 0x%x!", rc);
+				"Failed to retrieve link rc = 0x%x!\n", rc);
 			goto out;
 		}
 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
@@ -1082,6 +1054,12 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 
 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
 
+#define ALLOW_FUNC(x)	\
+	{ \
+		typeof(x) arg = (x); \
+		bp->pf.vf_req_fwd[((arg) >> 5)] &= \
+		~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
+	}
 static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1091,13 +1069,15 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	if (version_printed++ == 0)
-		RTE_LOG(INFO, PMD, "%s", bnxt_version);
+		RTE_LOG(INFO, PMD, "%s\n", bnxt_version);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
 
+	bp->dev_stopped = 1;
+
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
 		bp->flags |= BNXT_FLAG_VF;
 
@@ -1130,20 +1110,22 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
 		goto error_free;
 	}
+	if (bp->max_tx_rings == 0) {
+		RTE_LOG(ERR, PMD, "No TX rings available!\n");
+		rc = -EBUSY;
+		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",
+			"Failed to alloc %u bytes needed to store MAC addr tbl\n",
 			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(bp->mac_addr, bp->dflt_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);
@@ -1155,11 +1137,32 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error_free;
 	}
 
-	rc = bnxt_hwrm_func_driver_register(bp, 0,
-					    bp->pf.vf_req_fwd);
+	/* Forward all requests if firmware is new enough */
+	if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
+	    (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
+	    ((bp->fw_ver >= ((20 << 24) | (8 << 16)))))
+		memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
+	else {
+		RTE_LOG(WARNING, PMD,
+			"Firmware too old for VF mailbox functionality\n");
+		memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
+	}
+
+	/*
+	 * The following are used for driver cleanup.  If we disallow these,
+	 * VF drivers can't clean up cleanly.
+	 */
+	ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
+	ALLOW_FUNC(HWRM_VNIC_FREE);
+	ALLOW_FUNC(HWRM_RING_FREE);
+	ALLOW_FUNC(HWRM_RING_GRP_FREE);
+	ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
+	ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
+	ALLOW_FUNC(HWRM_STAT_CTX_FREE);
+	rc = bnxt_hwrm_func_driver_register(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
-			"Failed to register driver");
+			"Failed to register driver\n");
 		rc = -EBUSY;
 		goto error_free;
 	}
@@ -1169,10 +1172,59 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		pci_dev->mem_resource[0].phys_addr,
 		pci_dev->mem_resource[0].addr);
 
-	bp->dev_stopped = 0;
+	rc = bnxt_hwrm_func_reset(bp);
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc);
+		rc = -1;
+		goto error_free;
+	}
+
+	if (BNXT_PF(bp)) {
+		//if (bp->pf.active_vfs) {
+			// TODO: Deallocate VF resources?
+		//}
+		if (bp->pdev->max_vfs) {
+			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
+			if (rc) {
+				RTE_LOG(ERR, PMD, "Failed to allocate VFs\n");
+				goto error_free;
+			}
+		} else {
+			rc = bnxt_hwrm_allocate_pf_only(bp);
+			if (rc) {
+				RTE_LOG(ERR, PMD,
+					"Failed to allocate PF resources\n");
+				goto error_free;
+			}
+		}
+	}
+
+	rc = bnxt_setup_int(bp);
+	if (rc)
+		goto error_free;
+
+	rc = bnxt_alloc_mem(bp);
+	if (rc)
+		goto error_free_int;
+
+	rc = bnxt_request_int(bp);
+	if (rc)
+		goto error_free_int;
+
+	rc = bnxt_alloc_def_cp_ring(bp);
+	if (rc)
+		goto error_free_int;
+
+	bnxt_enable_int(bp);
 
 	return 0;
 
+error_free_int:
+	bnxt_disable_int(bp);
+	bnxt_free_def_cp_ring(bp);
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 error_free:
 	bnxt_dev_uninit(eth_dev);
 error:
@@ -1184,6 +1236,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	int rc;
 
+	bnxt_disable_int(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 	if (eth_dev->data->mac_addrs != NULL) {
 		rte_free(eth_dev->data->mac_addrs);
 		eth_dev->data->mac_addrs = NULL;
@@ -1196,6 +1251,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	bnxt_free_hwrm_resources(bp);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
+	if (bp->pf.vf_info)
+		rte_free(bp->pf.vf_info);
 	eth_dev->dev_ops = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 	eth_dev->tx_pkt_burst = NULL;
@@ -1203,6 +1260,24 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	return rc;
 }
 
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+	struct rte_pmd_bnxt_mb_event_param cb_param;
+
+	cb_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+	cb_param.vf_id = vf_id;
+	cb_param.msg = msg;
+
+	_rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+			&cb_param);
+
+	/* Default to approve */
+	if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+		cb_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+	return cb_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? true : false;
+}
+
 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index df1042c..146ab33 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -73,19 +73,11 @@ 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;
-	}
+	max_filters = bp->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;
+		filter->fw_l2_filter_id = UINT64_MAX;
 		STAILQ_INSERT_TAIL(&bp->free_filter_list, filter, next);
 	}
 }
@@ -122,15 +114,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 		return;
 
 	/* 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
 		if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
@@ -142,7 +126,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 				       "HWRM filter cannot be freed rc = %d\n",
 					rc);
 		}
-		filter->fw_l2_filter_id = -1;
+		filter->fw_l2_filter_id = UINT64_MAX;
 	}
 	STAILQ_INIT(&bp->free_filter_list);
 
@@ -155,21 +139,13 @@ 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;
-	}
+	max_filters = bp->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",
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d filters\n",
 			max_filters);
 		return -ENOMEM;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3849d1a..c248631 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -54,6 +56,38 @@
 
 #define HWRM_CMD_TIMEOUT		2000
 
+struct bnxt_plcmodes_cfg {
+	uint32_t	flags;
+	uint16_t	jumbo_thresh;
+	uint16_t	hds_offset;
+	uint16_t	hds_threshold;
+};
+
+static int page_getenum(size_t size)
+{
+	if (size <= 1 << 4)
+		return 4;
+	if (size <= 1 << 12)
+		return 12;
+	if (size <= 1 << 13)
+		return 13;
+	if (size <= 1 << 16)
+		return 16;
+	if (size <= 1 << 21)
+		return 21;
+	if (size <= 1 << 22)
+		return 22;
+	if (size <= 1 << 30)
+		return 30;
+	RTE_LOG(ERR, PMD, "Page size %zu out of range\n", size);
+	return sizeof(void *) * 8 - 1;
+}
+
+static int page_roundup(size_t size)
+{
+	return 1 << page_getenum(size);
+}
+
 /*
  * HWRM Functions (sent to HWRM)
  * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message()
@@ -252,29 +286,13 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	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_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;
+	uint16_t new_max_vfs;
+	int i;
 
 	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
 
@@ -286,31 +304,52 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	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;
-
-		pf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		pf->port_id = resp->port_id;
-		memcpy(pf->mac_addr, resp->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);
+		bp->pf.port_id = resp->port_id;
+		bp->pf.first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+		new_max_vfs = bp->pdev->max_vfs;
+		if (new_max_vfs != bp->pf.max_vfs) {
+			if (bp->pf.vf_info)
+				rte_free(bp->pf.vf_info);
+			bp->pf.vf_info = rte_malloc("bnxt_vf_info",
+			    sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0);
+			bp->pf.max_vfs = new_max_vfs;
+			for (i = 0; i < new_max_vfs; i++) {
+				bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i;
+				bp->pf.vf_info[i].vlan_table =
+					rte_zmalloc("VF VLAN table",
+						    getpagesize(),
+						    getpagesize());
+				if (bp->pf.vf_info[i].vlan_table == NULL)
+					RTE_LOG(ERR, PMD,
+					"Fail to alloc VLAN table for VF %d\n",
+					i);
+				else
+					rte_mem_lock_page(
+						bp->pf.vf_info[i].vlan_table);
+				STAILQ_INIT(&bp->pf.vf_info[i].filter);
+			}
+		}
+	}
+
+	bp->fw_fid = rte_le_to_cpu_32(resp->fid);
+	memcpy(bp->dflt_mac_addr, &resp->mac_address, ETHER_ADDR_LEN);
+	bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	if (BNXT_PF(bp)) {
+		if (bp->pf.max_vfs)
+			bp->max_vnics = 1;
+		else
+			bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
 	} else {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		vf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		memcpy(vf->mac_addr, &resp->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);
+		bp->max_vnics = 1;
 	}
+	bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+	if (BNXT_PF(bp))
+		bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
 
 	return rc;
 }
@@ -332,8 +371,7 @@ int bnxt_hwrm_func_reset(struct bnxt *bp)
 	return rc;
 }
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd)
+int bnxt_hwrm_func_driver_register(struct bnxt *bp)
 {
 	int rc;
 	struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
@@ -343,16 +381,22 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 		return 0;
 
 	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
-	req.flags = flags;
-	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
-			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD;
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
 	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));
+	if (BNXT_PF(bp)) {
+		req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_INPUT_FWD);
+		memcpy(req.vf_req_fwd, bp->pf.vf_req_fwd,
+		       RTE_MIN(sizeof(req.vf_req_fwd),
+			       sizeof(bp->pf.vf_req_fwd)));
+	}
 
 	req.async_event_fwd[0] |= rte_cpu_to_le_32(0x1);   /* TODO: Use MACRO */
+	memset(req.async_event_fwd, 0xff, sizeof(req.async_event_fwd));
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -391,6 +435,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		resp->hwrm_intf_maj, resp->hwrm_intf_min,
 		resp->hwrm_intf_upd,
 		resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
+	bp->fw_ver = (resp->hwrm_fw_maj << 24) | (resp->hwrm_fw_min << 16) |
+			(resp->hwrm_fw_bld << 8) | resp->hwrm_fw_rsvd;
 	RTE_LOG(INFO, PMD, "Driver HWRM version: %d.%d.%d\n",
 		HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);
 
@@ -825,10 +871,12 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		}
 		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;
-
+	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
+	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				ETHER_CRC_LEN + VLAN_TAG_SIZE;
 	HWRM_PREP(req, VNIC_ALLOC, -1, resp);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -839,37 +887,155 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+static int bnxt_hwrm_vnic_plcmodes_qcfg(struct bnxt *bp,
+					struct bnxt_vnic_info *vnic,
+					struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_QCFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	pmode->flags = rte_le_to_cpu_32(resp->flags);
+	/* dflt_vnic bit doesn't exist in the _cfg command */
+	pmode->flags &= ~(HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC);
+	pmode->jumbo_thresh = rte_le_to_cpu_16(resp->jumbo_thresh);
+	pmode->hds_offset = rte_le_to_cpu_16(resp->hds_offset);
+	pmode->hds_threshold = rte_le_to_cpu_16(resp->hds_threshold);
+
+	return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
+				       struct bnxt_vnic_info *vnic,
+				       struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+	req.flags = rte_cpu_to_le_32(pmode->flags);
+	req.jumbo_thresh = rte_cpu_to_le_16(pmode->jumbo_thresh);
+	req.hds_offset = rte_cpu_to_le_16(pmode->hds_offset);
+	req.hds_threshold = rte_cpu_to_le_16(pmode->hds_threshold);
+	req.enables = rte_cpu_to_le_32(
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID
+	);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	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;
+	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	struct bnxt_plcmodes_cfg pmodes;
+
+	rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
+	if (rc)
+		return rc;
 
 	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);
+	if (vnic->lb_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE;
+	if (vnic->cos_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE;
+	if (vnic->rss_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	req.enables |= rte_cpu_to_le_32(ctx_enable_flag);
 	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);
+	req.dflt_ring_grp = rte_cpu_to_le_16(vnic->dflt_ring_grp);
+	req.rss_rule = rte_cpu_to_le_16(vnic->rss_rule);
+	req.cos_rule = rte_cpu_to_le_16(vnic->cos_rule);
+	req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
+	req.mru = rte_cpu_to_le_16(vnic->mru);
 	if (vnic->func_default)
-		req.flags = 1;
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
 	if (vnic->vlan_strip)
 		req.flags |=
 		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+	if (vnic->bd_stall)
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+	if (vnic->roce_dual)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE);
+	if (vnic->roce_only)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE);
+	if (vnic->rss_dflt_cr)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	rc = bnxt_hwrm_vnic_plcmodes_cfg(bp, vnic, &pmodes);
+
+	return rc;
+}
+
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+		int16_t fw_vf_id)
+{
+	int rc = 0;
+	struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_QCFG, -1, resp);
+
+	req.enables =
+		rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.vf_id = rte_cpu_to_le_16(fw_vf_id);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
 	HWRM_CHECK_RESULT;
 
+	vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_rule);
+	vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+	vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+	vnic->mru = rte_le_to_cpu_16(resp->mru);
+	vnic->func_default = rte_le_to_cpu_32(
+			resp->flags) & HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+	vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+	vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+	vnic->roce_dual = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE;
+	vnic->roce_only = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE;
+	vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE;
+
 	return rc;
 }
 
@@ -886,7 +1052,7 @@ int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
 
 	return rc;
 }
@@ -900,13 +1066,13 @@ int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	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);
+	req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+	vnic->rss_rule = INVALID_HW_RING_ID;
 
 	return rc;
 }
@@ -947,7 +1113,7 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	    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);
+	req.rss_ctx_idx = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -956,6 +1122,28 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+	memcpy(req.dflt_mac_addr, mac_addr, sizeof(req.dflt_mac_addr));
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	bp->pf.vf_info[vf].random_mac = false;
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -1217,7 +1405,8 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		return;
 
 	vnic = &bp->vnic_info[0];
-	bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
+	if (BNXT_PF(bp))
+		bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
 
 	/* VNIC resources */
 	for (i = 0; i < bp->nr_vnics; i++) {
@@ -1512,12 +1701,8 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
-	if (BNXT_VF(bp)) {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		/* Hard Coded.. 0xfff VLAN ID mask */
-		vf->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
-	}
+	/* Hard Coded.. 0xfff VLAN ID mask */
+	bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
 
 	switch (resp->port_partition_type) {
 	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
@@ -1532,3 +1717,436 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	return rc;
 }
+
+static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg,
+				   struct hwrm_func_qcaps_output *qcaps)
+{
+	qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs;
+	memcpy(qcaps->mac_address, fcfg->dflt_mac_addr,
+	       sizeof(qcaps->mac_address));
+	qcaps->max_l2_ctxs = fcfg->num_l2_ctxs;
+	qcaps->max_rx_rings = fcfg->num_rx_rings;
+	qcaps->max_tx_rings = fcfg->num_tx_rings;
+	qcaps->max_cmpl_rings = fcfg->num_cmpl_rings;
+	qcaps->max_stat_ctx = fcfg->num_stat_ctxs;
+	qcaps->max_vfs = 0;
+	qcaps->first_vf_id = 0;
+	qcaps->max_vnics = fcfg->num_vnics;
+	qcaps->max_decap_records = 0;
+	qcaps->max_encap_records = 0;
+	qcaps->max_tx_wm_flows = 0;
+	qcaps->max_tx_em_flows = 0;
+	qcaps->max_rx_wm_flows = 0;
+	qcaps->max_rx_em_flows = 0;
+	qcaps->max_flow_id = 0;
+	qcaps->max_mcast_filters = fcfg->num_mcast_filters;
+	qcaps->max_sp_tx_rings = 0;
+	qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps;
+}
+
+static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
+	req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx);
+	req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings);
+	req.num_tx_rings = rte_cpu_to_le_16(tx_rings);
+	req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings);
+	req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx);
+	req.num_vnics = rte_cpu_to_le_16(bp->max_vnics);
+	req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps);
+	req.fid = rte_cpu_to_le_16(0xffff);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+static void populate_vf_func_cfg_req(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *req,
+				     int num_vfs)
+{
+	req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+
+	req->mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx /
+						(num_vfs + 1));
+	req->num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1));
+	req->num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings /
+					       (num_vfs + 1));
+	req->num_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1));
+	req->num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1));
+	req->num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1));
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	req->num_vnics = rte_cpu_to_le_16(1);
+	req->num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps /
+						 (num_vfs + 1));
+}
+
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	memcpy(mac->addr_bytes, resp->mac_address, ETHER_ADDR_LEN);
+	return rc;
+}
+
+static void add_random_mac_if_needed(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *cfg_req,
+				     int vf)
+{
+	struct ether_addr mac;
+
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac))
+		return;
+
+	if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) {
+		cfg_req->enables |=
+		rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+		eth_random_addr(cfg_req->dflt_mac_addr);
+		bp->pf.vf_info[vf].random_mac = true;
+	} else {
+		memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, ETHER_ADDR_LEN);
+	}
+}
+
+static void reserve_resources_from_vf(struct bnxt *bp,
+				      struct hwrm_func_cfg_input *cfg_req,
+				      int vf)
+{
+	struct hwrm_func_qcaps_input req = {0};
+	struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Get the actual allocated values now */
+	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps failed rc:%d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps error %d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	}
+
+	bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx);
+	bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/*
+	 * TODO: While not supporting VMDq with VFs, max_vnics is always
+	 * forced to 1 in this case
+	 */
+	//bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics);
+	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
+}
+
+static int update_pf_resource_max(struct bnxt *bp)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* And copy the allocated numbers into the pf struct */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+	bp->pf.evb_mode = resp->evb_mode;
+	/* TODO: Only TX ring value reflects actual allocation */
+	//bp->pf.active_vfs = rte_le_to_cpu_16(resp->alloc_vfs);
+	//bp->max_rx_rings = rte_le_to_cpu_16(resp->alloc_rx_rings);
+	//bp->max_cp_rings = rte_le_to_cpu_16(resp->alloc_cmpl_rings);
+	//bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->alloc_rsscos_ctx);
+	//bp->max_vnics = rte_le_to_cpu_16(resp->alloc_vnics);
+	//bp->max_l2_ctx = rte_le_to_cpu_16(resp->alloc_l2_ctx);
+	//bp->max_ring_grps = rte_le_to_cpu_32(resp->alloc_hw_ring_grps);
+
+	return rc;
+}
+
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
+{
+	int rc;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+	if (rc)
+		return rc;
+
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	return rc;
+}
+
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int i;
+	size_t sz;
+	int rc = 0;
+	size_t req_buf_sz;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+
+	if (rc)
+		return rc;
+
+	bp->pf.active_vfs = num_vfs;
+
+	/*
+	 * First, configure the PF to only use one TX ring.  This ensures that
+	 * there are enough rings for all VFs.
+	 *
+	 * If we don't do this, when we call func_alloc() later, we will lock
+	 * extra rings to the PF that won't be available during func_cfg() of
+	 * the VFs.
+	 *
+	 * This has been fixed with firmware versions above 20.6.54
+	 */
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, 1);
+	if (rc)
+		return rc;
+
+	/*
+	 * Now, create and register a buffer to hold forwarded VF requests
+	 */
+	req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN;
+	bp->pf.vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz,
+		page_roundup(num_vfs * HWRM_MAX_REQ_LEN));
+	if (bp->pf.vf_req_buf == NULL) {
+		rc = -ENOMEM;
+		goto error_free;
+	}
+	for (sz = 0; sz < req_buf_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)bp->pf.vf_req_buf) + sz);
+	for (i = 0; i < num_vfs; i++)
+		bp->pf.vf_info[i].req_buf = ((char *)bp->pf.vf_req_buf) +
+					(i * HWRM_MAX_REQ_LEN);
+
+	rc = bnxt_hwrm_func_buf_rgtr(bp);
+	if (rc)
+		goto error_free;
+
+	populate_vf_func_cfg_req(bp, &req, num_vfs);
+
+	bp->pf.active_vfs = 0;
+	for (i = 0; i < num_vfs; i++) {
+		add_random_mac_if_needed(bp, &req, i);
+
+		HWRM_PREP(req, FUNC_CFG, -1, resp);
+		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
+		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
+		rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+		/* Clear enable flag for next pass */
+		req.enables &= ~rte_cpu_to_le_32(
+				HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+
+		if (rc || resp->error_code) {
+			RTE_LOG(ERR, PMD,
+				"Failed to initizlie VF %d\n", i);
+			RTE_LOG(ERR, PMD,
+				"Not all VFs available. (%d, %d)\n",
+				rc, resp->error_code);
+			break;
+		}
+
+		reserve_resources_from_vf(bp, &req, i);
+		bp->pf.active_vfs++;
+	}
+
+	/*
+	 * Now configure the PF to use "the rest" of the resources
+	 * We're using STD_TX_RING_MODE here though which will limit the TX
+	 * rings.  This will allow QoS to function properly.  Not setting this
+	 * will cause PF rings to break bandwidth settings.
+	 */
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	if (rc)
+		goto error_free;
+
+	rc = update_pf_resource_max(bp);
+	if (rc)
+		goto error_free;
+
+	return rc;
+
+error_free:
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	return rc;
+}
+
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	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);
+
+	req.req_buf_num_pages = rte_cpu_to_le_16(1);
+	req.req_buf_page_size = rte_cpu_to_le_16(
+			 page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN));
+	req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
+	req.req_buf_page_addr[0] =
+		rte_cpu_to_le_64(rte_mem_virt2phy(bp->pf.vf_req_buf));
+	if (req.req_buf_page_addr[0] == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map buffer address to physical memory\n");
+		return -ENOMEM;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
+	struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_BUF_UNRGTR, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_reject_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_reject_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, REJECT_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_exec_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, EXEC_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6519ef2..61d8e1a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,14 +51,18 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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, uint16_t target_id,
+			    void *encaped, size_t ec_size);
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size);
 
-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_buf_rgtr(struct bnxt *bp);
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
@@ -81,6 +85,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_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				int16_t fw_vf_id);
 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);
@@ -101,5 +107,11 @@ 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);
 int bnxt_hwrm_func_qcfg(struct bnxt *bp);
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
+			  const uint8_t *mac_addr);
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index 20e17ff..a3d235d 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -66,16 +66,26 @@ static void bnxt_int_handler(void *param)
 			/* Handle any async event */
 			bnxt_handle_async_event(bp, cmp);
 			break;
-		case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+		case CMPL_BASE_TYPE_HWRM_FWD_REQ:
 			/* Handle HWRM forwarded responses */
 			bnxt_handle_fwd_req(bp, cmp);
 			break;
 		default:
 			/* Ignore any other events */
+			if (cmp->type & rte_cpu_to_le_16(0x01)) {
+				if (!CMP_VALID(cmp, raw_cons,
+					       cpr->cp_ring_struct))
+					goto no_more;
+			}
+			RTE_LOG(INFO, PMD,
+				"Ignoring %02x completion\n", CMP_TYPE(cmp));
 			break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
-	}
+
+	};
+no_more:
+	cpr->cp_raw_cons = raw_cons;
 	B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
 }
 
@@ -102,14 +112,15 @@ 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);
+	if (cpr != NULL && cpr->cp_doorbell != NULL)
+		B_CP_DB_DISARM(cpr);
 }
 
 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);
+	B_CP_DB_ARM(cpr);
 }
 
 int bnxt_setup_int(struct bnxt *bp)
@@ -136,7 +147,7 @@ int bnxt_setup_int(struct bnxt *bp)
 	return 0;
 
 setup_exit:
-	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed\n");
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0fafa13..0ad7810 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -213,21 +213,6 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 	unsigned int i;
 	int rc = 0;
 
-	/* Default completion ring */
-	{
-		struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-		struct bnxt_ring *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 = 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;
@@ -259,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		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!");
+			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 33fdde2..1979228 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -69,21 +69,14 @@ void bnxt_init_vnics(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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;
+		vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
 		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
 			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
@@ -181,15 +174,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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);
@@ -232,15 +217,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp)
 	if (bp->vnic_info == NULL)
 		return;
 
-	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;
-	}
+	max_vnics = bp->max_vnics;
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
 		if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
@@ -258,20 +235,12 @@ 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;
-	}
+	max_vnics = bp->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",
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for %d VNICs\n",
 			max_vnics);
 		return -ENOMEM;
 	}
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 9671ba4..ca1c9cf 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -42,8 +42,7 @@ struct bnxt_vnic_info {
 	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;
+	uint16_t	rss_rule;
 #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 + \
@@ -51,6 +50,8 @@ struct bnxt_vnic_info {
 	uint16_t	start_grp_id;
 	uint16_t	end_grp_id;
 	uint16_t	fw_grp_ids[MAX_QUEUES_PER_VNIC];
+	uint16_t	dflt_ring_grp;
+	uint16_t	mru;
 	uint16_t	hash_type;
 	phys_addr_t	rss_table_dma_addr;
 	uint16_t	*rss_table;
@@ -60,8 +61,14 @@ struct bnxt_vnic_info {
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
 
+	uint16_t	cos_rule;
+	uint16_t	lb_rule;
 	bool		vlan_strip;
 	bool		func_default;
+	bool		bd_stall;
+	bool		roce_dual;
+	bool		roce_only;
+	bool		rss_dflt_cr;
 
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 03/23] bnxt: add tunneling support
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 01/23] bnxt: add various hwrm input/output structures Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 02/23] bnxt: code reorg to properly allocate resources in PF/VF modes Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 04/23] bnxt: support lack of huge pages Ajit Khaparde
                   ` (20 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for udp_tunnel_port_add/del dev_ops to configure a UDP port
for VXLAN and Geneve Tunnel protocols.
The HWRM supports only one global destination port for a tunnel type,
use a referene counter to keep track of its usage.
Cache the configured VXLAN/Geneve ports and use that value to check
if the right UDP port is being freed up.
Skip calling bnxt_hwrm_tunnel_dst_port_alloc if the same UDP port is
being programmed.
Skip calling bnxt_hwrm_tunnel_dst_port_free if no UDP port has been
configured.
Also update tx offload capabilities

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   6 +
 drivers/net/bnxt/bnxt_ethdev.c         | 119 +++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.c           |  56 +++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   5 +
 drivers/net/bnxt/bnxt_txr.c            |   3 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 273 +++++++++++++++++++++++++++++++++
 6 files changed, 460 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 1522eb4..e85cbee 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -188,6 +188,12 @@ struct bnxt {
 	struct bnxt_pf_info		pf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint8_t			vxlan_port_cnt;
+	uint8_t			geneve_port_cnt;
+	uint16_t		vxlan_port;
+	uint16_t		geneve_port;
+	uint16_t		vxlan_fw_dst_port_id;
+	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index a7f183c..18263a4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -363,7 +363,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
+					DEV_TX_OFFLOAD_TCP_TSO |
+					DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+					DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+					DEV_TX_OFFLOAD_GRE_TNL_TSO |
+					DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+					DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
 
 	/* *INDENT-OFF* */
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -975,6 +980,116 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
 	return bnxt_set_hwrm_link_config(bp, true);
 }
 
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->vxlan_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->vxlan_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+		bp->vxlan_port_cnt++;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->geneve_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->geneve_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+		bp->geneve_port_cnt++;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+					     tunnel_type);
+	return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	uint16_t port = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (!bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->vxlan_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->vxlan_port);
+			return -EINVAL;
+		}
+		if (--bp->vxlan_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+		port = bp->vxlan_fw_dst_port_id;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (!bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->geneve_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->geneve_port);
+			return -EINVAL;
+		}
+		if (--bp->geneve_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+		port = bp->geneve_fw_dst_port_id;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+	if (!rc) {
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+			bp->vxlan_port = 0;
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+			bp->geneve_port = 0;
+	}
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1006,6 +1121,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.mac_addr_remove = bnxt_mac_addr_remove_op,
 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
+	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
+	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_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 c248631..c8abbcb 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1396,6 +1396,18 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+void bnxt_free_tunnel_ports(struct bnxt *bp)
+{
+	if (bp->vxlan_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN);
+	bp->vxlan_port = 0;
+	if (bp->geneve_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+	bp->geneve_port = 0;
+}
+
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 {
 	struct bnxt_vnic_info *vnic;
@@ -1421,6 +1433,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	bnxt_free_all_hwrm_rings(bp);
 	bnxt_free_all_hwrm_ring_grps(bp);
 	bnxt_free_all_hwrm_stat_ctxs(bp);
+	bnxt_free_tunnel_ports(bp);
 }
 
 static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
@@ -2045,6 +2058,49 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_alloc_input req = {0};
+	struct hwrm_tunnel_dst_port_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_val = port;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	switch (tunnel_type) {
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN:
+		bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->vxlan_port = port;
+		break;
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE:
+		bp->geneve_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->geneve_port = port;
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_free_input req = {0};
+	struct hwrm_tunnel_dst_port_free_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_FREE, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_id = rte_cpu_to_be_16(port);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
 
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 61d8e1a..20fe2c6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -113,5 +113,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+void bnxt_free_tunnel_ports(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 0d15bb1..6870b16 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -213,7 +213,8 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 			/* TSO */
 			txbd1->lflags = TX_BD_LONG_LFLAGS_LSO;
 			txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
-					tx_pkt->l4_len;
+					tx_pkt->l4_len + tx_pkt->outer_l2_len +
+					tx_pkt->outer_l3_len;
 			txbd1->mss = tx_pkt->tso_segsz;
 
 		} else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM |
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index a091a0b..da3771a 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -6990,6 +6990,279 @@ struct hwrm_cfa_l2_set_rx_mask_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_tunnel_dst_port_query */
+/*
+ * Description: This function is called by a driver to query tunnel type
+ * specific destination port configuration.
+ */
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_query_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0[7];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_query_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tunnel_dst_port_id;
+	/*
+	 * This field represents the identifier of L4 destination port
+	 * used for the given tunnel type. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling.
+	 */
+	uint16_t tunnel_dst_port_val;
+	/*
+	 * This field represents the value of L4 destination port
+	 * identified by tunnel_dst_port_id. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling. This field is in network byte order. A value
+	 * of 0 means that the destination port is not configured.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_tunnel_dst_port_alloc */
+/*
+ * Description: This function is called by a driver to allocate l4 destination
+ * port for a specific tunnel type. The destination port value is provided in
+ * the input. If the HWRM supports only one global destination port for a tunnel
+ * type, then the HWRM shall keep track of its usage as described below. # The
+ * first caller that allocates a destination port shall always succeed and the
+ * HWRM shall save the destination port configuration for that tunnel type and
+ * increment the usage count to 1. # Subsequent callers allocating the same
+ * destination port for that tunnel type shall succeed and the HWRM shall
+ * increment the usage count for that port for each subsequent caller that
+ * succeeds. # Any subsequent caller trying to allocate a different destination
+ * port for that tunnel type shall fail until the usage count for the original
+ * destination port goes to zero. # A caller that frees a port will cause the
+ * usage count for that port to decrement.
+ */
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_alloc_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_val;
+	/*
+	 * This field represents the value of L4 destination port used
+	 * for the given tunnel type. This field is valid for specific
+	 * tunnel types that use layer 4	(e.g. UDP) transports for
+	 * tunneling. This field is in network byte order. A value of 0
+	 * shall fail the command.
+	 */
+	uint32_t unused_1;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tunnel_dst_port_id;
+	/*
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_tunnel_dst_port_free */
+/*
+ * Description: This function is called by a driver to free l4 destination port
+ * for a specific tunnel type.
+ */
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_free_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_id;
+	/*
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
+	 */
+	uint32_t unused_1;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_free_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_stat_ctx_alloc */
 /*
  * Description: This command allocates and does basic preparation for a stat
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 04/23] bnxt: support lack of huge pages
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (2 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 03/23] bnxt: add tunneling support Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 05/23] bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en Ajit Khaparde
                   ` (19 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

rte_malloc_virt2phy() does not return a physical address if huge pages
aren't in use.  Further, rte_memzone->phys_addr is not a physical address.

Use rte_mem_virt2phy() and manually lock pages to support lack of
huge pages.

Also check the return value of rte_mem_virt2phy()

Verify the function returns an address. Otherwise return an error and
log a message.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 17 +++++++++++++++--
 drivers/net/bnxt/bnxt_ring.c | 31 +++++++++++++++++++++++++------
 drivers/net/bnxt/bnxt_vnic.c | 16 +++++++++++++++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index c8abbcb..db00a74 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -487,8 +487,15 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto error;
 		}
+		rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 		bp->hwrm_cmd_resp_dma_addr =
-			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+			rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+		if (bp->hwrm_cmd_resp_dma_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"Unable to map response buffer to physical memory.\n");
+			rc = -ENOMEM;
+			goto error;
+		}
 		bp->max_resp_len = max_resp_len;
 	}
 
@@ -1361,10 +1368,16 @@ 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);
+	rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 	if (bp->hwrm_cmd_resp_addr == NULL)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
-		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+	if (bp->hwrm_cmd_resp_dma_addr == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map response address to physical memory\n");
+		return -ENOMEM;
+	}
 	rte_spinlock_init(&bp->hwrm_lock);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0ad7810..642ec53 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -32,6 +32,7 @@
  */
 
 #include <rte_memzone.h>
+#include <unistd.h>
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
@@ -96,6 +97,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	struct rte_pci_device *pdev = bp->pdev;
 	const struct rte_memzone *mz = NULL;
 	char mz_name[RTE_MEMZONE_NAMESIZE];
+	phys_addr_t mz_phys_addr;
+	int sz;
 
 	int stats_len = (tx_ring_info || rx_ring_info) ?
 	    RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats64)) : 0;
@@ -136,21 +139,37 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
 	mz = rte_memzone_lookup(mz_name);
 	if (!mz) {
-		mz = rte_memzone_reserve(mz_name, total_alloc_len,
+		mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
-					 RTE_MEMZONE_SIZE_HINT_ONLY);
+					 RTE_MEMZONE_SIZE_HINT_ONLY,
+					 getpagesize());
 		if (mz == NULL)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		for (sz = 0; sz < total_alloc_len; sz += getpagesize())
+			rte_mem_lock_page(((char *)mz->addr) + sz);
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map ring address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	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->bd_dma = mz_phys_addr + tx_ring_start;
 		tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
 		tx_ring->mem_zone = (const void *)mz;
 
@@ -170,7 +189,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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->bd_dma = mz_phys_addr + rx_ring_start;
 		rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
 		rx_ring->mem_zone = (const void *)mz;
 
@@ -185,7 +204,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
-	cp_ring->bd_dma = mz->phys_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;
 	cp_ring->mem_zone = (const void *)mz;
@@ -196,7 +215,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		*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_map = mz_phys_addr;
 	}
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 1979228..1521f4d 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -173,6 +173,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 				HW_HASH_KEY_SIZE);
 	uint16_t max_vnics;
 	int i;
+	phys_addr_t mz_phys_addr;
 
 	max_vnics = bp->max_vnics;
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
@@ -189,6 +190,19 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 		if (!mz)
 			return -ENOMEM;
 	}
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map vnic address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
@@ -198,7 +212,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 			(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_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));
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 05/23] bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (3 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 04/23] bnxt: support lack of huge pages Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 06/23] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
                   ` (18 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

Add functions rte_pmd_bnxt_set_tx_loopback,
rte_pmd_bnxt_set_all_queues_drop_en and
rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
queue_drop and VF MAC address setting in the hardware.
It also adds the necessary functions to send the HWRM commands
to the firmware.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/Makefile                 |   4 +
 drivers/net/bnxt/bnxt_hwrm.c              | 108 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |   4 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h    |  79 +++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 163 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  87 ++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   9 ++
 7 files changed, 454 insertions(+)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0fffe35..b03f65d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -38,6 +38,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnxt.a
 
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
 LIBABIVER := 1
 
 CFLAGS += -O3
@@ -60,10 +62,12 @@ 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
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
 
 #
 # Export include files
 #
 SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include := rte_pmd_bnxt.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index db00a74..c1cf95d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2071,6 +2071,24 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+	req.evb_mode = bp->pf.evb_mode;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type)
 {
@@ -2219,3 +2237,93 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
+					uint16_t *vnic_ids)
+{
+	struct hwrm_func_vf_vnic_ids_query_input req = {0};
+	struct hwrm_func_vf_vnic_ids_query_output *resp =
+						bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* First query all VNIC ids */
+	HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY, -1, resp_vf_vnic_ids);
+
+	req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+	req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+	req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2phy(vnic_ids));
+
+	if (req.vnic_id_tbl_addr == 0) {
+		RTE_LOG(ERR, PMD,
+		"unable to map VNIC ID table address to physical memory\n");
+		//rte_free(vnic_ids);
+		return -ENOMEM;
+	}
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query error %d\n", rc);
+		return -1;
+	}
+
+	return rte_le_to_cpu_32(resp->vnic_id_cnt);
+}
+
+/*
+ * This function queries the VNIC IDs  for a specified VF. It then calls
+ * the vnic_cb to update the necessary field in vnic_info with cbdata.
+ * Then it calls the hwrm_cb function to program this new vnic configuration.
+ */
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic))
+{
+	struct bnxt_vnic_info vnic;
+	int rc = 0;
+	int i, num_vnic_ids;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	size_t sz;
+
+	/* First query all VNIC ids */
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	num_vnic_ids = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+
+	if (num_vnic_ids < 0)
+		return num_vnic_ids;
+
+	/* Retrieve VNIC, update bd_stall then update */
+
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+		if (rc)
+			break;
+		if (vnic.mru == 4)	// Unallocated
+			continue;
+
+		vnic_cb(&vnic, cbdata);
+
+		rc = hwrm_cb(bp, &vnic);
+		if (rc)
+			break;
+	}
+
+	rte_free(vnic_ids);
+
+	return rc;
+}
+
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 20fe2c6..09b935c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -111,6 +111,7 @@ int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
 int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -118,5 +119,8 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
 
 #endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index da3771a..c730337 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -2766,6 +2766,85 @@ struct hwrm_func_cfg_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_func_vf_vnic_ids_query */
+/* Description: This command is used to query vf vnic ids. */
+/* Input	(32 bytes) */
+struct hwrm_func_vf_vnic_ids_query_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_vnic_id_cnt;
+	/* Max number of vnic ids in vnic id table */
+	uint64_t vnic_id_tbl_addr;
+	/* This is the address for VF VNIC ID table */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_vf_vnic_ids_query_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id_cnt;
+	/*
+	 * Actual number of vnic ids Each VNIC ID is written as a 32-bit
+	 * number.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_func_drv_rgtr */
 /*
  * Description: This command is used by the function driver to register its
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 0000000..667b24c
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,163 @@
+/*-
+ *   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>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set Tx loopback on non-PF port %d!\n",
+			port);
+		return -ENOTSUP;
+	}
+
+	if (on)
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+	else
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+	rc = bnxt_hwrm_pf_evb_mode(bp);
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->bd_stall = !(*on);
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	uint32_t i;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set all queues drop on non-PF port!\n");
+		return -ENOTSUP;
+	}
+
+	if (bp->vnic_info == NULL)
+		return -ENODEV;
+
+	/* Stall PF */
+	for (i = 0; i < bp->nr_vnics; i++) {
+		bp->vnic_info[i].bd_stall = !on;
+		rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update PF VNIC %d.\n", i);
+			return rc;
+		}
+	}
+
+	/* Stall all active VFs */
+	for (i = 0; i < bp->pf.active_vfs; i++) {
+		rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
+				rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", i);
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs || mac_addr == NULL)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d mac address on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 0000000..eec2313
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,87 @@
+/*-
+ *   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 _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+		struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+#endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 349c6e1..8b77163 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,13 @@
 DPDK_16.04 {
 
 	local: *;
+
+};
+
+DPDK_17.08 {
+	global:
+
+	rte_pmd_bnxt_set_tx_loopback;
+	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_set_vf_mac_addr;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 06/23] bnxt: add support for set VF QOS and MAC anti spoof
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (4 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 05/23] bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 07/23] bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs Ajit Khaparde
                   ` (17 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to
1) enable VF MAC anti spoof.
2) QOS configuration for specified VF.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                   |  2 +
 drivers/net/bnxt/bnxt_hwrm.c              | 33 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  3 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 95 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 37 ++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  2 +
 6 files changed, 172 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e85cbee..8db2ed4 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -67,6 +67,8 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
+	uint16_t		max_tx_rate;
+	uint8_t			mac_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index c1cf95d..88704b7 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2133,6 +2133,21 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 	return rc;
 }
 
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
@@ -2194,6 +2209,24 @@ int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(enables);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.max_bw = rte_cpu_to_le_32(max_bw);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 09b935c..857772b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -112,6 +112,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -119,6 +121,7 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 667b24c..9d331eb 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -161,3 +161,98 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk)
+{
+	struct rte_eth_dev *eth_dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	uint16_t tot_rate = 0;
+	uint64_t idx;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	eth_dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!bp->pf.active_vfs)
+		return -EINVAL;
+
+	if (vf >= bp->pf.max_vfs)
+		return -EINVAL;
+
+	/* Add up the per queue BW and configure MAX BW of the VF */
+	for (idx = 0; idx < 64; idx++) {
+		if ((1ULL << idx) & q_msk)
+			tot_rate += tx_rate;
+	}
+
+	/* Requested BW can't be greater than link speed */
+	if (tot_rate > eth_dev->data->dev_link.link_speed) {
+		RTE_LOG(ERR, PMD, "Rate > Link speed. Set to %d\n", tot_rate);
+		return -EINVAL;
+	}
+
+	/* Requested BW already configured */
+	if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
+		return 0;
+
+	rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
+				HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
+
+	if (!rc)
+		bp->pf.vf_info[vf].max_tx_rate = tot_rate;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	uint32_t func_flags;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	/* Prev setting same as new setting. */
+	if (on == bp->pf.vf_info[vf].mac_spoof_en)
+		return 0;
+
+	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+	if (on)
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
+	else
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+
+	bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf);
+	if (!rc)
+		bp->pf.vf_info[vf].mac_spoof_en = on;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index eec2313..118acd2 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -37,6 +37,24 @@
 #include <rte_ethdev.h>
 
 /**
+ * Enable/Disable VF MAC anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF MAC anti spoof.
+ *    0 - Disable VF MAC anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
  * Set the VF MAC address.
  *
  * @param port
@@ -84,4 +102,23 @@ int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * Set the VF rate limit.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param tx_rate
+ *   Tx rate for the VF
+ * @param q_msk
+ *   Mask of the Tx queue
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 8b77163..4155640 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -10,4 +10,6 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
 	rte_pmd_bnxt_set_vf_mac_addr;
+	rte_pmd_bnxt_set_vf_mac_anti_spoof;
+	rte_pmd_bnxt_set_vf_rate_limit;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 07/23] bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (5 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 06/23] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 08/23] bnxt: add support to get and clear VF specific stats Ajit Khaparde
                   ` (16 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support for VF VLAN stripq, VF VLAN anti spoof and
VF VLAN filtering.
The VF VLAN filtering needs the VLAN anti spoof setting to be set first
before the command to program the VLAN table is sent to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                   |   2 +
 drivers/net/bnxt/bnxt_ethdev.c            |  12 +--
 drivers/net/bnxt/bnxt_filter.h            |   2 +
 drivers/net/bnxt/bnxt_hwrm.c              |  89 ++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   9 +-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 174 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  60 +++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   3 +
 8 files changed, 339 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8db2ed4..5f458cd 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -68,7 +68,9 @@ struct bnxt_child_vf_info {
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
 	uint16_t		max_tx_rate;
+	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
+	uint8_t			vlan_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 18263a4..fcb7679 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -278,7 +278,7 @@ static int bnxt_init_chip(struct bnxt *bp)
 			}
 		}
 	}
-	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"HWRM cfa l2 rx mask failure rc: %x\n", rc);
@@ -628,7 +628,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
 	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
 	filter->mac_index = index;
 	memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
-	return bnxt_hwrm_set_filter(bp, vnic, filter);
+	return bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 }
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
@@ -677,7 +677,7 @@ static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
@@ -691,7 +691,7 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
@@ -705,7 +705,7 @@ static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
@@ -719,7 +719,7 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 06fe134..353b7f7 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -63,6 +63,8 @@ struct bnxt_filter_info {
 	uint32_t		vni;
 	uint8_t			pri_hint;
 	uint64_t		l2_filter_id_hint;
+	uint32_t		src_id;
+	uint8_t			src_type;
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 88704b7..05f7034 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -196,7 +196,10 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
-int bnxt_hwrm_cfa_l2_set_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,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table)
 {
 	int rc = 0;
 	struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
@@ -215,6 +218,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		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_BCAST |
 				    mask);
+	if (vlan_count && vlan_table) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
+			 rte_mem_virt2phy(vlan_table));
+		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
+	}
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -244,7 +253,7 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 }
 
 int bnxt_hwrm_set_filter(struct bnxt *bp,
-			 struct bnxt_vnic_info *vnic,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter)
 {
 	int rc = 0;
@@ -258,7 +267,7 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 
 	enables = filter->enables |
 	      HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
-	req.dst_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.dst_id = rte_cpu_to_le_16(dst_id);
 
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
@@ -274,6 +283,10 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
 		req.l2_ovlan_mask = filter->l2_ovlan_mask;
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
+		req.src_id = rte_cpu_to_le_32(filter->src_id);
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
+		req.src_type = filter->src_type;
 
 	req.enables = rte_cpu_to_le_32(enables);
 
@@ -1402,7 +1415,7 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	int rc = 0;
 
 	STAILQ_FOREACH(filter, &vnic->filter, next) {
-		rc = bnxt_hwrm_set_filter(bp, vnic, filter);
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
 			break;
 	}
@@ -2360,3 +2373,71 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE);
+	req.vlan_antispoof_mode = on ?
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN :
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
+{
+	struct bnxt_vnic_info vnic;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	int num_vnic_ids, i;
+	size_t sz;
+	int rc;
+
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	rc = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+	if (rc <= 0)
+		goto exit;
+	num_vnic_ids = rc;
+
+	/*
+	 * Loop through to find the default VNIC ID.
+	 * TODO: The easier way would be to obtain the resp->dflt_vnic_id
+	 * by sending the hwrm_func_qcfg command to the firmware.
+	 */
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic,
+					bp->pf.first_vf_id + vf);
+		if (rc)
+			goto exit;
+		if (vnic.func_default) {
+			rte_free(vnic_ids);
+			return vnic.fw_vnic_id;
+		}
+	}
+	/* Could not find a default VNIC. */
+	RTE_LOG(ERR, PMD, "No default VNIC\n");
+exit:
+	rte_free(vnic_ids);
+	return -1;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 857772b..1ecd660 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -45,11 +45,13 @@ 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_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table);
 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,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter);
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			    void *encaped, size_t ec_size);
@@ -125,5 +127,8 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on);
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
 
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 9d331eb..1f71d3a 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -33,6 +33,7 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <unistd.h>
 
 #include <rte_dev.h>
 #include <rte_ethdev.h>
@@ -256,3 +257,176 @@ int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	struct bnxt *bp;
+	int rc;
+	int dflt_vnic;
+	struct bnxt_vnic_info vnic;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
+	if (!rc) {
+		bp->pf.vf_info[vf].vlan_spoof_en = on;
+		if (on) {
+			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+			if (dflt_vnic < 0) {
+				/*
+				 * This simply indicates there's no driver
+				 * loaded.  This is not an error.
+				 */
+				RTE_LOG(ERR, PMD,
+				      "Unable to get default VNIC for VF %d\n",
+					vf);
+			} else {
+				vnic.fw_vnic_id = dflt_vnic;
+				if (bnxt_hwrm_vnic_qcfg(bp,
+					&vnic, bp->pf.first_vf_id + vf) == 0) {
+					if (bnxt_hwrm_cfa_l2_set_rx_mask(bp,
+					   &vnic, bp->pf.vf_info[vf].vlan_count,
+					   bp->pf.vf_info[vf].vlan_table))
+						rc = -1;
+				}
+			}
+		}
+	} else {
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+	}
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->vlan_strip = *on;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d stripq on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+				rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+	if (rc)
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	int i, j;
+	int rc = 0;
+	struct bnxt_vlan_table_entry *ve;
+	uint16_t cnt;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	for (i = 0; vf_mask; i++, vf_mask >>= 1) {
+		cnt = bp->pf.vf_info[i].vlan_count;
+		if (vf_mask & 1) {
+			if (bp->pf.vf_info[i].vlan_table == NULL) {
+				rc = -1;
+				continue;
+			}
+			if (vlan_on) {
+				/* First, search for a duplicate... */
+				for (j = 0; j < cnt; j++) {
+					if (rte_be_to_cpu_16(
+					 bp->pf.vf_info[i].vlan_table[j].vid) ==
+					    vlan)
+						break;
+				}
+				if (j == cnt) {
+					/* Now check that there's space */
+					if (cnt == getpagesize() /
+					 sizeof(struct bnxt_vlan_table_entry)) {
+						RTE_LOG(ERR, PMD,
+						  "VF %d VLAN table is full\n",
+						  i);
+						RTE_LOG(ERR, PMD,
+							"cannot add VLAN %u\n",
+							vlan);
+						rc = -1;
+						continue;
+					}
+
+					cnt = bp->pf.vf_info[i].vlan_count++;
+					/*
+					 * And finally, add to the
+					 * end of the table
+					 */
+					ve = &bp->pf.vf_info[i].vlan_table[cnt];
+					// TODO: Hardcoded TPID
+					ve->tpid = rte_cpu_to_be_16(0x8100);
+					ve->vid = rte_cpu_to_be_16(vlan);
+				}
+			} else {
+				for (j = 0; cnt; j++) {
+					if (rte_be_to_cpu_16(
+					bp->pf.vf_info[i].vlan_table[j].vid) !=
+					    vlan)
+						continue;
+					memmove(
+					 &bp->pf.vf_info[i].vlan_table[j],
+					 &bp->pf.vf_info[i].vlan_table[j + 1],
+					 getpagesize() -
+					 ((j + 1) *
+					 sizeof(struct bnxt_vlan_table_entry)));
+					j--;
+					cnt = bp->pf.vf_info[i].vlan_count--;
+				}
+			}
+			rte_pmd_bnxt_set_vf_vlan_anti_spoof(dev->data->port_id,
+					 i, bp->pf.vf_info[i].vlan_spoof_en);
+		}
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 118acd2..87d1787 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -72,6 +72,48 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 		struct ether_addr *mac_addr);
 
 /**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
+ * received VLAN packets tagged with a given VLAN Tag Identifier.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vlan
+ *   The VLAN Tag Identifier whose filtering must be enabled or disabled.
+ * @param vf_mask
+ *    Bitmap listing which VFs participate in the VLAN filtering.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN filtering.
+ *    0 - Disable VFs VLAN filtering.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on);
+
+/**
  * Enable/Disable tx loopback
  *
  * @param port
@@ -121,4 +163,22 @@ int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
  */
 int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
+
+/**
+ * Enable/Disable VF VLAN anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF VLAN anti spoof.
+ *    0 - Disable VF VLAN anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 4155640..c98ed19 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -12,4 +12,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
+	rte_pmd_bnxt_set_vf_vlan_stripq;
+	rte_pmd_bnxt_set_vf_vlan_filter;
+	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 08/23] bnxt: add support to get and clear VF specific stats
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (6 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 07/23] bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:57 ` [PATCH 09/23] bnxt: add code to determine the Rx status of VF Ajit Khaparde
                   ` (15 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to get and clear VF stats.
It also adds the necessary HWRM structures to send the command
to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |  75 ++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h           |   5 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 217 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.c        |  87 +++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h        |  64 ++++++++++
 5 files changed, 448 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 05f7034..589d327 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1164,6 +1164,81 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (dropped)
+		*dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+	return rc;
+}
+
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->ierrors = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->oerrors = rte_le_to_cpu_64(resp->tx_err_pkts);
+
+	stats->imissed = rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	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 1ecd660..f5bc4cc 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -64,6 +64,11 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 
 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 c730337..45d1117 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -2766,6 +2766,223 @@ struct hwrm_func_cfg_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_func_qstats */
+/*
+ * Description: This command returns statistics 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 HWRM shall return any unsupported counter with a value
+ * of 0xFFFFFFFF for 32-bit counters and 0xFFFFFFFFFFFFFFFF for 64-bit counters.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_qstats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function that is being queried. 0xFF...
+	 *	(All Fs) if the query is for the requesting function.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(176 bytes) */
+struct hwrm_func_qstats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets on the function. */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets on the function. */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets on the function. */
+	uint64_t tx_err_pkts;
+	/*
+	 * Number of transmitted packets that were discarded due to
+	 * internal NIC resource problems. For transmit, this can only
+	 * happen if TMP is configured to allow dropping in HOL blocking
+	 * conditions, which is not a normal configuration.
+	 */
+	uint64_t tx_drop_pkts;
+	/*
+	 * Number of dropped packets on transmit path on the function.
+	 * These are packets that have been marked for drop by the TE
+	 * CFA block or are packets that exceeded the transmit MTU limit
+	 * for the function.
+	 */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic on the function. */
+	uint64_t tx_mcast_bytes;
+	/*
+	 * Number of transmitted bytes for multicast traffic on the
+	 * function.
+	 */
+	uint64_t tx_bcast_bytes;
+	/*
+	 * Number of transmitted bytes for broadcast traffic on the
+	 * function.
+	 */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets on the function. */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets on the function. */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets on the function. */
+	uint64_t rx_err_pkts;
+	/*
+	 * Number of received packets that were discarded on the
+	 * function due to resource limitations. This can happen for 3
+	 * reasons. # The BD used for the packet has a bad format. #
+	 * There were no BDs available in the ring for the packet. #
+	 * There were no BDs available on-chip for the packet.
+	 */
+	uint64_t rx_drop_pkts;
+	/*
+	 * Number of dropped packets on received path on the function.
+	 * These are packets that have been marked for drop by the RE
+	 * CFA.
+	 */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic on the function. */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic on the function. */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic on the function. */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets on the function. */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes on the function. */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events on the function. */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations on the function. */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_clr_stats */
+/*
+ * Description: This command clears statistics of a function. The input FID
+ * value is used to indicate what function's statistics is being cleared. This
+ * allows a physical function driver to clear statistics of virtual functions
+ * that are children of the physical function.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function. 0xFF...	(All Fs) if the query is
+	 * for the requesting function.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_func_vf_vnic_ids_query */
 /* Description: This command is used to query vf vnic ids. */
 /* Input	(32 bytes) */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 1f71d3a..f17b8c8 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -430,3 +430,90 @@ int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to get VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to reset VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d TX drops on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+					     count);
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 87d1787..2fa4786 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -165,6 +165,41 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
 
 /**
+ * Get VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param stats
+ *    A pointer to a structure of type *rte_eth_stats* to be filled with
+ *    the values of device counters supported statistics:
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id);
+
+/**
  * Enable/Disable VF VLAN anti spoof
  *
  * @param port
@@ -181,4 +216,33 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ */
+int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count);
 #endif /* _PMD_BNXT_H_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 09/23] bnxt: add code to determine the Rx status of VF
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (7 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 08/23] bnxt: add support to get and clear VF specific stats Ajit Khaparde
@ 2017-05-18  1:57 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 10/23] bnxt: add support to add a VF MAC address Ajit Khaparde
                   ` (14 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:57 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to determine the Rx status of a VF.
It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
the VNIC count of the function to get the Rx status.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 23 +++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 17 +++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  5 +++++
 5 files changed, 70 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 589d327..8b1a73c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2359,6 +2359,30 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 	return rc;
 }
 
+static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
+{
+	uint32_t *count = cbdata;
+
+	if (vnic->func_default)
+		*count = *count + 1;
+}
+
+static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
+				     struct bnxt_vnic_info *vnic __rte_unused)
+{
+	return 0;
+}
+
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf)
+{
+	uint32_t count = 0;
+
+	bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, bnxt_vnic_count,
+	    &count, bnxt_vnic_count_hwrm_stub);
+
+	return count;
+}
+
 static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
 					uint16_t *vnic_ids)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index f5bc4cc..a0779d4 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -129,6 +129,7 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index f17b8c8..82fe313 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -480,6 +480,29 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
 	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
 }
 
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d RX stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_vf_default_vnic_count(bp, vf_id);
+}
+
 int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
 {
 	struct rte_eth_dev *dev;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 2fa4786..a35e577 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -217,6 +217,23 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+
+/**
+ * Returns the number of default RX queues on a VF
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @return
+ *   - Non-negative value - Number of default RX queues
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if on a function without VFs
+ *   - (-ENOMEM) on an allocation failure
+ *   - (-1) firmware interface error
+ */
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
+
 /**
  * Queries the TX drop counter for the function
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index c98ed19..7fb9a28 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -9,6 +9,11 @@ DPDK_17.08 {
 
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_get_vf_stats;
+	rte_pmd_bnxt_reset_vf_stats;
+	rte_pmd_bnxt_get_vf_rx_status;
+	rte_pmd_bnxt_get_vf_tx_drop_count;
+	rte_pmd_bnxt_get_tx_drop_count;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 10/23] bnxt: add support to add a VF MAC address
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (8 preceding siblings ...)
  2017-05-18  1:57 ` [PATCH 09/23] bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 11/23] bnxt: add support for xstats get/reset Ajit Khaparde
                   ` (13 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support to allocate a filter and program
it in the hardware for every MAC address added to the specified
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_filter.c            | 22 ++++++++++
 drivers/net/bnxt/bnxt_filter.h            |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 73 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 18 ++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 115 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 146ab33..78aa0ae 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -68,6 +68,22 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
 	return filter;
 }
 
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+	struct bnxt_filter_info *filter;
+
+	filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+	if (!filter) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for VF %hu filters\n",
+			vf);
+		return NULL;
+	}
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+	return filter;
+}
+
 void bnxt_init_filters(struct bnxt *bp)
 {
 	struct bnxt_filter_info *filter;
@@ -102,6 +118,12 @@ void bnxt_free_all_filters(struct bnxt *bp)
 			STAILQ_INIT(&vnic->filter);
 		}
 	}
+
+	for (i = 0; i < bp->pf.max_vfs; i++) {
+		STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+			bnxt_hwrm_clear_filter(bp, filter);
+		}
+	}
 }
 
 void bnxt_free_filter_mem(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 353b7f7..613b2ee 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -68,6 +68,7 @@ struct bnxt_filter_info {
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
 void bnxt_init_filters(struct bnxt *bp);
 void bnxt_free_all_filters(struct bnxt *bp);
 void bnxt_free_filter_mem(struct bnxt *bp);
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 82fe313..a2bd39e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -540,3 +540,76 @@ int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
 					     count);
 }
+
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
+				uint32_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	struct bnxt_filter_info *filter;
+	struct bnxt_vnic_info vnic;
+	struct ether_addr dflt_mac;
+	int rc;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to config VF %d MAC on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	/* If the VF currently uses a random MAC, update default to this one */
+	if (bp->pf.vf_info[vf_id].random_mac) {
+		if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+			rc = bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+	}
+
+	/* query the default VNIC id used by the function */
+	rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+	if (rc < 0)
+		goto exit;
+
+	memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+	vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+	rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+	if (rc < 0)
+		goto exit;
+
+	STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+		if (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) &&
+		    memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+			bnxt_hwrm_clear_filter(bp, filter);
+			break;
+		}
+	}
+
+	if (filter == NULL)
+		filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	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, addr, ETHER_ADDR_LEN);
+	memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+	/* Do not add a filter for the default MAC */
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+	    memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+		rc = bnxt_hwrm_set_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index a35e577..9b1777c 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -262,4 +262,22 @@ int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count);
  */
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param mac_addr
+ *    The MAC address to be programmed in the filter.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ *   - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
+				uint32_t vf_id);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 7fb9a28..17c8bd9 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -14,6 +14,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_rx_status;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_get_tx_drop_count;
+	rte_pmd_bnxt_mac_addr_add;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 11/23] bnxt: add support for xstats get/reset
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (9 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 10/23] bnxt: add support to add a VF MAC address Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 12/23] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
                   ` (12 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to get and reset xstats dev_ops

dev_ops added:
xstats_get, xstats_get_name, xstats_reset

HWRM commands added:
hwrm_port_qstats, hwrm_port_clr_stats

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   7 +
 drivers/net/bnxt/bnxt_ethdev.c         |  84 ++++++
 drivers/net/bnxt/bnxt_hwrm.c           |  33 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/bnxt_stats.c          | 202 ++++++++++++++
 drivers/net/bnxt/bnxt_stats.h          |  10 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 495 +++++++++++++++++++++++++++++++++
 7 files changed, 833 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 5f458cd..8b32375 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -134,6 +134,7 @@ struct bnxt {
 	uint32_t		flags;
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
+#define BNXT_FLAG_PORT_STATS	(1 << 2)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -142,10 +143,16 @@ struct bnxt {
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	struct bnxt_rx_queue **rx_queues;
+	const void		*rx_mem_zone;
+	struct rx_port_stats    *hw_rx_port_stats;
+	phys_addr_t		hw_rx_port_stats_map;
 
 	unsigned int		tx_nr_rings;
 	unsigned int		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
+	const void		*tx_mem_zone;
+	struct tx_port_stats    *hw_tx_port_stats;
+	phys_addr_t		hw_tx_port_stats_map;
 
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index fcb7679..e110e9b 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -533,6 +533,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
+	bnxt_hwrm_port_clr_stats(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1123,6 +1124,9 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.xstats_get = bnxt_dev_xstats_get_op,
+	.xstats_get_names = bnxt_dev_xstats_get_names_op,
+	.xstats_reset = bnxt_dev_xstats_reset_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1181,7 +1185,11 @@ static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	const struct rte_memzone *mz = NULL;
 	static int version_printed;
+	uint32_t total_alloc_len;
+	phys_addr_t mz_phys_addr;
 	struct bnxt *bp;
 	int rc;
 
@@ -1208,6 +1216,80 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
+	if (BNXT_PF(bp) && pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) {
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "rx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct rx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->rx_mem_zone = (const void *)mz;
+		bp->hw_rx_port_stats = mz->addr;
+		bp->hw_rx_port_stats_map = mz_phys_addr;
+
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "tx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct tx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->tx_mem_zone = (const void *)mz;
+		bp->hw_tx_port_stats = mz->addr;
+		bp->hw_tx_port_stats_map = mz_phys_addr;
+
+		bp->flags |= BNXT_FLAG_PORT_STATS;
+	}
+
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
@@ -1366,6 +1448,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	}
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
+	rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
+	rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
 	if (bp->pf.vf_info)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 8b1a73c..30d4891 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2472,6 +2472,39 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_port_qstats(struct bnxt *bp)
+{
+	struct hwrm_port_qstats_input req = {0};
+	struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_QSTATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	req.tx_stat_host_addr = rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+	req.rx_stat_host_addr = rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+	struct hwrm_port_clr_stats_input req = {0};
+	struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	HWRM_PREP(req, PORT_CLR_STATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
+
 int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
 					      bool on)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index a0779d4..23f490b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -133,6 +133,8 @@ int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_port_qstats(struct bnxt *bp);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
 					      bool on);
 int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 40c9cac..1db678b 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -43,6 +43,128 @@
 #include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
+static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
+	{"rx_64b_frames", offsetof(struct rx_port_stats,
+				rx_64b_frames)},
+	{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
+				rx_65b_127b_frames)},
+	{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
+				rx_128b_255b_frames)},
+	{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
+				rx_256b_511b_frames)},
+	{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
+				rx_512b_1023b_frames)},
+	{"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
+				rx_1024b_1518_frames)},
+	{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
+				rx_good_vlan_frames)},
+	{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
+				rx_1519b_2047b_frames)},
+	{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
+				rx_2048b_4095b_frames)},
+	{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
+				rx_4096b_9216b_frames)},
+	{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
+				rx_9217b_16383b_frames)},
+	{"rx_total_frames", offsetof(struct rx_port_stats,
+				rx_total_frames)},
+	{"rx_ucast_frames", offsetof(struct rx_port_stats,
+				rx_ucast_frames)},
+	{"rx_mcast_frames", offsetof(struct rx_port_stats,
+				rx_mcast_frames)},
+	{"rx_bcast_frames", offsetof(struct rx_port_stats,
+				rx_bcast_frames)},
+	{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
+				rx_fcs_err_frames)},
+	{"rx_ctrl_frames", offsetof(struct rx_port_stats,
+				rx_ctrl_frames)},
+	{"rx_pause_frames", offsetof(struct rx_port_stats,
+				rx_pause_frames)},
+	{"rx_pfc_frames", offsetof(struct rx_port_stats,
+				rx_pfc_frames)},
+	{"rx_align_err_frames", offsetof(struct rx_port_stats,
+				rx_align_err_frames)},
+	{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
+				rx_ovrsz_frames)},
+	{"rx_jbr_frames", offsetof(struct rx_port_stats,
+				rx_jbr_frames)},
+	{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
+				rx_mtu_err_frames)},
+	{"rx_tagged_frames", offsetof(struct rx_port_stats,
+				rx_tagged_frames)},
+	{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
+				rx_double_tagged_frames)},
+	{"rx_good_frames", offsetof(struct rx_port_stats,
+				rx_good_frames)},
+	{"rx_undrsz_frames", offsetof(struct rx_port_stats,
+				rx_undrsz_frames)},
+	{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
+				rx_eee_lpi_events)},
+	{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
+				rx_eee_lpi_duration)},
+	{"rx_bytes", offsetof(struct rx_port_stats,
+				rx_bytes)},
+	{"rx_runt_bytes", offsetof(struct rx_port_stats,
+				rx_runt_bytes)},
+	{"rx_runt_frames", offsetof(struct rx_port_stats,
+				rx_runt_frames)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
+	{"tx_64b_frames", offsetof(struct tx_port_stats,
+				tx_64b_frames)},
+	{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
+				tx_65b_127b_frames)},
+	{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
+				tx_128b_255b_frames)},
+	{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
+				tx_256b_511b_frames)},
+	{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
+				tx_512b_1023b_frames)},
+	{"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
+				tx_1024b_1518_frames)},
+	{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
+				tx_good_vlan_frames)},
+	{"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
+				tx_1519b_2047_frames)},
+	{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
+				tx_2048b_4095b_frames)},
+	{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
+				tx_4096b_9216b_frames)},
+	{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
+				tx_9217b_16383b_frames)},
+	{"tx_good_frames", offsetof(struct tx_port_stats,
+				tx_good_frames)},
+	{"tx_total_frames", offsetof(struct tx_port_stats,
+				tx_total_frames)},
+	{"tx_ucast_frames", offsetof(struct tx_port_stats,
+				tx_ucast_frames)},
+	{"tx_mcast_frames", offsetof(struct tx_port_stats,
+				tx_mcast_frames)},
+	{"tx_bcast_frames", offsetof(struct tx_port_stats,
+				tx_bcast_frames)},
+	{"tx_pause_frames", offsetof(struct tx_port_stats,
+				tx_pause_frames)},
+	{"tx_pfc_frames", offsetof(struct tx_port_stats,
+				tx_pfc_frames)},
+	{"tx_jabber_frames", offsetof(struct tx_port_stats,
+				tx_jabber_frames)},
+	{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
+				tx_fcs_err_frames)},
+	{"tx_err", offsetof(struct tx_port_stats,
+				tx_err)},
+	{"tx_fifo_underruns", offsetof(struct tx_port_stats,
+				tx_fifo_underruns)},
+	{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
+				tx_eee_lpi_events)},
+	{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
+				tx_eee_lpi_duration)},
+	{"tx_total_collisions", offsetof(struct tx_port_stats,
+				tx_total_collisions)},
+	{"tx_bytes", offsetof(struct tx_port_stats,
+				tx_bytes)},
+};
+
 /*
  * Statistics functions
  */
@@ -140,3 +262,83 @@ void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
 
 	bnxt_clear_all_hwrm_stat_ctxs(bp);
 }
+
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	unsigned int count, i;
+
+	bnxt_hwrm_port_qstats(bp);
+
+	count = RTE_DIM(bnxt_rx_stats_strings) +
+		RTE_DIM(bnxt_tx_stats_strings);
+
+	if (n < count)
+		return count;
+
+	count = 0;
+	for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+		uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				*(uint64_t *)((char *)rx_stats +
+				bnxt_rx_stats_strings[i].offset));
+		count++;
+	}
+
+	for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+		uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				 *(uint64_t *)((char *)tx_stats +
+				bnxt_tx_stats_strings[i].offset));
+		count++;
+	}
+
+	return count;
+}
+
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit)
+{
+	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+				RTE_DIM(bnxt_tx_stats_strings);
+	unsigned int i, count;
+
+	if (xstats_names != NULL) {
+		count = 0;
+
+		for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_rx_stats_strings[i].name);
+			count++;
+		}
+
+		for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_tx_stats_strings[i].name);
+			count++;
+		}
+	}
+	return stat_cnt;
+}
+
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->flags & BNXT_FLAG_PORT_STATS && !BNXT_NPAR_PF(bp))
+		bnxt_hwrm_port_clr_stats(bp);
+
+	if (BNXT_VF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a VF device\n");
+	if (BNXT_NPAR_PF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a MF device\n");
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		RTE_LOG(ERR, PMD, "Operation not supported\n");
+}
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
index 65408a4..b6d133e 100644
--- a/drivers/net/bnxt/bnxt_stats.h
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -40,5 +40,15 @@ 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);
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit);
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n);
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev);
 
+struct bnxt_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	uint64_t offset;
+};
 #endif
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 45d1117..935cb90 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -108,6 +108,7 @@ struct ctx_hw_stats64 {
 #define HWRM_PORT_MAC_CFG		(UINT32_C(0x21))
 #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_PHY_QCFG		(UINT32_C(0x27))
 #define HWRM_PORT_MAC_QCFG		(UINT32_C(0x28))
 #define HWRM_PORT_PHY_QCAPS		(UINT32_C(0x2a))
@@ -4818,6 +4819,156 @@ struct hwrm_port_phy_qcfg_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_port_qstats */
+/* Description: This function returns per port Ethernet statistics. */
+/* Input	(40 bytes) */
+struct hwrm_port_qstats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2[3];
+	uint8_t unused_3;
+	uint64_t tx_stat_host_addr;
+	/* This is the host address where Tx port statistics will be stored */
+	uint64_t rx_stat_host_addr;
+	/* This is the host address where Rx port statistics will be stored */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_qstats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tx_stat_size;
+	/* The size of TX port statistics block in bytes. */
+	uint16_t rx_stat_size;
+	/* The size of RX port statistics block in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_clr_stats */
+/*
+ * Description: This function clears per port statistics. The HWRM shall not
+ * allow a VF driver to clear port statistics. The HWRM shall not allow a PF
+ * driver to clear port statistics in a partitioning mode. The HWRM may allow a
+ * PF driver to clear port statistics in the non-partitioning mode.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+
 /* hwrm_queue_qportcfg */
 /*
  * Description: This function is called by a driver to query queue configuration
@@ -7773,6 +7924,350 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 */
 } __attribute__((packed));
 
+/* Port Tx Statistics Formats	(408 bytes) */
+struct tx_port_stats {
+	uint64_t tx_64b_frames;
+	/* Total Number of 64 Bytes frames transmitted */
+	uint64_t tx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames transmitted */
+	uint64_t tx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames transmitted */
+	uint64_t tx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames transmitted */
+	uint64_t tx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames transmitted */
+	uint64_t tx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames transmitted */
+	uint64_t tx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * transmitted which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t tx_1519b_2047_frames;
+	/* Total Number of 1519-2047 Bytes frames transmitted */
+	uint64_t tx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames transmitted */
+	uint64_t tx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames transmitted */
+	uint64_t tx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames transmitted */
+	uint64_t tx_good_frames;
+	/* Total Number of good frames transmitted */
+	uint64_t tx_total_frames;
+	/* Total Number of frames transmitted */
+	uint64_t tx_ucast_frames;
+	/* Total number of unicast frames transmitted */
+	uint64_t tx_mcast_frames;
+	/* Total number of multicast frames transmitted */
+	uint64_t tx_bcast_frames;
+	/* Total number of broadcast frames transmitted */
+	uint64_t tx_pause_frames;
+	/* Total number of PAUSE control frames transmitted */
+	uint64_t tx_pfc_frames;
+	/* Total number of PFC/per-priority PAUSE control frames transmitted */
+	uint64_t tx_jabber_frames;
+	/* Total number of jabber frames transmitted */
+	uint64_t tx_fcs_err_frames;
+	/* Total number of frames transmitted with FCS error */
+	uint64_t tx_control_frames;
+	/* Total number of control frames transmitted */
+	uint64_t tx_oversz_frames;
+	/* Total number of over-sized frames transmitted */
+	uint64_t tx_single_dfrl_frames;
+	/* Total number of frames with single deferral */
+	uint64_t tx_multi_dfrl_frames;
+	/* Total number of frames with multiple deferrals */
+	uint64_t tx_single_coll_frames;
+	/* Total number of frames with single collision */
+	uint64_t tx_multi_coll_frames;
+	/* Total number of frames with multiple collisions */
+	uint64_t tx_late_coll_frames;
+	/* Total number of frames with late collisions */
+	uint64_t tx_excessive_coll_frames;
+	/* Total number of frames with excessive collisions */
+	uint64_t tx_frag_frames;
+	/* Total number of fragmented frames transmitted */
+	uint64_t tx_err;
+	/* Total number of transmit errors */
+	uint64_t tx_tagged_frames;
+	/* Total number of single VLAN tagged frames transmitted */
+	uint64_t tx_dbl_tagged_frames;
+	/* Total number of double VLAN tagged frames transmitted */
+	uint64_t tx_runt_frames;
+	/* Total number of runt frames transmitted */
+	uint64_t tx_fifo_underruns;
+	/* Total number of TX FIFO under runs */
+	uint64_t tx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 0
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 1
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 2
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 3
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 4
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 5
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 6
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 7
+	 * transmitted
+	 */
+	uint64_t tx_eee_lpi_events;
+	/* Total number of EEE LPI Events on TX */
+	uint64_t tx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on TX */
+	uint64_t tx_llfc_logical_msgs;
+	/*
+	 * Total number of Link Level Flow Control	(LLFC) messages
+	 * transmitted
+	 */
+	uint64_t tx_hcfc_msgs;
+	/* Total number of HCFC messages transmitted */
+	uint64_t tx_total_collisions;
+	/* Total number of TX collisions */
+	uint64_t tx_bytes;
+	/* Total number of transmitted bytes */
+	uint64_t tx_xthol_frames;
+	/* Total number of end-to-end HOL frames */
+	uint64_t tx_stat_discard;
+	/* Total Tx Drops per Port reported by STATS block */
+	uint64_t tx_stat_error;
+	/* Total Tx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Port Rx Statistics Formats	(528 bytes) */
+struct rx_port_stats {
+	uint64_t rx_64b_frames;
+	/* Total Number of 64 Bytes frames received */
+	uint64_t rx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames received */
+	uint64_t rx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames received */
+	uint64_t rx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames received */
+	uint64_t rx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames received */
+	uint64_t rx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames received */
+	uint64_t rx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * received which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t rx_1519b_2047b_frames;
+	/* Total Number of 1519-2047 Bytes frames received */
+	uint64_t rx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames received */
+	uint64_t rx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames received */
+	uint64_t rx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames received */
+	uint64_t rx_total_frames;
+	/* Total number of frames received */
+	uint64_t rx_ucast_frames;
+	/* Total number of unicast frames received */
+	uint64_t rx_mcast_frames;
+	/* Total number of multicast frames received */
+	uint64_t rx_bcast_frames;
+	/* Total number of broadcast frames received */
+	uint64_t rx_fcs_err_frames;
+	/* Total number of received frames with FCS error */
+	uint64_t rx_ctrl_frames;
+	/* Total number of control frames received */
+	uint64_t rx_pause_frames;
+	/* Total number of PAUSE frames received */
+	uint64_t rx_pfc_frames;
+	/* Total number of PFC frames received */
+	uint64_t rx_unsupported_opcode_frames;
+	/* Total number of frames received with an unsupported opcode */
+	uint64_t rx_unsupported_da_pausepfc_frames;
+	/*
+	 * Total number of frames received with an unsupported DA for
+	 * pause and PFC
+	 */
+	uint64_t rx_wrong_sa_frames;
+	/* Total number of frames received with an unsupported SA */
+	uint64_t rx_align_err_frames;
+	/* Total number of received packets with alignment error */
+	uint64_t rx_oor_len_frames;
+	/* Total number of received frames with out-of-range length */
+	uint64_t rx_code_err_frames;
+	/* Total number of received frames with error termination */
+	uint64_t rx_false_carrier_frames;
+	/*
+	 * Total number of received frames with a false carrier is
+	 * detected during idle, as defined by RX_ER samples active and
+	 * RXD is 0xE. The event is reported along with the statistics
+	 * generated on the next received frame. Only one false carrier
+	 * condition can be detected and logged between frames. Carrier
+	 * event, valid for 10M/100M speed modes only.
+	 */
+	uint64_t rx_ovrsz_frames;
+	/* Total number of over-sized frames received */
+	uint64_t rx_jbr_frames;
+	/* Total number of jabber packets received */
+	uint64_t rx_mtu_err_frames;
+	/* Total number of received frames with MTU error */
+	uint64_t rx_match_crc_frames;
+	/* Total number of received frames with CRC match */
+	uint64_t rx_promiscuous_frames;
+	/* Total number of frames received promiscuously */
+	uint64_t rx_tagged_frames;
+	/* Total number of received frames with one or two VLAN tags */
+	uint64_t rx_double_tagged_frames;
+	/* Total number of received frames with two VLAN tags */
+	uint64_t rx_trunc_frames;
+	/* Total number of truncated frames received */
+	uint64_t rx_good_frames;
+	/* Total number of good frames	(without errors) received */
+	uint64_t rx_pfc_xon2xoff_frames_pri0;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 0
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri1;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 1
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri2;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 2
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri3;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 3
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri4;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 4
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri5;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 5
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri6;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 6
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri7;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 7
+	 */
+	uint64_t rx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 0
+	 */
+	uint64_t rx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 1
+	 */
+	uint64_t rx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 2
+	 */
+	uint64_t rx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 3
+	 */
+	uint64_t rx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 4
+	 */
+	uint64_t rx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 5
+	 */
+	uint64_t rx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 6
+	 */
+	uint64_t rx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 7
+	 */
+	uint64_t rx_sch_crc_err_frames;
+	/* Total Number of frames received with SCH CRC error */
+	uint64_t rx_undrsz_frames;
+	/* Total Number of under-sized frames received */
+	uint64_t rx_frag_frames;
+	/* Total Number of fragmented frames received */
+	uint64_t rx_eee_lpi_events;
+	/* Total number of RX EEE LPI Events */
+	uint64_t rx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on RX */
+	uint64_t rx_llfc_physical_msgs;
+	/*
+	 * Total number of physical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_logical_msgs;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_msgs_with_crc_err;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received with CRC error
+	 */
+	uint64_t rx_hcfc_msgs;
+	/* Total number of HCFC messages received */
+	uint64_t rx_hcfc_msgs_with_crc_err;
+	/* Total number of HCFC messages received with CRC error */
+	uint64_t rx_bytes;
+	/* Total number of received bytes */
+	uint64_t rx_runt_bytes;
+	/* Total number of bytes received in runt frames */
+	uint64_t rx_runt_frames;
+	/* Total number of runt frames received */
+	uint64_t rx_stat_discard;
+	/* Total Rx Discards per Port reported by STATS block */
+	uint64_t rx_stat_err;
+	/* Total Rx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
 /* hwrm_exec_fwd_resp */
 /*
  * Description: This command is used to send an encapsulated request to the
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 12/23] bnxt: Add support for VLAN filter and strip dev_ops
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (10 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 11/23] bnxt: add support for xstats get/reset Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 13/23] bnxt: add code to configure a default VF VLAN Ajit Khaparde
                   ` (11 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds VLAN strip and offload callbacks.
To add a VLAN filter:
    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

To remove a VLAN filter:
    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

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 201 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 201 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e110e9b..1dc2327 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -141,6 +141,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_TCP |	\
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
+static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
 /***********************/
 
 /*
@@ -487,6 +488,7 @@ static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	int vlan_mask = 0;
 	int rc;
 
 	bp->dev_stopped = 0;
@@ -496,6 +498,13 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 		goto error;
 
 	bnxt_link_update_op(eth_dev, 0);
+
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter)
+		vlan_mask |= ETH_VLAN_FILTER_MASK;
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
+		vlan_mask |= ETH_VLAN_STRIP_MASK;
+	bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+
 	return 0;
 
 error:
@@ -1091,6 +1100,196 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
 	return rc;
 }
 
+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 int i;
+	int rc = 0;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk &&
+				    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 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->fw_vnic_id,
+							new_filter);
+					if (rc)
+						goto exit;
+					RTE_LOG(INFO, PMD,
+						"Del Vlan filter for %d\n",
+						vlan_id);
+				}
+				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 int i;
+	int rc = 0;
+	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
+		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk) {
+					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 |= en;
+				rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id,
+							  new_filter);
+				if (rc)
+					goto exit;
+				RTE_LOG(INFO, PMD,
+					"Added Vlan filter for %d\n", vlan_id);
+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_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	unsigned int i;
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (!dev->data->dev_conf.rxmode.hw_vlan_filter) {
+			/* Remove any VLAN filters programmed */
+			for (i = 0; i < 4095; i++)
+				bnxt_del_vlan_filter(bp, i);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Filtering: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_filter);
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		/* Enable or disable VLAN stripping */
+		for (i = 0; i < bp->nr_vnics; i++) {
+			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+			if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+				vnic->vlan_strip = true;
+			else
+				vnic->vlan_strip = false;
+			bnxt_hwrm_vnic_cfg(bp, vnic);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Strip Offload: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_strip);
+	}
+
+	if (mask & ETH_VLAN_EXTEND_MASK)
+		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
+}
+
 /*
  * Initialization
  */
@@ -1124,6 +1323,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.vlan_filter_set = bnxt_vlan_filter_set_op,
+	.vlan_offload_set = bnxt_vlan_offload_set_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 13/23] bnxt: add code to configure a default VF VLAN
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (11 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 12/23] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 14/23] bnxt: add support for set_mc_addr_list and mac_addr_set Ajit Khaparde
                   ` (10 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to insert a default VF VLAN.
Also track the current default VLAN per vnic for the VF.
When setting the default VLAN, avoid setting it to the current value.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                   |  1 +
 drivers/net/bnxt/bnxt_hwrm.c              | 39 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 35 +++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 20 ++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 6 files changed, 98 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8b32375..335482b 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -68,6 +68,7 @@ struct bnxt_child_vf_info {
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
 	uint16_t		max_tx_rate;
+	uint16_t		dflt_vlan;
 	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
 	uint8_t			vlan_spoof_en;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 30d4891..f66a760 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2002,6 +2002,27 @@ static void reserve_resources_from_vf(struct bnxt *bp,
 	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
 }
 
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Check for zero MAC address */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg error %d\n", rc);
+		return -1;
+	}
+	return rte_le_to_cpu_16(resp->vlan);
+}
+
 static int update_pf_resource_max(struct bnxt *bp)
 {
 	struct hwrm_func_qcfg_input req = {0};
@@ -2315,6 +2336,24 @@ int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(bp->pf.vf_info[vf].dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 23f490b..46a8fde 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -121,8 +121,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 			uint16_t max_bw, uint16_t enables);
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index a2bd39e..ca14ff3 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -356,6 +356,41 @@ rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
 	return rc;
 }
 
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d vlan insert on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	bp->pf.vf_info[vf].dflt_vlan = vlan_id;
+	if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
+	    bp->pf.vf_info[vf].dflt_vlan)
+		return 0;
+
+	rc = bnxt_hwrm_set_vf_vlan(bp, vf);
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 9b1777c..d6cefc4 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -92,6 +92,26 @@ int
 rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
 
 /**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param vlan_id
+ *    0 - Disable VF's vlan insert.
+ *    n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id);
+
+/**
  * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
  * received VLAN packets tagged with a given VLAN Tag Identifier.
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 17c8bd9..04fce9a 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -21,4 +21,5 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_stripq;
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+	rte_pmd_bnxt_set_vf_vlan_insert;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 14/23] bnxt: add support for set_mc_addr_list and mac_addr_set
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (12 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 13/23] bnxt: add code to configure a default VF VLAN Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 15/23] bnxt: add support for fw_version_get dev_op Ajit Khaparde
                   ` (9 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for set_mc_addr_list and
mac_addr_set dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 68 ++++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 11 +++++--
 drivers/net/bnxt/bnxt_vnic.c   |  7 ++++-
 drivers/net/bnxt/bnxt_vnic.h   |  4 +++
 4 files changed, 86 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1dc2327..9a0acee 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1290,6 +1290,72 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
 }
 
+static void
+bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	/* Default Filter is tied to VNIC 0 */
+	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+	struct bnxt_filter_info *filter;
+	int rc;
+
+	if (BNXT_VF(bp))
+		return;
+
+	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
+	memcpy(&dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+	STAILQ_FOREACH(filter, &vnic->filter, next) {
+		/* Default Filter is at Index 0 */
+		if (filter->mac_index != 0)
+			continue;
+		rc = bnxt_hwrm_clear_filter(bp, filter);
+		if (rc)
+			break;
+		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
+		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+		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;
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
+		if (rc)
+			break;
+		filter->mac_index = 0;
+		RTE_LOG(DEBUG, PMD, "Set MAC addr\n");
+	}
+}
+
+static int
+bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
+			  struct ether_addr *mc_addr_set,
+			  uint32_t nb_mc_addr)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	char *mc_addr_list = (char *)mc_addr_set;
+	struct bnxt_vnic_info *vnic;
+	uint32_t off = 0, i = 0;
+
+	vnic = &bp->vnic_info[0];
+
+	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
+		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+		goto allmulti;
+	}
+
+	/* TODO Check for Duplicate mcast addresses */
+	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+	for (i = 0; i < nb_mc_addr; i++) {
+		memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN);
+		off += ETHER_ADDR_LEN;
+	}
+
+	vnic->mc_addr_cnt = i;
+
+allmulti:
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
+}
+
 /*
  * Initialization
  */
@@ -1325,9 +1391,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_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 f66a760..9d37a50 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -215,15 +215,20 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
 	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_BCAST |
-				    mask);
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+	if (vnic->mc_addr_cnt) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
+		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
+	}
 	if (vlan_count && vlan_table) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
 		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
 			 rte_mem_virt2phy(vlan_table));
 		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
 	}
+	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
+				    mask);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 1521f4d..fab5f20 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -170,7 +170,8 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	char mz_name[RTE_MEMZONE_NAMESIZE];
 	uint32_t entry_length = RTE_CACHE_LINE_ROUNDUP(
 				HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
-				HW_HASH_KEY_SIZE);
+				HW_HASH_KEY_SIZE +
+				BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN);
 	uint16_t max_vnics;
 	int i;
 	phys_addr_t mz_phys_addr;
@@ -218,6 +219,10 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 
 		vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
 			     HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+		vnic->mc_list = (void *)((char *)vnic->rss_hash_key +
+				HW_HASH_KEY_SIZE);
+		vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr +
+				HW_HASH_KEY_SIZE;
 	}
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index ca1c9cf..0d50224 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -57,6 +57,10 @@ struct bnxt_vnic_info {
 	uint16_t	*rss_table;
 	phys_addr_t	rss_hash_key_dma_addr;
 	void		*rss_hash_key;
+	phys_addr_t	mc_list_dma_addr;
+	char		*mc_list;
+	uint32_t	mc_addr_cnt;
+#define BNXT_MAX_MC_ADDRS		16
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 15/23] bnxt: add support for fw_version_get dev_op
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (13 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 14/23] bnxt: add support for set_mc_addr_list and mac_addr_set Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 16/23] bnxt: add support to set MTU Ajit Khaparde
                   ` (8 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for fw_version_get dev_op

Signed-off-by: Ajit 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 9a0acee..9d503b7 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1356,6 +1356,25 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 }
 
+static int
+bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
+	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
+	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
+	int ret;
+
+	ret = snprintf(fw_version, fw_size, "%d.%d.%d",
+			fw_major, fw_minor, fw_updt);
+
+	ret += 1; /* add the size of '\0' */
+	if (fw_size < (uint32_t)ret)
+		return ret;
+	else
+		return 0;
+}
+
 /*
  * Initialization
  */
@@ -1395,6 +1414,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 };
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 16/23] bnxt: add support to set MTU
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (14 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 15/23] bnxt: add support for fw_version_get dev_op Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 17/23] bnxt: add support for LRO Ajit Khaparde
                   ` (7 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to modify MTU using the set_mtu dev_op.
To support frames > 2k, the PMD creates an aggregator ring.
When a frame greater than 2k is received, it is fragmented
and the resulting fragments are DMA'ed to the aggregator ring.
Now the driver can support jumbo frames upto 9500 bytes.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |   4 +-
 drivers/net/bnxt/bnxt_cpr.c    |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c |  59 +++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 123 ++++++++++++++++----------
 drivers/net/bnxt/bnxt_hwrm.h   |   4 +-
 drivers/net/bnxt/bnxt_ring.c   |  81 +++++++++++++++--
 drivers/net/bnxt/bnxt_ring.h   |   2 +
 drivers/net/bnxt/bnxt_rxq.c    |  29 ++++--
 drivers/net/bnxt/bnxt_rxq.h    |   1 +
 drivers/net/bnxt/bnxt_rxr.c    | 195 ++++++++++++++++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_rxr.h    |   6 ++
 11 files changed, 420 insertions(+), 87 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 335482b..f25a1c4 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,7 +45,7 @@
 
 #include "bnxt_cpr.h"
 
-#define BNXT_MAX_MTU		9000
+#define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
 
 enum bnxt_hw_context {
@@ -136,6 +136,7 @@ struct bnxt {
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
 #define BNXT_FLAG_PORT_STATS	(1 << 2)
+#define BNXT_FLAG_JUMBO		(1 << 3)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -239,4 +240,5 @@ struct rte_pmd_bnxt_mb_event_param {
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
+#define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index f0b8728..6eb32ab 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -159,7 +159,8 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
 
 	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 				  HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
-				  0, HWRM_NA_SIGNATURE);
+				  0, HWRM_NA_SIGNATURE,
+				  HWRM_NA_SIGNATURE);
 	if (rc)
 		goto err_out;
 	cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 9d503b7..5f22091 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -199,6 +199,14 @@ static int bnxt_init_chip(struct bnxt *bp)
 	struct rte_eth_link new;
 	int rc;
 
+	if (bp->eth_dev->data->mtu > ETHER_MTU) {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+		bp->flags |= BNXT_FLAG_JUMBO;
+	} else {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
 	rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc);
@@ -1375,6 +1383,56 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+	struct bnxt *bp = eth_dev->data->dev_private;
+	struct rte_eth_dev_info dev_info;
+	uint32_t max_dev_mtu;
+	uint32_t rc = 0;
+	uint32_t i;
+
+	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 * 2;
+
+	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) {
+		bp->flags |= BNXT_FLAG_JUMBO;
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+	} else {
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
+	eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+		new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+
+	eth_dev->data->mtu = new_mtu;
+	RTE_LOG(INFO, PMD, "New MTU is %d\n", eth_dev->data->mtu);
+
+	for (i = 0; i < bp->nr_vnics; i++) {
+		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+		vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+		if (rc)
+			break;
+
+		rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1410,6 +1468,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9d37a50..136365c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -661,20 +661,20 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id)
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id)
 {
 	int rc = 0;
+	uint32_t enables = 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);
+	req.length = rte_cpu_to_le_32(ring->ring_size);
 
 	switch (ring_type) {
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
@@ -682,12 +682,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		/* FALLTHROUGH */
 	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.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id);
 		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);
+		if (stats_ctx_id != INVALID_STATS_CTX_ID)
+			enables |=
+			HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
 		req.ring_type = ring_type;
@@ -696,13 +695,13 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		 * 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:
 		RTE_LOG(ERR, PMD, "hwrm alloc invalid ring type %d\n",
 			ring_type);
 		return -1;
 	}
+	req.enables = rte_cpu_to_le_32(enables);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -833,8 +832,8 @@ 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 int idx)
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
@@ -853,13 +852,12 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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_ctx_free(struct bnxt *bp,
-			    struct bnxt_cp_ring_info *cpr, unsigned int idx)
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
@@ -874,9 +872,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 
 	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;
 }
 
@@ -887,15 +882,10 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
-		}
+	RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
+		vnic->start_grp_id, vnic->end_grp_id);
+	for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++)
 		vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
-	}
 	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
 	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
 	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
@@ -1147,6 +1137,39 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t size;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.flags = rte_cpu_to_le_32(
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
+			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+	req.enables = rte_cpu_to_le_32(
+		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
+//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
+
+	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+	size -= RTE_PKTMBUF_HEADROOM;
+
+	req.jumbo_thresh = rte_cpu_to_le_16(size);
+//	req.hds_threshold = rte_cpu_to_le_16(size);
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1280,14 +1303,20 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
 	struct bnxt_cp_ring_info *cpr;
 
 	for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
-		unsigned int 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);
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
+			cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+			/*
+			 * TODO. Need a better way to reset grp_info.stats_ctx
+			 * for Rx rings only. stats_ctx is not saved for Tx
+			 * in grp_info.
+			 */
+			bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 			if (rc)
 				return rc;
 		}
@@ -1304,7 +1333,6 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 		struct bnxt_tx_queue *txq;
 		struct bnxt_rx_queue *rxq;
 		struct bnxt_cp_ring_info *cpr;
-		unsigned int idx = i + 1;
 
 		if (i >= bp->rx_cp_nr_rings) {
 			txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
@@ -1314,7 +1342,7 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 			cpr = rxq->cp_ring;
 		}
 
-		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, idx);
+		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i);
 
 		if (rc)
 			return rc;
@@ -1324,11 +1352,10 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 
 int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 {
-	uint16_t i;
+	uint16_t idx;
 	uint32_t rc = 0;
 
-	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int idx = i + 1;
+	for (idx = 0; idx < bp->rx_cp_nr_rings; idx++) {
 
 		if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) {
 			RTE_LOG(ERR, PMD,
@@ -1345,15 +1372,13 @@ 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 int idx)
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	struct bnxt_ring *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;
@@ -1384,8 +1409,10 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 			txr->tx_prod = 0;
 			txr->tx_cons = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
@@ -1407,17 +1434,26 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 					rxr->rx_ring_struct->ring_size *
 					sizeof(*rxr->rx_buf_ring));
 			rxr->rx_prod = 0;
+			memset(rxr->ag_buf_ring, 0,
+					rxr->ag_ring_struct->ring_size *
+					sizeof(*rxr->ag_buf_ring));
+			rxr->ag_prod = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	/* 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)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, 0);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	return rc;
@@ -1429,14 +1465,7 @@ int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 	uint32_t rc = 0;
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int 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);
-
+		rc = bnxt_hwrm_ring_grp_alloc(bp, i);
 		if (rc)
 			return rc;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 46a8fde..9478d12 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -76,7 +76,7 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id);
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id);
 int bnxt_hwrm_ring_free(struct bnxt *bp,
 			struct bnxt_ring *ring, uint32_t ring_type);
 int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);
@@ -99,6 +99,8 @@ 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_hwrm_vnic_plcmode_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);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 642ec53..3eed354 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -115,8 +115,15 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	int rx_vmem_len = rx_ring_info ?
 		RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
 						rx_ring_struct->vmem_size) : 0;
+	int ag_vmem_start = 0;
+	int ag_vmem_len = 0;
+	int cp_ring_start =  0;
+
+	ag_vmem_start = rx_vmem_start + rx_vmem_len;
+	ag_vmem_len = rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(
+				rx_ring_info->ag_ring_struct->vmem_size) : 0;
+	cp_ring_start = ag_vmem_start + ag_vmem_len;
 
-	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));
 
@@ -131,6 +138,10 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
+	int ag_ring_start = 0;
+
+	ag_ring_start = rx_ring_start + rx_ring_len;
+	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -201,6 +212,24 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->rx_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring = rx_ring_info->ag_ring_struct;
+
+		rx_ring->bd = ((char *)mz->addr + ag_ring_start);
+		rx_ring_info->ag_desc_ring =
+		    (struct rx_prod_pkt_bd *)rx_ring->bd;
+		rx_ring->bd_dma = mz->phys_addr + ag_ring_start;
+		rx_ring_info->ag_desc_mapping = rx_ring->bd_dma;
+		rx_ring->mem_zone = (const void *)mz;
+
+		if (!rx_ring->bd)
+			return -ENOMEM;
+		if (rx_ring->vmem_size) {
+			rx_ring->vmem =
+			    (void **)((char *)mz->addr + ag_vmem_start);
+			rx_ring_info->ag_buf_ring =
+			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+		}
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
@@ -239,35 +268,64 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
 		struct bnxt_ring *ring = rxr->rx_ring_struct;
 		unsigned int idx = i + 1;
+		unsigned int map_idx = idx + bp->rx_cp_nr_rings;
+
+		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+		bp->grp_info[i].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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 		rxr->rx_prod = 0;
 		rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
+		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+		ring = rxr->ag_ring_struct;
+		/* Agg ring */
+		if (ring == NULL)
+			RTE_LOG(ERR, PMD, "Alloc AGG Ring is NULL!\n");
+
+		rc = bnxt_hwrm_ring_alloc(bp, ring,
+				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+				map_idx, HWRM_NA_SIGNATURE,
+				cp_ring->fw_ring_id);
+		if (rc)
+			goto err_out;
+		RTE_LOG(DEBUG, PMD, "Alloc AGG Done!\n");
+		rxr->ag_prod = 0;
+		rxr->ag_doorbell =
+		    (char *)pci_dev->mem_resource[2].addr +
+		    map_idx * 0x80;
+		bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+		rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
 		if (bnxt_init_one_rx_ring(rxq)) {
 			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+		rxq->index = idx;
 	}
 
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
@@ -276,29 +334,34 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 		struct bnxt_tx_ring_info *txr = txq->tx_ring;
 		struct bnxt_ring *ring = txr->tx_ring_struct;
-		unsigned int idx = 1 + bp->rx_cp_nr_rings + i;
+		unsigned int idx = i + 1 + bp->rx_cp_nr_rings;
+
+		/* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
+		idx += bp->rx_cp_nr_rings;
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 
 		cpr->cp_doorbell = (char *)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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 
 		txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
+		txq->index = idx;
 	}
 
 err_out:
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 8656549..b5bd287 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -58,6 +58,7 @@
 #define DEFAULT_TX_RING_SIZE	256
 
 #define MAX_TPA		128
+#define AGG_RING_SIZE_FACTOR 2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
@@ -65,6 +66,7 @@
 #define MAX_CP_DESC_CNT (16 * 1024)
 
 #define INVALID_HW_RING_ID      ((uint16_t)-1)
+#define INVALID_STATS_CTX_ID		((uint16_t)-1)
 
 struct bnxt_ring {
 	void			*bd;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index cddf17d..5a5def5 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -84,9 +84,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 		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;
+		vnic->start_grp_id = 0;
+		vnic->end_grp_id = vnic->start_grp_id;
 		filter = bnxt_alloc_filter(bp);
 		if (!filter) {
 			RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -126,8 +125,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			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;
+		start_grp_id = 0;
+		end_grp_id = nb_q_per_grp;
 
 		ring_idx = 0;
 		for (i = 0; i < pools; i++) {
@@ -188,9 +187,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 	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;
+	vnic->start_grp_id = 0;
+	vnic->end_grp_id = bp->rx_cp_nr_rings;
 	filter = bnxt_alloc_filter(bp);
 	if (!filter) {
 		RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -228,6 +226,16 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 				}
 			}
 		}
+		/* Free up mbufs in Agg ring */
+		sw_ring = rxq->rx_ring->ag_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;
+				}
+			}
+		}
 	}
 }
 
@@ -251,6 +259,8 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 
 		/* Free RX ring hardware descriptors */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* Free RX Agg ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
 
 		/* Free RX completion ring hardware descriptors */
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -295,6 +305,9 @@ 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;
 
+	RTE_LOG(DEBUG, PMD, "RX Buf size is %d\n", rxq->rx_buf_use_size);
+	RTE_LOG(DEBUG, PMD, "RX Buf MTU %d\n", eth_dev->data->mtu);
+
 	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
 	if (rc)
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 9554329..0695214 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -52,6 +52,7 @@ struct bnxt_rx_queue {
 	uint8_t			crc_len; /* 0 if CRC stripped, 4 otherwise */
 
 	struct bnxt		*bp;
+	int			index;
 	struct bnxt_vnic_info	*vnic;
 
 	uint32_t			rx_buf_size;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 5d93de2..12869a4 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -77,6 +77,32 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
+static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
+				     struct bnxt_rx_ring_info *rxr,
+				     uint16_t prod)
+{
+	struct rx_prod_pkt_bd *rxbd = &rxr->ag_desc_ring[prod];
+	struct bnxt_sw_rx_bd *rx_buf = &rxr->ag_buf_ring[prod];
+	struct rte_mbuf *data;
+
+	data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	if (!data)
+		return -ENOMEM;
+
+	if (rxbd == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
+	if (rx_buf == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rx_buf is NULL\n");
+
+
+	rx_buf->mbuf = data;
+
+	rxbd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf));
+
+	return 0;
+}
+
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -94,6 +120,24 @@ static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 	prod_bd->addr = cons_bd->addr;
 }
 
+static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+			       struct rte_mbuf *mbuf)
+{
+	uint16_t prod = rxr->ag_prod;
+	struct bnxt_sw_rx_bd *prod_rx_buf;
+	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+	prod_rx_buf = &rxr->ag_buf_ring[prod];
+
+	prod_rx_buf->mbuf = mbuf;
+
+	prod_bd = &rxr->ag_desc_ring[prod];
+	cons_bd = &rxr->ag_desc_ring[cons];
+
+	prod_bd->addr = cons_bd->addr;
+}
+#endif
+
 static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 			    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -104,9 +148,12 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+	uint16_t ag_cons, ag_prod = rxr->ag_prod;
 	struct bnxt_sw_rx_bd *rx_buf;
 	struct rte_mbuf *mbuf;
 	int rc = 0;
+	uint8_t i;
+	uint8_t agg_buf = 0;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -126,6 +173,9 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	mbuf = rx_buf->mbuf;
 	rte_prefetch0(mbuf);
 
+	if (mbuf == NULL)
+		return -ENOMEM;
+
 	mbuf->nb_segs = 1;
 	mbuf->next = NULL;
 	mbuf->pkt_len = rxcmp->len;
@@ -139,6 +189,63 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->hash.fdir.id = rxcmp1->cfa_code;
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf) {
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
+			       cpr->cp_ring_struct))
+			return -EBUSY;
+		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
+			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
+	}
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		ag_cons = rxcmp->opaque;
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		ag_mbuf->nb_segs = 1;
+		ag_mbuf->data_len = rxcmp->len;
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+		if (mbuf->next == NULL) {
+			mbuf->next = ag_mbuf;
+		} else {
+			struct rte_mbuf *temp_mbuf = mbuf;
+
+			while (temp_mbuf->next != NULL)
+				temp_mbuf = temp_mbuf->next;
+			temp_mbuf->next = ag_mbuf;
+		}
+		ag_buf->mbuf = NULL;
+
+		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
+		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n",
+				ag_prod);
+			rc = -ENOMEM;
+		}
+		rxr->ag_prod = ag_prod;
+
+#ifdef BNXT_DEBUG
+		if (!CMP_VALID((struct cmpl_base *)
+			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
+			cpr->cp_ring_struct))
+			return -EBUSY;
+#endif
+	}
+
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
 			(RX_PKT_CMPL_METADATA_VID_MASK |
@@ -148,13 +255,17 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	}
 
 	rx_buf->mbuf = NULL;
+#ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
 		bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+		if (agg_buf)
+			bnxt_reuse_ag_mbuf(rxr, ag_cons, mbuf);
 
 		rc = -EIO;
 		goto next_rx;
 	}
+#endif
 	/*
 	 * TODO: Redesign this....
 	 * If the allocation fails, the packet does not get received.
@@ -170,24 +281,23 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 * calls in favour of a tight loop with the same function being called
 	 * in it.
 	 */
+	prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	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;
+		//goto next_rx;
 	}
-
+	rxr->rx_prod = prod;
 	/*
 	 * 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;
+#ifdef BNXT_DEBUG
 next_rx:
-	rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
+#endif
+	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -203,8 +313,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	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;
+	uint16_t prod = rxr->rx_prod;
+	uint16_t ag_prod = rxr->ag_prod;
 
 	/* Handle RX burst request */
 	while (1) {
@@ -224,13 +335,13 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 				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) {
+
+	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
 		 * the doorbell if there are no new completions
@@ -240,8 +351,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **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);
+	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+	/* Ring the AGG ring DB */
+	B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
 	return nb_rx_pkts;
 }
 
@@ -257,6 +369,12 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
 		rte_free(rxq->rx_ring->rx_ring_struct);
+
+		/* Free the Aggregator ring */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+		rte_free(rxq->rx_ring->ag_ring_struct);
+		rxq->rx_ring->ag_ring_struct = NULL;
+
 		rte_free(rxq->rx_ring);
 
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -270,13 +388,11 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 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;
 	struct bnxt_rx_ring_info *rxr;
 	struct bnxt_ring *ring;
 
-	rxq->rx_buf_use_size = bp->eth_dev->data->mtu +
-			       ETHER_HDR_LEN + ETHER_CRC_LEN +
+	rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN +
 			       (2 * VLAN_TAG_SIZE);
 	rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
 
@@ -313,13 +429,29 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 	if (ring == NULL)
 		return -ENOMEM;
 	cpr->cp_ring_struct = ring;
-	ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	ring->ring_size = rte_align32pow2(rxr->rx_ring_struct->ring_size *
+					  (2 + AGG_RING_SIZE_FACTOR));
 	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;
 
+	/* Allocate Aggregator rings */
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (ring == NULL)
+		return -ENOMEM;
+	rxr->ag_ring_struct = ring;
+	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc *
+					  AGG_RING_SIZE_FACTOR);
+	ring->ring_mask = ring->ring_size - 1;
+	ring->bd = (void *)rxr->ag_desc_ring;
+	ring->bd_dma = rxr->ag_desc_mapping;
+	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+	ring->vmem = (void **)&rxr->ag_buf_ring;
+
 	return 0;
 }
 
@@ -332,8 +464,8 @@ static void bnxt_init_rxbds(struct bnxt_ring *ring, uint32_t type,
 	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].flags_type = rte_cpu_to_le_16(type);
+		rx_bd_ring[j].len = rte_cpu_to_le_16(len);
 		rx_bd_ring[j].opaque = j;
 	}
 }
@@ -344,12 +476,17 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	struct bnxt_ring *ring;
 	uint32_t prod, type;
 	unsigned int i;
+	uint16_t size;
+
+	size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+	if (rxq->rx_buf_use_size <= size)
+		size = rxq->rx_buf_use_size;
 
-	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
 
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
-	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
+	bnxt_init_rxbds(ring, type, size);
 
 	prod = rxr->rx_prod;
 	for (i = 0; i < ring->ring_size; i++) {
@@ -362,6 +499,24 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		rxr->rx_prod = prod;
 		prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	}
+	RTE_LOG(DEBUG, PMD, "bnxt_init_one_rx_ring!\n");
+
+	ring = rxr->ag_ring_struct;
+	type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
+	bnxt_init_rxbds(ring, type, size);
+	prod = rxr->ag_prod;
+
+	for (i = 0; i < ring->ring_size; i++) {
+		if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+			RTE_LOG(WARNING, PMD,
+			"init'ed AG ring %d with %d/%d mbufs only\n",
+			rxq->queue_id, i, ring->ring_size);
+			break;
+		}
+		rxr->ag_prod = prod;
+		prod = RING_NEXT(rxr->ag_ring_struct, prod);
+	}
+	RTE_LOG(DEBUG, PMD, "bnxt_init_one_rx_ring AGG Done!\n");
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index f766b26..e104fbd 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -43,14 +43,20 @@ struct bnxt_sw_rx_bd {
 
 struct bnxt_rx_ring_info {
 	uint16_t		rx_prod;
+	uint16_t		ag_prod;
 	void			*rx_doorbell;
+	void			*ag_doorbell;
 
 	struct rx_prod_pkt_bd	*rx_desc_ring;
+	struct rx_prod_pkt_bd	*ag_desc_ring;
 	struct bnxt_sw_rx_bd	*rx_buf_ring; /* sw ring */
+	struct bnxt_sw_rx_bd	*ag_buf_ring; /* sw ring */
 
 	phys_addr_t		rx_desc_mapping;
+	phys_addr_t		ag_desc_mapping;
 
 	struct bnxt_ring	*rx_ring_struct;
+	struct bnxt_ring	*ag_ring_struct;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 17/23] bnxt: add support for LRO
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (15 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 16/23] bnxt: add support to set MTU Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 18/23] bnxt: add rxq_info_get and txq_info_get dev_ops Ajit Khaparde
                   ` (6 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to enable and disable LRO
To support this feature, the driver creates an aggregrator ring.
When the hardware starts doing LRO, it sends a tpa_start completion.
When the driver receives a tpa_end completion, it indicates that the
LRO chaining is complete.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c         |   7 +
 drivers/net/bnxt/bnxt_hwrm.c           |  44 ++-
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/bnxt_ring.c           |  32 +-
 drivers/net/bnxt/bnxt_ring.h           |   4 +-
 drivers/net/bnxt/bnxt_rxq.c            |  12 +
 drivers/net/bnxt/bnxt_rxq.h            |   2 +
 drivers/net/bnxt/bnxt_rxr.c            | 315 ++++++++++++----
 drivers/net/bnxt/bnxt_rxr.h            |  40 ++
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 647 ++++++++++++++++++++++++++++++++-
 10 files changed, 1019 insertions(+), 86 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5f22091..7fafd02 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -286,6 +286,13 @@ static int bnxt_init_chip(struct bnxt *bp)
 				goto err_out;
 			}
 		}
+
+		bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
+		else
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 136365c..bea855e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1148,19 +1148,15 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
 
 	req.flags = rte_cpu_to_le_32(
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
 			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+
 	req.enables = rte_cpu_to_le_32(
 		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
-//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
 
 	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
 	size -= RTE_PKTMBUF_HEADROOM;
 
 	req.jumbo_thresh = rte_cpu_to_le_16(size);
-//	req.hds_threshold = rte_cpu_to_le_16(size);
 	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -1170,6 +1166,41 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic, bool enable)
+{
+	int rc = 0;
+	struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_TPA_CFG, -1, resp);
+
+	if (enable) {
+		req.enables = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+		req.flags = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+			HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
+		req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+		req.max_agg_segs = rte_cpu_to_le_16(5);
+		req.max_aggs =
+			rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+		req.min_agg_len = rte_cpu_to_le_32(512);
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1562,6 +1593,9 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		bnxt_clear_hwrm_vnic_filters(bp, vnic);
 
 		bnxt_hwrm_vnic_ctx_free(bp, vnic);
+
+		bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
+
 		bnxt_hwrm_vnic_free(bp, vnic);
 	}
 	/* Ring resources */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 9478d12..2d707a3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -101,6 +101,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 				struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic, bool enable);
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 3eed354..dd68a3f 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bitmap.h>
 #include <rte_memzone.h>
 #include <unistd.h>
 
@@ -137,11 +138,23 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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;
-	int ag_ring_start = 0;
+	int ag_ring_start = rx_ring_start + rx_ring_len;
+	int ag_ring_len = rx_ring_len * AGG_RING_SIZE_FACTOR;
 
-	ag_ring_start = rx_ring_start + rx_ring_len;
-	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
+	int ag_bitmap_start = ag_ring_start + ag_ring_len;
+	int ag_bitmap_len =  rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(rte_bitmap_get_memory_footprint(
+			rx_ring_info->rx_ring_struct->ring_size *
+			AGG_RING_SIZE_FACTOR)) : 0;
+
+	int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
+	int tpa_info_len = rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
+				       sizeof(struct bnxt_tpa_info)) : 0;
+
+	int total_alloc_len = tpa_info_start;
+	if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+		total_alloc_len += tpa_info_len;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -230,6 +243,17 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->ag_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring_info->ag_bitmap =
+		    rte_bitmap_init(rx_ring_info->rx_ring_struct->ring_size *
+				    AGG_RING_SIZE_FACTOR, (uint8_t *)mz->addr +
+				    ag_bitmap_start, ag_bitmap_len);
+
+		/* TPA info */
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			rx_ring_info->tpa_info =
+				((struct bnxt_tpa_info *)((char *)mz->addr +
+							  tpa_info_start));
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index b5bd287..6d1eb58 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -57,8 +57,8 @@
 #define DEFAULT_RX_RING_SIZE	256
 #define DEFAULT_TX_RING_SIZE	256
 
-#define MAX_TPA		128
-#define AGG_RING_SIZE_FACTOR 2
+#define BNXT_TPA_MAX		64
+#define AGG_RING_SIZE_FACTOR	2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 5a5def5..b0bbed1 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -214,6 +214,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 {
 	struct bnxt_sw_rx_bd *sw_ring;
+	struct bnxt_tpa_info *tpa_info;
 	uint16_t i;
 
 	if (rxq) {
@@ -236,6 +237,17 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 				}
 			}
 		}
+
+		/* Free up mbufs in TPA */
+		tpa_info = rxq->rx_ring->tpa_info;
+		if (tpa_info) {
+			for (i = 0; i < BNXT_TPA_MAX; i++) {
+				if (tpa_info[i].mbuf) {
+					rte_pktmbuf_free_seg(tpa_info[i].mbuf);
+					tpa_info[i].mbuf = NULL;
+				}
+			}
+		}
 	}
 }
 
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 0695214..01aaa00 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -59,6 +59,8 @@ struct bnxt_rx_queue {
 	uint32_t			rx_buf_use_size;  /* useable size */
 	struct bnxt_rx_ring_info	*rx_ring;
 	struct bnxt_cp_ring_info	*cp_ring;
+
+	struct bnxt_tpa_info		*rx_tpa;
 };
 
 void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 12869a4..de86161 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -34,6 +34,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <rte_bitmap.h>
 #include <rte_byteorder.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
@@ -102,24 +103,28 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
-#ifdef BNXT_DEBUG
-static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+static inline void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr,
 			       struct rte_mbuf *mbuf)
 {
-	uint16_t prod = rxr->rx_prod;
+	uint16_t prod = RING_NEXT(rxr->rx_ring_struct, rxr->rx_prod);
 	struct bnxt_sw_rx_bd *prod_rx_buf;
-	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+	struct rx_prod_pkt_bd *prod_bd;
 
 	prod_rx_buf = &rxr->rx_buf_ring[prod];
 
+	RTE_ASSERT(prod_rx_buf->mbuf == NULL);
+	RTE_ASSERT(mbuf != NULL);
+
 	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;
+	prod_bd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(mbuf));
+
+	rxr->rx_prod = prod;
 }
 
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -138,7 +143,192 @@ static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 }
 #endif
 
-static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+static inline
+struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr,
+				     uint16_t cons)
+{
+	struct bnxt_sw_rx_bd *cons_rx_buf;
+	struct rte_mbuf *mbuf;
+
+	cons_rx_buf = &rxr->rx_buf_ring[cons];
+	RTE_ASSERT(cons_rx_buf->mbuf != NULL);
+	mbuf = cons_rx_buf->mbuf;
+	cons_rx_buf->mbuf = NULL;
+	return mbuf;
+}
+
+static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
+			   struct rx_tpa_start_cmpl *tpa_start,
+			   struct rx_tpa_start_cmpl_hi *tpa_start1)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
+		RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+	uint16_t data_cons;
+	struct bnxt_tpa_info *tpa_info;
+	struct rte_mbuf *mbuf;
+
+	data_cons = tpa_start->opaque;
+	tpa_info = &rxr->tpa_info[agg_id];
+
+	mbuf = bnxt_consume_rx_buf(rxr, data_cons);
+
+	bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
+
+	tpa_info->mbuf = mbuf;
+	tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
+
+	mbuf->nb_segs = 1;
+	mbuf->next = NULL;
+	mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len);
+	mbuf->data_len = mbuf->pkt_len;
+	mbuf->port = rxq->port_id;
+	mbuf->ol_flags = PKT_RX_LRO;
+	if (likely(tpa_start->flags_type &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS_RSS_VALID))) {
+		mbuf->hash.rss = rte_le_to_cpu_32(tpa_start->rss_hash);
+		mbuf->ol_flags |= PKT_RX_RSS_HASH;
+	} else {
+		mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code);
+		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+	}
+	if (tpa_start1->flags2 &
+	    rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) {
+		mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata);
+		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+	}
+	if (likely(tpa_start1->flags2 &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC)))
+		mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+
+	/* recycle next mbuf */
+	data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons);
+	bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons));
+}
+
+static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr,
+		uint8_t agg_bufs, uint32_t raw_cp_cons)
+{
+	uint16_t last_cp_cons;
+	struct rx_pkt_cmpl *agg_cmpl;
+
+	raw_cp_cons = ADV_RAW_CMP(raw_cp_cons, agg_bufs);
+	last_cp_cons = RING_CMP(cpr->cp_ring_struct, raw_cp_cons);
+	agg_cmpl = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[last_cp_cons];
+	return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct);
+}
+
+/* TPA consume agg buffer out of order, allocate connected data only */
+static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t next = RING_NEXT(rxr->ag_ring_struct, rxr->ag_prod);
+
+	/* TODO batch allocation for better performance */
+	while (rte_bitmap_get(rxr->ag_bitmap, next)) {
+		if (unlikely(bnxt_alloc_ag_data(rxq, rxr, next))) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n", next);
+			break;
+		}
+		rte_bitmap_clear(rxr->ag_bitmap, next);
+		rxr->ag_prod = next;
+		next = RING_NEXT(rxr->ag_ring_struct, next);
+	}
+
+	return 0;
+}
+
+static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
+			 struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
+			 uint8_t agg_buf)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	int i;
+	uint16_t cp_cons, ag_cons;
+	struct rx_pkt_cmpl *rxcmp;
+	struct rte_mbuf *last = mbuf;
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+		bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+		ag_cons = rxcmp->opaque;
+		RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		RTE_ASSERT(ag_mbuf != NULL);
+
+		ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+
+		last->next = ag_mbuf;
+		last = ag_mbuf;
+
+		ag_buf->mbuf = NULL;
+
+		/*
+		 * As aggregation buffer consumed out of order in TPA module,
+		 * use bitmap to track freed slots to be allocated and notified
+		 * to NIC
+		 */
+		rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+	}
+	bnxt_prod_ag_mbuf(rxq);
+	return 0;
+}
+
+static inline struct rte_mbuf *bnxt_tpa_end(
+		struct bnxt_rx_queue *rxq,
+		uint32_t *raw_cp_cons,
+		struct rx_tpa_end_cmpl *tpa_end,
+		struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
+			>> RX_TPA_END_CMPL_AGG_ID_SFT;
+	struct rte_mbuf *mbuf;
+	uint8_t agg_bufs;
+	//unsigned int len;
+	struct bnxt_tpa_info *tpa_info;
+
+	tpa_info = &rxr->tpa_info[agg_id];
+	mbuf = tpa_info->mbuf;
+	RTE_ASSERT(mbuf != NULL);
+
+	rte_prefetch0(mbuf);
+	//len = tpa_info->len;
+	agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
+		RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
+	if (agg_bufs) {
+		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+			return NULL;
+		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+	}
+	mbuf->l4_len = tpa_end->payload_offset;
+
+	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	RTE_ASSERT(new_data != NULL);
+	if (!new_data)
+		return NULL;
+	tpa_info->mbuf = new_data;
+
+	return mbuf;
+}
+
+static int 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;
@@ -148,12 +338,13 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-	uint16_t ag_cons, ag_prod = rxr->ag_prod;
-	struct bnxt_sw_rx_bd *rx_buf;
+#ifdef BNXT_DEBUG
+	uint16_t ag_cons;
+#endif
 	struct rte_mbuf *mbuf;
 	int rc = 0;
-	uint8_t i;
 	uint8_t agg_buf = 0;
+	uint16_t cmp_type;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -165,12 +356,34 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct))
 		return -EBUSY;
 
+	cmp_type = CMP_TYPE(rxcmp);
+	if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_START) {
+		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
+			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
+		rc = -EINVAL; /* Continue w/o new mbuf */
+		goto next_rx;
+	} else if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_END) {
+		mbuf = bnxt_tpa_end(rxq, &tmp_raw_cons,
+				   (struct rx_tpa_end_cmpl *)rxcmp,
+				   (struct rx_tpa_end_cmpl_hi *)rxcmp1);
+		if (unlikely(!mbuf))
+			return -EBUSY;
+		*rx_pkt = mbuf;
+		goto next_rx;
+	} else if (cmp_type != 0x11) {
+		rc = -EINVAL;
+		goto next_rx;
+	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+		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;
+	mbuf = bnxt_consume_rx_buf(rxr, cons);
 	rte_prefetch0(mbuf);
 
 	if (mbuf == NULL)
@@ -190,61 +403,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
 
-	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
-			>> RX_PKT_CMPL_AGG_BUFS_SFT;
-	if (agg_buf) {
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
-			       cpr->cp_ring_struct))
-			return -EBUSY;
-		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
-			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
-	}
-
-	for (i = 0; i < agg_buf; i++) {
-		struct bnxt_sw_rx_bd *ag_buf;
-		struct rte_mbuf *ag_mbuf;
-		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		ag_cons = rxcmp->opaque;
-		ag_buf = &rxr->ag_buf_ring[ag_cons];
-		ag_mbuf = ag_buf->mbuf;
-		ag_mbuf->nb_segs = 1;
-		ag_mbuf->data_len = rxcmp->len;
-
-		mbuf->nb_segs++;
-		mbuf->pkt_len += ag_mbuf->data_len;
-		if (mbuf->next == NULL) {
-			mbuf->next = ag_mbuf;
-		} else {
-			struct rte_mbuf *temp_mbuf = mbuf;
-
-			while (temp_mbuf->next != NULL)
-				temp_mbuf = temp_mbuf->next;
-			temp_mbuf->next = ag_mbuf;
-		}
-		ag_buf->mbuf = NULL;
-
-		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
-		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
-			RTE_LOG(ERR, PMD,
-				"agg mbuf alloc failed: prod=0x%x\n",
-				ag_prod);
-			rc = -ENOMEM;
-		}
-		rxr->ag_prod = ag_prod;
-
-#ifdef BNXT_DEBUG
-		if (!CMP_VALID((struct cmpl_base *)
-			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
-			cpr->cp_ring_struct))
-			return -EBUSY;
-#endif
-	}
+	if (agg_buf)
+		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
 
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
@@ -254,7 +414,6 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
 	}
 
-	rx_buf->mbuf = NULL;
 #ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
@@ -294,10 +453,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 */
 
 	*rx_pkt = mbuf;
-#ifdef BNXT_DEBUG
+
 next_rx:
-#endif
-	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -333,7 +490,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
 			if (likely(!rc))
 				nb_rx_pkts++;
-			else if (rc == -EBUSY)	/* partial completion */
+			if (rc == -EBUSY)	/* partial completion */
 				break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
@@ -341,6 +498,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			break;
 	}
 
+	cpr->cp_raw_cons = raw_cons;
 	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
@@ -348,7 +506,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		 */
 		return nb_rx_pkts;
 	}
-	cpr->cp_raw_cons = raw_cons;
 
 	B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -516,6 +673,16 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		rxr->ag_prod = prod;
 		prod = RING_NEXT(rxr->ag_ring_struct, prod);
 	}
+
+	if (rxr->tpa_info) {
+		for (i = 0; i < BNXT_TPA_MAX; i++) {
+			rxr->tpa_info[i].mbuf =
+				__bnxt_alloc_rx_data(rxq->mb_pool);
+			if (!rxr->tpa_info[i].mbuf)
+				return -ENOMEM;
+		}
+	}
+
 	RTE_LOG(DEBUG, PMD, "bnxt_init_one_rx_ring AGG Done!\n");
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e104fbd..f8d6dc8 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -37,6 +37,39 @@
 #define B_RX_DB(db, prod)						\
 		(*(uint32_t *)db = (DB_KEY_RX | prod))
 
+#define BNXT_TPA_L4_SIZE(x)	\
+	{ \
+		typeof(x) hdr_info = (x); \
+		(((hdr_info) & 0xf8000000) ? ((hdr_info) >> 27) : 32) \
+	}
+
+#define BNXT_TPA_INNER_L3_OFF(hdr_info)	\
+	(((hdr_info) >> 18) & 0x1ff)
+
+#define BNXT_TPA_INNER_L2_OFF(hdr_info)	\
+	(((hdr_info) >> 9) & 0x1ff)
+
+#define BNXT_TPA_OUTER_L3_OFF(hdr_info)	\
+	((hdr_info) & 0x1ff)
+
+enum pkt_hash_types {
+	PKT_HASH_TYPE_NONE,	/* Undefined type */
+	PKT_HASH_TYPE_L2,	/* Input: src_MAC, dest_MAC */
+	PKT_HASH_TYPE_L3,	/* Input: src_IP, dst_IP */
+	PKT_HASH_TYPE_L4,	/* Input: src_IP, dst_IP, src_port, dst_port */
+};
+
+struct bnxt_tpa_info {
+	struct rte_mbuf		*mbuf;
+	uint16_t			len;
+	unsigned short		gso_type;
+	uint32_t			flags2;
+	uint32_t			metadata;
+	enum pkt_hash_types	hash_type;
+	uint32_t			rss_hash;
+	uint32_t			hdr_info;
+};
+
 struct bnxt_sw_rx_bd {
 	struct rte_mbuf		*mbuf; /* data associated with RX descriptor */
 };
@@ -57,6 +90,13 @@ struct bnxt_rx_ring_info {
 
 	struct bnxt_ring	*rx_ring_struct;
 	struct bnxt_ring	*ag_ring_struct;
+
+	/*
+	 * To deal with out of order return from TPA, use free buffer indicator
+	 */
+	struct rte_bitmap	*ag_bitmap;
+
+	struct bnxt_tpa_info *tpa_info;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 935cb90..987ff53 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -821,7 +821,9 @@ struct rx_pkt_cmpl {
 	 * RX L2 completion: Completion of and L2 RX
 	 * packet. Length = 32B
 	 */
-	#define RX_PKT_CMPL_TYPE_RX_L2	UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2			UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_START	UINT32_C(0x13)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_END		UINT32_C(0x15)
 	/*
 	 * When this bit is '1', it indicates a packet that has an error
 	 * of some type. Type of error is indicated in error_flags.
@@ -1229,6 +1231,473 @@ struct rx_pkt_cmpl_hi {
 	#define RX_PKT_CMPL_REORDER_SFT	0
 } __attribute__((packed));
 
+/* RX L2 TPA Start Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_start_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_START_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_START_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA Start Completion: Completion at the
+	 * beginning of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_START_CMPL_TYPE_RX_TPA_START	UINT32_C(0x13)
+	/* This bit will always be '0' for TPA start completions. */
+	#define RX_TPA_START_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+		(UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS (UINT32_C(0x6) << 7)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_TPA_START_CMPL_FLAGS_RSS_VALID	UINT32_C(0x400)
+	/* unused is 1 b */
+	#define RX_TPA_START_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_SFT	12
+	/* TCP Packet: Indicates that the packet was IP and TCP. */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_TCP	(UINT32_C(0x2) << 12)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_LAST \
+		RX_TPA_START_CMPL_FLAGS_ITYPE_TCP
+	#define RX_TPA_START_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_START_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value indicates the amount of packet data written to the
+	 * buffer the opaque field in this completion corresponds to.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t v1;
+	/* unused1 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 RX_TPA_START_CMPL_V1	UINT32_C(0x1)
+	/* unused1 is 7 b */
+	uint8_t rss_hash_type;
+	/*
+	 * 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]}
+	 * . The value of tuple_extrac_op provides the information about
+	 * what fields the hash was computed on. * 0: The RSS hash was
+	 * computed over source IP address, destination IP address,
+	 * source port, and destination port of inner IP and TCP or UDP
+	 * headers. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 1: The RSS hash was computed over
+	 * source IP address and destination IP address of inner IP
+	 * header. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 2: The RSS hash was computed over
+	 * source IP address, destination IP address, source port, and
+	 * destination port of IP and TCP or UDP headers of outer tunnel
+	 * headers. Note: For non-tunneled packets, this value is not
+	 * applicable. * 3: The RSS hash was computed over source IP
+	 * address and destination IP address of IP header of outer
+	 * tunnel headers. Note: For non-tunneled packets, this value is
+	 * not applicable. Note that 4-tuples values listed above are
+	 * applicable for layer 4 protocols supported and enabled for
+	 * RSS in the hardware, HWRM firmware, and drivers. For example,
+	 * if RSS hash is supported and enabled for TCP traffic only,
+	 * then the values of tuple_extract_op corresponding to 4-tuples
+	 * are only valid for TCP traffic.
+	 */
+	uint16_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 9 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_START_CMPL_AGG_ID_MASK	UINT32_C(0xfe00)
+	#define RX_TPA_START_CMPL_AGG_ID_SFT	9
+	uint32_t rss_hash;
+	/*
+	 * This value is the RSS hash value calculated for the packet
+	 * based on the mode bits and key value in the VNIC.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX L2 TPA Start Completion Record */
+struct rx_tpa_start_cmpl_hi {
+	uint32_t flags2;
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * inner packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_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 sum passed for
+	 * all segments included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC	UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * tunnel header and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_IP_CS_CALC	UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the
+	 * tunnel packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_L4_CS_CALC	UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_SFT	4
+	/* No metadata informtaion. Value is zero. */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_LAST \
+		RX_TPA_START_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.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_IP_TYPE	UINT32_C(0x100)
+	uint32_t metadata;
+	/*
+	 * 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_TPA_START_CMPL_METADATA_VID_MASK	UINT32_C(0xfff)
+	#define RX_TPA_START_CMPL_METADATA_VID_SFT	0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_TPA_START_CMPL_METADATA_DE	UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_TPA_START_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+	#define RX_TPA_START_CMPL_METADATA_PRI_SFT	13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_TPA_START_CMPL_METADATA_TPID_MASK	UINT32_C(0xffff0000)
+	#define RX_TPA_START_CMPL_METADATA_TPID_SFT	16
+	uint16_t v2;
+	/* unused4 is 15 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 RX_TPA_START_CMPL_V2	UINT32_C(0x1)
+	/* unused4 is 15 b */
+	uint16_t cfa_code;
+	/*
+	 * This field identifies the CFA action rule that was used for
+	 * this packet.
+	 */
+	uint32_t inner_l4_size_inner_l3_offset_inner_l2_offset_outer_l3_offset;
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the outer L3 header. If there is no outer L3 header, then
+	 * this value is zero.
+	 */
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_MASK	UINT32_C(0x1ff)
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_SFT	0
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L2 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_MASK	UINT32_C(0x3fe00)
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_SFT	9
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L3 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_MASK	UINT32_C(0x7fc0000)
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_SFT	18
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_MASK	UINT32_C(0xf8000000)
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_SFT	27
+} __attribute__((packed));
+
+/* RX TPA End Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_end_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_END_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_END_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA End Completion: Completion at the
+	 * end of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_END_CMPL_TYPE_RX_TPA_END	UINT32_C(0x15)
+	/*
+	 * 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_TPA_END_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_END_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_TPA_END_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_JUMBO (UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS	(UINT32_C(0x6) << 7)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* unused is 2 b */
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_MASK	UINT32_C(0xc00)
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_SFT	10
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was. - 2 TCP Packet Indicates that the packet was IP
+	 * and TCP. This indicates that the ip_cs field is valid and
+	 * that the tcp_udp_cs field is valid and contains the TCP
+	 * checksum. This also indicates that the payload_offset field
+	 * is valid.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_SFT	12
+	#define RX_TPA_END_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_END_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value is zero for TPA End completions. There is no data
+	 * in the buffer that corresponds to the opaque value in this
+	 * completion.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t agg_bufs_v1;
+	/* unused1 is 1 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 RX_TPA_END_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
+	 * aggregation packet. If the value is zero, then the packet is
+	 * completely contained in the buffer space provided in the
+	 * aggregation start completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_BUFS_MASK	UINT32_C(0x7e)
+	#define RX_TPA_END_CMPL_AGG_BUFS_SFT	1
+	/* unused1 is 1 b */
+	uint8_t tpa_segs;
+	/* This value is the number of segments in the TPA operation. */
+	uint8_t payload_offset;
+	/*
+	 * This value indicates the offset in bytes from the beginning
+	 * of the packet where the inner payload starts. This value is
+	 * valid for TCP, UDP, FCoE, and RoCE packets. A value of zero
+	 * indicates an offset of 256 bytes.
+	 */
+	uint8_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 1 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_ID_MASK	UINT32_C(0xfe)
+	#define RX_TPA_END_CMPL_AGG_ID_SFT	1
+	uint32_t tsdelta;
+	/*
+	 * For non-GRO packets, this value is the timestamp delta
+	 * between earliest and latest timestamp values for TPA packet.
+	 * If packets were not time stamped, then delta will be zero.
+	 * For GRO packets, this field is zero except for the following
+	 * sub-fields. - tsdelta[31] Timestamp present indication. When
+	 * '0', no Timestamp option is in the packet. When '1', then a
+	 * Timestamp option is present in the packet.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX TPA End Completion Record */
+struct rx_tpa_end_cmpl_hi {
+	uint32_t tpa_dup_acks;
+	/* unused3 is 28 b */
+	/*
+	 * This value is the number of duplicate ACKs that have been
+	 * received as part of the TPA operation.
+	 */
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_MASK	UINT32_C(0xf)
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_SFT	0
+	/* unused3 is 28 b */
+	uint16_t tpa_seg_len;
+	/*
+	 * This value is the valid when TPA completion is active. It
+	 * indicates the length of the longest segment of the TPA
+	 * operation for LRO mode and the length of the first segment in
+	 * GRO mode. This value may be used by GRO software to re-
+	 * construct the original packet stream from the TPA packet.
+	 * This is the length of all but the last segment for GRO. In
+	 * LRO mode this value may be used to indicate MSS size to the
+	 * stack.
+	 */
+	uint16_t unused_3;
+	/* unused4 is 16 b */
+	uint16_t errors_v2;
+	/*
+	 * 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_TPA_END_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_TPA_END_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+	/*
+	 * This error occurs when there is a fatal HW
+	 * problem in the chip only. It indicates that
+	 * there were not BDs on chip but that there was
+	 * adequate reservation. provided by the TPA
+	 * block.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+		(UINT32_C(0x2) << 1)
+	/*
+	 * This error occurs when TPA block was not
+	 * configured to reserve adequate BDs for TPA
+	 * operations on this RX ring. All data for the
+	 * TPA operation was not placed. This error can
+	 * also be generated when the number of segments
+	 * is not programmed correctly in TPA and the 33
+	 * total aggregation buffers allowed for the TPA
+	 * operation has been exceeded.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR \
+		(UINT32_C(0x4) << 1)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_LAST \
+		RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR
+	#define RX_TPA_END_CMPL_ERRORS_MASK	UINT32_C(0xfffe)
+	#define RX_TPA_END_CMPL_ERRORS_SFT	1
+	uint16_t unused_4;
+	/* unused5 is 16 b */
+	uint32_t start_opaque;
+	/*
+	 * This is the opaque value that was completed for the TPA start
+	 * completion that corresponds to this TPA end completion.
+	 */
+} __attribute__((packed));
+
 /* HWRM Forwarded Request (16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	uint16_t req_len_type;
@@ -6304,6 +6773,182 @@ struct hwrm_vnic_rss_cos_lb_ctx_free_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_vnic_tpa_cfg */
+/* Description: This function is used to enable/configure TPA on the VNIC. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_tpa_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of non-tunneled TCP
+	 * packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of tunneled TCP packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Windows
+	 * Receive Segment Coalescing	(RSC) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Linux
+	 * Generic Receive Offload	(GRO) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for TCP packets with IP
+	 * ECN set to non-zero.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for GRE tunneled TCP
+	 * packets only if all packets have the same GRE sequence.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ	\
+		UINT32_C(0x20)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP/IPv4 packets with consecutively increasing
+	 * IPIDs. In other words, the last packet that is being
+	 * aggregated to an already existing aggregation context shall
+	 * have IPID 1 more than the IPID of the last packet that was
+	 * aggregated in that aggregation context.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_IPID_CHECK	UINT32_C(0x40)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP packets with the same TTL	(IPv4) or Hop limit
+	 *	(IPv6) value.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_TTL_CHECK	UINT32_C(0x80)
+	uint32_t enables;
+	/* This bit must be '1' for the max_agg_segs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS	UINT32_C(0x1)
+	/* This bit must be '1' for the max_aggs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS	UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the max_agg_timer field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER	UINT32_C(0x4)
+	/* This bit must be '1' for the min_agg_len field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN	UINT32_C(0x8)
+	uint16_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t max_agg_segs;
+	/*
+	 * This is the maximum number of TCP segments that can be
+	 * aggregated	(unit is Log2). Max value is 31.
+	 */
+	/* 1 segment */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1	UINT32_C(0x0)
+	/* 2 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2	UINT32_C(0x1)
+	/* 4 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4	UINT32_C(0x2)
+	/* 8 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8	UINT32_C(0x3)
+	/* Any segment size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX	UINT32_C(0x1f)
+	uint16_t max_aggs;
+	/*
+	 * This is the maximum number of aggregations this VNIC is
+	 * allowed	(unit is Log2). Max value is 7
+	 */
+	/* 1 aggregation */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1	UINT32_C(0x0)
+	/* 2 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2	UINT32_C(0x1)
+	/* 4 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4	UINT32_C(0x2)
+	/* 8 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8	UINT32_C(0x3)
+	/* 16 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16	UINT32_C(0x4)
+	/* Any aggregation size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX	UINT32_C(0x7)
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_agg_timer;
+	/*
+	 * This is the maximum amount of time allowed for an aggregation
+	 * context to complete after it was initiated.
+	 */
+	uint32_t min_agg_len;
+	/*
+	 * This is the minimum amount of payload length required to
+	 * start an aggregation context.
+	 */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_tpa_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_ring_alloc */
 /*
  * Description: This command allocates and does basic preparation for a ring.
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 18/23] bnxt: add rxq_info_get and txq_info_get dev_ops
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (16 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 17/23] bnxt: add support for LRO Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 19/23] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
                   ` (5 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for txq_info_get and rxq_info_get dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7fafd02..d6c36b9 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1390,6 +1390,43 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static void
+bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_rxq_info *qinfo)
+{
+	struct bnxt_rx_queue *rxq;
+
+	rxq = dev->data->rx_queues[queue_id];
+
+	qinfo->mp = rxq->mb_pool;
+	qinfo->scattered_rx = dev->data->scattered_rx;
+	qinfo->nb_desc = rxq->nb_rx_desc;
+
+	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+	qinfo->conf.rx_drop_en = 0;
+	qinfo->conf.rx_deferred_start = 0;
+}
+
+static void
+bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_txq_info *qinfo)
+{
+	struct bnxt_tx_queue *txq;
+
+	txq = dev->data->tx_queues[queue_id];
+
+	qinfo->nb_desc = txq->nb_tx_desc;
+
+	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
+	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
+	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+
+	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
+	qinfo->conf.tx_rs_thresh = 0;
+	qinfo->conf.txq_flags = txq->txq_flags;
+	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
 static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
@@ -1482,6 +1519,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_reset = bnxt_dev_xstats_reset_op,
 	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
+	.rxq_info_get = bnxt_rxq_info_get_op,
+	.txq_info_get = bnxt_txq_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 19/23] bnxt: add additonal HWRM debug info to error messages
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (17 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 18/23] bnxt: add rxq_info_get and txq_info_get dev_ops Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 20/23] bnxt: reorg the query stats code Ajit Khaparde
                   ` (4 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

Add the cmd_err and opaque_0 and opaque_1 fields to HWRM error
messages.  These allow better debugging of some classes of HWRM
errors.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           | 19 ++++++++++++++++--
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 36 ++++++++++++++++++++++++++++++++++
 2 files changed, 53 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index bea855e..b6fff91 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -137,7 +137,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 	}
 
 	if (i >= HWRM_CMD_TIMEOUT) {
-		RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+		RTE_LOG(ERR, PMD, "Error sending msg 0x%04x\n",
 			req->req_type);
 		goto err_ret;
 	}
@@ -174,7 +174,22 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 		if (resp->error_code) { \
 			rc = rte_le_to_cpu_16(resp->error_code); \
-			RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \
+			if (resp->resp_len >= 16) { \
+				struct hwrm_err_output *tmp_hwrm_err_op = \
+							(void *)resp; \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d:%d:%08x:%04x\n", \
+					__func__, \
+					rc, tmp_hwrm_err_op->cmd_err, \
+					rte_le_to_cpu_32(\
+						tmp_hwrm_err_op->opaque_0), \
+					rte_le_to_cpu_16(\
+						tmp_hwrm_err_op->opaque_1)); \
+			} \
+			else { \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d\n", __func__, rc); \
+			} \
 			return rc; \
 		} \
 	}
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 987ff53..84c53d7 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -8569,6 +8569,42 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 */
 } __attribute__((packed));
 
+struct hwrm_err_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t opaque_0;
+	/* debug info for this error response. */
+	uint16_t opaque_1;
+	/* debug info for this error response. */
+	uint8_t cmd_err;
+	/*
+	 * In the case of an error response, command specific error code
+	 * is returned in this field.
+	 */
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* Port Tx Statistics Formats	(408 bytes) */
 struct tx_port_stats {
 	uint64_t tx_64b_frames;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 20/23] bnxt: reorg the query stats code
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (18 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 19/23] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 21/23] bnxt: update to HWRM version 1.7.5 Ajit Khaparde
                   ` (3 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

1) Use hwrm_stat_ctx_query command to query statistics
Using hwrm_stat_ctx_query command will allow polling
the statistics from hardware instead of using the current push
model from the hardware which does a DMA of the stats to the host
at fixed intervals.
2) Use the rx_mbuf_alloc_fail to track mbuf alloc failures.
3) We were wrongly incrementing hwrm_cmd_seq in bnxt_hwrm_stat_clear
and bnxt_hwrm_stat_ctx_alloc functions.  This patch fixes that.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |   1 +
 drivers/net/bnxt/bnxt_ethdev.c         |   1 +
 drivers/net/bnxt/bnxt_hwrm.c           |  45 ++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/bnxt_rxr.c            |  16 +++--
 drivers/net/bnxt/bnxt_stats.c          |  59 +++---------------
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 108 +++++++++++++++++++++++++++++++++
 7 files changed, 170 insertions(+), 62 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index f25a1c4..387dab7 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -208,6 +208,7 @@ struct bnxt {
 	uint16_t		vxlan_fw_dst_port_id;
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
+	rte_atomic64_t		rx_mbuf_alloc_fail;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d6c36b9..80b85ab 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1595,6 +1595,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 
 	bp = eth_dev->data->dev_private;
 
+	rte_atomic64_init(&bp->rx_mbuf_alloc_fail);
 	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index b6fff91..7808f28 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -832,13 +832,12 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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;
 
+	HWRM_PREP(req, STAT_CTX_CLR_STATS, -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));
 
@@ -856,9 +855,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 
 	HWRM_PREP(req, STAT_CTX_ALLOC, -1, resp);
 
-	req.update_period_ms = rte_cpu_to_le_32(1000);
+	req.update_period_ms = rte_cpu_to_le_32(0);
 
-	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);
 
@@ -881,7 +879,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	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));
 
@@ -2481,6 +2478,42 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 	return rc;
 }
 
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats)
+{
+	int rc = 0;
+	struct hwrm_stat_ctx_query_input req = {.req_type = 0};
+	struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, STAT_CTX_QUERY, -1, resp);
+
+	req.stat_ctx_id = rte_cpu_to_le_32(cid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->tx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
 {
 	uint32_t *count = cbdata;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 2d707a3..7fc7b57 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -87,6 +87,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned int idx);
 int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 			    struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index de86161..4e4f071 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -68,8 +68,10 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	rx_buf->mbuf = data;
 
@@ -87,8 +89,10 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	if (rxbd == NULL)
 		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
@@ -321,8 +325,10 @@ static inline struct rte_mbuf *bnxt_tpa_end(
 
 	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
 	RTE_ASSERT(new_data != NULL);
-	if (!new_data)
+	if (!new_data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return NULL;
+	}
 	tpa_info->mbuf = new_data;
 
 	return mbuf;
@@ -678,8 +684,10 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		for (i = 0; i < BNXT_TPA_MAX; i++) {
 			rxr->tpa_info[i].mbuf =
 				__bnxt_alloc_rx_data(rxq->mb_pool);
-			if (!rxr->tpa_info[i].mbuf)
+			if (!rxr->tpa_info[i].mbuf) {
+				rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 				return -ENOMEM;
+			}
 		}
 	}
 
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 1db678b..fa2f467 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -196,64 +196,18 @@ void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
 
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
+	bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
+	bnxt_stats->rx_nombuf = rte_atomic64_read(&bp->rx_mbuf_alloc_fail);
 }
 
 void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
@@ -261,6 +215,7 @@ 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);
+	rte_atomic64_clear(&bp->rx_mbuf_alloc_fail);
 }
 
 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 84c53d7..28c69d0 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -163,6 +163,7 @@ struct ctx_hw_stats64 {
 #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_EXEC_FWD_RESP		(UINT32_C(0xd0))
 #define HWRM_REJECT_FWD_RESP		(UINT32_C(0xd1))
@@ -3378,6 +3379,113 @@ struct hwrm_func_qstats_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_stat_ctx_query */
+/* Description: This command returns statistics of a context. */
+/* Input	(24 bytes) */
+struct hwrm_stat_ctx_query_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(176 bytes) */
+struct hwrm_stat_ctx_query_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t tx_err_pkts;
+	/* Number of transmitted packets with error */
+	uint64_t tx_drop_pkts;
+	/* Number of dropped packets on transmit path */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t tx_mcast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t tx_bcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t rx_err_pkts;
+	/* Number of received packets with error */
+	uint64_t rx_drop_pkts;
+	/* Number of dropped packets on received path */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_func_clr_stats */
 /*
  * Description: This command clears statistics of a function. The input FID
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 21/23] bnxt: update to HWRM version 1.7.5
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (19 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 20/23] bnxt: reorg the query stats code Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 22/23] bnxt: Add support to set VF rxmode Ajit Khaparde
                   ` (2 subsequent siblings)
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch updates the Broadcom bnxt PMD to version 1.7.5
Most of the changes in the patch are in the hsi_struct_def_dpdk.h - an
autogenerated file. The changes in the *.c files are because of changes
in the macro names.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_cpr.c            |    2 +-
 drivers/net/bnxt/bnxt_hwrm.c           |   10 +-
 drivers/net/bnxt/bnxt_ring.c           |    4 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 2083 ++++++++++++++++++--------------
 4 files changed, 1212 insertions(+), 887 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 6eb32ab..32d08b4 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -158,7 +158,7 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
 	int rc;
 
 	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-				  HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 				  0, HWRM_NA_SIGNATURE,
 				  HWRM_NA_SIGNATURE);
 	if (rc)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7808f28..e16fb3a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -597,7 +597,7 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 		req.enables = rte_cpu_to_le_32(enables);
 	} else {
 		req.flags =
-		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN);
+		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
 		RTE_LOG(INFO, PMD, "Force Link Down\n");
 	}
 
@@ -703,7 +703,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			enables |=
 			HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
 		break;
-	case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL:
+	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
 		/*
 		 * TODO: Some HWRM versions crash with
@@ -724,7 +724,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD,
 				"hwrm_ring_alloc cp failed. rc:%d\n", rc);
 			return rc;
@@ -765,7 +765,7 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 			rc = rte_le_to_cpu_16(resp->error_code);
 
 		switch (ring_type) {
-		case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD, "hwrm_ring_free cp failed. rc:%d\n",
 				rc);
 			return rc;
@@ -1421,7 +1421,7 @@ static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
 	bnxt_hwrm_ring_free(bp, cp_ring,
-			HWRM_RING_FREE_INPUT_RING_TYPE_CMPL);
+			HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL);
 	memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *
 			sizeof(*cpr->cp_desc_ring));
 	cpr->cp_raw_cons = 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index dd68a3f..9d0ae27 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -298,7 +298,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE,
 					HWRM_NA_SIGNATURE);
 		if (rc)
@@ -365,7 +365,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE,
 					HWRM_NA_SIGNATURE);
 		if (rc)
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 28c69d0..4b289f8 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) Broadcom Limited.
+ *   Copyright(c) 2001-2017 Broadcom Limited.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -31,55 +31,27 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
-#define _HSI_STRUCT_DEF_EXTERNAL_H_
-
-/*
- * per-context HW statistics -- chip view
- */
-
-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_discard_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_discard_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;
-} __attribute__((packed));
-
-/* HW Resource Manager Specification 1.5.1 */
+#ifndef _HSI_STRUCT_DEF_DPDK_
+#define _HSI_STRUCT_DEF_DPDK_
+/* HSI and HWRM Specification 1.7.4 */
 #define HWRM_VERSION_MAJOR	1
-#define HWRM_VERSION_MINOR	5
-#define HWRM_VERSION_UPDATE	1
-
-#define HWRM_VERSION_STR	"1.5.1"
+#define HWRM_VERSION_MINOR	7
+#define HWRM_VERSION_UPDATE	5
 
+#define HWRM_VERSION_STR	"1.7.5"
 /*
  * 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.
+ * applicable	(All F's). Need to cast it the size of the field if needed.
  */
-#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
+#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_MAX_RESP_LEN	(248)  /* hwrm_selftest_qlist */
+#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 */
+#define HWRM_ROCE_SP_HSI_VERSION_MAJOR	1
+#define HWRM_ROCE_SP_HSI_VERSION_MINOR	7
+#define HWRM_ROCE_SP_HSI_VERSION_UPDATE	4
 
 /*
  * Request types
@@ -140,10 +112,10 @@ struct ctx_hw_stats64 {
 #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_PARAM	(UINT32_C(0x53))
 #define HWRM_RING_RESET			(UINT32_C(0x5e))
 #define HWRM_RING_GRP_ALLOC		(UINT32_C(0x60))
+#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))
@@ -193,11 +165,27 @@ struct ctx_hw_stats64 {
 #define HWRM_NVM_WRITE			(UINT32_C(0xfffe))
 #define HWRM_NVM_RAW_WRITE_BLK		(UINT32_C(0xffff))
 
-/* Return Codes */
-#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
-#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
-
-/* Short TX BD (16 bytes) */
+/*
+ * Note: The Host Software Interface (HSI) and Hardware Resource Manager (HWRM)
+ * specification describes the data structures used in Ethernet packet or RDMA
+ * message data transfers as well as an abstract interface for managing Ethernet
+ * NIC hardware resources.
+ */
+/* Ethernet Data path Host Structures */
+/*
+ * Description: The following three sections document the host structures used
+ * between device and software drivers for communicating Ethernet packets.
+ */
+/* BD Ring Structures */
+/*
+ * Description: This structure is used to inform the NIC of a location for and
+ * an aggregation buffer that will be used for packet data that is received. An
+ * aggregation buffer creates a different kind of completion operation for a
+ * packet where a variable number of BDs may be used to place the packet in the
+ * host. RX Rings that have aggregation buffers are known as aggregation rings
+ * and must contain only aggregation buffers.
+ */
+/* Short TX BD	(16 bytes) */
 struct tx_bd_short {
 	uint16_t flags_type;
 	/*
@@ -230,10 +218,10 @@ struct tx_bd_short {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -254,7 +242,8 @@ struct tx_bd_short {
 	#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
+	#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
@@ -294,7 +283,7 @@ struct tx_bd_short {
 	 */
 } __attribute__((packed));
 
-/* Long TX BD (32 bytes split to 2 16-byte struct) */
+/* Long TX BD	(32 bytes split to 2 16-byte struct) */
 struct tx_bd_long {
 	uint16_t flags_type;
 	/*
@@ -327,10 +316,10 @@ struct tx_bd_long {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -351,7 +340,8 @@ struct tx_bd_long {
 	#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
+	#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
@@ -441,7 +431,7 @@ struct tx_bd_long_hi {
 	 * bit is set, outer UDP checksum will be calculated for the
 	 * following cases: 1. Packets with tcp_udp_chksum flag set to
 	 * offload checksum for inner packet AND the inner packet is
-	 * TCP/UDP. If the inner packet is ICMP for example (non-
+	 * TCP/UDP. If the inner packet is ICMP for example	(non-
 	 * TCP/UDP), even if the tcp_udp_chksum is set, the outer UDP
 	 * checksum will not be calculated. 2. Packets with lso flag set
 	 * which implies inner TCP checksum calculation as part of LSO
@@ -473,7 +463,7 @@ struct tx_bd_long_hi {
 	 * 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. The flag is ignored if the LSO packet is a normal
-	 * (non-tunneled) TCP packet.
+	 *	(non-tunneled) TCP packet.
 	 */
 	#define TX_BD_LONG_LFLAGS_T_IPID	UINT32_C(0x80)
 	/*
@@ -541,7 +531,7 @@ struct tx_bd_long_hi {
 	#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	\
+	#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)
@@ -555,15 +545,16 @@ struct tx_bd_long_hi {
 	/* No editing */
 	#define TX_BD_LONG_CFA_META_KEY_NONE	(UINT32_C(0x0) << 28)
 	/*
-	 * - meta[17:16] - TPID select value (0 =
+	 * - 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
+	#define TX_BD_LONG_CFA_META_KEY_LAST \
+		TX_BD_LONG_CFA_META_KEY_VLAN_TAG
 } __attribute__((packed));
 
-/* RX Producer Packet BD (16 bytes) */
+/* RX Producer Packet BD	(16 bytes) */
 struct rx_prod_pkt_bd {
 	uint16_t flags_type;
 	/* This value identifies the type of buffer descriptor. */
@@ -571,7 +562,7 @@ struct rx_prod_pkt_bd {
 	#define RX_PROD_PKT_BD_TYPE_SFT	0
 	/*
 	 * Indicates that this BD is 16B long and is an
-	 * RX Producer (ie. empty) buffer descriptor.
+	 * RX Producer	(ie. empty) buffer descriptor.
 	 */
 	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT	UINT32_C(0x4)
 	/*
@@ -639,7 +630,7 @@ struct rx_prod_pkt_bd {
 
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
-/* Base Completion Record (16 bytes) */
+/* Base Completion Record	(16 bytes) */
 struct cmpl_base {
 	uint16_t type;
 	/* unused is 10 b */
@@ -718,7 +709,7 @@ struct cmpl_base {
 	/* info4 is 32 b */
 } __attribute__((packed));
 
-/* TX Completion Record (16 bytes) */
+/* TX Completion Record	(16 bytes) */
 struct tx_cmpl {
 	uint16_t flags_type;
 	/*
@@ -770,7 +761,7 @@ struct tx_cmpl {
 	#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	\
+	#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
@@ -807,7 +798,7 @@ struct tx_cmpl {
 	/* unused3 is 32 b */
 } __attribute__((packed));
 
-/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+/* RX Packet Completion Record	(32 bytes split to 2 16-byte struct) */
 struct rx_pkt_cmpl {
 	uint16_t flags_type;
 	/*
@@ -844,10 +835,12 @@ struct rx_pkt_cmpl {
 	 * 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
+	#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)
 	/* unused is 1 b */
+	#define RX_PKT_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
 	/*
 	 * This value indicates what the inner packet determined for the
 	 * packet was.
@@ -903,7 +896,8 @@ struct rx_pkt_cmpl {
 	 * 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_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 len;
@@ -1021,7 +1015,7 @@ struct rx_pkt_cmpl_hi {
 	 * the vlan TPID value.
 	 */
 	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
-	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST	\
+	#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
@@ -1071,15 +1065,18 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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	\
+	#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)
@@ -1120,39 +1117,45 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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
+	 * 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	\
+	#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
@@ -1172,15 +1175,17 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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
+	 * 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)
@@ -1189,18 +1194,21 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
@@ -1209,9 +1217,9 @@ struct rx_pkt_cmpl_hi {
 	 * 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	\
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
 		(UINT32_C(0x8) << 12)
-	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST	\
+	#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
@@ -1699,7 +1707,7 @@ struct rx_tpa_end_cmpl_hi {
 	 */
 } __attribute__((packed));
 
-/* HWRM Forwarded Request (16 bytes) */
+/* HWRM Forwarded Request	(16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	uint16_t req_len_type;
 	/* Length of forwarded request in bytes. */
@@ -1738,7 +1746,7 @@ struct hwrm_fwd_req_cmpl {
 	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
 } __attribute__((packed));
 
-/* HWRM Asynchronous Event Completion Record (16 bytes) */
+/* HWRM Asynchronous Event Completion Record	(16 bytes) */
 struct hwrm_async_event_cmpl {
 	uint16_t type;
 	/* unused1 is 10 b */
@@ -1760,19 +1768,20 @@ struct hwrm_async_event_cmpl {
 	/* Link MTU changed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE	UINT32_C(0x1)
 	/* Link speed changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE  UINT32_C(0x2)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE UINT32_C(0x2)
 	/* DCB Configuration changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE  UINT32_C(0x3)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE UINT32_C(0x3)
 	/* Port connection not allowed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED UINT32_C(0x4)
 	/* Link speed configuration was not allowed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED UINT32_C(0x5)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+		UINT32_C(0x5)
 	/* Link speed configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE UINT32_C(0x6)
 	/* Port PHY configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE UINT32_C(0x7)
 	/* Function driver unloaded */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD   UINT32_C(0x10)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD UINT32_C(0x10)
 	/* Function driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD	UINT32_C(0x11)
 	/* Function FLR related processing has completed */
@@ -1781,12 +1790,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD	UINT32_C(0x20)
 	/* PF driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD	UINT32_C(0x21)
-	/* VF Function Level Reset (FLR) */
+	/* VF Function Level Reset	(FLR) */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	UINT32_C(0x30)
 	/* VF MAC Address Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE UINT32_C(0x31)
 	/* PF-VF communication channel status change. */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE UINT32_C(0x32)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+		UINT32_C(0x32)
 	/* VF Configuration Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE	UINT32_C(0x33)
 	/* HWRM Error */
@@ -1805,69 +1815,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK	UINT32_C(0xfe)
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT	1
 	uint8_t timestamp_lo;
-	/* 8-lsb timestamp from POR (100-msec resolution) */
+	/* 8-lsb timestamp from POR	(100-msec resolution) */
 	uint16_t timestamp_hi;
-	/* 16-lsb timestamp from POR (100-msec resolution) */
+	/* 16-lsb timestamp from POR	(100-msec resolution) */
 	uint32_t event_data1;
 	/* Event specific data */
 } __attribute__((packed));
 
-/*
- * 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 service is vital part of the chip.
- * The chip can not be used by a driver or HWRM client without the HWRM.
- */
-
-/* Input (16 bytes) */
-struct input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
-/* Output (8 bytes) */
-struct output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
@@ -1877,7 +1831,7 @@ struct output {
  * interface or firmware version with major = 0, minor = 0, and update = 0 shall
  * be considered an invalid version.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ver_get_input {
 	uint16_t req_type;
 	/*
@@ -1934,7 +1888,7 @@ struct hwrm_ver_get_input {
 	uint8_t unused_0[5];
 } __attribute__((packed));
 
-/* Output (128 bytes) */
+/* Output	(128 bytes) */
 struct hwrm_ver_get_output {
 	uint16_t error_code;
 	/*
@@ -2004,7 +1958,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version of the HWRM
 	 * firmware.
 	 */
 	uint8_t mgmt_fw_maj;
@@ -2027,7 +1981,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint8_t netctrl_fw_maj;
 	/*
@@ -2050,7 +2004,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint32_t dev_caps_cfg;
 	/*
@@ -2062,13 +2016,27 @@ struct hwrm_ver_get_output {
 	 * supported. If set to 0, then secure firmware update behavior
 	 * is not supported.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  UINT32_C(0x1)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  \
+		UINT32_C(0x1)
 	/*
 	 * If set to 1, then firmware based DCBX agent is supported. If
 	 * set to 0, then firmware based DCBX agent capability is not
 	 * supported on this device.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, then HWRM short command format is supported. If
+	 * set to 0, then HWRM short command format is not supported.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED	 \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, then HWRM short command format is required. If
+	 * set to 0, then HWRM short command format is not required.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_INPUTUIRED	\
+		UINT32_C(0x8)
 	uint8_t roce_fw_maj;
 	/*
 	 * This field represents the major version of RoCE firmware. A
@@ -2089,22 +2057,22 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	char hwrm_fw_name[16];
 	/*
-	 * This field represents the name of HWRM FW (ASCII chars with
+	 * This field represents the name of HWRM FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char mgmt_fw_name[16];
 	/*
-	 * This field represents the name of mgmt FW (ASCII chars with
+	 * This field represents the name of mgmt FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char netctrl_fw_name[16];
 	/*
 	 * This field represents the name of network control firmware
-	 * (ASCII chars with NULL at the end).
+	 *	(ASCII chars with NULL at the end).
 	 */
 	uint32_t reserved2[4];
 	/*
@@ -2113,7 +2081,7 @@ struct hwrm_ver_get_output {
 	 */
 	char roce_fw_name[16];
 	/*
-	 * This field represents the name of RoCE FW (ASCII chars with
+	 * This field represents the name of RoCE FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	uint16_t chip_num;
@@ -2134,7 +2102,7 @@ struct hwrm_ver_get_output {
 	/* FPGA platform of the chip. */
 	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA	UINT32_C(0x1)
 	/* Palladium platform of the chip. */
-	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM	UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM UINT32_C(0x2)
 	uint16_t max_req_win_len;
 	/*
 	 * This field returns the maximum value of request window that
@@ -2164,7 +2132,7 @@ struct hwrm_ver_get_output {
 
 /* hwrm_func_reset */
 /*
- * Description: This command resets a hardware function (PCIe function) and
+ * 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
@@ -2176,7 +2144,7 @@ struct hwrm_ver_get_output {
  * idled. The command returns all the resources owned by the function so a new
  * driver may allocate and configure resources normally.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_reset_input {
 	uint16_t req_type;
 	/*
@@ -2218,7 +2186,7 @@ struct hwrm_func_reset_input {
 	/* This value indicates the level of a function reset. */
 	/*
 	 * Reset the caller function and its children
-	 * VFs (if any). If no children functions exist,
+	 * 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)
@@ -2231,7 +2199,8 @@ struct hwrm_func_reset_input {
 	 * 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)
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+		UINT32_C(0x2)
 	/*
 	 * Reset a specific VF of the caller function
 	 * driver if the caller is the parent PF driver.
@@ -2244,7 +2213,7 @@ struct hwrm_func_reset_input {
 	uint8_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_reset_output {
 	uint16_t error_code;
 	/*
@@ -2284,7 +2253,7 @@ struct hwrm_func_reset_output {
  * 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) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcaps_input {
 	uint16_t req_type;
 	/*
@@ -2315,12 +2284,12 @@ struct hwrm_func_qcaps_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (80 bytes) */
+/* Output	(80 bytes) */
 struct hwrm_func_qcaps_output {
 	uint16_t error_code;
 	/*
@@ -2345,54 +2314,56 @@ struct hwrm_func_qcaps_output {
 	uint16_t port_id;
 	/*
 	 * 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
+	 * 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.
 	 */
 	uint32_t flags;
 	/* If 1, then Push mode is supported on this function. */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED	UINT32_C(0x1)
+	#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)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING	 \
+		UINT32_C(0x2)
 	/*
-	 * If 1, then the Precision Time Protocol (PTP) processing is
+	 * 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.
+	 * only a single Physical Function	(PF) per port.
 	 */
 	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED	UINT32_C(0x4)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v1 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v1 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED	UINT32_C(0x8)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED UINT32_C(0x8)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v2 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v2 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED	UINT32_C(0x10)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED UINT32_C(0x10)
 	/*
 	 * If 1, then control and configuration of WoL magic packet are
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	UINT32_C(0x20)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	\
+		UINT32_C(0x20)
 	/*
 	 * If 1, then control and configuration of bitmap pattern packet
 	 * are supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED	UINT32_C(0x40)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED UINT32_C(0x40)
 	/*
 	 * If set to 1, then the control and configuration of rate limit
 	 * of an allocated TX ring on the queried function is supported.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED	UINT32_C(0x80)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED UINT32_C(0x80)
 	/*
 	 * If 1, then control and configuration of minimum and maximum
 	 * bandwidths are supported on the queried function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED	UINT32_C(0x100)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED UINT32_C(0x100)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -2401,7 +2372,8 @@ struct hwrm_func_qcaps_output {
 	 * set to 0, then the PF does not have the capability to set the
 	 * rate limits on the TX rings of its children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	UINT32_C(0x200)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	 \
+		UINT32_C(0x200)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -2411,7 +2383,17 @@ struct hwrm_func_qcaps_output {
 	 * capability to set the minimum or maximum bandwidths for its
 	 * children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED	UINT32_C(0x400)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED UINT32_C(0x400)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is supported on the
+	 * queried function. If set to 0, then standard TX ring mode is
+	 * not available on the queried function.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_STD_TX_RING_MODE_SUPPORTED   \
+		UINT32_C(0x800)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -2451,7 +2433,7 @@ struct hwrm_func_qcaps_output {
 	uint16_t first_vf_id;
 	/*
 	 * 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
+	 * 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.
 	 */
@@ -2459,7 +2441,7 @@ struct hwrm_func_qcaps_output {
 	/*
 	 * 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-
+	 * 0xFF...	(All Fs) if this command is called on a PF with SR-
 	 * IOV disabled or on a VF.
 	 */
 	uint16_t max_stat_ctx;
@@ -2479,22 +2461,22 @@ struct hwrm_func_qcaps_output {
 	 */
 	uint32_t max_tx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_tx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_rx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_rx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_mcast_filters;
@@ -2518,7 +2500,7 @@ struct hwrm_func_qcaps_output {
 	 * be allocated to the function. This number indicates the
 	 * maximum number of TX rings that can be assigned strict
 	 * priorities out of the maximum number of TX rings that can be
-	 * allocated (max_tx_rings) to the function.
+	 * allocated	(max_tx_rings) to the function.
 	 */
 	uint8_t unused_0;
 	uint8_t valid;
@@ -2539,9 +2521,13 @@ struct hwrm_func_qcaps_output {
  * 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.
+ * the PCI bus. This command should be called by every driver after
+ * 'hwrm_func_cfg' to get the actual number of resources allocated by the HWRM.
+ * The values returned by hwrm_func_qcfg are the values the driver shall use.
+ * These values may be different than what was originally requested in the
+ * 'hwrm_func_cfg' command.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcfg_input {
 	uint16_t req_type;
 	/*
@@ -2572,12 +2558,12 @@ struct hwrm_func_qcfg_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (72 bytes) */
+/* Output	(72 bytes) */
 struct hwrm_func_qcfg_output {
 	uint16_t error_code;
 	/*
@@ -2602,7 +2588,7 @@ struct hwrm_func_qcfg_output {
 	uint16_t port_id;
 	/*
 	 * Port ID of port that this function is associated with.
-	 * 0xFF... (All Fs) if this function is not associated with any
+	 * 0xFF...	(All Fs) if this function is not associated with any
 	 * port.
 	 */
 	uint16_t vlan;
@@ -2610,15 +2596,15 @@ struct hwrm_func_qcfg_output {
 	 * This value is the current VLAN setting for this function. The
 	 * value of 0 for this field indicates no priority tagging or
 	 * VLAN is used. This field's format is same as 802.1Q Tag's Tag
-	 * Control Information (TCI) format that includes both Priority
-	 * Code Point (PCP) and VLAN Identifier (VID).
+	 * Control Information	(TCI) format that includes both Priority
+	 * Code Point	(PCP) and VLAN Identifier	(VID).
 	 */
 	uint16_t flags;
 	/*
 	 * If 1, then magic packet based Out-Of-Box WoL is enabled on
 	 * the port associated with this function.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	 \
 		UINT32_C(0x1)
 	/*
 	 * If 1, then bitmap pattern based Out-Of-Box WoL packet is
@@ -2630,8 +2616,27 @@ struct hwrm_func_qcfg_output {
 	 * on the port associated with this function. If set to 0, then
 	 * DCBX agent is not running in the firmware.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED \
 		UINT32_C(0x4)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is enabled on the
+	 * queried function. If set to 0, then the standard TX ring mode
+	 * is disabled on the queried function. In this extended TX ring
+	 * resource mode, the minimum and maximum bandwidth settings are
+	 * not supported to allow the allocation of TX rings to span
+	 * multiple scheduler nodes.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_STD_TX_RING_MODE_ENABLED	 \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1 then FW based LLDP agent is enabled and running
+	 * on the port associated with this function. If set to 0 then
+	 * the LLDP agent is not running in the firmware.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED UINT32_C(0x10)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -2641,8 +2646,8 @@ struct hwrm_func_qcfg_output {
 	uint16_t pci_id;
 	/*
 	 * This value is current PCI ID of this function. If ARI is
-	 * enabled, then it is Bus Number (8b):Function Number(8b).
-	 * Otherwise, it is Bus Number (8b):Device Number (4b):Function
+	 * enabled, then it is Bus Number	(8b):Function Number(8b).
+	 * Otherwise, it is Bus Number	(8b):Device Number	(4b):Function
 	 * Number(4b).
 	 */
 	uint16_t alloc_rsscos_ctx;
@@ -2696,17 +2701,13 @@ struct hwrm_func_qcfg_output {
 	/* Multiple physical functions */
 	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS	UINT32_C(0x1)
 	/* Network Partitioning 1.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0	\
-		UINT32_C(0x2)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 UINT32_C(0x2)
 	/* Network Partitioning 1.5 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5	\
-		UINT32_C(0x3)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 UINT32_C(0x3)
 	/* Network Partitioning 2.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0	\
-		UINT32_C(0x4)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 UINT32_C(0x4)
 	/* Unknown */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN	\
-		UINT32_C(0xff)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN UINT32_C(0xff)
 	uint8_t unused_0;
 	uint16_t dflt_vnic_id;
 	/* The default VNIC ID assigned to a function that is being queried. */
@@ -2719,26 +2720,41 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * the minimum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID
 	uint32_t max_bw;
 	/*
@@ -2747,43 +2763,58 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * that the maximum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID
 	uint8_t evb_mode;
 	/*
 	 * This value indicates the Edge virtual bridge mode for the
 	 * domain that this function belongs to.
 	 */
-	/* No Edge Virtual Bridging (EVB) */
+	/* No Edge Virtual Bridging	(EVB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
-	/* Virtual Ethernet Bridge (VEB) */
+	/* Virtual Ethernet Bridge	(VEB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB	UINT32_C(0x1)
-	/* Virtual Ethernet Port Aggregator (VEPA) */
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA	UINT32_C(0x2)
 	uint8_t unused_3;
 	uint16_t alloc_vfs;
 	/*
 	 * The number of VFs that are allocated to the function. This is
-	 * valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if
+	 * 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.
 	 */
@@ -2797,7 +2828,7 @@ struct hwrm_func_qcfg_output {
 	uint16_t alloc_sp_tx_rings;
 	/*
 	 * The number of strict priority transmit rings out of currently
-	 * allocated TX rings to the function (alloc_tx_rings).
+	 * allocated TX rings to the function	(alloc_tx_rings).
 	 */
 	uint8_t unused_4;
 	uint8_t valid;
@@ -3068,8 +3099,7 @@ struct hwrm_func_cfg_input {
 	 * for the scheduler inside the device.
 	 */
 	/* The bandwidth value. */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT	0
 	/* The granularity of the value	(bits or bytes). */
 	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
@@ -3084,22 +3114,22 @@ struct hwrm_func_cfg_input {
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
 	/* Value is in Mb or MB	(base 10). */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA	\
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
 	/* Value is in Kb or KB	(base 10). */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO	\
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO \
 		(UINT32_C(0x2) << 29)
 	/* Value is in bits or bytes. */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE	\
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE \
 		(UINT32_C(0x4) << 29)
 	/* Value is in Gb or GB	(base 10). */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA	\
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
 		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
 	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
 	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
 		FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
@@ -3110,7 +3140,7 @@ struct hwrm_func_cfg_input {
 	 * for the scheduler inside the device.
 	 */
 	/* The bandwidth value. */
-	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK	\
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK \
 		UINT32_C(0xfffffff)
 	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT	0
 	/* The granularity of the value	(bits or bytes). */
@@ -3132,16 +3162,16 @@ struct hwrm_func_cfg_input {
 	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
 		(UINT32_C(0x2) << 29)
 	/* Value is in bits or bytes. */
-	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
 		(UINT32_C(0x4) << 29)
 	/* Value is in Gb or GB	(base 10). */
-	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
 		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
 	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
 	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
@@ -3379,10 +3409,15 @@ struct hwrm_func_qstats_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_stat_ctx_query */
-/* Description: This command returns statistics of a context. */
+/* hwrm_func_clr_stats */
+/*
+ * Description: This command clears statistics of a function. The input FID
+ * value is used to indicate what function's statistics is being cleared. This
+ * allows a physical function driver to clear statistics of virtual functions
+ * that are children of the physical function.
+ */
 /* Input	(24 bytes) */
-struct hwrm_stat_ctx_query_input {
+struct hwrm_func_clr_stats_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -3409,13 +3444,16 @@ struct hwrm_stat_ctx_query_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint16_t fid;
+	/*
+	 * Function ID of the function. 0xFF...	(All Fs) if the query is
+	 * for the requesting function.
+	 */
+	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output	(176 bytes) */
-struct hwrm_stat_ctx_query_output {
+/* Output	(16 bytes) */
+struct hwrm_func_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3431,46 +3469,6 @@ struct hwrm_stat_ctx_query_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint64_t tx_ucast_pkts;
-	/* Number of transmitted unicast packets */
-	uint64_t tx_mcast_pkts;
-	/* Number of transmitted multicast packets */
-	uint64_t tx_bcast_pkts;
-	/* Number of transmitted broadcast packets */
-	uint64_t tx_err_pkts;
-	/* Number of transmitted packets with error */
-	uint64_t tx_drop_pkts;
-	/* Number of dropped packets on transmit path */
-	uint64_t tx_ucast_bytes;
-	/* Number of transmitted bytes for unicast traffic */
-	uint64_t tx_mcast_bytes;
-	/* Number of transmitted bytes for multicast traffic */
-	uint64_t tx_bcast_bytes;
-	/* Number of transmitted bytes for broadcast traffic */
-	uint64_t rx_ucast_pkts;
-	/* Number of received unicast packets */
-	uint64_t rx_mcast_pkts;
-	/* Number of received multicast packets */
-	uint64_t rx_bcast_pkts;
-	/* Number of received broadcast packets */
-	uint64_t rx_err_pkts;
-	/* Number of received packets with error */
-	uint64_t rx_drop_pkts;
-	/* Number of dropped packets on received path */
-	uint64_t rx_ucast_bytes;
-	/* Number of received bytes for unicast traffic */
-	uint64_t rx_mcast_bytes;
-	/* Number of received bytes for multicast traffic */
-	uint64_t rx_bcast_bytes;
-	/* Number of received bytes for broadcast traffic */
-	uint64_t rx_agg_pkts;
-	/* Number of aggregated unicast packets */
-	uint64_t rx_agg_bytes;
-	/* Number of aggregated unicast bytes */
-	uint64_t rx_agg_events;
-	/* Number of aggregation events */
-	uint64_t rx_agg_aborts;
-	/* Number of aborted aggregations */
 	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
@@ -3486,15 +3484,10 @@ struct hwrm_stat_ctx_query_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_func_clr_stats */
-/*
- * Description: This command clears statistics of a function. The input FID
- * value is used to indicate what function's statistics is being cleared. This
- * allows a physical function driver to clear statistics of virtual functions
- * that are children of the physical function.
- */
-/* Input	(24 bytes) */
-struct hwrm_func_clr_stats_input {
+/* hwrm_func_vf_vnic_ids_query */
+/* Description: This command is used to query vf vnic ids. */
+/* Input	(32 bytes) */
+struct hwrm_func_vf_vnic_ids_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -3521,87 +3514,17 @@ struct hwrm_func_clr_stats_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint16_t fid;
+	uint16_t vf_id;
 	/*
-	 * Function ID of the function. 0xFF...	(All Fs) if the query is
-	 * for the requesting function.
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
 	 */
-	uint16_t unused_0[3];
-} __attribute__((packed));
-
-/* Output	(16 bytes) */
-struct hwrm_func_clr_stats_output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t valid;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
-/* hwrm_func_vf_vnic_ids_query */
-/* Description: This command is used to query vf vnic ids. */
-/* Input	(32 bytes) */
-struct hwrm_func_vf_vnic_ids_query_input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint16_t vf_id;
-	/*
-	 * This value is used to identify a Virtual Function	(VF). The
-	 * scope of VF ID is local within a PF.
-	 */
-	uint8_t unused_0;
-	uint8_t unused_1;
-	uint32_t max_vnic_id_cnt;
-	/* Max number of vnic ids in vnic id table */
-	uint64_t vnic_id_tbl_addr;
-	/* This is the address for VF VNIC ID table */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_vnic_id_cnt;
+	/* Max number of vnic ids in vnic id table */
+	uint64_t vnic_id_tbl_addr;
+	/* This is the address for VF VNIC ID table */
 } __attribute__((packed));
 
 /* Output	(16 bytes) */
@@ -3647,7 +3570,7 @@ struct hwrm_func_vf_vnic_ids_query_output {
  * function driver shall use this command during the driver initialization right
  * after the HWRM version discovery and default ring resources allocation.
  */
-/* Input (80 bytes) */
+/* Input	(80 bytes) */
 struct hwrm_func_drv_rgtr_input {
 	uint16_t req_type;
 	/*
@@ -3705,7 +3628,10 @@ struct hwrm_func_drv_rgtr_input {
 	 */
 	#define HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD	UINT32_C(0x10)
 	uint16_t os_type;
-	/* This value indicates the type of OS. */
+	/*
+	 * This value indicates the type of OS. The values are based on
+	 * CIM_OperatingSystem.mof file as published by the DMTF.
+	 */
 	/* Unknown */
 	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
 	/* Other OS not listed below. */
@@ -3753,17 +3679,17 @@ struct hwrm_func_drv_rgtr_input {
 	uint32_t async_event_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
+	 *	(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
+	 * 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.
 	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_drv_rgtr_output {
 	uint16_t error_code;
 	/*
@@ -3801,7 +3727,7 @@ struct hwrm_func_drv_rgtr_output {
  * the HWRM. A function driver shall implement this command. A function driver
  * shall use this command during the driver unloading.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_drv_unrgtr_input {
 	uint16_t req_type;
 	/*
@@ -3834,11 +3760,12 @@ struct hwrm_func_drv_unrgtr_input {
 	 * 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)
+	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN	\
+		UINT32_C(0x1)
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_drv_unrgtr_output {
 	uint16_t error_code;
 	/*
@@ -4165,9 +4092,9 @@ struct hwrm_func_vf_cfg_output {
 	/* This field provides original sequence number of the command. */
 	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
 	uint32_t unused_0;
 	uint8_t unused_1;
@@ -4192,7 +4119,7 @@ struct hwrm_func_vf_cfg_output {
  * 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) */
+/* Input	(56 bytes) */
 struct hwrm_port_phy_cfg_input {
 	uint16_t req_type;
 	/*
@@ -4232,19 +4159,8 @@ struct hwrm_port_phy_cfg_input {
 	 * 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)
+	/* deprecated bit. Do not use!!! */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_DEPRECATED	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
@@ -4262,14 +4178,14 @@ struct hwrm_port_phy_cfg_input {
 	 */
 	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG	UINT32_C(0x8)
 	/*
-	 * When this bit is set to '1', Energy Efficient Ethernet (EEE)
+	 * 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)
+	 * 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.
@@ -4304,35 +4220,53 @@ struct hwrm_port_phy_cfg_input {
 	 * then this flag shall be ignored. If FEC autonegotiation is
 	 * not supported, then the HWRM shall ignore this flag.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	UINT32_C(0x200)
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	\
+		UINT32_C(0x200)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74 (Fire
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74	(Fire
 	 * Code) on this port if supported. When set to 0, then this
 	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
 	 * then the HWRM shall ignore this flag.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	UINT32_C(0x400)
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	\
+		UINT32_C(0x400)
 	/*
 	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
-	 * (Fire Code) on this port if supported. When set to 0, then
+	 *	(Fire Code) on this port if supported. When set to 0, then
 	 * this flag shall be ignored. If FEC CLAUSE 74 is not
 	 * supported, then the HWRM shall ignore this flag.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	UINT32_C(0x800)
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	\
+		UINT32_C(0x800)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91 (Reed
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91	(Reed
 	 * Solomon) on this port if supported. When set to 0, then this
 	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
 	 * then the HWRM shall ignore this flag.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	UINT32_C(0x1000)
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	\
+		UINT32_C(0x1000)
 	/*
 	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
-	 * (Reed Solomon) on this port if supported. When set to 0, then
+	 *	(Reed Solomon) on this port if supported. When set to 0, then
 	 * this flag shall be ignored. If FEC CLAUSE 91 is not
 	 * supported, then the HWRM shall ignore this flag.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	UINT32_C(0x2000)
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	\
+		UINT32_C(0x2000)
+	/*
+	 * 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_DWN UINT32_C(0x4000)
 	uint32_t enables;
 	/* 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)
@@ -4349,7 +4283,8 @@ struct hwrm_port_phy_cfg_input {
 	 * 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)
+	#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_WIOUTPUTEED	UINT32_C(0x20)
 	/* This bit must be '1' for the lpbk field to be configured. */
@@ -4362,7 +4297,8 @@ struct hwrm_port_phy_cfg_input {
 	 * 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)
+	#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)
 	uint16_t port_id;
@@ -4500,34 +4436,42 @@ struct hwrm_port_phy_cfg_input {
 	 * 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) */
+	/* 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
 	uint8_t wirespeed;
 	/* This value controls the wirespeed feature. */
 	/* Wirespeed feature is disabled. */
@@ -4570,7 +4514,7 @@ struct hwrm_port_phy_cfg_input {
 	uint32_t preemphasis;
 	/*
 	 * This value controls the pre-emphasis to be used for the link.
-	 * Driver should not set this value (use enable.preemphasis = 0)
+	 * Driver should not set this value	(use enable.preemphasis = 0)
 	 * unless driver is sure of setting. Normally HWRM FW will
 	 * determine proper pre-emphasis.
 	 */
@@ -4585,16 +4529,16 @@ struct hwrm_port_phy_cfg_input {
 	 */
 	/* Reserved */
 	#define HWRM_PORT_PHY_CFG_INPUT_EEE_LINK_SPEED_MASK_RSVD1	UINT32_C(0x1)
-	/* 100Mb link speed (Full-duplex) */
+	/* 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) */
+	/* 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)
+	#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)
+	#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)
 	uint8_t unused_2;
@@ -4605,11 +4549,11 @@ struct hwrm_port_phy_cfg_input {
 	 * 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_MASK UINT32_C(0xffffff)
 	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT	0
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_port_phy_cfg_output {
 	uint16_t error_code;
 	/*
@@ -4643,7 +4587,7 @@ struct hwrm_port_phy_cfg_output {
 
 /* hwrm_port_phy_qcfg */
 /* Description: This command queries the PHY configuration for the port. */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_port_phy_qcfg_input {
 	uint16_t req_type;
 	/*
@@ -4676,7 +4620,7 @@ struct hwrm_port_phy_qcfg_input {
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (96 bytes) */
+/* Output	(96 bytes) */
 struct hwrm_port_phy_qcfg_output {
 	uint16_t error_code;
 	/*
@@ -4754,50 +4698,47 @@ struct hwrm_port_phy_qcfg_output {
 	 * 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) */
+	/* 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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_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)
+	/* 10Mb link speed	(Full-duplex) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_10MB UINT32_C(0x2000)
 	uint16_t force_link_speed;
 	/*
 	 * 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)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB UINT32_C(0x1)
 	/* 1Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
 	/* 2Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
 	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB	\
-		UINT32_C(0x19)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
 	/* 10Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
 	/* 20Mb link speed */
@@ -4805,14 +4746,13 @@ struct hwrm_port_phy_qcfg_output {
 	/* 25Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
 	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB UINT32_C(0x190)
 	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB UINT32_C(0x1f4)
 	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB	\
-		UINT32_C(0x3e8)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
 	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB UINT32_C(0xffff)
 	uint8_t auto_mode;
 	/* Current setting of auto negotiation mode. */
 	/*
@@ -4834,8 +4774,7 @@ struct hwrm_port_phy_qcfg_output {
 	 * DEPRECATED. An HWRM client should not use
 	 * this mode.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW	\
-		UINT32_C(0x3)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW UINT32_C(0x3)
 	/*
 	 * Select the speeds based on the corresponding
 	 * link speed mask value that is provided.
@@ -4869,8 +4808,7 @@ struct hwrm_port_phy_qcfg_output {
 	 * 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)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE UINT32_C(0x4)
 	uint16_t auto_link_speed;
 	/*
 	 * Current setting for auto_link_speed. This field is only valid
@@ -4895,9 +4833,9 @@ struct hwrm_port_phy_qcfg_output {
 	/* 50Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
 	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
 	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB UINT32_C(0xffff)
 	uint16_t auto_link_speed_mask;
 	/*
 	 * Current setting for auto_link_speed_mask that is used to
@@ -4906,23 +4844,22 @@ struct hwrm_port_phy_qcfg_output {
 	 * in this field shall be a subset of supported speeds on this
 	 * port.
 	 */
-	/* 100Mb link speed (Half-duplex) */
+	/* 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	\
+	/* 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	\
+	/* 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)
+	/* 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	\
+	#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	\
@@ -4940,12 +4877,12 @@ struct hwrm_port_phy_qcfg_output {
 	#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	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_100GB	 \
 		UINT32_C(0x800)
-	/* 10Mb link speed (Half-duplex) */
+	/* 10Mb link speed	(Half-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MBHD	\
 		UINT32_C(0x1000)
-	/* 10Mb link speed (Full-duplex) */
+	/* 10Mb link speed	(Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_MASK_10MB	\
 		UINT32_C(0x2000)
 	uint8_t wirespeed;
@@ -4994,18 +4931,16 @@ struct hwrm_port_phy_qcfg_output {
 	/* Module is inserted and accepted */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE	UINT32_C(0x0)
 	/* Module is rejected and transmit side Laser is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX	\
-		UINT32_C(0x1)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX UINT32_C(0x1)
 	/* Module mismatch warning. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG	\
-		UINT32_C(0x2)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG UINT32_C(0x2)
 	/* Module is rejected and powered down. */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
 	/* Module is not inserted. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
 		UINT32_C(0x4)
 	/* Module status is not applicable. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
 		UINT32_C(0xff)
 	uint32_t preemphasis;
 	/* Current setting for preemphasis. */
@@ -5021,13 +4956,13 @@ struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
 	/* BASE-CR */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
-	/* BASE-KR4 (Deprecated) */
+	/* BASE-KR4	(Deprecated) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
 	/* BASE-LR */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
 	/* BASE-SR */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
-	/* BASE-KR2 (Deprecated) */
+	/* BASE-KR2	(Deprecated) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
 	/* BASE-KX */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
@@ -5039,6 +4974,35 @@ struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
 	/* SGMII connected external PHY */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
+	/* 25G_BASECR_CA_L */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L UINT32_C(0xb)
+	/* 25G_BASECR_CA_S */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S UINT32_C(0xc)
+	/* 25G_BASECR_CA_N */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N UINT32_C(0xd)
+	/* 25G_BASESR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR	UINT32_C(0xe)
+	/* 100G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4	UINT32_C(0xf)
+	/* 100G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4	UINT32_C(0x10)
+	/* 100G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4	UINT32_C(0x11)
+	/* 100G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4	UINT32_C(0x12)
+	/* 100G_BASESR10 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10 UINT32_C(0x13)
+	/* 40G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4	UINT32_C(0x14)
+	/* 40G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4	UINT32_C(0x15)
+	/* 40G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4	UINT32_C(0x16)
+	/* 40G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4	UINT32_C(0x17)
+	/* 40G_ACTIVE_CABLE */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE \
+		UINT32_C(0x18)
 	uint8_t media_type;
 	/* This value represents a media type. */
 	/* Unknown */
@@ -5052,35 +5016,34 @@ struct hwrm_port_phy_qcfg_output {
 	uint8_t xcvr_pkg_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	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_INTERNAL \
 		UINT32_C(0x1)
 	/* PHY and MAC are in different packages */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
 		UINT32_C(0x2)
 	uint8_t eee_config_phy_addr;
 	/*
 	 * 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
+	 * 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
+	 * 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)
+	#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
+	 * 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
+	 * 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)
@@ -5088,16 +5051,16 @@ struct hwrm_port_phy_qcfg_output {
 	 * 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
+	 * 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.
+	 *	(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
+	 * 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)
@@ -5119,16 +5082,16 @@ struct hwrm_port_phy_qcfg_output {
 	 * The advertised speeds for the port by the link partner. Each
 	 * advertised speed will be set to '1'.
 	 */
-	/* 100Mb link speed (Half-duplex) */
+	/* 100Mb link speed	(Half-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MBHD \
 		UINT32_C(0x1)
-	/* 100Mb link speed (Full-duplex) */
+	/* 100Mb link speed	(Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100MB   \
 		UINT32_C(0x2)
-	/* 1Gb link speed (Half-duplex) */
+	/* 1Gb link speed	(Half-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GBHD   \
 		UINT32_C(0x4)
-	/* 1Gb link speed (Full-duplex) */
+	/* 1Gb link speed	(Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_1GB	\
 		UINT32_C(0x8)
 	/* 2Gb link speed */
@@ -5155,10 +5118,10 @@ struct hwrm_port_phy_qcfg_output {
 	/* 100Gb link speed */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_100GB   \
 		UINT32_C(0x800)
-	/* 10Mb link speed (Half-duplex) */
+	/* 10Mb link speed	(Half-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MBHD  \
 		UINT32_C(0x1000)
-	/* 10Mb link speed (Full-duplex) */
+	/* 10Mb link speed	(Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_10MB	\
 		UINT32_C(0x2000)
 	uint8_t link_partner_adv_auto_mode;
@@ -5175,13 +5138,14 @@ struct hwrm_port_phy_qcfg_output {
 	/* Select all possible speeds for autoneg mode. */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
-	UINT32_C(0x1)
+		UINT32_C(0x1)
 	/*
 	 * 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 \
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
 		UINT32_C(0x2)
 	/*
 	 * Select the auto_link_speed or any speed below
@@ -5191,14 +5155,14 @@ struct hwrm_port_phy_qcfg_output {
 	 */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
-	UINT32_C(0x3)
+		UINT32_C(0x3)
 	/*
 	 * 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)
+		UINT32_C(0x4)
 	uint8_t link_partner_adv_pause;
 	/* The advertised pause settings on the port by the link partner. */
 	/*
@@ -5224,13 +5188,13 @@ struct hwrm_port_phy_qcfg_output {
 	/* Reserved */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_RSVD1   \
 		UINT32_C(0x1)
-	/* 100Mb link speed (Full-duplex) */
+	/* 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) */
+	/* 1Gb link speed	(Full-duplex) */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_ADV_EEE_LINK_SPEED_MASK_1GB	\
 		UINT32_C(0x8)
 	/* Reserved */
@@ -5251,31 +5215,31 @@ struct hwrm_port_phy_qcfg_output {
 	/* Reserved */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD1 \
-	UINT32_C(0x1)
-	/* 100Mb link speed (Full-duplex) */
+		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)
+		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) */
+		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)
+		UINT32_C(0x8)
 	/* Reserved */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD3 \
-	UINT32_C(0x10)
+		UINT32_C(0x10)
 	/* Reserved */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_RSVD4 \
-	UINT32_C(0x20)
+		UINT32_C(0x20)
 	/* 10Gb link speed */
 	#define \
 	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
-	UINT32_C(0x40)
+		UINT32_C(0x40)
 	uint32_t xcvr_identifier_type_tx_lpi_timer;
 	/* This value represents transceiver identifier type. */
 	/*
@@ -5283,32 +5247,31 @@ struct hwrm_port_phy_qcfg_output {
 	 * 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_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   \
+	#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	\
+	#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	\
+	#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  \
+	#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	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \
 		(UINT32_C(0x11) << 24)
 	uint16_t fec_cfg;
 	/*
 	 * This value represents the current configuration of Forward
-	 * Error Correction (FEC) on the port.
+	 * Error Correction	(FEC) on the port.
 	 */
 	/*
 	 * When set to 1, then FEC is not supported on this port. If
@@ -5319,7 +5282,7 @@ struct hwrm_port_phy_qcfg_output {
 	 * then the HWRM shall set this flag to 1 when reporting FEC
 	 * capability.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	\
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	 \
 		UINT32_C(0x1)
 	/*
 	 * When set to 1, then FEC autonegotiation is supported on this
@@ -5337,30 +5300,30 @@ struct hwrm_port_phy_qcfg_output {
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
 		UINT32_C(0x4)
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is supported on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is supported on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
 	 * not supported on this port.
 	 */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
 		UINT32_C(0x8)
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is enabled on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is enabled on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
 	 * disabled if supported. This flag should be ignored if FEC
 	 * CLAUSE 74 is not supported on this port.
 	 */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
 		UINT32_C(0x10)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is supported
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is supported
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
 	 * Solomon) is not supported on this port.
 	 */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
 		UINT32_C(0x20)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is enabled
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is enabled
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
 	 * Solomon) is disabled if supported. This flag should be
 	 * ignored if FEC CLAUSE 91 is not supported on this port.
 	 */
@@ -5545,7 +5508,6 @@ struct hwrm_port_clr_stats_output {
 	 */
 } __attribute__((packed));
 
-
 /* hwrm_queue_qportcfg */
 /*
  * Description: This function is called by a driver to query queue configuration
@@ -5557,7 +5519,7 @@ struct hwrm_port_clr_stats_output {
  * then the driver shall only use queues for which service profiles are pre-
  * configured.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_queue_qportcfg_input {
 	uint16_t req_type;
 	/*
@@ -5596,7 +5558,7 @@ struct hwrm_queue_qportcfg_input {
 	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX	UINT32_C(0x0)
 	/* rx path */
 	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST	\
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
 		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
 	uint16_t port_id;
 	/*
@@ -5606,7 +5568,7 @@ struct hwrm_queue_qportcfg_input {
 	uint16_t unused_0;
 } __attribute__((packed));
 
-/* Output (32 bytes) */
+/* Output	(32 bytes) */
 struct hwrm_queue_qportcfg_output {
 	uint16_t error_code;
 	/*
@@ -5655,18 +5617,18 @@ struct hwrm_queue_qportcfg_output {
 	 * TX side is the same as the corresponding queue configuration
 	 * on the RX side.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG	\
-		UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG UINT32_C(0x1)
 	uint8_t queue_pfcenable_cfg_allowed;
 	/*
 	 * Bitmask indicating which queues can be configured by the
 	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pfcenable_cfg command.
-	 * # A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pfcenable_cfg command shall return error when
-	 * trying to configure a queue that is not configurable.
+	 * specific priority where bit 0 represents priority 0 and bit 7
+	 * represents priority 7. # A value of 0 indicates that the
+	 * priority is not configurable by the hwrm_queue_pfcenable_cfg
+	 * command. # A value of 1 indicates that the priority is
+	 * configurable. # A hwrm_queue_pfcenable_cfg command shall
+	 * return error when trying to configure a priority that is not
+	 * configurable.
 	 */
 	uint8_t queue_pri2cos_cfg_allowed;
 	/*
@@ -5702,14 +5664,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id0_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
@@ -5726,14 +5688,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id1_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
@@ -5750,14 +5712,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id2_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
@@ -5774,14 +5736,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id3_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
@@ -5798,14 +5760,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id4_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
@@ -5822,14 +5784,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id5_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
@@ -5846,14 +5808,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id6_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
@@ -5870,14 +5832,14 @@ struct hwrm_queue_qportcfg_output {
 	 */
 	uint8_t queue_id7_service_profile;
 	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
+	/* Lossy	(best-effort) */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
 		UINT32_C(0x0)
 	/* Lossless */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
+	 * Set to 0xFF...	(All Fs) if there is no
 	 * service profile specified
 	 */
 	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
@@ -5910,7 +5872,7 @@ struct hwrm_queue_qportcfg_output {
  * enabled, then the internal VNIC to SVIF mapping data structures shall be
  * programmed at the time of VNIC allocation.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_vnic_alloc_input {
 	uint16_t req_type;
 	/*
@@ -5947,7 +5909,7 @@ struct hwrm_vnic_alloc_input {
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_alloc_output {
 	uint16_t error_code;
 	/*
@@ -5986,7 +5948,7 @@ struct hwrm_vnic_alloc_output {
  * VNIC as well as the VNIC. Reset and release all resources associated with the
  * VNIC.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_vnic_free_input {
 	uint16_t req_type;
 	/*
@@ -6019,7 +5981,7 @@ struct hwrm_vnic_free_input {
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_free_output {
 	uint16_t error_code;
 	/*
@@ -6053,7 +6015,7 @@ struct hwrm_vnic_free_output {
 
 /* hwrm_vnic_cfg */
 /* Description: Configure the RX VNIC structure. */
-/* Input (40 bytes) */
+/* Input	(40 bytes) */
 struct hwrm_vnic_cfg_input {
 	uint16_t req_type;
 	/*
@@ -6113,10 +6075,10 @@ struct hwrm_vnic_cfg_input {
 	 * 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)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE UINT32_C(0x10)
 	/*
 	 * When a VNIC uses one destination ring group for certain
-	 * application (e.g. Receive Flow Steering) where exact match is
+	 * application	(e.g. Receive Flow Steering) where exact match is
 	 * used to direct packets to a VNIC with one destination ring
 	 * group only, there is no need to configure RSS indirection
 	 * table for that VNIC as only one destination ring group is
@@ -6152,17 +6114,17 @@ struct hwrm_vnic_cfg_input {
 	 */
 	uint16_t rss_rule;
 	/*
-	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
 	 * there is no RSS rule.
 	 */
 	uint16_t cos_rule;
 	/*
-	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
 	 * there is no COS rule.
 	 */
 	uint16_t lb_rule;
 	/*
-	 * RSS ID for load balancing rule/table structure. 0xFF... (All
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
 	 * Fs) if there is no LB rule.
 	 */
 	uint16_t mru;
@@ -6176,7 +6138,7 @@ struct hwrm_vnic_cfg_input {
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_cfg_output {
 	uint16_t error_code;
 	/*
@@ -6354,7 +6316,7 @@ struct hwrm_vnic_qcfg_output {
 
 /* hwrm_vnic_rss_cfg */
 /* Description: This function is used to enable RSS configuration. */
-/* Input (48 bytes) */
+/* Input	(48 bytes) */
 struct hwrm_vnic_rss_cfg_input {
 	uint16_t req_type;
 	/*
@@ -6427,7 +6389,7 @@ struct hwrm_vnic_rss_cfg_input {
 	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_rss_cfg_output {
 	uint16_t error_code;
 	/*
@@ -6746,10 +6708,8 @@ struct hwrm_vnic_plcmodes_qcfg_output {
 } __attribute__((packed));
 
 /* hwrm_vnic_rss_cos_lb_ctx_alloc */
-/*
- * Description: This function is used to allocate COS/Load Balance context.
- */
-/* Input (16 bytes) */
+/* Description: This function is used to allocate COS/Load Balance context. */
+/* Input	(16 bytes) */
 struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	uint16_t req_type;
 	/*
@@ -6779,7 +6739,7 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	uint16_t error_code;
 	/*
@@ -6816,7 +6776,7 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 
 /* hwrm_vnic_rss_cos_lb_ctx_free */
 /* Description: This function can be used to free COS/Load Balance context. */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_vnic_rss_cos_lb_ctx_free_input {
 	uint16_t req_type;
 	/*
@@ -6849,7 +6809,7 @@ struct hwrm_vnic_rss_cos_lb_ctx_free_input {
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_vnic_rss_cos_lb_ctx_free_output {
 	uint16_t error_code;
 	/*
@@ -7057,11 +7017,12 @@ struct hwrm_vnic_tpa_cfg_output {
 	 */
 } __attribute__((packed));
 
+
 /* hwrm_ring_alloc */
 /*
  * Description: This command allocates and does basic preparation for a ring.
  */
-/* Input (80 bytes) */
+/* Input	(80 bytes) */
 struct hwrm_ring_alloc_input {
 	uint16_t req_type;
 	/*
@@ -7107,12 +7068,14 @@ struct hwrm_ring_alloc_input {
 	#define HWRM_RING_ALLOC_INPUT_ENABLES_MAX_BW_VALID	UINT32_C(0x20)
 	uint8_t ring_type;
 	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
 	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
+	/* RX Ring	(RR) */
 	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
 	uint8_t unused_0;
 	uint16_t unused_1;
 	uint64_t page_tbl_addr;
@@ -7175,23 +7138,22 @@ struct hwrm_ring_alloc_input {
 	 * a TX ring.
 	 */
 	/* Arbitration policy used for the ring. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK	\
-		UINT32_C(0xf)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK UINT32_C(0xf)
 	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
 	/*
 	 * Use strict priority for the TX ring. Priority
 	 * value is specified in arb_policy_param
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP	\
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP \
 		(UINT32_C(0x1) << 0)
 	/*
 	 * Use weighted fair queue arbitration for the
 	 * TX ring. Weight is specified in
 	 * arb_policy_param
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ	\
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ \
 		(UINT32_C(0x2) << 0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST	\
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST \
 		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
 	/* Reserved field. */
 	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
@@ -7208,7 +7170,7 @@ struct hwrm_ring_alloc_input {
 	 */
 	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
 		UINT32_C(0xff00)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT   8
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT	8
 	uint8_t unused_6;
 	uint8_t unused_7;
 	uint32_t reserved3;
@@ -7228,26 +7190,40 @@ struct hwrm_ring_alloc_input {
 	 * translate this value into byte counter and time interval used
 	 * for this ring inside the device.
 	 */
-	/* Bandwidth value */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES (UINT32_C(0x1) << 28)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_LAST \
+		RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
 	uint8_t int_mode;
 	/*
@@ -7267,7 +7243,7 @@ struct hwrm_ring_alloc_input {
 	uint8_t unused_8[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_ring_alloc_output {
 	uint16_t error_code;
 	/*
@@ -7308,8 +7284,16 @@ struct hwrm_ring_alloc_output {
 /* hwrm_ring_free */
 /*
  * Description: This command is used to free a ring and associated resources.
+ * With QoS and DCBx agents, it is possible the traffic classes will be moved
+ * from one CoS queue to another. When this occurs, the driver shall call
+ * 'hwrm_ring_free' to free the allocated rings and then call 'hwrm_ring_alloc'
+ * to re-allocate each ring and assign it to a new CoS queue. hwrm_ring_free
+ * shall be called on a ring only after it has been idle for 500ms or more and
+ * no frames have been posted to the ring during this time. All frames queued
+ * for transmission shall be completed and at least 500ms time elapsed from the
+ * last completion before calling this command.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ring_free_input {
 	uint16_t req_type;
 	/*
@@ -7339,19 +7323,21 @@ struct hwrm_ring_free_input {
 	 */
 	uint8_t ring_type;
 	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
 	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
+	/* RX Ring	(RR) */
 	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
 	uint8_t unused_0;
 	uint16_t ring_id;
 	/* Physical number of ring allocated. */
 	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_ring_free_output {
 	uint16_t error_code;
 	/*
@@ -7387,7 +7373,7 @@ struct hwrm_ring_free_output {
 /*
  * Description: This API allocates and does basic preparation for a ring group.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ring_grp_alloc_input {
 	uint16_t req_type;
 	/*
@@ -7422,7 +7408,7 @@ struct hwrm_ring_grp_alloc_input {
 	uint16_t ar;
 	/*
 	 * This value identifies the aggregation RR associated with the
-	 * ring group. If this value is 0xFF... (All Fs), then no
+	 * ring group. If this value is 0xFF...	(All Fs), then no
 	 * Aggregation ring will be set.
 	 */
 	uint16_t sc;
@@ -7432,7 +7418,7 @@ struct hwrm_ring_grp_alloc_input {
 	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_ring_grp_alloc_output {
 	uint16_t error_code;
 	/*
@@ -7478,7 +7464,7 @@ struct hwrm_ring_grp_alloc_output {
  * a part of executing this command, the HWRM shall reset all associated ring
  * group resources.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ring_grp_free_input {
 	uint16_t req_type;
 	/*
@@ -7511,7 +7497,7 @@ struct hwrm_ring_grp_free_input {
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_ring_grp_free_output {
 	uint16_t error_code;
 	/*
@@ -7545,12 +7531,61 @@ struct hwrm_ring_grp_free_output {
 
 /* hwrm_cfa_l2_filter_alloc */
 /*
- * A filter is used to identify traffic that contains a matching set of
- * parameters like unicast or broadcast MAC address or a VLAN tag amongst
- * other things which then allows the ASIC to direct the  incoming traffic
- * to an appropriate VNIC or Rx ring.
+ * 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) */
+/* Input	(96 bytes) */
 struct hwrm_cfa_l2_filter_alloc_input {
 	uint16_t req_type;
 	/*
@@ -7589,7 +7624,7 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	#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	\
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_LAST \
 		CFA_L2_FILTER_ALLOC_INPUT_FLAGS_PATH_RX
 	/*
 	 * Setting of this flag indicates the applicability to the
@@ -7606,60 +7641,70 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 * 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)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_FLAGS_OUTERMOST UINT32_C(0x8)
 	uint32_t enables;
 	/* 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_MIRROR_VNIC_ID	\
+		UINT32_C(0x10000)
 	uint8_t l2_addr[6];
 	/*
 	 * This value sets the match value for the L2 MAC address.
@@ -7747,34 +7792,38 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	uint8_t tunnel_type;
 	/* Tunnel Type. */
 	/* Non-tunnel */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL	UINT32_C(0x0)
-	/* Virtual eXtensible Local Area Network (VXLAN) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN	UINT32_C(0x1)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+		UINT32_C(0x0)
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
 	/*
 	 * Network Virtualization Generic Routing
-	 * Encapsulation (NVGRE)
+	 * Encapsulation	(NVGRE)
 	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE	UINT32_C(0x2)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+		UINT32_C(0x2)
 	/*
-	 * Generic Routing Encapsulation (GRE) inside
+	 * Generic Routing Encapsulation	(GRE) inside
 	 * Ethernet payload
 	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE	UINT32_C(0x3)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE UINT32_C(0x3)
 	/* IP in IP */
 	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
-	/* Generic Network Virtualization Encapsulation (Geneve) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE	UINT32_C(0x5)
-	/* Multi-Protocol Lable Switching (MPLS) */
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	/* Multi-Protocol Lable Switching	(MPLS) */
 	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
-	/* Stateless Transport Tunnel (STT) */
+	/* Stateless Transport Tunnel	(STT) */
 	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
 	/*
-	 * Generic Routing Encapsulation (GRE) inside IP
+	 * Generic Routing Encapsulation	(GRE) inside IP
 	 * datagram payload
 	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE	UINT32_C(0x8)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE UINT32_C(0x8)
 	/* Any tunneled traffic */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL	UINT32_C(0xff)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+		UINT32_C(0xff)
 	uint8_t unused_7;
 	uint16_t dst_id;
 	/*
@@ -7790,11 +7839,14 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 * filter table.
 	 */
 	/* No preference */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER	UINT32_C(0x0)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+		UINT32_C(0x0)
 	/* Above the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER	UINT32_C(0x1)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+		UINT32_C(0x1)
 	/* Below the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER	UINT32_C(0x2)
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+		UINT32_C(0x2)
 	/* As high as possible */
 	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
 	/* As low as possible */
@@ -7809,7 +7861,7 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 */
 } __attribute__((packed));
 
-/* Output (24 bytes) */
+/* Output	(24 bytes) */
 struct hwrm_cfa_l2_filter_alloc_output {
 	uint16_t error_code;
 	/*
@@ -7857,7 +7909,7 @@ struct hwrm_cfa_l2_filter_alloc_output {
  * Description: Free a L2 filter. The HWRM shall free all associated filter
  * resources with the L2 filter.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_cfa_l2_filter_free_input {
 	uint16_t req_type;
 	/*
@@ -7892,7 +7944,7 @@ struct hwrm_cfa_l2_filter_free_input {
 	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_cfa_l2_filter_free_output {
 	uint16_t error_code;
 	/*
@@ -7926,7 +7978,7 @@ struct hwrm_cfa_l2_filter_free_output {
 
 /* hwrm_cfa_l2_filter_cfg */
 /* Description: Change the configuration of an existing L2 filter */
-/* Input (40 bytes) */
+/* Input	(40 bytes) */
 struct hwrm_cfa_l2_filter_cfg_input {
 	uint16_t req_type;
 	/*
@@ -7965,7 +8017,7 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX	(UINT32_C(0x0) << 0)
 	/* rx path */
 	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX	(UINT32_C(0x1) << 0)
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST	\
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST \
 		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
 	/*
 	 * Setting of this flag indicates drop action. If this flag is
@@ -7979,7 +8031,8 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	 * This bit must be '1' for the new_mirror_vnic_id field to be
 	 * configured.
 	 */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   UINT32_C(0x2)
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   \
+		UINT32_C(0x2)
 	uint64_t l2_filter_id;
 	/*
 	 * This value identifies a set of CFA data structures used for
@@ -7995,7 +8048,7 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_cfa_l2_filter_cfg_output {
 	uint16_t error_code;
 	/*
@@ -8029,7 +8082,7 @@ struct hwrm_cfa_l2_filter_cfg_output {
 
 /* hwrm_cfa_l2_set_rx_mask */
 /* Description: This command will set rx mask of the function. */
-/* Input (56 bytes) */
+/* Input	(56 bytes) */
 struct hwrm_cfa_l2_set_rx_mask_input {
 	uint16_t req_type;
 	/*
@@ -8082,14 +8135,14 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * 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
+	 * 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
+	 * 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
+	 * 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
@@ -8102,7 +8155,7 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * 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)
+	#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
@@ -8135,7 +8188,8 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * set at most one flag out of vlanonly, vlan_nonvlan, and
 	 * anyvlan_nonvlan.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	UINT32_C(0x100)
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	\
+		UINT32_C(0x100)
 	uint64_t mc_tbl_addr;
 	/* This is the address for mcast address tbl. */
 	uint32_t num_mc_entries;
@@ -8158,7 +8212,7 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_cfa_l2_set_rx_mask_output {
 	uint16_t error_code;
 	/*
@@ -8468,7 +8522,7 @@ struct hwrm_tunnel_dst_port_free_output {
  * Description: This command allocates and does basic preparation for a stat
  * context.
  */
-/* Input (32 bytes) */
+/* Input	(32 bytes) */
 struct hwrm_stat_ctx_alloc_input {
 	uint16_t req_type;
 	/*
@@ -8506,10 +8560,24 @@ struct hwrm_stat_ctx_alloc_input {
 	 * used. In this case, the stat block can only be read by
 	 * hwrm_stat_ctx_query command.
 	 */
-	uint32_t unused_0;
+	uint8_t stat_ctx_flags;
+	/*
+	 * This field is used to specify statistics context specific
+	 * configuration flags.
+	 */
+	/*
+	 * When this bit is set to '1', the statistics context shall be
+	 * allocated for RoCE traffic only. In this case, traffic other
+	 * than offloaded RoCE traffic shall not be included in this
+	 * statistic context. When this bit is set to '0', the
+	 * statistics context shall be used for the network traffic
+	 * other than offloaded RoCE traffic.
+	 */
+	#define HWRM_STAT_CTX_ALLOC_INPUT_STAT_CTX_FLAGS_ROCE	UINT32_C(0x1)
+	uint8_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_stat_ctx_alloc_output {
 	uint16_t error_code;
 	/*
@@ -8544,7 +8612,7 @@ struct hwrm_stat_ctx_alloc_output {
 
 /* hwrm_stat_ctx_free */
 /* Description: This command is used to free a stat context. */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_stat_ctx_free_input {
 	uint16_t req_type;
 	/*
@@ -8577,7 +8645,7 @@ struct hwrm_stat_ctx_free_input {
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_stat_ctx_free_output {
 	uint16_t error_code;
 	/*
@@ -8612,7 +8680,7 @@ struct hwrm_stat_ctx_free_output {
 
 /* hwrm_stat_ctx_clr_stats */
 /* Description: This command clears statistics of a context. */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_stat_ctx_clr_stats_input {
 	uint16_t req_type;
 	/*
@@ -8640,13 +8708,363 @@ struct hwrm_stat_ctx_clr_stats_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_stat_ctx_query */
+/* Description: This command returns statistics of a context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_query_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (176 bytes) */
+
+struct hwrm_stat_ctx_query_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t tx_err_pkts;
+	/* Number of transmitted packets with error */
+	uint64_t tx_drop_pkts;
+	/* Number of dropped packets on transmit path */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t tx_mcast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t tx_bcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t rx_err_pkts;
+	/* Number of received packets with error */
+	uint64_t rx_drop_pkts;
+	/* Number of dropped packets on received path */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t encap_request[26];
+	/*
+	 * 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.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_exec_fwd_resp_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_reject_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to reject the request and forward the
+ * error 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_reject_fwd_resp_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t encap_request[26];
+	/*
+	 * This is an encapsulated request. This request should be
+	 * rejected by the HWRM and the error response should be
+	 * provided in the response buffer inside the encapsulated
+	 * request.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_reject_fwd_resp_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* Hardware Resource Manager Specification */
+/* Description: This structure is used to specify port description. */
+/*
+ * 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 service is vital part of the chip.
+ * The chip can not be used by a driver or HWRM client without the HWRM.
+ */
+/* Input	(16 bytes) */
+struct input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_clr_stats_output {
+/* Output	(8 bytes) */
+struct output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -8662,21 +9080,71 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t valid;
+} __attribute__((packed));
+
+#define HWRM_GET_HWRM_ERROR_CODE(arg) \
+	{ \
+		typeof(arg) x = (arg); \
+	((x) == 0xf ? "HWRM_ERROR" : \
+	((x) == 0xffff ? "CMD_NOT_SUPPORTED" : \
+	((x) == 0xfffe ? "UNKNOWN_ERR" : \
+	((x) == 0x4 ? "RESOURCE_ALLOC_ERROR" : \
+	((x) == 0x5 ? "INVALID_FLAGS" : \
+	((x) == 0x6 ? "INVALID_ENABLES" : \
+	((x) == 0x0 ? "SUCCESS" : \
+	((x) == 0x1 ? "FAIL" : \
+	((x) == 0x2 ? "INVALID_PARAMS" : \
+	((x) == 0x3 ? "RESOURCE_ACCESS_DENIED" : \
+	"Unknown error_code")))))))))) \
+	}
+
+/* Return Codes	(8 bytes) */
+struct ret_codes {
+	uint16_t error_code;
+	/* These are numbers assigned to return/error codes. */
+	/* Request was successfully executed by the HWRM. */
+	#define HWRM_ERR_CODE_SUCCESS	(UINT32_C(0x0))
+	/* THe HWRM failed to execute the request. */
+	#define HWRM_ERR_CODE_FAIL	(UINT32_C(0x1))
 	/*
-	 * 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.
+	 * The request contains invalid argument(s) or
+	 * input parameters.
+	 */
+	#define HWRM_ERR_CODE_INVALID_PARAMS	(UINT32_C(0x2))
+	/*
+	 * The requester is not allowed to access the
+	 * requested resource. This error code shall be
+	 * provided in a response to a request to query
+	 * or modify an existing resource that is not
+	 * accessible by the requester.
+	 */
+	#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED	(UINT32_C(0x3))
+	/*
+	 * The HWRM is unable to allocate the requested
+	 * resource. This code only applies to requests
+	 * for HWRM resource allocations.
+	 */
+	#define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR	(UINT32_C(0x4))
+	/* Invalid combination of flags is specified in the request. */
+	#define HWRM_ERR_CODE_INVALID_FLAGS	(UINT32_C(0x5))
+	/*
+	 * Invalid combination of enables fields is
+	 * specified in the request.
+	 */
+	#define HWRM_ERR_CODE_INVALID_ENABLES	(UINT32_C(0x6))
+	/*
+	 * Generic HWRM execution error that represents
+	 * an internal error.
 	 */
+	#define HWRM_ERR_CODE_HWRM_ERROR	(UINT32_C(0xf))
+	/* Unknown error */
+	#define HWRM_ERR_CODE_UNKNOWN_ERR	(UINT32_C(0xfffe))
+	/* Unsupported or invalid command */
+	#define HWRM_ERR_CODE_CMD_NOT_SUPPORTED	(UINT32_C(0xffff))
+	uint16_t unused_0[3];
 } __attribute__((packed));
 
+/* Output	(16 bytes) */
 struct hwrm_err_output {
 	uint16_t error_code;
 	/*
@@ -9057,177 +9525,34 @@ struct rx_port_stats {
 	/* Total Rx Error Drops per Port reported by STATS block */
 } __attribute__((packed));
 
-/* hwrm_exec_fwd_resp */
+/* Periodic Statistics Context DMA to host	(160 bytes) */
 /*
- * 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.
+ * per-context HW statistics -- chip view
  */
-/* Input (128 bytes) */
-struct hwrm_exec_fwd_resp_input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint32_t encap_request[26];
-	/*
-	 * 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.
-	 */
-	uint16_t encap_resp_target_id;
-	/*
-	 * 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 unused_0[3];
-} __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_exec_fwd_resp_output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t valid;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
+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_discard_pkts;
+	uint64_t rx_ucast_bytes;
+	uint64_t rx_mcast_bytes;
+	uint64_t rx_bcast_bytes;
 
-/* hwrm_reject_fwd_resp */
-/*
- * Description: This command is used to send an encapsulated request to the
- * HWRM. This command instructs the HWRM to reject the request and forward the
- * error 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_reject_fwd_resp_input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint32_t encap_request[26];
-	/*
-	 * This is an encapsulated request. This request should be
-	 * rejected by the HWRM and the error response should be
-	 * provided in the response buffer inside the encapsulated
-	 * request.
-	 */
-	uint16_t encap_resp_target_id;
-	/*
-	 * 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 unused_0[3];
-} __attribute__((packed));
+	uint64_t tx_ucast_pkts;
+	uint64_t tx_mcast_pkts;
+	uint64_t tx_bcast_pkts;
+	uint64_t tx_drop_pkts;
+	uint64_t tx_discard_pkts;
+	uint64_t tx_ucast_bytes;
+	uint64_t tx_mcast_bytes;
+	uint64_t tx_bcast_bytes;
 
-/* Output	(16 bytes) */
-struct hwrm_reject_fwd_resp_output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t valid;
-	/*
-	 * 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.
-	 */
+	uint64_t tpa_pkts;
+	uint64_t tpa_bytes;
+	uint64_t tpa_events;
+	uint64_t tpa_aborts;
 } __attribute__((packed));
 
-#endif
+#endif /* _HSI_STRUCT_DEF_DPDK_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 22/23] bnxt: Add support to set VF rxmode
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (20 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 21/23] bnxt: update to HWRM version 1.7.5 Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-18  1:58 ` [PATCH 23/23] bnxt: add code to support vlan_pvid_set dev_op Ajit Khaparde
  2017-05-22 10:55 ` [PATCH 00/23] bnxt patchset Ferruh Yigit
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to configure the VF L2 Rx settings.
The per VF setting is maintained in bnxt_child_vf_info.l2_rx_mask

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c              | 20 +++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/bnxt_rxq.c               | 13 ++++++--
 drivers/net/bnxt/bnxt_vnic.h              |  5 +++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 51 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 19 ++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 7 files changed, 107 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index e16fb3a..f1dc3bb 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -227,10 +227,16 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
 	/* FIXME add multicast flag, when multicast adding options is supported
 	 * by ethtool.
 	 */
+	if (vnic->flags & BNXT_VNIC_INFO_BCAST)
+		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST;
+	if (vnic->flags & BNXT_VNIC_INFO_UNTAGGED)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN;
 	if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
-		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+		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;
+	if (vnic->flags & BNXT_VNIC_INFO_MCAST)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 	if (vnic->mc_addr_cnt) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
@@ -2337,6 +2343,18 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
 	return rc;
 }
 
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp)
+{
+	uint32_t *flag = flagp;
+
+	vnic->flags = *flag;
+}
+
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 7fc7b57..2c2c124 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -137,6 +137,8 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index b0bbed1..bef48df 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -76,6 +76,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto err_out;
 		}
+		vnic->flags |= BNXT_VNIC_INFO_BCAST;
 		STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
 		bp->nr_vnics++;
 
@@ -120,6 +121,9 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		}
 		/* For each pool, allocate MACVLAN CFA rule & VNIC */
 		if (!pools) {
+			pools = RTE_MIN(bp->max_vnics,
+			    RTE_MIN(bp->max_l2_ctx,
+			     RTE_MIN(bp->max_rsscos_ctx, ETH_64_POOLS)));
 			RTE_LOG(ERR, PMD,
 				"VMDq pool not set, defaulted to 64\n");
 			pools = ETH_64_POOLS;
@@ -137,6 +141,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 				rc = -ENOMEM;
 				goto err_out;
 			}
+			vnic->flags |= BNXT_VNIC_INFO_BCAST;
 			STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
 			bp->nr_vnics++;
 
@@ -177,6 +182,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		rc = -ENOMEM;
 		goto err_out;
 	}
+	vnic->flags |= BNXT_VNIC_INFO_BCAST;
 	/* 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];
@@ -295,7 +301,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
-		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+		RTE_LOG(ERR, PMD, "nb_desc %d is invalid\n", nb_desc);
 		rc = -EINVAL;
 		goto out;
 	}
@@ -308,7 +314,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	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!");
+		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -333,7 +339,8 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	/* Allocate RX ring hardware descriptors */
 	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
 			"rxr")) {
-		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
+		RTE_LOG(ERR, PMD,
+			"ring_dma_zone_reserve for rx_ring failed!\n");
 		bnxt_rx_queue_release_op(rxq);
 		rc = -ENOMEM;
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 0d50224..993f221 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -64,6 +64,11 @@ struct bnxt_vnic_info {
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
+#define BNXT_VNIC_INFO_BCAST			(1 << 2)
+#define BNXT_VNIC_INFO_UCAST			(1 << 3)
+#define BNXT_VNIC_INFO_MCAST			(1 << 4)
+#define BNXT_VNIC_INFO_TAGGED			(1 << 5)
+#define BNXT_VNIC_INFO_UNTAGGED			(1 << 6)
 
 	uint16_t	cos_rule;
 	uint16_t	lb_rule;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index ca14ff3..997173f 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -391,6 +391,57 @@ rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
 	return rc;
 }
 
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t flag = 0;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	if (vf >= bp->pdev->max_vfs)
+		return -EINVAL;
+
+	if (rx_mask & (ETH_VMDQ_ACCEPT_UNTAG | ETH_VMDQ_ACCEPT_HASH_MC)) {
+		RTE_LOG(ERR, PMD, "Currently cannot toggle this setting\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC && !on) {
+		RTE_LOG(ERR, PMD, "Currently cannot disable UC Rx\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
+		flag |= BNXT_VNIC_INFO_BCAST;
+	if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
+		flag |= BNXT_VNIC_INFO_ALLMULTI;
+
+	if (on)
+		bp->pf.vf_info[vf].l2_rx_mask |= flag;
+	else
+		bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+					vf_vnic_set_rxmask_cb,
+					&bp->pf.vf_info[vf].l2_rx_mask,
+					bnxt_set_rx_mask_no_vlan);
+	if (rc)
+		RTE_LOG(ERR, PMD, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index d6cefc4..e9f6cf2 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -237,6 +237,25 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+/**
+ * Set RX L2 Filtering mode of a VF of an Ethernet device.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param rx_mask
+ *    The RX mode mask
+ * @param on
+ *    1 - Enable a VF RX mode.
+ *    0 - Disable a VF RX mode.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on);
 
 /**
  * Returns the number of default RX queues on a VF
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 04fce9a..a0efa66 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -22,4 +22,5 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 	rte_pmd_bnxt_set_vf_vlan_insert;
+	rte_pmd_bnxt_set_vf_rxmode;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH 23/23] bnxt: add code to support vlan_pvid_set dev_op
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (21 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 22/23] bnxt: Add support to set VF rxmode Ajit Khaparde
@ 2017-05-18  1:58 ` Ajit Khaparde
  2017-05-22 10:55 ` [PATCH 00/23] bnxt patchset Ferruh Yigit
  23 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-18  1:58 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds code to support vlan_pvid_set dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 21 +++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 31 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |  1 +
 3 files changed, 53 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 80b85ab..a8484bb 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1477,6 +1477,26 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 	return rc;
 }
 
+static int
+bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint16_t vlan = bp->vlan;
+	int rc;
+
+	if (BNXT_NPAR_PF(bp) || BNXT_VF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"PVID cannot be modified for this function\n");
+		return -ENOTSUP;
+	}
+	bp->vlan = on ? pvid : 0;
+
+	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
+	if (rc)
+		bp->vlan = vlan;
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1512,6 +1532,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
 	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index f1dc3bb..f3a4483 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2434,6 +2434,37 @@ int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t dflt_vlan, fid;
+	uint32_t func_cfg_flags;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	if (is_vf) {
+		dflt_vlan = bp->pf.vf_info[vf].dflt_vlan;
+		fid = bp->pf.vf_info[vf].fid;
+		func_cfg_flags = bp->pf.vf_info[vf].func_cfg_flags;
+	} else {
+		fid = rte_cpu_to_le_16(0xffff);
+		func_cfg_flags = bp->pf.func_cfg_flags;
+		dflt_vlan = bp->vlan;
+	}
+
+	req.flags = rte_cpu_to_le_32(func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
 {
 	struct hwrm_func_cfg_input req = {0};
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 2c2c124..28203b7 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -136,6 +136,7 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
 int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
-- 
2.10.1 (Apple Git-78)

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

* Re: [PATCH 00/23] bnxt patchset
  2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
                   ` (22 preceding siblings ...)
  2017-05-18  1:58 ` [PATCH 23/23] bnxt: add code to support vlan_pvid_set dev_op Ajit Khaparde
@ 2017-05-22 10:55 ` Ferruh Yigit
  2017-05-22 23:02   ` Thomas Monjalon
  2017-05-23 17:58   ` Ajit Khaparde
  23 siblings, 2 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-22 10:55 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Thomas Monjalon

On 5/18/2017 2:57 AM, Ajit Khaparde wrote:
> This patchset amongst other changes adds support few more dev_ops,
> updates HWRM to version 1.7.5, switches to polling stats from the
> hardware, support for LRO etc..
> 
>   bnxt: add various hwrm input/output structures
>   bnxt: code reorg to properly allocate resources in PF/VF modes
>   bnxt: add tunneling support
>   bnxt: support lack of huge pages
>   bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en
>   bnxt: add support for set VF QOS and MAC anti spoof
>   bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs
>   bnxt: add support to get and clear VF specific stats
>   bnxt: add code to determine the Rx status of VF
>   bnxt: add support to add a VF MAC address
>   bnxt: add support for xstats get/reset
>   bnxt: Add support for VLAN filter and strip dev_ops
>   bnxt: add code to configure a default VF VLAN
>   bnxt: add support for set_mc_addr_list and mac_addr_set
>   bnxt: add support for fw_version_get dev_op
>   bnxt: add support to set MTU
>   bnxt: add support for LRO
>   bnxt: add rxq_info_get and txq_info_get dev_ops
>   bnxt: add additonal HWRM debug info to error messages
>   bnxt: reorg the query stats code
>   bnxt: update to HWRM version 1.7.5
>   bnxt: Add support to set VF rxmode
>   bnxt: add code to support vlan_pvid_set dev_op

>  25 files changed, 10407 insertions(+), 3036 deletions(-)

Hi Ajit,

This is a big patch, and as far as I can see it does mainly three things:

1) Update base driver kind of updates (although bnxt doesn't have a base
folder, there are files we can put into this category).
2) Add some new driver features.
3) Add PMD specific APIs mainly to control VF from PF.

- Is it possible to group patches in the patchset as above, currently
patches are all mixed and harder to understand?

- for 3), Some of the PMD specific APIs are common with exiting ones in
i40e and ixgbe, should we extract them into eth_dev_ops now? @Thomas,
any comment?

- For 2), can you please update features/bnxt.ini file in each patch
that adds a feature, to enable that feature in the document. And finally
a release doc update in separate patch can be good.

- Some commits has function names updated in the patch subject, can you
please update them to describe the feature added, function name detail
can be in commit log. You can use ./devtools/check-git-log.sh to verify
commit logs, there are some set of errors now.

Thanks,
ferruh

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

* Re: [PATCH 00/23] bnxt patchset
  2017-05-22 10:55 ` [PATCH 00/23] bnxt patchset Ferruh Yigit
@ 2017-05-22 23:02   ` Thomas Monjalon
  2017-05-23 17:58   ` Ajit Khaparde
  1 sibling, 0 replies; 130+ messages in thread
From: Thomas Monjalon @ 2017-05-22 23:02 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Ajit Khaparde, dev

22/05/2017 12:55, Ferruh Yigit:
> - for 3), Some of the PMD specific APIs are common with exiting ones in
> i40e and ixgbe, should we extract them into eth_dev_ops now? @Thomas,
> any comment?

I don't think so.
Please let's discuss it in a separate thread.

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

* Re: [PATCH 00/23] bnxt patchset
  2017-05-22 10:55 ` [PATCH 00/23] bnxt patchset Ferruh Yigit
  2017-05-22 23:02   ` Thomas Monjalon
@ 2017-05-23 17:58   ` Ajit Khaparde
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
  1 sibling, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-23 17:58 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Thomas Monjalon

On Mon, May 22, 2017 at 5:55 AM, Ferruh Yigit <ferruh.yigit@intel.com>
wrote:

> On 5/18/2017 2:57 AM, Ajit Khaparde wrote:
> > This patchset amongst other changes adds support few more dev_ops,
> > updates HWRM to version 1.7.5, switches to polling stats from the
> > hardware, support for LRO etc..
> >
> >   bnxt: add various hwrm input/output structures
> >   bnxt: code reorg to properly allocate resources in PF/VF modes
> >   bnxt: add tunneling support
> >   bnxt: support lack of huge pages
> >   bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en
> >   bnxt: add support for set VF QOS and MAC anti spoof
> >   bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering
> for VFs
> >   bnxt: add support to get and clear VF specific stats
> >   bnxt: add code to determine the Rx status of VF
> >   bnxt: add support to add a VF MAC address
> >   bnxt: add support for xstats get/reset
> >   bnxt: Add support for VLAN filter and strip dev_ops
> >   bnxt: add code to configure a default VF VLAN
> >   bnxt: add support for set_mc_addr_list and mac_addr_set
> >   bnxt: add support for fw_version_get dev_op
> >   bnxt: add support to set MTU
> >   bnxt: add support for LRO
> >   bnxt: add rxq_info_get and txq_info_get dev_ops
> >   bnxt: add additonal HWRM debug info to error messages
> >   bnxt: reorg the query stats code
> >   bnxt: update to HWRM version 1.7.5
> >   bnxt: Add support to set VF rxmode
> >   bnxt: add code to support vlan_pvid_set dev_op
>
> >  25 files changed, 10407 insertions(+), 3036 deletions(-)
>
> Hi Ajit,
>
> This is a big patch, and as far as I can see it does mainly three things:
>
> 1) Update base driver kind of updates (although bnxt doesn't have a base
> ​​
> folder, there are files we can put into this category).
>

Since all the hardware specific code
is abstracted by the HWRM api
​,
we feel doing a base folder will be pretty much another abstraction above
this HWRM.​
​But ​
​I will try to break down the bigger patch
​​
into smaller ones.
​​

Its just that I tried to keep the related code in one patch to keep the
functionality together.

2) Add some new driver features.
> 3) Add PMD specific APIs mainly to control VF from PF.
>
> - Is it possible to group patches in the patchset as above, currently
> patches are all mixed and harder to understand?
>
​I will do my best.
​


>
> - for 3), Some of the PMD specific APIs are common with exiting ones in
> i40e and ixgbe, should we extract them into eth_dev_ops now? @Thomas,
> any comment?
>
> - For 2), can you please update features/bnxt.ini file in each patch
> that adds a feature, to enable that feature in the document. And finally
> a release doc update in separate patch can be good.
>
​Ok. I will work on that.
​


>
> - Some commits has function names updated in the patch subject, can you
> please update them to describe the feature added, function name detail
> can be in commit log. You can use ./devtools/check-git-log.sh to verify
> ​​
> commit logs, there are some set of errors now.
>
​Sure.
​


>
> Thanks,
> ferruh
>

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

* [PATCH v2 00/25] bnxt patchset
  2017-05-23 17:58   ` Ajit Khaparde
@ 2017-05-26 18:39     ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 01/25] bnxt: update to new HWRM version Ajit Khaparde
                         ` (25 more replies)
  0 siblings, 26 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patchset amongst other changes adds support few more dev_ops,
updates HWRM to version 1.7.7, switches to polling stats from the
hardware, support for Jumbo MTU, LRO etc..
As suggedted for the previous submission:
 Grouped in the end, it also has PMD specific APIs to control VF from PF.
 I have updated the release notes and the features file wherever possible.

--
  bnxt: update to new HWRM version
  bnxt: code reorg to properly allocate resources for PF/VF
  bnxt: handle VF/PF initialization appropriately
  bnxt: support lack of huge pages
  bnxt: add additonal HWRM debug info to error messages
  bnxt: add tunneling support
  bnxt: add support for xstats get/reset
  bnxt: Add support for VLAN filter and strip dev_ops
  bnxt: add support for set multicast addr list and MAC addr set
  bnxt: add support for fw_version_get dev_op
  bnxt: add support to set MTU
  bnxt: add support for LRO
  bnxt: add rxq/txq info_get dev_ops
  bnxt: add code to support VLAN pvid set dev_op
  bnxt: reorg the query stats code
  bnxt: add support for led on/off
  bnxt: add support for tx loopback, set vf mac and queues drop
  bnxt: add support for set VF QOS and MAC anti spoof
  bnxt: add support for VLAN stripq, anti spoof and filtering for VFs
  bnxt: add support to get and clear VF specific stats
  bnxt: add code to determine the Rx status of VF
  bnxt: add support to add a VF MAC address
  bnxt: add code to configure a default VF VLAN
  bnxt: Add support to set VF rxmode
  update release notes

 doc/guides/nics/features/bnxt.ini         |    9 +
 doc/guides/rel_notes/release_17_08.rst    |    8 +
 drivers/net/bnxt/Makefile                 |    4 +
 drivers/net/bnxt/bnxt.h                   |  142 +-
 drivers/net/bnxt/bnxt_cpr.c               |  132 +-
 drivers/net/bnxt/bnxt_cpr.h               |   17 +
 drivers/net/bnxt/bnxt_ethdev.c            |  837 ++-
 drivers/net/bnxt/bnxt_filter.c            |   54 +-
 drivers/net/bnxt/bnxt_filter.h            |    3 +
 drivers/net/bnxt/bnxt_hwrm.c              | 1606 ++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   66 +-
 drivers/net/bnxt/bnxt_irq.c               |   21 +-
 drivers/net/bnxt/bnxt_ring.c              |  159 +-
 drivers/net/bnxt/bnxt_ring.h              |    4 +-
 drivers/net/bnxt/bnxt_rxq.c               |   54 +-
 drivers/net/bnxt/bnxt_rxq.h               |    3 +
 drivers/net/bnxt/bnxt_rxr.c               |  396 +-
 drivers/net/bnxt/bnxt_rxr.h               |   46 +
 drivers/net/bnxt/bnxt_stats.c             |  266 +-
 drivers/net/bnxt/bnxt_stats.h             |   10 +
 drivers/net/bnxt/bnxt_txr.c               |    3 +-
 drivers/net/bnxt/bnxt_vnic.c              |   68 +-
 drivers/net/bnxt/bnxt_vnic.h              |   20 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h    | 9678 +++++++++++++++++++++--------
 drivers/net/bnxt/rte_pmd_bnxt.c           |  701 +++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  322 +
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   22 +
 27 files changed, 11705 insertions(+), 2946 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 01/25] bnxt: update to new HWRM version
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 02/25] bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
                         ` (24 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch updates the Broadcom bnxt PMD to version 1.7.7
Most of the changes in the patch are in the hsi_struct_def_dpdk.h - an
autogenerated file. The changes in the *.c files are because of changes
in the macro names.

--
v1->v2: regroup related patches per review comment

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c           |   10 +-
 drivers/net/bnxt/bnxt_ring.c           |    8 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 8710 +++++++++++++++++++++++---------
 3 files changed, 6241 insertions(+), 2487 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3849d1a..9100b7b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -511,7 +511,7 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 		req.enables = rte_cpu_to_le_32(enables);
 	} else {
 		req.flags =
-		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN);
+		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
 		RTE_LOG(INFO, PMD, "Force Link Down\n");
 	}
 
@@ -618,7 +618,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
 		/*
 		 * TODO: Some HWRM versions crash with
@@ -639,7 +639,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD,
 				"hwrm_ring_alloc cp failed. rc:%d\n", rc);
 			return rc;
@@ -680,7 +680,7 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 			rc = rte_le_to_cpu_16(resp->error_code);
 
 		switch (ring_type) {
-		case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD, "hwrm_ring_free cp failed. rc:%d\n",
 				rc);
 			return rc;
@@ -1063,7 +1063,7 @@ static void bnxt_free_cp_ring(struct bnxt *bp,
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
 	bnxt_hwrm_ring_free(bp, cp_ring,
-			HWRM_RING_FREE_INPUT_RING_TYPE_CMPL);
+			HWRM_RING_FREE_INPUT_RING_TYPE_L2_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 *
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0fafa13..52fbd89 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -219,8 +219,8 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *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);
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+					0, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = pci_dev->mem_resource[2].addr;
@@ -238,7 +238,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
@@ -276,7 +276,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index f024837..518f16d 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) Broadcom Limited.
+ *   Copyright(c) 2001-2017 Broadcom Limited.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -31,74 +31,88 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
-#define _HSI_STRUCT_DEF_EXTERNAL_H_
-
-/*
- * per-context HW statistics -- chip view
- */
-
-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_discard_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_discard_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;
-} __attribute__((packed));
-
-/* HW Resource Manager Specification 1.5.1 */
+#ifndef _HSI_STRUCT_DEF_DPDK_
+#define _HSI_STRUCT_DEF_DPDK_
+/* HSI and HWRM Specification 1.7.7 */
 #define HWRM_VERSION_MAJOR	1
-#define HWRM_VERSION_MINOR	5
-#define HWRM_VERSION_UPDATE	1
-
-#define HWRM_VERSION_STR	"1.5.1"
+#define HWRM_VERSION_MINOR	7
+#define HWRM_VERSION_UPDATE	7
 
+#define HWRM_VERSION_STR	"1.7.7"
 /*
  * 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.
+ * applicable	(All F's). Need to cast it the size of the field if needed.
  */
-#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
+#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_MAX_RESP_LEN	(248)  /* hwrm_selftest_qlist */
+#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 */
+#define HWRM_ROCE_SP_HSI_VERSION_MAJOR	1
+#define HWRM_ROCE_SP_HSI_VERSION_MINOR	7
+#define HWRM_ROCE_SP_HSI_VERSION_UPDATE	4
 
 /*
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_BUF_UNRGTR		(UINT32_C(0xe))
+#define HWRM_FUNC_VF_CFG		(UINT32_C(0xf))
+    /* Reserved for future use */
+#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 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_PHY_QCFG		(UINT32_C(0x27))
+#define HWRM_PORT_MAC_QCFG		(UINT32_C(0x28))
+#define HWRM_PORT_PHY_QCAPS		(UINT32_C(0x2a))
+#define HWRM_PORT_LED_CFG		(UINT32_C(0x2d))
+#define HWRM_PORT_LED_QCFG		(UINT32_C(0x2e))
+#define HWRM_PORT_LED_QCAPS		(UINT32_C(0x2f))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_QUEUE_QCFG			(UINT32_C(0x31))
+#define HWRM_QUEUE_CFG			(UINT32_C(0x32))
+#define HWRM_FUNC_VLAN_CFG		(UINT32_C(0x33))
+#define HWRM_FUNC_VLAN_QCFG		(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_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_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_CFG_AGGINT_PARAM	(UINT32_C(0x53))
+#define HWRM_RING_RESET			(UINT32_C(0x5e))
+#define HWRM_RING_GRP_ALLOC		(UINT32_C(0x60))
 #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))
@@ -107,16 +121,69 @@ 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))
+    /* Reserved for future use */
+#define RESERVED4			(UINT32_C(0x94))
+#define HWRM_CFA_TUNNEL_FILTER_ALLOC	(UINT32_C(0x95))
+#define HWRM_CFA_TUNNEL_FILTER_FREE	(UINT32_C(0x96))
+#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_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_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_WOL_FILTER_ALLOC		(UINT32_C(0xf0))
+#define HWRM_WOL_FILTER_FREE		(UINT32_C(0xf1))
+#define HWRM_WOL_FILTER_QCFG		(UINT32_C(0xf2))
+#define HWRM_WOL_REASON_QCFG		(UINT32_C(0xf3))
+#define HWRM_DBG_DUMP			(UINT32_C(0xff14))
+#define HWRM_NVM_VALIDATE_OPTION	(UINT32_C(0xffef))
+#define HWRM_NVM_FLUSH			(UINT32_C(0xfff0))
+#define HWRM_NVM_GET_VARIABLE		(UINT32_C(0xfff1))
+#define HWRM_NVM_SET_VARIABLE		(UINT32_C(0xfff2))
+#define HWRM_NVM_INSTALL_UPDATE		(UINT32_C(0xfff3))
+#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_RAW_DUMP		(UINT32_C(0xfffc))
+#define HWRM_NVM_READ			(UINT32_C(0xfffd))
+#define HWRM_NVM_WRITE			(UINT32_C(0xfffe))
+#define HWRM_NVM_RAW_WRITE_BLK		(UINT32_C(0xffff))
 
-/* Return Codes */
-#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
-#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
-
-/* Short TX BD (16 bytes) */
+/*
+ * Note: The Host Software Interface (HSI) and Hardware Resource Manager (HWRM)
+ * specification describes the data structures used in Ethernet packet or RDMA
+ * message data transfers as well as an abstract interface for managing Ethernet
+ * NIC hardware resources.
+ */
+/* Ethernet Data path Host Structures */
+/*
+ * Description: The following three sections document the host structures used
+ * between device and software drivers for communicating Ethernet packets.
+ */
+/* BD Ring Structures */
+/*
+ * Description: This structure is used to inform the NIC of a location for and
+ * an aggregation buffer that will be used for packet data that is received. An
+ * aggregation buffer creates a different kind of completion operation for a
+ * packet where a variable number of BDs may be used to place the packet in the
+ * host. RX Rings that have aggregation buffers are known as aggregation rings
+ * and must contain only aggregation buffers.
+ */
+/* Short TX BD	(16 bytes) */
 struct tx_bd_short {
 	uint16_t flags_type;
 	/*
@@ -149,10 +216,10 @@ struct tx_bd_short {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -173,7 +240,8 @@ struct tx_bd_short {
 	#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
+	#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
@@ -213,7 +281,7 @@ struct tx_bd_short {
 	 */
 } __attribute__((packed));
 
-/* Long TX BD (32 bytes split to 2 16-byte struct) */
+/* Long TX BD	(32 bytes split to 2 16-byte struct) */
 struct tx_bd_long {
 	uint16_t flags_type;
 	/*
@@ -246,10 +314,10 @@ struct tx_bd_long {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -270,7 +338,8 @@ struct tx_bd_long {
 	#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
+	#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
@@ -360,7 +429,7 @@ struct tx_bd_long_hi {
 	 * bit is set, outer UDP checksum will be calculated for the
 	 * following cases: 1. Packets with tcp_udp_chksum flag set to
 	 * offload checksum for inner packet AND the inner packet is
-	 * TCP/UDP. If the inner packet is ICMP for example (non-
+	 * TCP/UDP. If the inner packet is ICMP for example	(non-
 	 * TCP/UDP), even if the tcp_udp_chksum is set, the outer UDP
 	 * checksum will not be calculated. 2. Packets with lso flag set
 	 * which implies inner TCP checksum calculation as part of LSO
@@ -392,7 +461,7 @@ struct tx_bd_long_hi {
 	 * 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. The flag is ignored if the LSO packet is a normal
-	 * (non-tunneled) TCP packet.
+	 *	(non-tunneled) TCP packet.
 	 */
 	#define TX_BD_LONG_LFLAGS_T_IPID	UINT32_C(0x80)
 	/*
@@ -460,7 +529,7 @@ struct tx_bd_long_hi {
 	#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	\
+	#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)
@@ -474,15 +543,16 @@ struct tx_bd_long_hi {
 	/* No editing */
 	#define TX_BD_LONG_CFA_META_KEY_NONE	(UINT32_C(0x0) << 28)
 	/*
-	 * - meta[17:16] - TPID select value (0 =
+	 * - 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
+	#define TX_BD_LONG_CFA_META_KEY_LAST \
+		TX_BD_LONG_CFA_META_KEY_VLAN_TAG
 } __attribute__((packed));
 
-/* RX Producer Packet BD (16 bytes) */
+/* RX Producer Packet BD	(16 bytes) */
 struct rx_prod_pkt_bd {
 	uint16_t flags_type;
 	/* This value identifies the type of buffer descriptor. */
@@ -490,7 +560,7 @@ struct rx_prod_pkt_bd {
 	#define RX_PROD_PKT_BD_TYPE_SFT	0
 	/*
 	 * Indicates that this BD is 16B long and is an
-	 * RX Producer (ie. empty) buffer descriptor.
+	 * RX Producer	(ie. empty) buffer descriptor.
 	 */
 	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT	UINT32_C(0x4)
 	/*
@@ -558,7 +628,7 @@ struct rx_prod_pkt_bd {
 
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
-/* Base Completion Record (16 bytes) */
+/* Base Completion Record	(16 bytes) */
 struct cmpl_base {
 	uint16_t type;
 	/* unused is 10 b */
@@ -637,7 +707,7 @@ struct cmpl_base {
 	/* info4 is 32 b */
 } __attribute__((packed));
 
-/* TX Completion Record (16 bytes) */
+/* TX Completion Record	(16 bytes) */
 struct tx_cmpl {
 	uint16_t flags_type;
 	/*
@@ -689,7 +759,7 @@ struct tx_cmpl {
 	#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	\
+	#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
@@ -726,7 +796,7 @@ struct tx_cmpl {
 	/* unused3 is 32 b */
 } __attribute__((packed));
 
-/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+/* RX Packet Completion Record	(32 bytes split to 2 16-byte struct) */
 struct rx_pkt_cmpl {
 	uint16_t flags_type;
 	/*
@@ -741,7 +811,9 @@ struct rx_pkt_cmpl {
 	 * RX L2 completion: Completion of and L2 RX
 	 * packet. Length = 32B
 	 */
-	#define RX_PKT_CMPL_TYPE_RX_L2	UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2			UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_START	UINT32_C(0x13)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_END		UINT32_C(0x15)
 	/*
 	 * When this bit is '1', it indicates a packet that has an error
 	 * of some type. Type of error is indicated in error_flags.
@@ -761,10 +833,12 @@ struct rx_pkt_cmpl {
 	 * 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
+	#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)
 	/* unused is 1 b */
+	#define RX_PKT_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
 	/*
 	 * This value indicates what the inner packet determined for the
 	 * packet was.
@@ -820,7 +894,8 @@ struct rx_pkt_cmpl {
 	 * 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_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 len;
@@ -938,7 +1013,7 @@ struct rx_pkt_cmpl_hi {
 	 * the vlan TPID value.
 	 */
 	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
-	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST	\
+	#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
@@ -988,15 +1063,18 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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	\
+	#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)
@@ -1037,39 +1115,45 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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
+	 * 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	\
+	#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
@@ -1089,15 +1173,17 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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
+	 * 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)
@@ -1106,18 +1192,21 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
@@ -1126,9 +1215,9 @@ struct rx_pkt_cmpl_hi {
 	 * 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	\
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
 		(UINT32_C(0x8) << 12)
-	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST	\
+	#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
@@ -1149,7 +1238,474 @@ struct rx_pkt_cmpl_hi {
 	#define RX_PKT_CMPL_REORDER_SFT	0
 } __attribute__((packed));
 
-/* HWRM Forwarded Request (16 bytes) */
+/* RX L2 TPA Start Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_start_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_START_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_START_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA Start Completion: Completion at the
+	 * beginning of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_START_CMPL_TYPE_RX_TPA_START	UINT32_C(0x13)
+	/* This bit will always be '0' for TPA start completions. */
+	#define RX_TPA_START_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+		(UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS (UINT32_C(0x6) << 7)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_TPA_START_CMPL_FLAGS_RSS_VALID	UINT32_C(0x400)
+	/* unused is 1 b */
+	#define RX_TPA_START_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_SFT	12
+	/* TCP Packet: Indicates that the packet was IP and TCP. */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_TCP	(UINT32_C(0x2) << 12)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_LAST \
+		RX_TPA_START_CMPL_FLAGS_ITYPE_TCP
+	#define RX_TPA_START_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_START_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value indicates the amount of packet data written to the
+	 * buffer the opaque field in this completion corresponds to.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t v1;
+	/* unused1 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 RX_TPA_START_CMPL_V1	UINT32_C(0x1)
+	/* unused1 is 7 b */
+	uint8_t rss_hash_type;
+	/*
+	 * 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]}
+	 * . The value of tuple_extrac_op provides the information about
+	 * what fields the hash was computed on. * 0: The RSS hash was
+	 * computed over source IP address, destination IP address,
+	 * source port, and destination port of inner IP and TCP or UDP
+	 * headers. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 1: The RSS hash was computed over
+	 * source IP address and destination IP address of inner IP
+	 * header. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 2: The RSS hash was computed over
+	 * source IP address, destination IP address, source port, and
+	 * destination port of IP and TCP or UDP headers of outer tunnel
+	 * headers. Note: For non-tunneled packets, this value is not
+	 * applicable. * 3: The RSS hash was computed over source IP
+	 * address and destination IP address of IP header of outer
+	 * tunnel headers. Note: For non-tunneled packets, this value is
+	 * not applicable. Note that 4-tuples values listed above are
+	 * applicable for layer 4 protocols supported and enabled for
+	 * RSS in the hardware, HWRM firmware, and drivers. For example,
+	 * if RSS hash is supported and enabled for TCP traffic only,
+	 * then the values of tuple_extract_op corresponding to 4-tuples
+	 * are only valid for TCP traffic.
+	 */
+	uint16_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 9 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_START_CMPL_AGG_ID_MASK	UINT32_C(0xfe00)
+	#define RX_TPA_START_CMPL_AGG_ID_SFT	9
+	uint32_t rss_hash;
+	/*
+	 * This value is the RSS hash value calculated for the packet
+	 * based on the mode bits and key value in the VNIC.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX L2 TPA Start Completion Record */
+struct rx_tpa_start_cmpl_hi {
+	uint32_t flags2;
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * inner packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_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 sum passed for
+	 * all segments included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC	UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * tunnel header and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_IP_CS_CALC	UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the
+	 * tunnel packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_L4_CS_CALC	UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_SFT	4
+	/* No metadata informtaion. Value is zero. */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_LAST \
+		RX_TPA_START_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.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_IP_TYPE	UINT32_C(0x100)
+	uint32_t metadata;
+	/*
+	 * 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_TPA_START_CMPL_METADATA_VID_MASK	UINT32_C(0xfff)
+	#define RX_TPA_START_CMPL_METADATA_VID_SFT	0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_TPA_START_CMPL_METADATA_DE	UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_TPA_START_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+	#define RX_TPA_START_CMPL_METADATA_PRI_SFT	13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_TPA_START_CMPL_METADATA_TPID_MASK	UINT32_C(0xffff0000)
+	#define RX_TPA_START_CMPL_METADATA_TPID_SFT	16
+	uint16_t v2;
+	/* unused4 is 15 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 RX_TPA_START_CMPL_V2	UINT32_C(0x1)
+	/* unused4 is 15 b */
+	uint16_t cfa_code;
+	/*
+	 * This field identifies the CFA action rule that was used for
+	 * this packet.
+	 */
+	uint32_t inner_l4_size_inner_l3_offset_inner_l2_offset_outer_l3_offset;
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the outer L3 header. If there is no outer L3 header, then
+	 * this value is zero.
+	 */
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_MASK	UINT32_C(0x1ff)
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_SFT	0
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L2 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_MASK	UINT32_C(0x3fe00)
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_SFT	9
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L3 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_MASK	UINT32_C(0x7fc0000)
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_SFT	18
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_MASK	UINT32_C(0xf8000000)
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_SFT	27
+} __attribute__((packed));
+
+/* RX TPA End Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_end_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_END_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_END_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA End Completion: Completion at the
+	 * end of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_END_CMPL_TYPE_RX_TPA_END	UINT32_C(0x15)
+	/*
+	 * 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_TPA_END_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_END_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_TPA_END_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_JUMBO (UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS	(UINT32_C(0x6) << 7)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* unused is 2 b */
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_MASK	UINT32_C(0xc00)
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_SFT	10
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was. - 2 TCP Packet Indicates that the packet was IP
+	 * and TCP. This indicates that the ip_cs field is valid and
+	 * that the tcp_udp_cs field is valid and contains the TCP
+	 * checksum. This also indicates that the payload_offset field
+	 * is valid.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_SFT	12
+	#define RX_TPA_END_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_END_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value is zero for TPA End completions. There is no data
+	 * in the buffer that corresponds to the opaque value in this
+	 * completion.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t agg_bufs_v1;
+	/* unused1 is 1 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 RX_TPA_END_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
+	 * aggregation packet. If the value is zero, then the packet is
+	 * completely contained in the buffer space provided in the
+	 * aggregation start completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_BUFS_MASK	UINT32_C(0x7e)
+	#define RX_TPA_END_CMPL_AGG_BUFS_SFT	1
+	/* unused1 is 1 b */
+	uint8_t tpa_segs;
+	/* This value is the number of segments in the TPA operation. */
+	uint8_t payload_offset;
+	/*
+	 * This value indicates the offset in bytes from the beginning
+	 * of the packet where the inner payload starts. This value is
+	 * valid for TCP, UDP, FCoE, and RoCE packets. A value of zero
+	 * indicates an offset of 256 bytes.
+	 */
+	uint8_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 1 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_ID_MASK	UINT32_C(0xfe)
+	#define RX_TPA_END_CMPL_AGG_ID_SFT	1
+	uint32_t tsdelta;
+	/*
+	 * For non-GRO packets, this value is the timestamp delta
+	 * between earliest and latest timestamp values for TPA packet.
+	 * If packets were not time stamped, then delta will be zero.
+	 * For GRO packets, this field is zero except for the following
+	 * sub-fields. - tsdelta[31] Timestamp present indication. When
+	 * '0', no Timestamp option is in the packet. When '1', then a
+	 * Timestamp option is present in the packet.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX TPA End Completion Record */
+struct rx_tpa_end_cmpl_hi {
+	uint32_t tpa_dup_acks;
+	/* unused3 is 28 b */
+	/*
+	 * This value is the number of duplicate ACKs that have been
+	 * received as part of the TPA operation.
+	 */
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_MASK	UINT32_C(0xf)
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_SFT	0
+	/* unused3 is 28 b */
+	uint16_t tpa_seg_len;
+	/*
+	 * This value is the valid when TPA completion is active. It
+	 * indicates the length of the longest segment of the TPA
+	 * operation for LRO mode and the length of the first segment in
+	 * GRO mode. This value may be used by GRO software to re-
+	 * construct the original packet stream from the TPA packet.
+	 * This is the length of all but the last segment for GRO. In
+	 * LRO mode this value may be used to indicate MSS size to the
+	 * stack.
+	 */
+	uint16_t unused_3;
+	/* unused4 is 16 b */
+	uint16_t errors_v2;
+	/*
+	 * 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_TPA_END_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_TPA_END_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+	/*
+	 * This error occurs when there is a fatal HW
+	 * problem in the chip only. It indicates that
+	 * there were not BDs on chip but that there was
+	 * adequate reservation. provided by the TPA
+	 * block.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+		(UINT32_C(0x2) << 1)
+	/*
+	 * This error occurs when TPA block was not
+	 * configured to reserve adequate BDs for TPA
+	 * operations on this RX ring. All data for the
+	 * TPA operation was not placed. This error can
+	 * also be generated when the number of segments
+	 * is not programmed correctly in TPA and the 33
+	 * total aggregation buffers allowed for the TPA
+	 * operation has been exceeded.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR \
+		(UINT32_C(0x4) << 1)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_LAST \
+		RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR
+	#define RX_TPA_END_CMPL_ERRORS_MASK	UINT32_C(0xfffe)
+	#define RX_TPA_END_CMPL_ERRORS_SFT	1
+	uint16_t unused_4;
+	/* unused5 is 16 b */
+	uint32_t start_opaque;
+	/*
+	 * This is the opaque value that was completed for the TPA start
+	 * completion that corresponds to this TPA end completion.
+	 */
+} __attribute__((packed));
+
+/* HWRM Forwarded Request	(16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	uint16_t req_len_type;
 	/* Length of forwarded request in bytes. */
@@ -1188,7 +1744,7 @@ struct hwrm_fwd_req_cmpl {
 	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
 } __attribute__((packed));
 
-/* HWRM Asynchronous Event Completion Record (16 bytes) */
+/* HWRM Asynchronous Event Completion Record	(16 bytes) */
 struct hwrm_async_event_cmpl {
 	uint16_t type;
 	/* unused1 is 10 b */
@@ -1210,19 +1766,20 @@ struct hwrm_async_event_cmpl {
 	/* Link MTU changed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE	UINT32_C(0x1)
 	/* Link speed changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE  UINT32_C(0x2)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE UINT32_C(0x2)
 	/* DCB Configuration changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE  UINT32_C(0x3)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE UINT32_C(0x3)
 	/* Port connection not allowed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED UINT32_C(0x4)
 	/* Link speed configuration was not allowed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED UINT32_C(0x5)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+		UINT32_C(0x5)
 	/* Link speed configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE UINT32_C(0x6)
 	/* Port PHY configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE UINT32_C(0x7)
 	/* Function driver unloaded */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD   UINT32_C(0x10)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD UINT32_C(0x10)
 	/* Function driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD	UINT32_C(0x11)
 	/* Function FLR related processing has completed */
@@ -1231,12 +1788,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD	UINT32_C(0x20)
 	/* PF driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD	UINT32_C(0x21)
-	/* VF Function Level Reset (FLR) */
+	/* VF Function Level Reset	(FLR) */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	UINT32_C(0x30)
 	/* VF MAC Address Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE UINT32_C(0x31)
 	/* PF-VF communication channel status change. */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE UINT32_C(0x32)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+		UINT32_C(0x32)
 	/* VF Configuration Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE	UINT32_C(0x33)
 	/* HWRM Error */
@@ -1255,69 +1813,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK	UINT32_C(0xfe)
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT	1
 	uint8_t timestamp_lo;
-	/* 8-lsb timestamp from POR (100-msec resolution) */
+	/* 8-lsb timestamp from POR	(100-msec resolution) */
 	uint16_t timestamp_hi;
-	/* 16-lsb timestamp from POR (100-msec resolution) */
+	/* 16-lsb timestamp from POR	(100-msec resolution) */
 	uint32_t event_data1;
 	/* Event specific data */
 } __attribute__((packed));
 
-/*
- * 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 service is vital part of the chip.
- * The chip can not be used by a driver or HWRM client without the HWRM.
- */
-
-/* Input (16 bytes) */
-struct input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
-/* Output (8 bytes) */
-struct output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
@@ -1327,7 +1829,7 @@ struct output {
  * interface or firmware version with major = 0, minor = 0, and update = 0 shall
  * be considered an invalid version.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ver_get_input {
 	uint16_t req_type;
 	/*
@@ -1384,7 +1886,7 @@ struct hwrm_ver_get_input {
 	uint8_t unused_0[5];
 } __attribute__((packed));
 
-/* Output (128 bytes) */
+/* Output	(128 bytes) */
 struct hwrm_ver_get_output {
 	uint16_t error_code;
 	/*
@@ -1454,7 +1956,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version of the HWRM
 	 * firmware.
 	 */
 	uint8_t mgmt_fw_maj;
@@ -1477,7 +1979,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint8_t netctrl_fw_maj;
 	/*
@@ -1500,7 +2002,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint32_t dev_caps_cfg;
 	/*
@@ -1512,13 +2014,27 @@ struct hwrm_ver_get_output {
 	 * supported. If set to 0, then secure firmware update behavior
 	 * is not supported.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  UINT32_C(0x1)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  \
+		UINT32_C(0x1)
 	/*
 	 * If set to 1, then firmware based DCBX agent is supported. If
 	 * set to 0, then firmware based DCBX agent capability is not
 	 * supported on this device.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, then HWRM short command format is supported. If
+	 * set to 0, then HWRM short command format is not supported.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED	 \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, then HWRM short command format is required. If
+	 * set to 0, then HWRM short command format is not required.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_INPUTUIRED	\
+		UINT32_C(0x8)
 	uint8_t roce_fw_maj;
 	/*
 	 * This field represents the major version of RoCE firmware. A
@@ -1539,22 +2055,22 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	char hwrm_fw_name[16];
 	/*
-	 * This field represents the name of HWRM FW (ASCII chars with
+	 * This field represents the name of HWRM FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char mgmt_fw_name[16];
 	/*
-	 * This field represents the name of mgmt FW (ASCII chars with
+	 * This field represents the name of mgmt FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char netctrl_fw_name[16];
 	/*
 	 * This field represents the name of network control firmware
-	 * (ASCII chars with NULL at the end).
+	 *	(ASCII chars with NULL at the end).
 	 */
 	uint32_t reserved2[4];
 	/*
@@ -1563,7 +2079,7 @@ struct hwrm_ver_get_output {
 	 */
 	char roce_fw_name[16];
 	/*
-	 * This field represents the name of RoCE FW (ASCII chars with
+	 * This field represents the name of RoCE FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	uint16_t chip_num;
@@ -1584,7 +2100,7 @@ struct hwrm_ver_get_output {
 	/* FPGA platform of the chip. */
 	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA	UINT32_C(0x1)
 	/* Palladium platform of the chip. */
-	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM	UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM UINT32_C(0x2)
 	uint16_t max_req_win_len;
 	/*
 	 * This field returns the maximum value of request window that
@@ -1614,7 +2130,7 @@ struct hwrm_ver_get_output {
 
 /* hwrm_func_reset */
 /*
- * Description: This command resets a hardware function (PCIe function) and
+ * 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
@@ -1626,7 +2142,7 @@ struct hwrm_ver_get_output {
  * idled. The command returns all the resources owned by the function so a new
  * driver may allocate and configure resources normally.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_reset_input {
 	uint16_t req_type;
 	/*
@@ -1668,7 +2184,7 @@ struct hwrm_func_reset_input {
 	/* This value indicates the level of a function reset. */
 	/*
 	 * Reset the caller function and its children
-	 * VFs (if any). If no children functions exist,
+	 * 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)
@@ -1681,7 +2197,8 @@ struct hwrm_func_reset_input {
 	 * 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)
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+		UINT32_C(0x2)
 	/*
 	 * Reset a specific VF of the caller function
 	 * driver if the caller is the parent PF driver.
@@ -1694,7 +2211,7 @@ struct hwrm_func_reset_input {
 	uint8_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_reset_output {
 	uint16_t error_code;
 	/*
@@ -1734,7 +2251,7 @@ struct hwrm_func_reset_output {
  * 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) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcaps_input {
 	uint16_t req_type;
 	/*
@@ -1765,12 +2282,12 @@ struct hwrm_func_qcaps_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (80 bytes) */
+/* Output	(80 bytes) */
 struct hwrm_func_qcaps_output {
 	uint16_t error_code;
 	/*
@@ -1795,54 +2312,56 @@ struct hwrm_func_qcaps_output {
 	uint16_t port_id;
 	/*
 	 * 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
+	 * 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.
 	 */
 	uint32_t flags;
 	/* If 1, then Push mode is supported on this function. */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED	UINT32_C(0x1)
+	#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)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING	 \
+		UINT32_C(0x2)
 	/*
-	 * If 1, then the Precision Time Protocol (PTP) processing is
+	 * 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.
+	 * only a single Physical Function	(PF) per port.
 	 */
 	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED	UINT32_C(0x4)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v1 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v1 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED	UINT32_C(0x8)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED UINT32_C(0x8)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v2 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v2 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED	UINT32_C(0x10)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED UINT32_C(0x10)
 	/*
 	 * If 1, then control and configuration of WoL magic packet are
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	UINT32_C(0x20)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	\
+		UINT32_C(0x20)
 	/*
 	 * If 1, then control and configuration of bitmap pattern packet
 	 * are supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED	UINT32_C(0x40)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED UINT32_C(0x40)
 	/*
 	 * If set to 1, then the control and configuration of rate limit
 	 * of an allocated TX ring on the queried function is supported.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED	UINT32_C(0x80)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED UINT32_C(0x80)
 	/*
 	 * If 1, then control and configuration of minimum and maximum
 	 * bandwidths are supported on the queried function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED	UINT32_C(0x100)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED UINT32_C(0x100)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1851,7 +2370,8 @@ struct hwrm_func_qcaps_output {
 	 * set to 0, then the PF does not have the capability to set the
 	 * rate limits on the TX rings of its children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	UINT32_C(0x200)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	 \
+		UINT32_C(0x200)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1861,7 +2381,17 @@ struct hwrm_func_qcaps_output {
 	 * capability to set the minimum or maximum bandwidths for its
 	 * children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED	UINT32_C(0x400)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED UINT32_C(0x400)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is supported on the
+	 * queried function. If set to 0, then standard TX ring mode is
+	 * not available on the queried function.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_STD_TX_RING_MODE_SUPPORTED   \
+		UINT32_C(0x800)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -1901,7 +2431,7 @@ struct hwrm_func_qcaps_output {
 	uint16_t first_vf_id;
 	/*
 	 * 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
+	 * 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.
 	 */
@@ -1909,7 +2439,7 @@ struct hwrm_func_qcaps_output {
 	/*
 	 * 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-
+	 * 0xFF...	(All Fs) if this command is called on a PF with SR-
 	 * IOV disabled or on a VF.
 	 */
 	uint16_t max_stat_ctx;
@@ -1929,22 +2459,22 @@ struct hwrm_func_qcaps_output {
 	 */
 	uint32_t max_tx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_tx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_rx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_rx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_mcast_filters;
@@ -1968,7 +2498,7 @@ struct hwrm_func_qcaps_output {
 	 * be allocated to the function. This number indicates the
 	 * maximum number of TX rings that can be assigned strict
 	 * priorities out of the maximum number of TX rings that can be
-	 * allocated (max_tx_rings) to the function.
+	 * allocated	(max_tx_rings) to the function.
 	 */
 	uint8_t unused_0;
 	uint8_t valid;
@@ -1989,9 +2519,13 @@ struct hwrm_func_qcaps_output {
  * 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.
+ * the PCI bus. This command should be called by every driver after
+ * 'hwrm_func_cfg' to get the actual number of resources allocated by the HWRM.
+ * The values returned by hwrm_func_qcfg are the values the driver shall use.
+ * These values may be different than what was originally requested in the
+ * 'hwrm_func_cfg' command.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcfg_input {
 	uint16_t req_type;
 	/*
@@ -2022,12 +2556,12 @@ struct hwrm_func_qcfg_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (72 bytes) */
+/* Output	(72 bytes) */
 struct hwrm_func_qcfg_output {
 	uint16_t error_code;
 	/*
@@ -2052,7 +2586,7 @@ struct hwrm_func_qcfg_output {
 	uint16_t port_id;
 	/*
 	 * Port ID of port that this function is associated with.
-	 * 0xFF... (All Fs) if this function is not associated with any
+	 * 0xFF...	(All Fs) if this function is not associated with any
 	 * port.
 	 */
 	uint16_t vlan;
@@ -2060,15 +2594,15 @@ struct hwrm_func_qcfg_output {
 	 * This value is the current VLAN setting for this function. The
 	 * value of 0 for this field indicates no priority tagging or
 	 * VLAN is used. This field's format is same as 802.1Q Tag's Tag
-	 * Control Information (TCI) format that includes both Priority
-	 * Code Point (PCP) and VLAN Identifier (VID).
+	 * Control Information	(TCI) format that includes both Priority
+	 * Code Point	(PCP) and VLAN Identifier	(VID).
 	 */
 	uint16_t flags;
 	/*
 	 * If 1, then magic packet based Out-Of-Box WoL is enabled on
 	 * the port associated with this function.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	 \
 		UINT32_C(0x1)
 	/*
 	 * If 1, then bitmap pattern based Out-Of-Box WoL packet is
@@ -2080,8 +2614,33 @@ struct hwrm_func_qcfg_output {
 	 * on the port associated with this function. If set to 0, then
 	 * DCBX agent is not running in the firmware.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED \
 		UINT32_C(0x4)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is enabled on the
+	 * queried function. If set to 0, then the standard TX ring mode
+	 * is disabled on the queried function. In this extended TX ring
+	 * resource mode, the minimum and maximum bandwidth settings are
+	 * not supported to allow the allocation of TX rings to span
+	 * multiple scheduler nodes.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_STD_TX_RING_MODE_ENABLED	 \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1 then FW based LLDP agent is enabled and running
+	 * on the port associated with this function. If set to 0 then
+	 * the LLDP agent is not running in the firmware.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED UINT32_C(0x10)
+	/*
+	 * If set to 1, then multi-host mode is active for this
+	 * function. If set to 0, then multi-host mode is inactive for
+	 * this function or not applicable for this device.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST		UINT32_C(0x20)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -2091,8 +2650,8 @@ struct hwrm_func_qcfg_output {
 	uint16_t pci_id;
 	/*
 	 * This value is current PCI ID of this function. If ARI is
-	 * enabled, then it is Bus Number (8b):Function Number(8b).
-	 * Otherwise, it is Bus Number (8b):Device Number (4b):Function
+	 * enabled, then it is Bus Number	(8b):Function Number(8b).
+	 * Otherwise, it is Bus Number	(8b):Device Number	(4b):Function
 	 * Number(4b).
 	 */
 	uint16_t alloc_rsscos_ctx;
@@ -2146,22 +2705,27 @@ struct hwrm_func_qcfg_output {
 	/* Multiple physical functions */
 	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS	UINT32_C(0x1)
 	/* Network Partitioning 1.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0	\
-		UINT32_C(0x2)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 UINT32_C(0x2)
 	/* Network Partitioning 1.5 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5	\
-		UINT32_C(0x3)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 UINT32_C(0x3)
 	/* Network Partitioning 2.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0	\
-		UINT32_C(0x4)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 UINT32_C(0x4)
 	/* Unknown */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN	\
-		UINT32_C(0xff)
-	uint8_t unused_0;
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN UINT32_C(0xff)
+	uint8_t port_pf_cnt;
+	/*
+	 * This field will indicate number of physical functions on this
+	 * port_partition. HWRM shall return unavail (i.e. value of 0)
+	 * for this field when this command is used to query VF's
+	 * configuration or from older firmware that doesn't support
+	 * this field.
+	 */
+	/* number of PFs is not available */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_UNAVAIL	UINT32_C(0x0)
 	uint16_t dflt_vnic_id;
 	/* The default VNIC ID assigned to a function that is being queried. */
+	uint8_t unused_0;
 	uint8_t unused_1;
-	uint8_t unused_2;
 	uint32_t min_bw;
 	/*
 	 * Minimum BW allocated for this function. The HWRM will
@@ -2169,26 +2733,41 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * the minimum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID
 	uint32_t max_bw;
 	/*
@@ -2197,43 +2776,58 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * that the maximum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID
 	uint8_t evb_mode;
 	/*
 	 * This value indicates the Edge virtual bridge mode for the
 	 * domain that this function belongs to.
 	 */
-	/* No Edge Virtual Bridging (EVB) */
+	/* No Edge Virtual Bridging	(EVB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
-	/* Virtual Ethernet Bridge (VEB) */
+	/* Virtual Ethernet Bridge	(VEB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB	UINT32_C(0x1)
-	/* Virtual Ethernet Port Aggregator (VEPA) */
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA	UINT32_C(0x2)
-	uint8_t unused_3;
+	uint8_t unused_2;
 	uint16_t alloc_vfs;
 	/*
 	 * The number of VFs that are allocated to the function. This is
-	 * valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if
+	 * 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.
 	 */
@@ -2247,9 +2841,9 @@ struct hwrm_func_qcfg_output {
 	uint16_t alloc_sp_tx_rings;
 	/*
 	 * The number of strict priority transmit rings out of currently
-	 * allocated TX rings to the function (alloc_tx_rings).
+	 * allocated TX rings to the function	(alloc_tx_rings).
 	 */
-	uint8_t unused_4;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -2261,15 +2855,14 @@ struct hwrm_func_qcfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_func_drv_rgtr */
+/* hwrm_func_vlan_qcfg */
 /*
- * 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.
+ * Description: This command should be called by PF driver to get the current
+ * C-TAG, S-TAG and correcponsing PCP and TPID values configured for the
+ * function.
  */
-/* Input (80 bytes) */
-struct hwrm_func_drv_rgtr_input {
+/* Input (24 bytes) */
+struct hwrm_func_vlan_qcfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2296,96 +2889,17 @@ struct hwrm_func_drv_rgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 enables;
-	/* 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_INPUT_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)
-	uint16_t os_type;
-	/* This value indicates the type of OS. */
-	/* Unknown */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Other OS not listed below. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
-	/* MSDOS OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
-	/* Windows OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
-	/* Solaris OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
-	/* Linux OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
-	/* FreeBSD OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
-	/* VMware ESXi OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
-	/* Microsoft Windows 8 64-bit OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
-	/* Microsoft Windows Server 2012 R2 OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
-	uint8_t ver_maj;
-	/* This is the major version of the driver. */
-	uint8_t ver_min;
-	/* This is the minor version of the driver. */
-	uint8_t ver_upd;
-	/* This is the update version of the driver. */
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint32_t timestamp;
-	/*
-	 * This is a 32-bit timestamp provided by the driver for keep
-	 * alive. The timestamp is in multiples of 1ms.
-	 */
-	uint32_t unused_2;
-	uint32_t vf_req_fwd[8];
-	/*
-	 * 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 async_event_fwd[8];
+	uint16_t fid;
 	/*
-	 * 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.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-} __attribute__((packed));
+	uint16_t unused_0[3];
+};
 
-/* Output (16 bytes) */
-struct hwrm_func_drv_rgtr_output {
+/* Output (40 bytes) */
+struct hwrm_func_vlan_qcfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2414,16 +2928,40 @@ struct hwrm_func_drv_rgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_4;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_5;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t rsvd3;
+	/* Future use. */
+	uint32_t unused_6;
+};
 
-/* hwrm_func_drv_unrgtr */
+/* hwrm_func_vlan_cfg */
 /*
- * 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.
+ * Description: This command allows PF driver to configure C-TAG, S-TAG and
+ * corresponding PCP and TPID values for a function.
  */
-/* Input (24 bytes) */
-struct hwrm_func_drv_unrgtr_input {
+/* Input (48 bytes) */
+struct hwrm_func_vlan_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2450,17 +2988,56 @@ struct hwrm_func_drv_unrgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint16_t fid;
 	/*
-	 * When this bit is '1', the function driver is notifying the
-	 * HWRM to prepare for the shutdown.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN	UINT32_C(0x1)
-	uint32_t unused_0;
-} __attribute__((packed));
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t enables;
+	/* This bit must be '1' for the stag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_VID	UINT32_C(0x1)
+	/* This bit must be '1' for the ctag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_VID	UINT32_C(0x2)
+	/* This bit must be '1' for the stag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_PCP	UINT32_C(0x4)
+	/* This bit must be '1' for the ctag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_PCP	UINT32_C(0x8)
+	/* This bit must be '1' for the stag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_TPID	UINT32_C(0x10)
+	/* This bit must be '1' for the ctag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_TPID	UINT32_C(0x20)
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_2;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_3;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd1;
+	/* Future use. */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t unused_4;
+};
 
 /* Output (16 bytes) */
-struct hwrm_func_drv_unrgtr_output {
+struct hwrm_func_vlan_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2489,19 +3066,45 @@ struct hwrm_func_drv_unrgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+};
 
-/* hwrm_port_phy_cfg */
+/* hwrm_func_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.
+ * Description: This command allows configuration of a PF by the corresponding
+ * PF driver. This command also allows configuration of a child VF by its parent
+ * PF driver. The input FID value is used to indicate what function is being
+ * configured. This allows a PF driver to configure the PF owned by itself or a
+ * virtual function that is a child of the PF. This command allows to reserve
+ * resources for a VF by its parent PF. To reverse the process, the command
+ * should be called with all enables flags cleared for resources. This will free
+ * allocated resources for the VF and return them to the resource pool. If this
+ * command is requested by a VF driver to configure or reserve resources, then
+ * the HWRM shall fail this command. If default MAC address and/or VLAN are
+ * provided in this command, then the HWRM shall set up appropriate MAC/VLAN
+ * filters for the function that is being configured. If source properties
+ * checks are enabled and default MAC address and/or IP address are provided in
+ * this command, then the HWRM shall set appropriate source property checks
+ * based on provided MAC and/or IP addresses. The parent PF driver should not
+ * set MTU/MRU for a VF using this command. This is to allow MTU/MRU setting by
+ * the VF driver. If the MTU or MRU for a VF is set by the PF driver, then the
+ * HWRM should ignore it. A function's MTU/MRU should be set prior to allocating
+ * RX VNICs or TX rings. A PF driver calls hwrm_func_cfg to allocate resources
+ * for itself or its children VFs. All function drivers shall call hwrm_func_cfg
+ * to reserve resources. A request to hwrm_func_cfg may not be fully granted;
+ * that is, a request for resources may be larger than what can be supported by
+ * the device and the HWRM will allocate the best set of resources available,
+ * but that may be less than requested. If all the amounts requested could not
+ * be fulfilled, the HWRM shall allocate what it could and return a status code
+ * of success. A function driver should call hwrm_func_qcfg immediately after
+ * hwrm_func_cfg to determine what resources were assigned to the configured
+ * function. A call by a PF driver to hwrm_func_cfg to allocate resources for
+ * itself shall only allocate resources for the PF driver to use, not for its
+ * children VFs. Likewise, a call to hwrm_func_qcfg shall return the resources
+ * available for the PF driver to use, not what is available to its children
+ * VFs.
  */
-/* Input (56 bytes) */
-struct hwrm_port_phy_cfg_input {
+/* Input	(88 bytes) */
+struct hwrm_func_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2528,397 +3131,560 @@ struct hwrm_port_phy_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF...	(All Fs), then the the configuration is for the
+	 * requesting function.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
 	uint32_t flags;
 	/*
-	 * 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.
+	 * When this bit is '1', the function is disabled with source
+	 * MAC address check. This is an anti-spoofing check. If this
+	 * flag is set, then the function shall be configured to
+	 * disallow transmission of frames with the source MAC address
+	 * that is configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY	UINT32_C(0x1)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE	 \
+		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.
+	 * When this bit is '1', the function is enabled with source MAC
+	 * address check. This is an anti-spoofing check. If this flag
+	 * is set, then the function shall be configured to allow
+	 * transmission of frames with the source MAC address that is
+	 * configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN	UINT32_C(0x2)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE	\
+		UINT32_C(0x2)
+	/* reserved */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_MASK	UINT32_C(0x1fc)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_SFT	2
 	/*
-	 * 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.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is requested to be
+	 * enabled on the function being configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE	UINT32_C(0x4)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE	\
+		UINT32_C(0x200)
 	/*
-	 * When this bit is set to '1', the auto-negotiation process
-	 * shall be restarted on the link.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then the standard TX ring mode is requested to be
+	 * disabled on the function being configured. In this extended
+	 * TX ring resource mode, the minimum and maximum bandwidth
+	 * settings are not supported to allow the allocation of TX
+	 * rings to span multiple scheduler nodes.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG	UINT32_C(0x8)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE	\
+		UINT32_C(0x400)
 	/*
-	 * 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.
+	 * If this bit is set, virtual mac address configured in this
+	 * command will be persistent over warm boot.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_VIRT_MAC_PERSIST	UINT32_C(0x800)
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MTU	UINT32_C(0x1)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MRU	UINT32_C(0x2)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_rsscos_ctxs field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS	UINT32_C(0x4)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_cmpl_rings field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_ENABLE	UINT32_C(0x40)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS	UINT32_C(0x8)
+	/* This bit must be '1' for the num_tx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS	UINT32_C(0x10)
+	/* This bit must be '1' for the num_rx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS	UINT32_C(0x20)
+	/* This bit must be '1' for the num_l2_ctxs field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS	UINT32_C(0x40)
+	/* This bit must be '1' for the num_vnics field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS	UINT32_C(0x80)
+	/*
+	 * This bit must be '1' for the num_stat_ctxs field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS	UINT32_C(0x100)
 	/*
-	 * When this bit is set to '1' and EEE is enabled on this link,
-	 * then TX LPI is requested to be disabled 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.
+	 * This bit must be '1' for the dflt_mac_addr field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR	UINT32_C(0x200)
+	/* This bit must be '1' for the dflt_vlan field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN	UINT32_C(0x400)
+	/* This bit must be '1' for the dflt_ip_addr field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_IP_ADDR	UINT32_C(0x800)
+	/* This bit must be '1' for the min_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MIN_BW	UINT32_C(0x1000)
+	/* This bit must be '1' for the max_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW	UINT32_C(0x2000)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_DISABLE	UINT32_C(0x80)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR	UINT32_C(0x4000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC
-	 * autonegotitation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the vlan_antispoof_mode field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE	UINT32_C(0x100)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE	UINT32_C(0x8000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC
-	 * autonegotiation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the allowed_vlan_pris field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	UINT32_C(0x200)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ALLOWED_VLAN_PRIS UINT32_C(0x10000)
+	/* This bit must be '1' for the evb_mode field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE	UINT32_C(0x20000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74 (Fire
-	 * Code) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_mcast_filters field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	UINT32_C(0x400)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MCAST_FILTERS UINT32_C(0x40000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
-	 * (Fire Code) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 74 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_hw_ring_grps field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	UINT32_C(0x800)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS UINT32_C(0x80000)
+	uint16_t mtu;
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91 (Reed
-	 * Solomon) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * The maximum transmission unit of the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed
+	 * the mtu of the physical port that this function is associated
+	 * with. In addition to configuring mtu per function, it is
+	 * possible to configure mtu per transmit ring. By default, the
+	 * mtu of each transmit ring associated with a function is equal
+	 * to the mtu of the function. The HWRM should make sure that
+	 * the mtu of each transmit ring that is assigned to a function
+	 * has a valid mtu.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	UINT32_C(0x1000)
+	uint16_t mru;
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
-	 * (Reed Solomon) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 91 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * The maximum receive unit of the function. The HWRM should
+	 * make sure that the mru of the function does not exceed the
+	 * mru of the physical port that this function is associated
+	 * with. In addition to configuring mru per function, it is
+	 * possible to configure mru per vnic. By default, the mru of
+	 * each vnic associated with a function is equal to the mru of
+	 * the function. The HWRM should make sure that the mru of each
+	 * vnic that is assigned to a function has a valid mru.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	UINT32_C(0x2000)
-	uint32_t enables;
-	/* 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)
+	uint16_t num_rsscos_ctxs;
+	/* The number of RSS/COS contexts requested for the function. */
+	uint16_t num_cmpl_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed field to be
-	 * configured.
+	 * The number of completion rings requested for the function.
+	 * This does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED	UINT32_C(0x8)
+	uint16_t num_tx_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed_mask field to be
-	 * configured.
+	 * The number of transmit rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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_WIOUTPUTEED	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)
+	uint16_t num_rx_rings;
 	/*
-	 * This bit must be '1' for the eee_link_speed_mask field to be
-	 * configured.
+	 * The number of receive rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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)
-	uint16_t port_id;
-	/* Port ID of port that is to be configured. */
-	uint16_t force_link_speed;
+	uint16_t num_l2_ctxs;
+	/* The requested number of L2 contexts for the function. */
+	uint16_t num_vnics;
+	/* The requested number of vnics for the function. */
+	uint16_t num_stat_ctxs;
+	/* The requested number of statistic contexts for the function. */
+	uint16_t num_hw_ring_grps;
 	/*
-	 * This is the speed that will be used if the force bit is '1'.
-	 * If unsupported speed is selected, an error will be generated.
+	 * The number of HW ring groups that should be reserved for this
+	 * function.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
+	uint8_t dflt_mac_addr[6];
+	/* The default MAC address for the function being configured. */
+	uint16_t dflt_vlan;
 	/*
-	 * This value is used to identify what autoneg mode is used when
-	 * the link speed is not being forced.
+	 * The default VLAN for the function being configured. This
+	 * field's format is same as 802.1Q Tag's Tag Control
+	 * Information	(TCI) format that includes both Priority Code
+	 * Point	(PCP) and VLAN Identifier	(VID).
 	 */
+	uint32_t dflt_ip_addr[4];
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * The default IP address for the function being configured.
+	 * This address is only used in enabling source property check.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	uint32_t min_bw;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Minimum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+	uint32_t max_bw;
+	/*
+	 * Maximum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK \
+		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous
+	 * event completions. If this field is not valid, then the HWRM
+	 * shall use the default completion ring of the function that is
+	 * being configured as the target completion ring for providing
+	 * any asynchronous event completions for that function. If this
+	 * field is valid, then the HWRM shall use the completion ring
+	 * identified by this ID as the target completion ring for
+	 * providing any asynchronous event completions for the function
+	 * that is being configured.
+	 */
+	uint8_t vlan_antispoof_mode;
+	/* VLAN Anti-spoofing mode. */
+	/* No VLAN anti-spoofing checks are enabled */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK	UINT32_C(0x0)
+	/* Validate VLAN against the configured VLAN(s) */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN \
+		UINT32_C(0x1)
+	/* Insert VLAN if it does not exist, otherwise discard */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_IF_VLANDNE \
+		UINT32_C(0x2)
 	/*
-	 * 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.
+	 * Insert VLAN if it does not exist, override
+	 * VLAN if it exists
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW	UINT32_C(0x3)
+	#define \
+	HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN \
+		UINT32_C(0x3)
+	uint8_t allowed_vlan_pris;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * This bit field defines VLAN PRIs that are allowed on this
+	 * function. If nth bit is set, then VLAN PRI n is allowed on
+	 * this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_duplex;
+	uint8_t evb_mode;
 	/*
-	 * This is the duplex setting that will be used if the
-	 * autoneg_mode is "one_speed" or "one_or_below".
+	 * The HWRM shall allow a PF driver to change EVB mode for the
+	 * partition it belongs to. The HWRM shall not allow a VF driver
+	 * to change the EVB mode. The HWRM shall take into account the
+	 * switching of EVB mode from one to another and reconfigure
+	 * hardware resources as appropriately. The switching from VEB
+	 * to VEPA mode requires the disabling of the loopback traffic.
+	 * Additionally, source knock outs are handled differently in
+	 * VEB and VEPA modes.
+	 */
+	/* No Edge Virtual Bridging	(EVB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
+	/* Virtual Ethernet Bridge	(VEB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEB	UINT32_C(0x1)
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA	UINT32_C(0x2)
+	uint8_t unused_2;
+	uint16_t num_mcast_filters;
+	/*
+	 * The number of multicast filters that should be reserved for
+	 * this function on the RX side.
 	 */
-	/* Half Duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
-	/* Both Half and Full dupex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
-	uint8_t auto_pause;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_cfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+} __attribute__((packed));
+
+/* hwrm_func_qstats */
+/*
+ * Description: This command returns statistics 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 HWRM shall return any unsupported counter with a value
+ * of 0xFFFFFFFF for 32-bit counters and 0xFFFFFFFFFFFFFFFF for 64-bit counters.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_qstats_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE	UINT32_C(0x4)
-	uint8_t unused_0;
-	uint16_t auto_link_speed;
+	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* This value controls the wirespeed feature. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* 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)
+	uint64_t resp_addr;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t fid;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Function ID of the function that is being queried. 0xFF...
+	 *	(All Fs) if the query is for the requesting function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(176 bytes) */
+struct hwrm_func_qstats_output {
+	uint16_t error_code;
 	/*
-	 * This value is used to configure the pause that will be used
-	 * for force mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
 	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets on the function. */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets on the function. */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets on the function. */
+	uint64_t tx_err_pkts;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of transmitted packets that were discarded due to
+	 * internal NIC resource problems. For transmit, this can only
+	 * happen if TMP is configured to allow dropping in HOL blocking
+	 * conditions, which is not a normal configuration.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	uint64_t tx_drop_pkts;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of dropped packets on transmit path on the function.
+	 * These are packets that have been marked for drop by the TE
+	 * CFA block or are packets that exceeded the transmit MTU limit
+	 * for the function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t unused_1;
-	uint32_t preemphasis;
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic on the function. */
+	uint64_t tx_mcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for multicast traffic on the
+	 * function.
 	 */
-	uint16_t eee_link_speed_mask;
+	uint64_t tx_bcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for broadcast traffic on the
+	 * function.
 	 */
-	/* 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)
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets on the function. */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets on the function. */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets on the function. */
+	uint64_t rx_err_pkts;
+	/*
+	 * Number of received packets that were discarded on the
+	 * function due to resource limitations. This can happen for 3
+	 * reasons. # The BD used for the packet has a bad format. #
+	 * There were no BDs available in the ring for the packet. #
+	 * There were no BDs available on-chip for the packet.
+	 */
+	uint64_t rx_drop_pkts;
+	/*
+	 * Number of dropped packets on received path on the function.
+	 * These are packets that have been marked for drop by the RE
+	 * CFA.
+	 */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic on the function. */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic on the function. */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic on the function. */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets on the function. */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes on the function. */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events on the function. */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations on the function. */
+	uint32_t unused_0;
+	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint32_t tx_lpi_timer;
-	uint32_t unused_4;
+	uint8_t valid;
 	/*
-	 * Reuested setting of TX LPI timer in microseconds. This field
-	 * is valid only when EEE is enabled and TX LPI is enabled.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK	UINT32_C(0xffffff)
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT	0
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_port_phy_cfg_output {
+/* hwrm_func_clr_stats */
+/*
+ * Description: This command clears statistics of a function. The input FID
+ * value is used to indicate what function's statistics is being cleared. This
+ * allows a physical function driver to clear statistics of virtual functions
+ * that are children of the physical function.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function. 0xFF...	(All Fs) if the query is
+	 * for the requesting function.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2949,10 +3715,10 @@ struct hwrm_port_phy_cfg_output {
 	 */
 } __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 {
+/* hwrm_func_vf_vnic_ids_query */
+/* Description: This command is used to query vf vnic ids. */
+/* Input	(32 bytes) */
+struct hwrm_func_vf_vnic_ids_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2979,13 +3745,21 @@ struct hwrm_port_phy_qcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint16_t port_id;
-	/* Port ID of port that is to be queried. */
-	uint16_t unused_0[3];
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_vnic_id_cnt;
+	/* Max number of vnic ids in vnic id table */
+	uint64_t vnic_id_tbl_addr;
+	/* This is the address for VF VNIC ID table */
 } __attribute__((packed));
 
-/* Output (96 bytes) */
-struct hwrm_port_phy_qcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_func_vf_vnic_ids_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3001,698 +3775,2769 @@ struct hwrm_port_phy_qcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t link;
-	/* 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)
-	/* There is no link, but a cable has been detected. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
-	/* There is a link. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t link_speed;
-	/* 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)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t duplex;
-	/* This value is indicates the duplex of the current connection. */
-	/* Half Duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
-	uint8_t pause;
+	uint32_t vnic_id_cnt;
 	/*
-	 * This value is used to indicate the current pause
-	 * configuration. When autoneg is enabled, this value represents
-	 * the autoneg results of pause configuration.
+	 * Actual number of vnic ids Each VNIC ID is written as a 32-bit
+	 * number.
 	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX	UINT32_C(0x1)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX	UINT32_C(0x2)
-	uint16_t support_speeds;
+	uint16_t cmpl_ring;
 	/*
-	 * 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)
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 enables;
+	/* 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_INPUT_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)
+	uint16_t os_type;
+	/*
+	 * This value indicates the type of OS. The values are based on
+	 * CIM_OperatingSystem.mof file as published by the DMTF.
+	 */
+	/* Unknown */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Other OS not listed below. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
+	/* MSDOS OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
+	/* Windows OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
+	/* Solaris OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
+	/* Linux OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
+	/* FreeBSD OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
+	/* VMware ESXi OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
+	/* Microsoft Windows 8 64-bit OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
+	/* Microsoft Windows Server 2012 R2 OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
+	uint8_t ver_maj;
+	/* This is the major version of the driver. */
+	uint8_t ver_min;
+	/* This is the minor version of the driver. */
+	uint8_t ver_upd;
+	/* This is the update version of the driver. */
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint32_t timestamp;
+	/*
+	 * This is a 32-bit timestamp provided by the driver for keep
+	 * alive. The timestamp is in multiples of 1ms.
+	 */
+	uint32_t unused_2;
+	uint32_t vf_req_fwd[8];
+	/*
+	 * 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 async_event_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.
+	 */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_rgtr */
+/*
+ * Description: This command is used by the PF driver to register buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * register buffers for each PF-VF channel. A parent PF may issue this command
+ * per child VF. If VF ID is not valid, then this command is used to register
+ * buffers for all children VFs of the PF.
+ */
+/* Input	(128 bytes) */
+struct hwrm_func_buf_rgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the err_buf_addr field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR	UINT32_C(0x2)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t req_buf_num_pages;
+	/*
+	 * This field represents the number of pages used for request
+	 * buffer(s).
+	 */
+	uint16_t req_buf_page_size;
+	/* This field represents the page size used for request buffer(s). */
+	/* 16 bytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_16B UINT32_C(0x4)
+	/* 4 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4K	UINT32_C(0xc)
+	/* 8 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_8K	UINT32_C(0xd)
+	/* 64 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_64K UINT32_C(0x10)
+	/* 2 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_2M	UINT32_C(0x15)
+	/* 4 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4M	UINT32_C(0x16)
+	/* 1 Gbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_1G	UINT32_C(0x1e)
+	uint16_t req_buf_len;
+	/* The length of the request buffer per VF in bytes. */
+	uint16_t resp_buf_len;
+	/* The length of the response buffer in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint64_t req_buf_page_addr[10];
+	/* This field represents the page address of req buffer. */
+	uint64_t error_buf_addr;
+	/*
+	 * This field is used to receive the error reporting from the
+	 * chipset. Only applicable for PFs.
+	 */
+	uint64_t resp_buf_addr;
+	/* This field is used to receive the response forwarded by the HWRM. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_unrgtr */
+/*
+ * Description: This command is used by the PF driver to unregister buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * unregister buffers for PF-VF communication. A parent PF may issue this
+ * command to unregister buffers for communication between the PF and a specific
+ * VF. If the VF ID is not valid, then this command is used to unregister
+ * buffers used for communications with all children VFs of the PF.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_buf_unrgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_UNRGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_vf_cfg */
+/*
+ * Description: This command allows configuration of a VF by its driver. If this
+ * function is called by a PF driver, then the HWRM shall fail this command. If
+ * guest VLAN and/or MAC address are provided in this command, then the HWRM
+ * shall set up appropriate MAC/VLAN filters for the VF that is being
+ * configured. A VF driver should set VF MTU/MRU using this command prior to
+ * allocating RX VNICs or TX rings for the corresponding VF.
+ */
+/* Input (32 bytes) */
+
+struct hwrm_func_vf_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_MTU                 UINT32_C(0x1)
+	/* This bit must be '1' for the guest_vlan field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_GUEST_VLAN          UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be configured.
+	 */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR      UINT32_C(0x4)
+	/* This bit must be '1' for the dflt_mac_addr field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR       UINT32_C(0x8)
+	uint16_t mtu;
+	/*
+	 * The maximum transmission unit requested on the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed the mtu
+	 * of the physical port that this function is associated with. In
+	 * addition to requesting mtu per function, it is possible to configure
+	 * mtu per transmit ring. By default, the mtu of each transmit ring
+	 * associated with a function is equal to the mtu of the function. The
+	 * HWRM should make sure that the mtu of each transmit ring that is
+	 * assigned to a function has a valid mtu.
+	 */
+	uint16_t guest_vlan;
+	/*
+	 * The guest VLAN for the function being configured. This field's format
+	 * is same as 802.1Q Tag's Tag Control Information (TCI) format that
+	 * includes both Priority Code Point (PCP) and VLAN Identifier (VID).
+	 */
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous event
+	 * completions. If this field is not valid, then the HWRM shall use the
+	 * default completion ring of the function that is being configured as
+	 * the target completion ring for providing any asynchronous event
+	 * completions for that function. If this field is valid, then the HWRM
+	 * shall use the completion ring identified by this ID as the target
+	 * completion ring for providing any asynchronous event completions for
+	 * the function that is being configured.
+	 */
+	uint8_t dflt_mac_addr[6];
+	/*
+	 * This value is the current MAC address requested by the VF driver to
+	 * be configured on this VF. A value of 00-00-00-00-00-00 indicates no
+	 * MAC address configuration is requested by the VF driver. The parent
+	 * PF driver may reject or overwrite this MAC address.
+	 */
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_vf_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* deprecated bit. Do not use!!! */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_DEPRECATED	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_ENABLE	UINT32_C(0x40)
+	/*
+	 * When this bit is set to '1' and EEE is enabled on this link,
+	 * then TX LPI is requested to be disabled 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_DISABLE UINT32_C(0x80)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC
+	 * autonegotitation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE UINT32_C(0x100)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC
+	 * autonegotiation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	\
+		UINT32_C(0x200)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74	(Fire
+	 * Code) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	\
+		UINT32_C(0x400)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
+	 *	(Fire Code) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 74 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	\
+		UINT32_C(0x800)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91	(Reed
+	 * Solomon) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	\
+		UINT32_C(0x1000)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
+	 *	(Reed Solomon) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 91 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	\
+		UINT32_C(0x2000)
+	/*
+	 * 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_DWN UINT32_C(0x4000)
+	uint32_t enables;
+	/* 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_WIOUTPUTEED	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)
+	uint16_t port_id;
+	/* Port ID of port that is to be configured. */
+	uint16_t force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_duplex;
+	/*
+	 * 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)
+	/* Full duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
+	/* Both Half and Full dupex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
+	uint8_t auto_pause;
+	/*
+	 * 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 unused_0;
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* This value controls the wirespeed feature. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 unused_1;
+	uint32_t preemphasis;
+	/*
+	 * 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.
+	 */
+	uint16_t eee_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t tx_lpi_timer;
+	uint32_t unused_4;
+	/*
+	 * 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
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_phy_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is to be queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(96 bytes) */
+struct hwrm_port_phy_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t link;
+	/* 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)
+	/* There is no link, but a cable has been detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
+	/* There is a link. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
+	uint8_t unused_0;
+	uint16_t link_speed;
+	/* 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t duplex;
+	/* This value is indicates the duplex of the current connection. */
+	/* Half Duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
+	/* Full duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
+	uint8_t pause;
+	/*
+	 * 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)
+	uint16_t support_speeds;
+	/*
+	 * 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 force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/* 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_pause;
+	/*
+	 * 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)
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* Current setting for wirespeed. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* Current setting for loopback. */
+	/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 module_status;
+	/*
+	 * 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)
+	/* Module is rejected and transmit side Laser is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX UINT32_C(0x1)
+	/* Module mismatch warning. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG UINT32_C(0x2)
+	/* Module is rejected and powered down. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
+	/* Module is not inserted. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+		UINT32_C(0x4)
+	/* Module status is not applicable. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+		UINT32_C(0xff)
+	uint32_t preemphasis;
+	/* Current setting for preemphasis. */
+	uint8_t phy_maj;
+	/* This field represents the major version of the PHY. */
+	uint8_t phy_min;
+	/* This field represents the minor version of the PHY. */
+	uint8_t phy_bld;
+	/* This field represents the build version of the PHY. */
+	uint8_t phy_type;
+	/* This value represents a PHY type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* BASE-CR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
+	/* BASE-KR4	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
+	/* BASE-LR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
+	/* BASE-SR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
+	/* BASE-KR2	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
+	/* BASE-KX */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
+	/* BASE-KR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
+	/* BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
+	/* EEE capable BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
+	/* SGMII connected external PHY */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
+	/* 25G_BASECR_CA_L */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L UINT32_C(0xb)
+	/* 25G_BASECR_CA_S */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S UINT32_C(0xc)
+	/* 25G_BASECR_CA_N */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N UINT32_C(0xd)
+	/* 25G_BASESR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR	UINT32_C(0xe)
+	/* 100G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4	UINT32_C(0xf)
+	/* 100G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4	UINT32_C(0x10)
+	/* 100G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4	UINT32_C(0x11)
+	/* 100G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4	UINT32_C(0x12)
+	/* 100G_BASESR10 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10 UINT32_C(0x13)
+	/* 40G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4	UINT32_C(0x14)
+	/* 40G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4	UINT32_C(0x15)
+	/* 40G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4	UINT32_C(0x16)
+	/* 40G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4	UINT32_C(0x17)
+	/* 40G_ACTIVE_CABLE */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE \
+		UINT32_C(0x18)
+	uint8_t media_type;
+	/* This value represents a media type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Twisted Pair */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
+	/* Direct Attached Copper */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
+	/* Fiber */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
+	uint8_t xcvr_pkg_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)
+	/* PHY and MAC are in different packages */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+		UINT32_C(0x2)
+	uint8_t eee_config_phy_addr;
+	/*
+	 * 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 parallel_detect;
+	/* 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
+	uint16_t link_partner_adv_speeds;
+	/*
+	 * 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_SUPPORT_SPEEDS_2GB	UINT32_C(0x10)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB	\
+		UINT32_C(0x10)
 	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB	UINT32_C(0x20)
+	#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)
+	uint8_t link_partner_adv_auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t link_partner_adv_pause;
+	/* 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)
+	uint16_t adv_eee_link_speed_mask;
+	/*
+	 * 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 link_partner_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_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 force_link_speed;
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+		UINT32_C(0x40)
+	uint32_t xcvr_identifier_type_tx_lpi_timer;
+	/* 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)
+	uint16_t fec_cfg;
+	/*
+	 * This value represents the current configuration of Forward
+	 * Error Correction	(FEC) on the port.
+	 */
+	/*
+	 * When set to 1, then FEC is not supported on this port. If
+	 * this flag is set to 1, then all other FEC configuration flags
+	 * shall be ignored. When set to 0, then FEC is supported as
+	 * indicated by other configuration flags. If no cable is
+	 * attached and the HWRM does not yet know the FEC capability,
+	 * then the HWRM shall set this flag to 1 when reporting FEC
+	 * capability.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	 \
+		UINT32_C(0x1)
+	/*
+	 * When set to 1, then FEC autonegotiation is supported on this
+	 * port. When set to 0, then FEC autonegotiation is not
+	 * supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
+		UINT32_C(0x2)
+	/*
+	 * When set to 1, then FEC autonegotiation is enabled on this
+	 * port. When set to 0, then FEC autonegotiation is disabled if
+	 * supported. This flag should be ignored if FEC autonegotiation
+	 * is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
+		UINT32_C(0x4)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is supported on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
+		UINT32_C(0x8)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is enabled on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * disabled if supported. This flag should be ignored if FEC
+	 * CLAUSE 74 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
+		UINT32_C(0x10)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is supported
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
+		UINT32_C(0x20)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is enabled
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is disabled if supported. This flag should be
+	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
+		UINT32_C(0x40)
+	uint8_t unused_1;
+	uint8_t unused_2;
+	char phy_vendor_name[16];
+	/*
+	 * 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_partnumber[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.
+	 */
+	uint32_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_qstats */
+/* Description: This function returns per port Ethernet statistics. */
+/* Input	(40 bytes) */
+struct hwrm_port_qstats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2[3];
+	uint8_t unused_3;
+	uint64_t tx_stat_host_addr;
+	/* This is the host address where Tx port statistics will be stored */
+	uint64_t rx_stat_host_addr;
+	/* This is the host address where Rx port statistics will be stored */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_qstats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tx_stat_size;
+	/* The size of TX port statistics block in bytes. */
+	uint16_t rx_stat_size;
+	/* The size of RX port statistics block in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_clr_stats */
+/*
+ * Description: This function clears per port statistics. The HWRM shall not
+ * allow a VF driver to clear port statistics. The HWRM shall not allow a PF
+ * driver to clear port statistics in a partitioning mode. The HWRM may allow a
+ * PF driver to clear port statistics in the non-partitioning mode.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* rx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+	uint16_t port_id;
+	/*
+	 * Port ID of port for which the queue configuration is being
+	 * queried. This field is only required when sent by IPC.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_queue_qportcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t max_configurable_queues;
+	/*
+	 * The maximum number of queues that can be configured on this
+	 * port. Valid values range from 1 through 8.
+	 */
+	uint8_t max_configurable_lossless_queues;
+	/*
+	 * The maximum number of lossless queues that can be configured
+	 * on this port. Valid values range from 0 through 8.
+	 */
+	uint8_t queue_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_cfg command. Each bit represents a specific queue
+	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
+	 * # A value of 0 indicates that the queue is not configurable
+	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
+	 * the queue is configurable. # A hwrm_queue_cfg command shall
+	 * return error when trying to configure a queue not
+	 * configurable.
+	 */
+	uint8_t queue_cfg_info;
+	/* Information about queue configuration. */
+	/*
+	 * If this flag is set to '1', then the queues are configured
+	 * asymmetrically on TX and RX sides. If this flag is set to
+	 * '0', then the queues are configured symmetrically on TX and
+	 * RX sides. For symmetric configuration, the queue
+	 * configuration including queue ids and service profiles on the
+	 * TX side is the same as the corresponding queue configuration
+	 * on the RX side.
+	 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG UINT32_C(0x1)
+	uint8_t queue_pfcenable_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
+	 * specific priority where bit 0 represents priority 0 and bit 7
+	 * represents priority 7. # A value of 0 indicates that the
+	 * priority is not configurable by the hwrm_queue_pfcenable_cfg
+	 * command. # A value of 1 indicates that the priority is
+	 * configurable. # A hwrm_queue_pfcenable_cfg command shall
+	 * return error when trying to configure a priority that is not
+	 * configurable.
+	 */
+	uint8_t queue_pri2cos_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue that is not configurable.
+	 */
+	uint8_t queue_cos2bw_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue not configurable.
+	 */
+	uint8_t queue_id0;
+	/*
+	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id0_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id1;
+	/*
+	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id1_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id2;
+	/*
+	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id2_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id3;
+	/*
+	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id3_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id4;
+	/*
+	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id4_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id5;
+	/*
+	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id5_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * Current setting of forced link speed. When the link speed is
-	 * not being forced, this value shall be set to 0.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB	\
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id6;
+	/*
+	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	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)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB	\
-		UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB	\
-		UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
-	/* Current setting of auto negotiation mode. */
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id7;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	uint8_t queue_id7_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * 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.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW	\
-		UINT32_C(0x3)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_pause;
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Current setting of pause autonegotiation. Move autoneg_pause
-	 * flag here.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE	\
-		UINT32_C(0x4)
-	uint16_t auto_link_speed;
+	uint32_t flags;
 	/*
-	 * Current setting for auto_link_speed. This field is only valid
-	 * when auto_mode is set to "one_speed" or "one_or_below".
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_free_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+} __attribute__((packed));
+
+/* hwrm_vnic_cfg */
+/* Description: Configure the RX VNIC structure. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_cfg_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* Current setting for wirespeed. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* Current setting for loopback. */
-	/* No loopback is selected. Normal operation. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	uint16_t cmpl_ring;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint64_t resp_addr;
 	/*
-	 * Current setting of forced pause. When the pause configuration
-	 * is not being forced, then this value shall be set to 0.
+	 * 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.
 	 */
+	uint32_t flags;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * When this bit is '1', the VNIC is requested to be the default
+	 * VNIC for the function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t module_status;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * This value indicates the current status of the optics module
-	 * on this port.
+	 * 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.
 	 */
-	/* Module is inserted and accepted */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE	UINT32_C(0x0)
-	/* Module is rejected and transmit side Laser is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX	\
-		UINT32_C(0x1)
-	/* Module mismatch warning. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG	\
-		UINT32_C(0x2)
-	/* Module is rejected and powered down. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
-	/* Module is not inserted. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED	\
-		UINT32_C(0x4)
-	/* Module status is not applicable. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE	\
-		UINT32_C(0xff)
-	uint32_t preemphasis;
-	/* Current setting for preemphasis. */
-	uint8_t phy_maj;
-	/* This field represents the major version of the PHY. */
-	uint8_t phy_min;
-	/* This field represents the minor version of the PHY. */
-	uint8_t phy_bld;
-	/* This field represents the build version of the PHY. */
-	uint8_t phy_type;
-	/* This value represents a PHY type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* BASE-CR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
-	/* BASE-KR4 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
-	/* BASE-LR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
-	/* BASE-SR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
-	/* BASE-KR2 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
-	/* BASE-KX */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
-	/* BASE-KR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
-	/* BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
-	/* EEE capable BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
-	/* SGMII connected external PHY */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
-	uint8_t media_type;
-	/* This value represents a media type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Twisted Pair */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
-	/* Direct Attached Copper */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
-	/* Fiber */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
-	uint8_t xcvr_pkg_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)
-	/* PHY and MAC are in different packages */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL	\
-		UINT32_C(0x2)
-	uint8_t eee_config_phy_addr;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * 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).
+	 * 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.
 	 */
-	/* 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
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * 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_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED	\
-		UINT32_C(0x20)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. This flag is used to enable a mode where RSS is enabled
+	 * in the VNIC using a RSS context for computing RSS hash but
+	 * the RSS indirection table is not configured using
+	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
+	 * should not program RSS indirection table for the RSS context
+	 * that is used for computing RSS hash only.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE	UINT32_C(0x40)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t enables;
 	/*
-	 * 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.
+	 * This bit must be '1' for the dflt_ring_grp field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI	UINT32_C(0x80)
+	#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)
+	uint16_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t dflt_ring_grp;
 	/*
-	 * 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).
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK	UINT32_C(0xe0)
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT	5
-	uint8_t parallel_detect;
-	/* Reserved field, set to 0 */
+	uint16_t rss_rule;
 	/*
-	 * 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.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#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
-	uint16_t link_partner_adv_speeds;
+	uint16_t cos_rule;
 	/*
-	 * The advertised speeds for the port by the link partner. Each
-	 * advertised speed will be set to '1'.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	/* 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)
-	uint8_t link_partner_adv_auto_mode;
+	uint16_t lb_rule;
 	/*
-	 * The advertised autoneg for the port by the link partner. This
-	 * field is deprecated and should be set to 0.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
+	uint16_t mru;
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
-		UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
-	UINT32_C(0x1)
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_cfg_output {
+	uint16_t error_code;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
-		UINT32_C(0x2)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
-	UINT32_C(0x3)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK \
-	UINT32_C(0x4)
-	uint8_t link_partner_adv_pause;
-	/* The advertised pause settings on the port by the link partner. */
+} __attribute__((packed));
+
+/* hwrm_vnic_qcfg */
+/*
+ * Description: Query the RX VNIC structure. This function can be used by a PF
+ * driver to query its own VNIC resource or VNIC resource of its child VF. This
+ * function can also be used by a VF driver to query its own VNIC resource.
+ */
+/* Input	(32 bytes) */
+struct hwrm_vnic_qcfg_input {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX	\
-		UINT32_C(0x1)
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX	\
-		UINT32_C(0x2)
-	uint16_t adv_eee_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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 link_partner_adv_eee_link_speed_mask;
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 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)
-	uint32_t xcvr_identifier_type_tx_lpi_timer;
-	/* This value represents transceiver identifier type. */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID	UINT32_C(0x1)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t vf_id;
+	/* ID of Virtual Function whose VNIC resource is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_vnic_qcfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#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)
-	uint16_t fec_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This value represents the current configuration of Forward
-	 * Error Correction (FEC) on the port.
+	 * 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 dflt_ring_grp;
+	/* Default Completion ring for the VNIC. */
+	uint16_t rss_rule;
 	/*
-	 * When set to 1, then FEC is not supported on this port. If
-	 * this flag is set to 1, then all other FEC configuration flags
-	 * shall be ignored. When set to 0, then FEC is supported as
-	 * indicated by other configuration flags. If no cable is
-	 * attached and the HWRM does not yet know the FEC capability,
-	 * then the HWRM shall set this flag to 1 when reporting FEC
-	 * capability.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	\
-		UINT32_C(0x1)
+	uint16_t cos_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is supported on this
-	 * port. When set to 0, then FEC autonegotiation is not
-	 * supported on this port.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
-		UINT32_C(0x2)
+	uint16_t lb_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is enabled on this
-	 * port. When set to 0, then FEC autonegotiation is disabled if
-	 * supported. This flag should be ignored if FEC autonegotiation
-	 * is not supported on this port.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
-		UINT32_C(0x4)
+	uint16_t mru;
+	/* The maximum receive unit of the vnic. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t flags;
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is supported on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * not supported on this port.
+	 * When this bit is '1', the VNIC is the default VNIC for the
+	 * function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
-		UINT32_C(0x8)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is enabled on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * disabled if supported. This flag should be ignored if FEC
-	 * CLAUSE 74 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled
+	 * on this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
-		UINT32_C(0x10)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is supported
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to buffer
+	 * receive packets in the hardware until the host posts new
+	 * receive buffers. If set to '0', then bd_stall is disabled on
+	 * this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
-		UINT32_C(0x20)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is enabled
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is disabled if supported. This flag should be
-	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is
+	 * not configured to operate in dual VNIC mode.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
-		UINT32_C(0x40)
-	uint8_t unused_1;
-	uint8_t unused_2;
-	char phy_vendor_name[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * When this flag is set to '1', the VNIC is configured to
+	 * receive only RoCE traffic. When this flag is set to '0', the
+	 * VNIC is not configured to receive only RoCE traffic. If
+	 * roce_dual_vnic_mode flag and this flag both are set to '1',
+	 * then it is an invalid configuration of the VNIC. The HWRM
+	 * should not allow that type of mis-configuration by HWRM
+	 * clients.
 	 */
-	char phy_vendor_partnumber[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. When this bit is set to '1', then the VNIC is enabled
+	 * in a mode where RSS is enabled in the VNIC using a RSS
+	 * context for computing RSS hash but the RSS indirection table
+	 * is not configured.
 	 */
-	uint32_t unused_3;
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t unused_2;
+	uint8_t unused_3;
 	uint8_t unused_4;
 	uint8_t unused_5;
-	uint8_t unused_6;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -3704,19 +6549,10 @@ struct hwrm_port_phy_qcfg_output {
 	 */
 } __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 {
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+/* Input	(48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -3743,29 +6579,53 @@ struct hwrm_queue_qportcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t hash_type;
 	/*
-	 * 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.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source and destination IPv4 addresses of IPv4 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX	UINT32_C(0x0)
-	/* rx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST	\
-		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
-	uint16_t port_id;
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4	UINT32_C(0x1)
 	/*
-	 * Port ID of port for which the queue configuration is being
-	 * queried. This field is only required when sent by IPC.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination
+	 * ports of TCP/IPv4 packets.
 	 */
-	uint16_t unused_0;
+	#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 unused_0;
+	uint64_t ring_grp_tbl_addr;
+	/* This is the address for rss ring group table */
+	uint64_t hash_key_tbl_addr;
+	/* This is the address for rss hash key table */
+	uint16_t rss_ctx_idx;
+	/* Index to the rss indirection table. */
+	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (32 bytes) */
-struct hwrm_queue_qportcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3781,265 +6641,363 @@ struct hwrm_queue_qportcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t max_configurable_queues;
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * The maximum number of queues that can be configured on this
-	 * port. Valid values range from 1 through 8.
+	 * 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 max_configurable_lossless_queues;
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_cfg */
+/*
+ * Description: This function can be used to set placement mode configuration of
+ * the VNIC.
+ */
+/* Input (40 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_input {
+	uint16_t req_type;
 	/*
-	 * The maximum number of lossless queues that can be configured
-	 * on this port. Valid values range from 0 through 8.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
-	uint8_t queue_cfg_allowed;
+	uint16_t cmpl_ring;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_cfg command. Each bit represents a specific queue
-	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
-	 * # A value of 0 indicates that the queue is not configurable
-	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
-	 * the queue is configurable. # A hwrm_queue_cfg command shall
-	 * return error when trying to configure a queue not
-	 * configurable.
+	 * 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.
 	 */
-	uint8_t queue_cfg_info;
-	/* Information about queue configuration. */
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * If this flag is set to '1', then the queues are configured
-	 * asymmetrically on TX and RX sides. If this flag is set to
-	 * '0', then the queues are configured symmetrically on TX and
-	 * RX sides. For symmetric configuration, the queue
-	 * configuration including queue ids and service profiles on the
-	 * TX side is the same as the corresponding queue configuration
-	 * on the RX side.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to use regular
+	 * placement algorithm. By default, the regular placement algorithm
+	 * shall be enabled on the VNIC.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG	\
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
-	uint8_t queue_pfcenable_cfg_allowed;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pfcenable_cfg command.
-	 * # A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pfcenable_cfg command shall return error when
-	 * trying to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured use the jumbo
+	 * placement algorithm.
 	 */
-	uint8_t queue_pri2cos_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv4 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv4, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv4, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv4 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv4 packet.
 	 */
-	uint8_t queue_cos2bw_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4        UINT32_C(0x4)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv6 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv6, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv6, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv6 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv6 packet.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6        UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for FCoE packets at the beginning of FC payload.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_FCOE       UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for RoCE packets at the beginning of RoCE payload (after
+	 * BTH/GRH headers).
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_ROCE       UINT32_C(0x20)
+	uint32_t enables;
+	/*
+	 * This bit must be '1' for the jumbo_thresh_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID \
+		UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the hds_offset_valid field to be configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID \
+		UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the hds_threshold_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID \
+		UINT32_C(0x4)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t jumbo_thresh;
+	/*
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
+	 */
+	uint16_t hds_offset;
+	/*
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
+	 */
+	uint16_t hds_threshold;
+	/*
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_qcfg */
+/*
+ * Description: This function can be used to query placement mode configuration
+ * of the VNIC.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
-	uint8_t queue_id0;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id0_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC is configured to use regular placement
+	 * algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to use the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id1;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv4 packets.
 	 */
-	uint8_t queue_id1_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV4      UINT32_C(0x4)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv6 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id2;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV6      UINT32_C(0x8)
 	/*
-	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for FCoE packets.
 	 */
-	uint8_t queue_id2_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_FCOE     UINT32_C(0x10)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for RoCE packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id3;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_ROCE     UINT32_C(0x20)
 	/*
-	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to be the default VNIC
+	 * of the requesting function.
 	 */
-	uint8_t queue_id3_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC    UINT32_C(0x40)
+	uint16_t jumbo_thresh;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id4;
+	uint16_t hds_offset;
 	/*
-	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
 	 */
-	uint8_t queue_id4_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t hds_threshold;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id5;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t valid;
 	/*
-	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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 queue_id5_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_alloc */
+/* Description: This function is used to allocate COS/Load Balance context. */
+/* Input	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+	uint16_t req_type;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id6;
+	uint16_t cmpl_ring;
 	/*
-	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	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)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id7;
+	uint64_t resp_addr;
 	/*
-	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id7_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+	uint16_t error_code;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4051,25 +7009,10 @@ struct hwrm_queue_qportcfg_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4096,17 +7039,13 @@ struct hwrm_vnic_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 unused_0;
+	uint16_t rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4122,11 +7061,10 @@ struct hwrm_vnic_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t vnic_id;
-	/* Logical vnic ID */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4134,18 +7072,14 @@ struct hwrm_vnic_alloc_output {
 	 * 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.
-	 */
-} __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 field is written last.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_tpa_cfg */
+/* Description: This function is used to enable/configure TPA on the VNIC. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_tpa_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4172,13 +7106,122 @@ struct hwrm_vnic_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of non-tunneled TCP
+	 * packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of tunneled TCP packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Windows
+	 * Receive Segment Coalescing	(RSC) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Linux
+	 * Generic Receive Offload	(GRO) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for TCP packets with IP
+	 * ECN set to non-zero.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for GRE tunneled TCP
+	 * packets only if all packets have the same GRE sequence.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ	\
+		UINT32_C(0x20)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP/IPv4 packets with consecutively increasing
+	 * IPIDs. In other words, the last packet that is being
+	 * aggregated to an already existing aggregation context shall
+	 * have IPID 1 more than the IPID of the last packet that was
+	 * aggregated in that aggregation context.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_IPID_CHECK	UINT32_C(0x40)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP packets with the same TTL	(IPv4) or Hop limit
+	 *	(IPv6) value.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_TTL_CHECK	UINT32_C(0x80)
+	uint32_t enables;
+	/* This bit must be '1' for the max_agg_segs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS	UINT32_C(0x1)
+	/* This bit must be '1' for the max_aggs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS	UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the max_agg_timer field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER	UINT32_C(0x4)
+	/* This bit must be '1' for the min_agg_len field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN	UINT32_C(0x8)
+	uint16_t vnic_id;
 	/* Logical vnic ID */
-	uint32_t unused_0;
+	uint16_t max_agg_segs;
+	/*
+	 * This is the maximum number of TCP segments that can be
+	 * aggregated	(unit is Log2). Max value is 31.
+	 */
+	/* 1 segment */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1	UINT32_C(0x0)
+	/* 2 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2	UINT32_C(0x1)
+	/* 4 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4	UINT32_C(0x2)
+	/* 8 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8	UINT32_C(0x3)
+	/* Any segment size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX	UINT32_C(0x1f)
+	uint16_t max_aggs;
+	/*
+	 * This is the maximum number of aggregations this VNIC is
+	 * allowed	(unit is Log2). Max value is 7
+	 */
+	/* 1 aggregation */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1	UINT32_C(0x0)
+	/* 2 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2	UINT32_C(0x1)
+	/* 4 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4	UINT32_C(0x2)
+	/* 8 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8	UINT32_C(0x3)
+	/* 16 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16	UINT32_C(0x4)
+	/* Any aggregation size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX	UINT32_C(0x7)
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_agg_timer;
+	/*
+	 * This is the maximum amount of time allowed for an aggregation
+	 * context to complete after it was initiated.
+	 */
+	uint32_t min_agg_len;
+	/*
+	 * This is the minimum amount of payload length required to
+	 * start an aggregation context.
+	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_free_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_tpa_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4209,10 +7252,13 @@ struct hwrm_vnic_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_cfg */
-/* Description: Configure the RX VNIC structure. */
-/* Input (40 bytes) */
-struct hwrm_vnic_cfg_input {
+
+/* hwrm_ring_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a ring.
+ */
+/* Input	(80 bytes) */
+struct hwrm_ring_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4239,103 +7285,295 @@ struct hwrm_vnic_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t enables;
+	/* 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 ring_arb_cfg field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
 	/*
-	 * When this bit is '1', the VNIC is requested to be the default
-	 * VNIC for the function.
+	 * This bit must be '1' for the stat_ctx_id_valid field to be
+	 * configured.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
+	#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)
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint64_t page_tbl_addr;
+	/* This value is a pointer to the page table for the Ring. */
+	uint32_t fbo;
+	/* First Byte Offset of the first entry in the first page. */
+	uint8_t page_size;
 	/*
-	 * 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.
+	 * 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. - 21 = 2
+	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
+	 * GB Page size is 1 GB.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	uint8_t page_tbl_depth;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t length;
 	/*
-	 * 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.
+	 * Number of 16B units in the ring. Minimum size for a ring is
+	 * 16 16B entries.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	uint16_t logical_id;
 	/*
-	 * 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'.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	uint16_t cmpl_ring_id;
 	/*
-	 * When a VNIC uses one destination ring group for certain
-	 * application (e.g. Receive Flow Steering) where exact match is
-	 * used to direct packets to a VNIC with one destination ring
-	 * group only, there is no need to configure RSS indirection
-	 * table for that VNIC as only one destination ring group is
-	 * used. This flag is used to enable a mode where RSS is enabled
-	 * in the VNIC using a RSS context for computing RSS hash but
-	 * the RSS indirection table is not configured using
-	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
-	 * should not program RSS indirection table for the RSS context
-	 * that is used for computing RSS hash only.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what completion ring the TX ring is
+	 * associated with.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
-	uint32_t enables;
+	uint16_t queue_id;
 	/*
-	 * This bit must be '1' for the dflt_ring_grp field to be
-	 * configured.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what CoS queue the TX ring is associated
+	 * with.
 	 */
-	#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)
-	uint16_t vnic_id;
-	/* Logical vnic ID */
-	uint16_t dflt_ring_grp;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint32_t reserved1;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint16_t ring_arb_cfg;
+	/*
+	 * This field is used only when ring_type is a TX ring. This
+	 * field is used to configure arbitration related parameters for
+	 * a TX ring.
+	 */
+	/* Arbitration policy used for the ring. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK UINT32_C(0xf)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	/*
+	 * Use strict priority for the TX ring. Priority
+	 * value is specified in arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP \
+		(UINT32_C(0x1) << 0)
+	/*
+	 * Use weighted fair queue arbitration for the
+	 * TX ring. Weight is specified in
+	 * arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ \
+		(UINT32_C(0x2) << 0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST \
+		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
+	/* Reserved field. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	/*
+	 * Arbitration policy specific parameter. # For strict priority
+	 * arbitration policy, this field represents a priority value.
+	 * If set to 0, then the priority is not specified and the HWRM
+	 * is allowed to select any priority for this TX ring. # For
+	 * weighted fair queue arbitration policy, this field represents
+	 * a weight value. If set to 0, then the weight is not specified
+	 * and the HWRM is allowed to select any weight for this TX
+	 * ring.
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
+		UINT32_C(0xff00)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT	8
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint32_t reserved3;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t stat_ctx_id;
+	/*
+	 * 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 reserved4;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t max_bw;
+	/*
+	 * This field is used only when ring_type is a TX ring to
+	 * specify maximum BW allocated to the TX ring. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for this ring inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES (UINT32_C(0x1) << 28)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_LAST \
+		RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
+		UINT32_C(0xe0000000)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint8_t int_mode;
+	/*
+	 * 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)
+	/* Reserved */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
+	/* MSI-X */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
+	/* No Interrupt - Polled mode */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
+	uint8_t unused_8[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_ring_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 ring_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.
+	 * Physical number of ring allocated. This value shall be unique
+	 * for a ring type.
 	 */
-	uint16_t rss_rule;
+	uint16_t logical_ring_id;
+	/* Logical number of ring allocated. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
-	 * there is no RSS rule.
+	 * 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.
 	 */
-	uint16_t cos_rule;
+} __attribute__((packed));
+
+/* hwrm_ring_free */
+/*
+ * Description: This command is used to free a ring and associated resources.
+ * With QoS and DCBx agents, it is possible the traffic classes will be moved
+ * from one CoS queue to another. When this occurs, the driver shall call
+ * 'hwrm_ring_free' to free the allocated rings and then call 'hwrm_ring_alloc'
+ * to re-allocate each ring and assign it to a new CoS queue. hwrm_ring_free
+ * shall be called on a ring only after it has been idle for 500ms or more and
+ * no frames have been posted to the ring during this time. All frames queued
+ * for transmission shall be completed and at least 500ms time elapsed from the
+ * last completion before calling this command.
+ */
+/* Input	(24 bytes) */
+struct hwrm_ring_free_input {
+	uint16_t req_type;
 	/*
-	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
-	 * there is no COS rule.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	uint16_t lb_rule;
+	uint16_t cmpl_ring;
 	/*
-	 * RSS ID for load balancing rule/table structure. 0xFF... (All
-	 * Fs) if there is no LB rule.
+	 * 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 mru;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t unused_0;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t ring_id;
+	/* Physical number of ring allocated. */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4366,10 +7604,12 @@ struct hwrm_vnic_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cfg */
-/* Description: This function is used to enable RSS configuration. */
-/* Input (48 bytes) */
-struct hwrm_vnic_rss_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4396,53 +7636,25 @@ struct hwrm_vnic_rss_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t hash_type;
-	/*
-	 * 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)
+	uint16_t cr;
+	/* This value identifies the CR associated with the ring group. */
+	uint16_t rr;
+	/* This value identifies the main RR associated with the ring group. */
+	uint16_t ar;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of TCP/IPv6 packets.
+	 * 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.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
+	uint16_t sc;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of UDP/IPv6 packets.
+	 * This value identifies the statistics context associated with
+	 * the ring group.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6	UINT32_C(0x20)
-	uint32_t unused_0;
-	uint64_t ring_grp_tbl_addr;
-	/* This is the address for rss ring group table */
-	uint64_t hash_key_tbl_addr;
-	/* This is the address for rss hash key table */
-	uint16_t rss_ctx_idx;
-	/* Index to the rss indirection table. */
-	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4458,10 +7670,15 @@ struct hwrm_vnic_rss_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t ring_group_id;
+	/*
+	 * 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.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4473,10 +7690,17 @@ struct hwrm_vnic_rss_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cos_lb_ctx_alloc */
-/* Description: This function is used to allocate COS/Load Balance context. */
-/* Input (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4503,10 +7727,13 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint32_t ring_group_id;
+	/* This is the ring group ID value. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4522,13 +7749,10 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4540,10 +7764,64 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4556,269 +7834,355 @@ struct hwrm_vnic_rss_cos_lb_ctx_free_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 \
+		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 enables;
+	/* 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)
+	uint8_t l2_addr[6];
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the match value for the L2 MAC address.
+	 * Destination MAC address for RX path. Source MAC address for
+	 * TX path.
 	 */
-	uint64_t resp_addr;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t l2_addr_mask[6];
 	/*
-	 * 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.
+	 * This value sets the mask value for the L2 address. A value of
+	 * 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint16_t unused_0[3];
-} __attribute__((packed));
-
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_free_output {
-	uint16_t error_code;
+	uint16_t l2_ovlan;
+	/* This value sets VLAN ID value for outer VLAN. */
+	uint16_t l2_ovlan_mask;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * This value sets the mask value for the ovlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
+	uint16_t l2_ivlan;
+	/* This value sets VLAN ID value for inner VLAN. */
+	uint16_t l2_ivlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the ivlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t valid;
+	uint8_t t_l2_addr[6];
 	/*
-	 * 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.
+	 * This value sets the match value for the tunnel L2 MAC
+	 * address. Destination MAC address for RX path. Source MAC
+	 * address for TX path.
 	 */
-} __attribute__((packed));
-
-/* hwrm_ring_alloc */
-/*
- * Description: This command allocates and does basic preparation for a ring.
- */
-/* Input (80 bytes) */
-struct hwrm_ring_alloc_input {
-	uint16_t req_type;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t t_l2_addr_mask[6];
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value sets the mask value for the tunnel L2 address. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t cmpl_ring;
+	uint16_t t_l2_ovlan;
+	/* This value sets VLAN ID value for tunnel outer VLAN. */
+	uint16_t t_l2_ovlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the tunnel ovlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t t_l2_ivlan;
+	/* This value sets VLAN ID value for tunnel inner VLAN. */
+	uint16_t t_l2_ivlan_mask;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the mask value for the tunnel ivlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint64_t resp_addr;
+	uint8_t src_type;
+	/* 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)
+	/* Physical function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
+	/* Virtual function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
+	/* Virtual NIC of a function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
+	/* Embedded processor for CFA management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
+	/* Embedded processor for OOB management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
+	/* Embedded processor for RoCE */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
+	/* Embedded processor for network proxy functions */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
+	uint8_t unused_6;
+	uint32_t src_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.
+	 * 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 enables;
-	/* 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 ring_arb_cfg field to be configured. */
-	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Non-tunnel */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+		UINT32_C(0x0)
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
 	/*
-	 * This bit must be '1' for the stat_ctx_id_valid field to be
-	 * configured.
+	 * Network Virtualization Generic Routing
+	 * Encapsulation	(NVGRE)
 	 */
-	#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)
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint64_t page_tbl_addr;
-	/* This value is a pointer to the page table for the Ring. */
-	uint32_t fbo;
-	/* First Byte Offset of the first entry in the first page. */
-	uint8_t page_size;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+		UINT32_C(0x2)
 	/*
-	 * 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. - 21 = 2
-	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
-	 * GB Page size is 1 GB.
+	 * Generic Routing Encapsulation	(GRE) inside
+	 * Ethernet payload
 	 */
-	uint8_t page_tbl_depth;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE UINT32_C(0x3)
+	/* IP in IP */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	/* Multi-Protocol Lable Switching	(MPLS) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
+	/* Stateless Transport Tunnel	(STT) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
 	/*
-	 * 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.
+	 * Generic Routing Encapsulation	(GRE) inside IP
+	 * datagram payload
 	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint32_t length;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE UINT32_C(0x8)
+	/* Any tunneled traffic */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+		UINT32_C(0xff)
+	uint8_t unused_7;
+	uint16_t dst_id;
 	/*
-	 * Number of 16B units in the ring. Minimum size for a ring is
-	 * 16 16B entries.
+	 * 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 logical_id;
+	uint16_t mirror_vnic_id;
+	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
+	uint8_t pri_hint;
 	/*
-	 * 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.
+	 * This hint is provided to help in placing the filter in the
+	 * filter table.
 	 */
-	uint16_t cmpl_ring_id;
+	/* No preference */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+		UINT32_C(0x0)
+	/* Above the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+		UINT32_C(0x1)
+	/* Below the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+		UINT32_C(0x2)
+	/* As high as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
+	/* As low as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
+	uint8_t unused_8;
+	uint32_t unused_9;
+	uint64_t l2_filter_id_hint;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what completion ring the TX ring is
-	 * associated with.
+	 * 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
 	 */
-	uint16_t queue_id;
+} __attribute__((packed));
+
+/* Output	(24 bytes) */
+struct hwrm_cfa_l2_filter_alloc_output {
+	uint16_t error_code;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what CoS queue the TX ring is associated
-	 * with.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint8_t unused_4;
-	uint8_t unused_5;
-	uint32_t reserved1;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint16_t ring_arb_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * field is used to configure arbitration related parameters for
-	 * a TX ring.
+	 * 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.
+	 */
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t flow_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.
 	 */
-	/* Arbitration policy used for the ring. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK	\
-		UINT32_C(0xf)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * Use strict priority for the TX ring. Priority
-	 * value is specified in arb_policy_param
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP	\
-		(UINT32_C(0x1) << 0)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Use weighted fair queue arbitration for the
-	 * TX ring. Weight is specified in
-	 * arb_policy_param
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ	\
-		(UINT32_C(0x2) << 0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST	\
-		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
-	/* Reserved field. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	uint16_t cmpl_ring;
 	/*
-	 * Arbitration policy specific parameter. # For strict priority
-	 * arbitration policy, this field represents a priority value.
-	 * If set to 0, then the priority is not specified and the HWRM
-	 * is allowed to select any priority for this TX ring. # For
-	 * weighted fair queue arbitration policy, this field represents
-	 * a weight value. If set to 0, then the weight is not specified
-	 * and the HWRM is allowed to select any weight for this TX
-	 * ring.
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
-		UINT32_C(0xff00)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT   8
-	uint8_t unused_6;
-	uint8_t unused_7;
-	uint32_t reserved3;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t stat_ctx_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * input indicates what statistics context this ring should be
-	 * associated with.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t reserved4;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t max_bw;
+	uint64_t resp_addr;
 	/*
-	 * This field is used only when ring_type is a TX ring to
-	 * specify maximum BW allocated to the TX ring. The HWRM will
-	 * translate this value into byte counter and time interval used
-	 * for this ring inside the device.
+	 * 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.
 	 */
-	/* Bandwidth value */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
-	/* bw_value_unit is 3 b */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
-		UINT32_C(0xe0000000)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
-		(UINT32_C(0x0) << 29)
-	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
-		(UINT32_C(0x1) << 29)
-	/* Invalid unit */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
-		(UINT32_C(0x7) << 29)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
-		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
-	uint8_t int_mode;
+	uint64_t l2_filter_id;
 	/*
-	 * 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.
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
 	 */
-	/* Legacy INTA */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY	UINT32_C(0x0)
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
-	/* MSI-X */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
-	/* No Interrupt - Polled mode */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
-	uint8_t unused_8[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4834,16 +8198,10 @@ struct hwrm_ring_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t ring_id;
-	/*
-	 * Physical number of ring allocated. This value shall be unique
-	 * for a ring type.
-	 */
-	uint16_t logical_ring_id;
-	/* Logical number of ring allocated. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4855,12 +8213,10 @@ struct hwrm_ring_alloc_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_filter_cfg */
+/* Description: Change the configuration of an existing L2 filter */
+/* Input	(40 bytes) */
+struct hwrm_cfa_l2_filter_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4887,22 +8243,52 @@ struct hwrm_ring_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t ring_id;
-	/* Physical number of ring allocated. */
-	uint32_t unused_1;
+	uint32_t flags;
+	/*
+	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
+	/* tx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX \
+		(UINT32_C(0x0) << 0)
+	/* rx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX \
+		(UINT32_C(0x1) << 0)
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST \
+		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
+	/*
+	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
+	uint32_t enables;
+	/* This bit must be '1' for the dst_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the new_mirror_vnic_id field to be
+	 * configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   \
+		UINT32_C(0x2)
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t dst_id;
+	/*
+	 * 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.
+	 */
+	uint32_t new_mirror_vnic_id;
+	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_free_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4933,12 +8319,10 @@ struct hwrm_ring_free_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_set_rx_mask */
+/* Description: This command will set rx mask of the function. */
+/* Input	(56 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4959,31 +8343,116 @@ struct hwrm_ring_grp_alloc_input {
 	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
 	 * - HWRM
 	 */
-	uint64_t resp_addr;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* VNIC ID */
+	uint32_t mask;
+	/* 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)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for the VLAN-
+	 * tagged packets that match the TPID and VID fields of VLAN
+	 * tags in the VLAN tag table specified in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets that match the TPID
+	 * and VID fields of VLAN tags in the VLAN tag table specified
+	 * in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
+	 * If this flag is set, then the HWRM shall ignore VLAN tags
+	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
+	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
+	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
+	 * set at most one flag out of vlanonly, vlan_nonvlan, and
+	 * anyvlan_nonvlan.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	\
+		UINT32_C(0x100)
+	uint64_t mc_tbl_addr;
+	/* This is the address for mcast address tbl. */
+	uint32_t num_mc_entries;
 	/*
-	 * 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.
+	 * This value indicates how many entries in mc_tbl are valid.
+	 * Each entry is 6 bytes.
 	 */
-	uint16_t cr;
-	/* This value identifies the CR associated with the ring group. */
-	uint16_t rr;
-	/* This value identifies the main RR associated with the ring group. */
-	uint16_t ar;
+	uint32_t unused_0;
+	uint64_t vlan_tag_tbl_addr;
 	/*
-	 * 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.
+	 * This is the address for VLAN tag table. Each VLAN entry in
+	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
+	 * and VID fields in network byte order.
 	 */
-	uint16_t sc;
+	uint32_t num_vlan_tags;
 	/*
-	 * This value identifies the statistics context associated with
-	 * the ring group.
+	 * This value indicates how many entries in vlan_tag_tbl are
+	 * valid. Each entry is 4 bytes.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4999,15 +8468,10 @@ struct hwrm_ring_grp_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t ring_group_id;
-	/*
-	 * 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.
-	 */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5019,17 +8483,13 @@ struct hwrm_ring_grp_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_ring_grp_free */
+/* hwrm_tunnel_dst_port_query */
 /*
- * 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.
+ * Description: This function is called by a driver to query tunnel type
+ * specific destination port configuration.
  */
-/* Input (24 bytes) */
-struct hwrm_ring_grp_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5056,13 +8516,19 @@ struct hwrm_ring_grp_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t ring_group_id;
-	/* This is the ring group ID value. */
-	uint32_t unused_0;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0[7];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5078,10 +8544,24 @@ struct hwrm_ring_grp_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint16_t tunnel_dst_port_id;
+	/*
+	 * This field represents the identifier of L4 destination port
+	 * used for the given tunnel type. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling.
+	 */
+	uint16_t tunnel_dst_port_val;
+	/*
+	 * This field represents the value of L4 destination port
+	 * identified by tunnel_dst_port_id. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling. This field is in network byte order. A value
+	 * of 0 means that the destination port is not configured.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5093,15 +8573,24 @@ struct hwrm_ring_grp_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_alloc */
+/* hwrm_tunnel_dst_port_alloc */
 /*
- * A filter is used to identify traffic that contains a matching set of
- * parameters like unicast or broadcast MAC address or a VLAN tag amongst
- * other things which then allows the ASIC to direct the  incoming traffic
- * to an appropriate VNIC or Rx ring.
+ * Description: This function is called by a driver to allocate l4 destination
+ * port for a specific tunnel type. The destination port value is provided in
+ * the input. If the HWRM supports only one global destination port for a tunnel
+ * type, then the HWRM shall keep track of its usage as described below. # The
+ * first caller that allocates a destination port shall always succeed and the
+ * HWRM shall save the destination port configuration for that tunnel type and
+ * increment the usage count to 1. # Subsequent callers allocating the same
+ * destination port for that tunnel type shall succeed and the HWRM shall
+ * increment the usage count for that port for each subsequent caller that
+ * succeeds. # Any subsequent caller trying to allocate a different destination
+ * port for that tunnel type shall fail until the usage count for the original
+ * destination port goes to zero. # A caller that frees a port will cause the
+ * usage count for that port to decrement.
  */
-/* Input (96 bytes) */
-struct hwrm_cfa_l2_filter_alloc_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5114,253 +8603,41 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint32_t flags;
-	/*
-	 * 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	\
-		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 enables;
-	/* 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)
-	uint8_t l2_addr[6];
-	/*
-	 * 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 unused_0;
-	uint8_t unused_1;
-	uint8_t l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the L2 address. A value of
-	 * 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ovlan;
-	/* This value sets VLAN ID value for outer VLAN. */
-	uint16_t l2_ovlan_mask;
-	/*
-	 * This value sets the mask value for the ovlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ivlan;
-	/* This value sets VLAN ID value for inner VLAN. */
-	uint16_t l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the ivlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t t_l2_addr[6];
-	/*
-	 * 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 unused_4;
-	uint8_t unused_5;
-	uint8_t t_l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the tunnel L2 address. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t t_l2_ovlan;
-	/* This value sets VLAN ID value for tunnel outer VLAN. */
-	uint16_t t_l2_ovlan_mask;
-	/*
-	 * 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_ivlan;
-	/* This value sets VLAN ID value for tunnel inner VLAN. */
-	uint16_t t_l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the tunnel ivlan id. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint8_t src_type;
-	/* 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)
-	/* Physical function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
-	/* Virtual function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
-	/* Virtual NIC of a function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
-	/* Embedded processor for CFA management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
-	/* Embedded processor for OOB management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
-	/* Embedded processor for RoCE */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
-	/* Embedded processor for network proxy functions */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
-	uint8_t unused_6;
-	uint32_t src_id;
-	/*
-	 * 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
-	 */
-	uint8_t tunnel_type;
-	/* Tunnel Type. */
-	/* Non-tunnel */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL	UINT32_C(0x0)
-	/* Virtual eXtensible Local Area Network (VXLAN) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN	UINT32_C(0x1)
-	/*
-	 * Network Virtualization Generic Routing
-	 * Encapsulation (NVGRE)
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE	UINT32_C(0x2)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside
-	 * Ethernet payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE	UINT32_C(0x3)
-	/* IP in IP */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
-	/* Generic Network Virtualization Encapsulation (Geneve) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE	UINT32_C(0x5)
-	/* Multi-Protocol Lable Switching (MPLS) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
-	/* Stateless Transport Tunnel (STT) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside IP
-	 * datagram payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE	UINT32_C(0x8)
-	/* Any tunneled traffic */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL	UINT32_C(0xff)
-	uint8_t unused_7;
-	uint16_t dst_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint16_t mirror_vnic_id;
-	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
-	uint8_t pri_hint;
+	uint64_t resp_addr;
 	/*
-	 * This hint is provided to help in placing the filter in the
-	 * filter table.
+	 * 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.
 	 */
-	/* No preference */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER	UINT32_C(0x0)
-	/* Above the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER	UINT32_C(0x1)
-	/* Below the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER	UINT32_C(0x2)
-	/* As high as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
-	/* As low as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
-	uint8_t unused_8;
-	uint32_t unused_9;
-	uint64_t l2_filter_id_hint;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_val;
 	/*
-	 * 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
+	 * This field represents the value of L4 destination port used
+	 * for the given tunnel type. This field is valid for specific
+	 * tunnel types that use layer 4	(e.g. UDP) transports for
+	 * tunneling. This field is in network byte order. A value of 0
+	 * shall fail the command.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (24 bytes) */
-struct hwrm_cfa_l2_filter_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5376,21 +8653,17 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint64_t l2_filter_id;
-	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
-	 */
-	uint32_t flow_id;
+	uint16_t tunnel_dst_port_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.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
 	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5402,13 +8675,13 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_free */
+/* hwrm_tunnel_dst_port_free */
 /*
- * Description: Free a L2 filter. The HWRM shall free all associated filter
- * resources with the L2 filter.
+ * Description: This function is called by a driver to free l4 destination port
+ * for a specific tunnel type.
  */
-/* Input (24 bytes) */
-struct hwrm_cfa_l2_filter_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5435,15 +8708,24 @@ struct hwrm_cfa_l2_filter_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint64_t l2_filter_id;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_id;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5474,10 +8756,13 @@ struct hwrm_cfa_l2_filter_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_cfg */
-/* Description: Change the configuration of an existing L2 filter */
-/* Input (40 bytes) */
-struct hwrm_cfa_l2_filter_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5504,49 +8789,35 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX	(UINT32_C(0x0) << 0)
-	/* rx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX	(UINT32_C(0x1) << 0)
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST	\
-		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
-	/*
-	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
-	uint32_t enables;
-	/* This bit must be '1' for the dst_id field to be configured. */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	uint64_t stats_dma_addr;
+	/* This is the address for statistic block. */
+	uint32_t update_period_ms;
 	/*
-	 * This bit must be '1' for the new_mirror_vnic_id field to be
-	 * configured.
+	 * The statistic block update period in ms. e.g. 250ms, 500ms,
+	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
+	 * update shall be never done and the DMA address shall not be
+	 * used. In this case, the stat block can only be read by
+	 * hwrm_stat_ctx_query command.
 	 */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   UINT32_C(0x2)
-	uint64_t l2_filter_id;
+	uint8_t stat_ctx_flags;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * This field is used to specify statistics context specific
+	 * configuration flags.
 	 */
-	uint32_t dst_id;
 	/*
-	 * 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.
+	 * When this bit is set to '1', the statistics context shall be
+	 * allocated for RoCE traffic only. In this case, traffic other
+	 * than offloaded RoCE traffic shall not be included in this
+	 * statistic context. When this bit is set to '0', the
+	 * statistics context shall be used for the network traffic
+	 * other than offloaded RoCE traffic.
 	 */
-	uint32_t new_mirror_vnic_id;
-	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
+	#define HWRM_STAT_CTX_ALLOC_INPUT_STAT_CTX_FLAGS_ROCE	UINT32_C(0x1)
+	uint8_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5562,10 +8833,11 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5577,10 +8849,10 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_set_rx_mask */
-/* Description: This command will set rx mask of the function. */
-/* Input (56 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_input {
+/* hwrm_stat_ctx_free */
+/* Description: This command is used to free a stat context. */
+/* Input	(24 bytes) */
+struct hwrm_stat_ctx_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5607,109 +8879,81 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
-	/* VNIC ID */
-	uint32_t mask;
-	/* 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)
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_free_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST	UINT32_C(0x20)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for the VLAN-
-	 * tagged packets that match the TPID and VID fields of VLAN
-	 * tags in the VLAN tag table specified in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets that match the TPID
-	 * and VID fields of VLAN tags in the VLAN tag table specified
-	 * in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
-	 * If this flag is set, then the HWRM shall ignore VLAN tags
-	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
-	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
-	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
-	 * set at most one flag out of vlanonly, vlan_nonvlan, and
-	 * anyvlan_nonvlan.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	UINT32_C(0x100)
-	uint64_t mc_tbl_addr;
-	/* This is the address for mcast address tbl. */
-	uint32_t num_mc_entries;
+	uint16_t cmpl_ring;
 	/*
-	 * This value indicates how many entries in mc_tbl are valid.
-	 * Each entry is 6 bytes.
+	 * 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.
 	 */
-	uint32_t unused_0;
-	uint64_t vlan_tag_tbl_addr;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This is the address for VLAN tag table. Each VLAN entry in
-	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
-	 * and VID fields in network byte order.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t num_vlan_tags;
-	/*
-	 * This value indicates how many entries in vlan_tag_tbl are
-	 * valid. Each entry is 4 bytes.
+	uint64_t resp_addr;
+	/*
+	 * 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.
 	 */
-	uint32_t unused_1;
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5740,58 +8984,48 @@ struct hwrm_cfa_l2_set_rx_mask_output {
 	 */
 } __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 {
+/* hwrm_stat_ctx_query */
+/* Description: This command returns statistics of a context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_query_input {
 	uint16_t req_type;
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
 	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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 seq_id;
 	/* This value indicates the command sequence number. */
 	uint16_t target_id;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
 	 */
 	uint64_t resp_addr;
 	/*
-	 * 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 stats_dma_addr;
-	/* This is the address for statistic block. */
-	uint32_t update_period_ms;
-	/*
-	 * The statistic block update period in ms. e.g. 250ms, 500ms,
-	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
-	 * update shall be never done and the DMA address shall not be
-	 * used. In this case, the stat block can only be read by
-	 * hwrm_stat_ctx_query command.
+	 * 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.
 	 */
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_alloc_output {
+/* Output (176 bytes) */
+
+struct hwrm_stat_ctx_query_output {
 	uint16_t error_code;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
 	uint16_t req_type;
 	/* This field returns the type of original request. */
@@ -5799,30 +9033,76 @@ struct hwrm_stat_ctx_alloc_output {
 	/* This field provides original sequence number of the command. */
 	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t tx_err_pkts;
+	/* Number of transmitted packets with error */
+	uint64_t tx_drop_pkts;
+	/* Number of dropped packets on transmit path */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t tx_mcast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t tx_bcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t rx_err_pkts;
+	/* Number of received packets with error */
+	uint64_t rx_drop_pkts;
+	/* Number of dropped packets on received path */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations */
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
-	 * 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.
+	 * 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.
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5849,13 +9129,24 @@ struct hwrm_stat_ctx_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * 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.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_free_output {
+/* Output	(16 bytes) */
+struct hwrm_exec_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5871,11 +9162,10 @@ struct hwrm_stat_ctx_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5887,10 +9177,18 @@ struct hwrm_stat_ctx_free_output {
 	 */
 } __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 {
+/* hwrm_reject_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to reject the request and forward the
+ * error 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_reject_fwd_resp_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5917,13 +9215,25 @@ struct hwrm_stat_ctx_clr_stats_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * This is an encapsulated request. This request should be
+	 * rejected by the HWRM and the error response should be
+	 * provided in the response buffer inside the encapsulated
+	 * request.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_clr_stats_output {
+/* Output	(16 bytes) */
+struct hwrm_reject_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5954,18 +9264,16 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_exec_fwd_resp */
+/* Hardware Resource Manager Specification */
+/* Description: This structure is used to specify port description. */
 /*
- * 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.
+ * 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 service is vital part of the chip.
+ * The chip can not be used by a driver or HWRM client without the HWRM.
  */
-/* Input (128 bytes) */
-struct hwrm_exec_fwd_resp_input {
+/* Input	(16 bytes) */
+struct input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5992,24 +9300,91 @@ struct hwrm_exec_fwd_resp_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t encap_request[26];
+} __attribute__((packed));
+
+/* Output	(8 bytes) */
+struct output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint16_t encap_resp_target_id;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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
+	 * 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.
+	 */
+} __attribute__((packed));
+
+#define HWRM_GET_HWRM_ERROR_CODE(arg) \
+	{ \
+		typeof(arg) x = (arg); \
+	((x) == 0xf ? "HWRM_ERROR" : \
+	((x) == 0xffff ? "CMD_NOT_SUPPORTED" : \
+	((x) == 0xfffe ? "UNKNOWN_ERR" : \
+	((x) == 0x4 ? "RESOURCE_ALLOC_ERROR" : \
+	((x) == 0x5 ? "INVALID_FLAGS" : \
+	((x) == 0x6 ? "INVALID_ENABLES" : \
+	((x) == 0x0 ? "SUCCESS" : \
+	((x) == 0x1 ? "FAIL" : \
+	((x) == 0x2 ? "INVALID_PARAMS" : \
+	((x) == 0x3 ? "RESOURCE_ACCESS_DENIED" : \
+	"Unknown error_code")))))))))) \
+	}
+
+/* Return Codes	(8 bytes) */
+struct ret_codes {
+	uint16_t error_code;
+	/* These are numbers assigned to return/error codes. */
+	/* Request was successfully executed by the HWRM. */
+	#define HWRM_ERR_CODE_SUCCESS	(UINT32_C(0x0))
+	/* THe HWRM failed to execute the request. */
+	#define HWRM_ERR_CODE_FAIL	(UINT32_C(0x1))
+	/*
+	 * The request contains invalid argument(s) or
+	 * input parameters.
+	 */
+	#define HWRM_ERR_CODE_INVALID_PARAMS	(UINT32_C(0x2))
+	/*
+	 * The requester is not allowed to access the
+	 * requested resource. This error code shall be
+	 * provided in a response to a request to query
+	 * or modify an existing resource that is not
+	 * accessible by the requester.
+	 */
+	#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED	(UINT32_C(0x3))
+	/*
+	 * The HWRM is unable to allocate the requested
+	 * resource. This code only applies to requests
+	 * for HWRM resource allocations.
 	 */
+	#define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR	(UINT32_C(0x4))
+	/* Invalid combination of flags is specified in the request. */
+	#define HWRM_ERR_CODE_INVALID_FLAGS	(UINT32_C(0x5))
+	/*
+	 * Invalid combination of enables fields is
+	 * specified in the request.
+	 */
+	#define HWRM_ERR_CODE_INVALID_ENABLES	(UINT32_C(0x6))
+	/*
+	 * Generic HWRM execution error that represents
+	 * an internal error.
+	 */
+	#define HWRM_ERR_CODE_HWRM_ERROR	(UINT32_C(0xf))
+	/* Unknown error */
+	#define HWRM_ERR_CODE_UNKNOWN_ERR	(UINT32_C(0xfffe))
+	/* Unsupported or invalid command */
+	#define HWRM_ERR_CODE_CMD_NOT_SUPPORTED	(UINT32_C(0xffff))
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_exec_fwd_resp_output {
+/* Output	(16 bytes) */
+struct hwrm_err_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -6025,10 +9400,15 @@ struct hwrm_exec_fwd_resp_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
+	uint32_t opaque_0;
+	/* debug info for this error response. */
+	uint16_t opaque_1;
+	/* debug info for this error response. */
+	uint8_t cmd_err;
+	/*
+	 * In the case of an error response, command specific error code
+	 * is returned in this field.
+	 */
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -6040,4 +9420,378 @@ struct hwrm_exec_fwd_resp_output {
 	 */
 } __attribute__((packed));
 
-#endif
+/* Port Tx Statistics Formats	(408 bytes) */
+struct tx_port_stats {
+	uint64_t tx_64b_frames;
+	/* Total Number of 64 Bytes frames transmitted */
+	uint64_t tx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames transmitted */
+	uint64_t tx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames transmitted */
+	uint64_t tx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames transmitted */
+	uint64_t tx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames transmitted */
+	uint64_t tx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames transmitted */
+	uint64_t tx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * transmitted which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t tx_1519b_2047_frames;
+	/* Total Number of 1519-2047 Bytes frames transmitted */
+	uint64_t tx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames transmitted */
+	uint64_t tx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames transmitted */
+	uint64_t tx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames transmitted */
+	uint64_t tx_good_frames;
+	/* Total Number of good frames transmitted */
+	uint64_t tx_total_frames;
+	/* Total Number of frames transmitted */
+	uint64_t tx_ucast_frames;
+	/* Total number of unicast frames transmitted */
+	uint64_t tx_mcast_frames;
+	/* Total number of multicast frames transmitted */
+	uint64_t tx_bcast_frames;
+	/* Total number of broadcast frames transmitted */
+	uint64_t tx_pause_frames;
+	/* Total number of PAUSE control frames transmitted */
+	uint64_t tx_pfc_frames;
+	/* Total number of PFC/per-priority PAUSE control frames transmitted */
+	uint64_t tx_jabber_frames;
+	/* Total number of jabber frames transmitted */
+	uint64_t tx_fcs_err_frames;
+	/* Total number of frames transmitted with FCS error */
+	uint64_t tx_control_frames;
+	/* Total number of control frames transmitted */
+	uint64_t tx_oversz_frames;
+	/* Total number of over-sized frames transmitted */
+	uint64_t tx_single_dfrl_frames;
+	/* Total number of frames with single deferral */
+	uint64_t tx_multi_dfrl_frames;
+	/* Total number of frames with multiple deferrals */
+	uint64_t tx_single_coll_frames;
+	/* Total number of frames with single collision */
+	uint64_t tx_multi_coll_frames;
+	/* Total number of frames with multiple collisions */
+	uint64_t tx_late_coll_frames;
+	/* Total number of frames with late collisions */
+	uint64_t tx_excessive_coll_frames;
+	/* Total number of frames with excessive collisions */
+	uint64_t tx_frag_frames;
+	/* Total number of fragmented frames transmitted */
+	uint64_t tx_err;
+	/* Total number of transmit errors */
+	uint64_t tx_tagged_frames;
+	/* Total number of single VLAN tagged frames transmitted */
+	uint64_t tx_dbl_tagged_frames;
+	/* Total number of double VLAN tagged frames transmitted */
+	uint64_t tx_runt_frames;
+	/* Total number of runt frames transmitted */
+	uint64_t tx_fifo_underruns;
+	/* Total number of TX FIFO under runs */
+	uint64_t tx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 0
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 1
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 2
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 3
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 4
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 5
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 6
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 7
+	 * transmitted
+	 */
+	uint64_t tx_eee_lpi_events;
+	/* Total number of EEE LPI Events on TX */
+	uint64_t tx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on TX */
+	uint64_t tx_llfc_logical_msgs;
+	/*
+	 * Total number of Link Level Flow Control	(LLFC) messages
+	 * transmitted
+	 */
+	uint64_t tx_hcfc_msgs;
+	/* Total number of HCFC messages transmitted */
+	uint64_t tx_total_collisions;
+	/* Total number of TX collisions */
+	uint64_t tx_bytes;
+	/* Total number of transmitted bytes */
+	uint64_t tx_xthol_frames;
+	/* Total number of end-to-end HOL frames */
+	uint64_t tx_stat_discard;
+	/* Total Tx Drops per Port reported by STATS block */
+	uint64_t tx_stat_error;
+	/* Total Tx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Port Rx Statistics Formats	(528 bytes) */
+struct rx_port_stats {
+	uint64_t rx_64b_frames;
+	/* Total Number of 64 Bytes frames received */
+	uint64_t rx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames received */
+	uint64_t rx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames received */
+	uint64_t rx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames received */
+	uint64_t rx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames received */
+	uint64_t rx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames received */
+	uint64_t rx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * received which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t rx_1519b_2047b_frames;
+	/* Total Number of 1519-2047 Bytes frames received */
+	uint64_t rx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames received */
+	uint64_t rx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames received */
+	uint64_t rx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames received */
+	uint64_t rx_total_frames;
+	/* Total number of frames received */
+	uint64_t rx_ucast_frames;
+	/* Total number of unicast frames received */
+	uint64_t rx_mcast_frames;
+	/* Total number of multicast frames received */
+	uint64_t rx_bcast_frames;
+	/* Total number of broadcast frames received */
+	uint64_t rx_fcs_err_frames;
+	/* Total number of received frames with FCS error */
+	uint64_t rx_ctrl_frames;
+	/* Total number of control frames received */
+	uint64_t rx_pause_frames;
+	/* Total number of PAUSE frames received */
+	uint64_t rx_pfc_frames;
+	/* Total number of PFC frames received */
+	uint64_t rx_unsupported_opcode_frames;
+	/* Total number of frames received with an unsupported opcode */
+	uint64_t rx_unsupported_da_pausepfc_frames;
+	/*
+	 * Total number of frames received with an unsupported DA for
+	 * pause and PFC
+	 */
+	uint64_t rx_wrong_sa_frames;
+	/* Total number of frames received with an unsupported SA */
+	uint64_t rx_align_err_frames;
+	/* Total number of received packets with alignment error */
+	uint64_t rx_oor_len_frames;
+	/* Total number of received frames with out-of-range length */
+	uint64_t rx_code_err_frames;
+	/* Total number of received frames with error termination */
+	uint64_t rx_false_carrier_frames;
+	/*
+	 * Total number of received frames with a false carrier is
+	 * detected during idle, as defined by RX_ER samples active and
+	 * RXD is 0xE. The event is reported along with the statistics
+	 * generated on the next received frame. Only one false carrier
+	 * condition can be detected and logged between frames. Carrier
+	 * event, valid for 10M/100M speed modes only.
+	 */
+	uint64_t rx_ovrsz_frames;
+	/* Total number of over-sized frames received */
+	uint64_t rx_jbr_frames;
+	/* Total number of jabber packets received */
+	uint64_t rx_mtu_err_frames;
+	/* Total number of received frames with MTU error */
+	uint64_t rx_match_crc_frames;
+	/* Total number of received frames with CRC match */
+	uint64_t rx_promiscuous_frames;
+	/* Total number of frames received promiscuously */
+	uint64_t rx_tagged_frames;
+	/* Total number of received frames with one or two VLAN tags */
+	uint64_t rx_double_tagged_frames;
+	/* Total number of received frames with two VLAN tags */
+	uint64_t rx_trunc_frames;
+	/* Total number of truncated frames received */
+	uint64_t rx_good_frames;
+	/* Total number of good frames	(without errors) received */
+	uint64_t rx_pfc_xon2xoff_frames_pri0;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 0
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri1;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 1
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri2;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 2
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri3;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 3
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri4;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 4
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri5;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 5
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri6;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 6
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri7;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 7
+	 */
+	uint64_t rx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 0
+	 */
+	uint64_t rx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 1
+	 */
+	uint64_t rx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 2
+	 */
+	uint64_t rx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 3
+	 */
+	uint64_t rx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 4
+	 */
+	uint64_t rx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 5
+	 */
+	uint64_t rx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 6
+	 */
+	uint64_t rx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 7
+	 */
+	uint64_t rx_sch_crc_err_frames;
+	/* Total Number of frames received with SCH CRC error */
+	uint64_t rx_undrsz_frames;
+	/* Total Number of under-sized frames received */
+	uint64_t rx_frag_frames;
+	/* Total Number of fragmented frames received */
+	uint64_t rx_eee_lpi_events;
+	/* Total number of RX EEE LPI Events */
+	uint64_t rx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on RX */
+	uint64_t rx_llfc_physical_msgs;
+	/*
+	 * Total number of physical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_logical_msgs;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_msgs_with_crc_err;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received with CRC error
+	 */
+	uint64_t rx_hcfc_msgs;
+	/* Total number of HCFC messages received */
+	uint64_t rx_hcfc_msgs_with_crc_err;
+	/* Total number of HCFC messages received with CRC error */
+	uint64_t rx_bytes;
+	/* Total number of received bytes */
+	uint64_t rx_runt_bytes;
+	/* Total number of bytes received in runt frames */
+	uint64_t rx_runt_frames;
+	/* Total number of runt frames received */
+	uint64_t rx_stat_discard;
+	/* Total Rx Discards per Port reported by STATS block */
+	uint64_t rx_stat_err;
+	/* Total Rx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Periodic Statistics Context DMA to host	(160 bytes) */
+/*
+ * per-context HW statistics -- chip view
+ */
+
+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_discard_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_discard_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;
+} __attribute__((packed));
+
+#endif /* _HSI_STRUCT_DEF_DPDK_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 02/25] bnxt: code reorg to properly allocate resources for PF/VF
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 01/25] bnxt: update to new HWRM version Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 03/25] bnxt: handle VF/PF initialization appropriately Ajit Khaparde
                         ` (23 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) Move the function reset to bnxt_dev_init.
On the same lines, setup, enable and request interrupt to init path.
Memory allocation is also being done in the init path.
2) After a function reset, configure the VFs.  Distribute resources
evenly between all functions (PF and VF) for now. In the future, this
should be controllable.
3) The bnxt_vf_info and bnxt_pf_info had lot of duplication. Move the
common items to struct bnxt. And only unique items specific to PF remain
in the struct bnxt_pf_info.
4) Program the firmware to allow certain commands sent by a VF.
Disallowing these will prevent clean VF driver cleanup.
5) Since PF/VF need to allocate resources from a pool in the hardware,
use func_qcaps and func_qcfg to appropriately query the capabilities
and available resources.
6) If a PF is being initialized and no VFs are allocated, explicitly
call func_cfg to allocate the resources.
7) Once resources are requested from the firmware, update local copy
of resource count in struct bnxt only after sending the func_qcfg to
make sure the allocation request in the firmware went through.

The changes in this patch will be used by the subsequent patches
to allow proper initialization of PF/VF instance.

--
v1->v2: Regroup related patches per review comment
  Also split bigger patch into smaller patches if possible.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  80 ++++--
 drivers/net/bnxt/bnxt_ethdev.c | 155 ++++++++---
 drivers/net/bnxt/bnxt_filter.c |  30 +-
 drivers/net/bnxt/bnxt_hwrm.c   | 614 +++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  17 +-
 drivers/net/bnxt/bnxt_vnic.c   |  45 +--
 drivers/net/bnxt/bnxt_vnic.h   |  11 +-
 7 files changed, 764 insertions(+), 188 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4418c7f..0c59c66 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -35,6 +35,7 @@
 #define _BNXT_H_
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <sys/queue.h>
 
 #include <rte_ethdev.h>
@@ -54,17 +55,19 @@ enum bnxt_hw_context {
 	HW_CONTEXT_IS_LB    = 3,
 };
 
-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;
-	uint16_t		vlan;
-	struct bnxt_pf_info	*pf;
+struct bnxt_vlan_table_entry {
+	uint16_t		tpid;
+	uint16_t		vid;
+} __attribute__((packed));
+
+struct bnxt_child_vf_info {
+	void			*req_buf;
+	struct bnxt_vlan_table_entry	*vlan_table;
+	STAILQ_HEAD(, bnxt_filter_info)	filter;
+	uint32_t		func_cfg_flags;
+	uint32_t		l2_rx_mask;
+	uint16_t		fid;
+	bool			random_mac;
 };
 
 struct bnxt_pf_info {
@@ -73,22 +76,20 @@ struct bnxt_pf_info {
 #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;
+	uint32_t		func_cfg_flags;
 	void			*vf_req_buf;
 	phys_addr_t		vf_req_buf_dma_addr;
 	uint32_t		vf_req_fwd[8];
-	struct bnxt_vf_info	*vf;
+	uint16_t		total_vnics;
+	struct bnxt_child_vf_info	*vf_info;
+#define BNXT_EVB_MODE_NONE	0
+#define BNXT_EVB_MODE_VEB	1
+#define BNXT_EVB_MODE_VEPA	2
+	uint8_t			evb_mode;
 };
 
 /* Max wait time is 10 * 100ms = 1s */
@@ -174,12 +175,49 @@ struct bnxt {
 	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
+	uint16_t		fw_fid;
+	uint8_t			dflt_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		max_stat_ctx;
+	uint16_t		vlan;
 	struct bnxt_pf_info		pf;
-	struct bnxt_vf_info		vf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint32_t		fw_ver;
+};
+
+/*
+ * Response sent back to the caller after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+	RTE_PMD_BNXT_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_PMD_BNXT_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_PMD_BNXT_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET			0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR	0x02 /* VF requests PF to set MAC addr */
+#define BNXT_VF_SET_VLAN		0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU			0x04 /* VF requests PF to set MTU */
+#define BNXT_VF_SET_MRU			0x05 /* VF requests PF to set MRU */
+
+/*
+ * Data sent to the caller when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+	uint16_t vf_id;	/* Virtual Function number */
+	int	retval;	/* return value */
+	void	*msg;	/* pointer to message */
 };
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index bb87361..f127d3a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -345,18 +345,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
-	}
+	if (BNXT_PF(bp))
+		dev_info->max_vfs = bp->pdev->max_vfs;
+	dev_info->max_rx_queues = bp->max_rx_rings;
+	dev_info->max_tx_queues = bp->max_tx_rings;
+	dev_info->reta_size = bp->max_rsscos_ctx;
+	max_vnics = bp->max_vnics;
 
 	/* Fast path specifics */
 	dev_info->min_rx_bufsize = 1;
@@ -488,41 +482,18 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	bp->dev_stopped = 0;
-	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);
-
 	bnxt_link_update_op(eth_dev, 0);
 	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;
 }
 
@@ -554,8 +525,6 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
-	bnxt_disable_int(bp);
-	bnxt_free_int(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1082,6 +1051,12 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 
 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
 
+#define ALLOW_FUNC(x)	\
+	{ \
+		typeof(x) arg = (x); \
+		bp->pf.vf_req_fwd[((arg) >> 5)] &= \
+		~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
+	}
 static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1097,6 +1072,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
 		bp->flags |= BNXT_FLAG_VF;
@@ -1130,6 +1106,11 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
 		goto error_free;
 	}
+	if (bp->max_tx_rings == 0) {
+		RTE_LOG(ERR, PMD, "No TX rings available!\n");
+		rc = -EBUSY;
+		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) {
@@ -1140,10 +1121,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		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(bp->mac_addr, bp->dflt_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);
@@ -1155,8 +1133,29 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error_free;
 	}
 
-	rc = bnxt_hwrm_func_driver_register(bp, 0,
-					    bp->pf.vf_req_fwd);
+	/* Forward all requests if firmware is new enough */
+	if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
+	    (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
+	    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
+		memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
+	} else {
+		RTE_LOG(WARNING, PMD,
+			"Firmware too old for VF mailbox functionality\n");
+		memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
+	}
+
+	/*
+	 * The following are used for driver cleanup.  If we disallow these,
+	 * VF drivers can't clean up cleanly.
+	 */
+	ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
+	ALLOW_FUNC(HWRM_VNIC_FREE);
+	ALLOW_FUNC(HWRM_RING_FREE);
+	ALLOW_FUNC(HWRM_RING_GRP_FREE);
+	ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
+	ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
+	ALLOW_FUNC(HWRM_STAT_CTX_FREE);
+	rc = bnxt_hwrm_func_driver_register(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"Failed to register driver");
@@ -1169,10 +1168,55 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		pci_dev->mem_resource[0].phys_addr,
 		pci_dev->mem_resource[0].addr);
 
-	bp->dev_stopped = 0;
+	rc = bnxt_hwrm_func_reset(bp);
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc);
+		rc = -1;
+		goto error_free;
+	}
+
+	if (BNXT_PF(bp)) {
+		//if (bp->pf.active_vfs) {
+			// TODO: Deallocate VF resources?
+		//}
+		if (bp->pdev->max_vfs) {
+			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
+			if (rc) {
+				RTE_LOG(ERR, PMD, "Failed to allocate VFs\n");
+				goto error_free;
+			}
+		} else {
+			rc = bnxt_hwrm_allocate_pf_only(bp);
+			if (rc) {
+				RTE_LOG(ERR, PMD,
+					"Failed to allocate PF resources\n");
+				goto error_free;
+			}
+		}
+	}
+
+	rc = bnxt_setup_int(bp);
+	if (rc)
+		goto error_free;
+
+	rc = bnxt_alloc_mem(bp);
+	if (rc)
+		goto error_free_int;
+
+	rc = bnxt_request_int(bp);
+	if (rc)
+		goto error_free_int;
+
+	bnxt_enable_int(bp);
 
 	return 0;
 
+error_free_int:
+	bnxt_disable_int(bp);
+	bnxt_free_def_cp_ring(bp);
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 error_free:
 	bnxt_dev_uninit(eth_dev);
 error:
@@ -1184,6 +1228,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	int rc;
 
+	bnxt_disable_int(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 	if (eth_dev->data->mac_addrs != NULL) {
 		rte_free(eth_dev->data->mac_addrs);
 		eth_dev->data->mac_addrs = NULL;
@@ -1196,6 +1243,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	bnxt_free_hwrm_resources(bp);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
+	if (bp->pf.vf_info)
+		rte_free(bp->pf.vf_info);
 	eth_dev->dev_ops = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 	eth_dev->tx_pkt_burst = NULL;
@@ -1203,6 +1252,24 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	return rc;
 }
 
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+	struct rte_pmd_bnxt_mb_event_param cb_param;
+
+	cb_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+	cb_param.vf_id = vf_id;
+	cb_param.msg = msg;
+
+	_rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+			&cb_param);
+
+	/* Default to approve */
+	if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+		cb_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+	return cb_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? true : false;
+}
+
 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index df1042c..137c7b7 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -73,15 +73,7 @@ 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	STAILQ_INIT(&bp->free_filter_list);
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
@@ -122,15 +114,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 		return;
 
 	/* 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
 		if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
@@ -155,15 +139,7 @@ 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;
-	}
+	max_filters = bp->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),
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9100b7b..7aece5d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -54,6 +56,38 @@
 
 #define HWRM_CMD_TIMEOUT		2000
 
+struct bnxt_plcmodes_cfg {
+	uint32_t	flags;
+	uint16_t	jumbo_thresh;
+	uint16_t	hds_offset;
+	uint16_t	hds_threshold;
+};
+
+static int page_getenum(size_t size)
+{
+	if (size <= 1 << 4)
+		return 4;
+	if (size <= 1 << 12)
+		return 12;
+	if (size <= 1 << 13)
+		return 13;
+	if (size <= 1 << 16)
+		return 16;
+	if (size <= 1 << 21)
+		return 21;
+	if (size <= 1 << 22)
+		return 22;
+	if (size <= 1 << 30)
+		return 30;
+	RTE_LOG(ERR, PMD, "Page size %zu out of range\n", size);
+	return sizeof(void *) * 8 - 1;
+}
+
+static int page_roundup(size_t size)
+{
+	return 1 << page_getenum(size);
+}
+
 /*
  * HWRM Functions (sent to HWRM)
  * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message()
@@ -275,6 +309,8 @@ 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;
+	uint16_t new_max_vfs;
+	int i;
 
 	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
 
@@ -286,31 +322,52 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	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;
-
-		pf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		pf->port_id = resp->port_id;
-		memcpy(pf->mac_addr, resp->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);
+		bp->pf.port_id = resp->port_id;
+		bp->pf.first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+		new_max_vfs = bp->pdev->max_vfs;
+		if (new_max_vfs != bp->pf.max_vfs) {
+			if (bp->pf.vf_info)
+				rte_free(bp->pf.vf_info);
+			bp->pf.vf_info = rte_malloc("bnxt_vf_info",
+			    sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0);
+			bp->pf.max_vfs = new_max_vfs;
+			for (i = 0; i < new_max_vfs; i++) {
+				bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i;
+				bp->pf.vf_info[i].vlan_table =
+					rte_zmalloc("VF VLAN table",
+						    getpagesize(),
+						    getpagesize());
+				if (bp->pf.vf_info[i].vlan_table == NULL)
+					RTE_LOG(ERR, PMD,
+					"Fail to alloc VLAN table for VF %d\n",
+					i);
+				else
+					rte_mem_lock_page(
+						bp->pf.vf_info[i].vlan_table);
+				STAILQ_INIT(&bp->pf.vf_info[i].filter);
+			}
+		}
+	}
+
+	bp->fw_fid = rte_le_to_cpu_32(resp->fid);
+	memcpy(bp->dflt_mac_addr, &resp->mac_address, ETHER_ADDR_LEN);
+	bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	if (BNXT_PF(bp)) {
+		if (bp->pf.max_vfs)
+			bp->max_vnics = 1;
+		else
+			bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
 	} else {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		vf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		memcpy(vf->mac_addr, &resp->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);
+		bp->max_vnics = 1;
 	}
+	bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+	if (BNXT_PF(bp))
+		bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
 
 	return rc;
 }
@@ -332,8 +389,7 @@ int bnxt_hwrm_func_reset(struct bnxt *bp)
 	return rc;
 }
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd)
+int bnxt_hwrm_func_driver_register(struct bnxt *bp)
 {
 	int rc;
 	struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
@@ -343,16 +399,22 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 		return 0;
 
 	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
-	req.flags = flags;
-	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
-			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD;
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
 	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));
+	if (BNXT_PF(bp)) {
+		req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_INPUT_FWD);
+		memcpy(req.vf_req_fwd, bp->pf.vf_req_fwd,
+		       RTE_MIN(sizeof(req.vf_req_fwd),
+			       sizeof(bp->pf.vf_req_fwd)));
+	}
 
 	req.async_event_fwd[0] |= rte_cpu_to_le_32(0x1);   /* TODO: Use MACRO */
+	memset(req.async_event_fwd, 0xff, sizeof(req.async_event_fwd));
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -391,6 +453,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		resp->hwrm_intf_maj, resp->hwrm_intf_min,
 		resp->hwrm_intf_upd,
 		resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
+	bp->fw_ver = (resp->hwrm_fw_maj << 24) | (resp->hwrm_fw_min << 16) |
+			(resp->hwrm_fw_bld << 8) | resp->hwrm_fw_rsvd;
 	RTE_LOG(INFO, PMD, "Driver HWRM version: %d.%d.%d\n",
 		HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);
 
@@ -825,10 +889,12 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		}
 		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;
-
+	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
+	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				ETHER_CRC_LEN + VLAN_TAG_SIZE;
 	HWRM_PREP(req, VNIC_ALLOC, -1, resp);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -844,27 +910,45 @@ 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;
+	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
 
 	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);
+	if (vnic->lb_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE;
+	if (vnic->cos_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE;
+	if (vnic->rss_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	req.enables |= rte_cpu_to_le_32(ctx_enable_flag);
 	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);
+	req.dflt_ring_grp = rte_cpu_to_le_16(vnic->dflt_ring_grp);
+	req.rss_rule = rte_cpu_to_le_16(vnic->rss_rule);
+	req.cos_rule = rte_cpu_to_le_16(vnic->cos_rule);
+	req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
+	req.mru = rte_cpu_to_le_16(vnic->mru);
 	if (vnic->func_default)
-		req.flags = 1;
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
 	if (vnic->vlan_strip)
 		req.flags |=
 		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+	if (vnic->bd_stall)
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+	if (vnic->roce_dual)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE);
+	if (vnic->roce_only)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE);
+	if (vnic->rss_dflt_cr)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -873,6 +957,45 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+		int16_t fw_vf_id)
+{
+	int rc = 0;
+	struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_QCFG, -1, resp);
+
+	req.enables =
+		rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.vf_id = rte_cpu_to_le_16(fw_vf_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_rule);
+	vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+	vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+	vnic->mru = rte_le_to_cpu_16(resp->mru);
+	vnic->func_default = rte_le_to_cpu_32(
+			resp->flags) & HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+	vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+	vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+	vnic->roce_dual = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE;
+	vnic->roce_only = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE;
+	vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE;
+
+	return rc;
+}
+
 int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0;
@@ -886,7 +1009,7 @@ int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
 
 	return rc;
 }
@@ -900,13 +1023,13 @@ int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	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);
+	req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+	vnic->rss_rule = INVALID_HW_RING_ID;
 
 	return rc;
 }
@@ -947,7 +1070,7 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	    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);
+	req.rss_ctx_idx = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -956,6 +1079,28 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+	memcpy(req.dflt_mac_addr, mac_addr, sizeof(req.dflt_mac_addr));
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	bp->pf.vf_info[vf].random_mac = false;
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -1217,7 +1362,8 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		return;
 
 	vnic = &bp->vnic_info[0];
-	bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
+	if (BNXT_PF(bp))
+		bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
 
 	/* VNIC resources */
 	for (i = 0; i < bp->nr_vnics; i++) {
@@ -1512,12 +1658,8 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
-	if (BNXT_VF(bp)) {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		/* Hard Coded.. 0xfff VLAN ID mask */
-		vf->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
-	}
+	/* Hard Coded.. 0xfff VLAN ID mask */
+	bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
 
 	switch (resp->port_partition_type) {
 	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
@@ -1532,3 +1674,369 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	return rc;
 }
+
+static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg,
+				   struct hwrm_func_qcaps_output *qcaps)
+{
+	qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs;
+	memcpy(qcaps->mac_address, fcfg->dflt_mac_addr,
+	       sizeof(qcaps->mac_address));
+	qcaps->max_l2_ctxs = fcfg->num_l2_ctxs;
+	qcaps->max_rx_rings = fcfg->num_rx_rings;
+	qcaps->max_tx_rings = fcfg->num_tx_rings;
+	qcaps->max_cmpl_rings = fcfg->num_cmpl_rings;
+	qcaps->max_stat_ctx = fcfg->num_stat_ctxs;
+	qcaps->max_vfs = 0;
+	qcaps->first_vf_id = 0;
+	qcaps->max_vnics = fcfg->num_vnics;
+	qcaps->max_decap_records = 0;
+	qcaps->max_encap_records = 0;
+	qcaps->max_tx_wm_flows = 0;
+	qcaps->max_tx_em_flows = 0;
+	qcaps->max_rx_wm_flows = 0;
+	qcaps->max_rx_em_flows = 0;
+	qcaps->max_flow_id = 0;
+	qcaps->max_mcast_filters = fcfg->num_mcast_filters;
+	qcaps->max_sp_tx_rings = 0;
+	qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps;
+}
+
+static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
+	req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx);
+	req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings);
+	req.num_tx_rings = rte_cpu_to_le_16(tx_rings);
+	req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings);
+	req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx);
+	req.num_vnics = rte_cpu_to_le_16(bp->max_vnics);
+	req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps);
+	req.fid = rte_cpu_to_le_16(0xffff);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+static void populate_vf_func_cfg_req(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *req,
+				     int num_vfs)
+{
+	req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+
+	req->mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx /
+						(num_vfs + 1));
+	req->num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1));
+	req->num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings /
+					       (num_vfs + 1));
+	req->num_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1));
+	req->num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1));
+	req->num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1));
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	req->num_vnics = rte_cpu_to_le_16(1);
+	req->num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps /
+						 (num_vfs + 1));
+}
+
+static void reserve_resources_from_vf(struct bnxt *bp,
+				      struct hwrm_func_cfg_input *cfg_req,
+				      int vf)
+{
+	struct hwrm_func_qcaps_input req = {0};
+	struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Get the actual allocated values now */
+	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps failed rc:%d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps error %d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	}
+
+	bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx);
+	bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/*
+	 * TODO: While not supporting VMDq with VFs, max_vnics is always
+	 * forced to 1 in this case
+	 */
+	//bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics);
+	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
+}
+
+static int update_pf_resource_max(struct bnxt *bp)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* And copy the allocated numbers into the pf struct */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	/* Only TX ring value reflects actual allocation? TODO */
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+	bp->pf.evb_mode = resp->evb_mode;
+
+	return rc;
+}
+
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
+{
+	int rc;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+	if (rc)
+		return rc;
+
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	return rc;
+}
+
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int i;
+	size_t sz;
+	int rc = 0;
+	size_t req_buf_sz;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+
+	if (rc)
+		return rc;
+
+	bp->pf.active_vfs = num_vfs;
+
+	/*
+	 * First, configure the PF to only use one TX ring.  This ensures that
+	 * there are enough rings for all VFs.
+	 *
+	 * If we don't do this, when we call func_alloc() later, we will lock
+	 * extra rings to the PF that won't be available during func_cfg() of
+	 * the VFs.
+	 *
+	 * This has been fixed with firmware versions above 20.6.54
+	 */
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, 1);
+	if (rc)
+		return rc;
+
+	/*
+	 * Now, create and register a buffer to hold forwarded VF requests
+	 */
+	req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN;
+	bp->pf.vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz,
+		page_roundup(num_vfs * HWRM_MAX_REQ_LEN));
+	if (bp->pf.vf_req_buf == NULL) {
+		rc = -ENOMEM;
+		goto error_free;
+	}
+	for (sz = 0; sz < req_buf_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)bp->pf.vf_req_buf) + sz);
+	for (i = 0; i < num_vfs; i++)
+		bp->pf.vf_info[i].req_buf = ((char *)bp->pf.vf_req_buf) +
+					(i * HWRM_MAX_REQ_LEN);
+
+	rc = bnxt_hwrm_func_buf_rgtr(bp);
+	if (rc)
+		goto error_free;
+
+	populate_vf_func_cfg_req(bp, &req, num_vfs);
+
+	bp->pf.active_vfs = 0;
+	for (i = 0; i < num_vfs; i++) {
+		HWRM_PREP(req, FUNC_CFG, -1, resp);
+		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
+		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
+		rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+		/* Clear enable flag for next pass */
+		req.enables &= ~rte_cpu_to_le_32(
+				HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+
+		if (rc || resp->error_code) {
+			RTE_LOG(ERR, PMD,
+				"Failed to initizlie VF %d\n", i);
+			RTE_LOG(ERR, PMD,
+				"Not all VFs available. (%d, %d)\n",
+				rc, resp->error_code);
+			break;
+		}
+
+		reserve_resources_from_vf(bp, &req, i);
+		bp->pf.active_vfs++;
+	}
+
+	/*
+	 * Now configure the PF to use "the rest" of the resources
+	 * We're using STD_TX_RING_MODE here though which will limit the TX
+	 * rings.  This will allow QoS to function properly.  Not setting this
+	 * will cause PF rings to break bandwidth settings.
+	 */
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	if (rc)
+		goto error_free;
+
+	rc = update_pf_resource_max(bp);
+	if (rc)
+		goto error_free;
+
+	return rc;
+
+error_free:
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	return rc;
+}
+
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	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);
+
+	req.req_buf_num_pages = rte_cpu_to_le_16(1);
+	req.req_buf_page_size = rte_cpu_to_le_16(
+			 page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN));
+	req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
+	req.req_buf_page_addr[0] =
+		rte_cpu_to_le_64(rte_mem_virt2phy(bp->pf.vf_req_buf));
+	if (req.req_buf_page_addr[0] == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map buffer address to physical memory\n");
+		return -ENOMEM;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
+	struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_BUF_UNRGTR, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_reject_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_reject_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, REJECT_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6519ef2..0046ba4 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,14 +51,17 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size);
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd);
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp);
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
@@ -81,6 +84,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_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				int16_t fw_vf_id);
 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);
@@ -101,5 +106,11 @@ 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);
 int bnxt_hwrm_func_qcfg(struct bnxt *bp);
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
+			  const uint8_t *mac_addr);
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 33fdde2..4e378a9 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -69,21 +69,14 @@ void bnxt_init_vnics(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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;
+		vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
 		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
 			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
@@ -181,15 +174,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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);
@@ -232,15 +217,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp)
 	if (bp->vnic_info == NULL)
 		return;
 
-	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;
-	}
+	max_vnics = bp->max_vnics;
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
 		if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
@@ -258,15 +235,7 @@ 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;
-	}
+	max_vnics = bp->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);
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 9671ba4..ca1c9cf 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -42,8 +42,7 @@ struct bnxt_vnic_info {
 	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;
+	uint16_t	rss_rule;
 #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 + \
@@ -51,6 +50,8 @@ struct bnxt_vnic_info {
 	uint16_t	start_grp_id;
 	uint16_t	end_grp_id;
 	uint16_t	fw_grp_ids[MAX_QUEUES_PER_VNIC];
+	uint16_t	dflt_ring_grp;
+	uint16_t	mru;
 	uint16_t	hash_type;
 	phys_addr_t	rss_table_dma_addr;
 	uint16_t	*rss_table;
@@ -60,8 +61,14 @@ struct bnxt_vnic_info {
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
 
+	uint16_t	cos_rule;
+	uint16_t	lb_rule;
 	bool		vlan_strip;
 	bool		func_default;
+	bool		bd_stall;
+	bool		roce_dual;
+	bool		roce_only;
+	bool		rss_dflt_cr;
 
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 03/25] bnxt: handle VF/PF initialization appropriately
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 01/25] bnxt: update to new HWRM version Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 02/25] bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 04/25] bnxt: support lack of huge pages Ajit Khaparde
                         ` (22 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) For a VF, query the firmware to determine if a MAC address is
already configured. If not configure a random default MAC address.
2) Do not initialize the default completion ring in
bnxt_alloc_hwrm_rings().
3) While registering for async events with the firmware,
use func_vf_cfg for a VF and use func_cfg for a PF.
4) Query the VNIC plcmode config using the bnxt_hwrm_vnic_plcmodes_qcfg
before a VNIC is updated. Reconfigure the VNIC with the plcmode
configuration queried earlier. Not doing this could overwrite
the plcmodes in some cases.
5) Reorg the bnxt_handle_fwd_req to properly handle the forwarded
requests. The previous code did not handle it completely.

--
v1->v2: regroup related patches and incorporate other
  review comments.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_cpr.c       | 131 ++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_cpr.h       |  17 ++++
 drivers/net/bnxt/bnxt_ethdev.c    |  30 +++++---
 drivers/net/bnxt/bnxt_filter.c    |   2 +-
 drivers/net/bnxt/bnxt_hwrm.c      | 158 +++++++++++++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_hwrm.h      |   4 +-
 drivers/net/bnxt/bnxt_irq.c       |  21 +++--
 drivers/net/bnxt/bnxt_ring.c      |  17 +---
 9 files changed, 294 insertions(+), 88 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 013a9cd..8fcabdb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -12,5 +12,7 @@ Multicast MAC filter = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
+SR-IOV               = Y
+Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 3aedcb8..d13e6cc 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -65,56 +65,115 @@ void bnxt_handle_async_event(struct bnxt *bp,
 
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
 {
+	struct hwrm_exec_fwd_resp_input *fwreq;
 	struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
 	struct input *fwd_cmd;
-	uint16_t logical_vf_id, error_code;
+	uint16_t fw_vf_id;
+	uint16_t vf_id;
+	uint16_t req_len;
+	int rc;
 
-	/* 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;
+	if (bp->pf.active_vfs <= 0) {
+		RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
+		return;
 	}
 
+	/* Qualify the fwd request */
+	fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+	vf_id = fw_vf_id - bp->pf.first_vf_id;
+
+	req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+		   HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+		HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+	if (req_len > sizeof(fwreq->encap_request))
+		req_len = sizeof(fwreq->encap_request);
+
 	/* 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;
+	fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
+
+	if (fw_vf_id < bp->pf.first_vf_id ||
+	    fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+		RTE_LOG(ERR, PMD,
+		"FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
+			fw_vf_id, bp->pf.first_vf_id,
+			(bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
+			bp->pf.first_vf_id, bp->pf.active_vfs);
 		goto reject;
 	}
 
-	/* Forward */
-	fwd_cmd->target_id = fwd_cmpl->source_id;
-	bnxt_hwrm_exec_fwd_resp(bp, fwd_cmd);
-	return;
+	if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
+		/*
+		 * In older firmware versions, the MAC had to be all zeros for
+		 * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
+		 * zeros if it's being configured and has been ok'd by caller.
+		 */
+		if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
+			struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
+
+			if (vfc->enables &
+			    HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
+				bnxt_hwrm_func_vf_mac(bp, vf_id,
+				(const uint8_t *)"\x00\x00\x00\x00\x00");
+			}
+		}
+		if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
+			struct hwrm_cfa_l2_set_rx_mask_input *srm =
+							(void *)fwd_cmd;
+
+			srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
+			srm->num_vlan_tags = rte_cpu_to_le_32(0);
+			srm->mask &= ~rte_cpu_to_le_32(
+				HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
+		}
+		/* Forward */
+		rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+		if (rc) {
+			RTE_LOG(ERR, PMD,
+				"Failed to send FWD req VF 0x%x, type 0x%x.\n",
+				fw_vf_id - bp->pf.first_vf_id,
+				rte_le_to_cpu_16(fwd_cmd->req_type));
+		}
+		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);
+	rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+	if (rc) {
+		RTE_LOG(ERR, PMD,
+			"Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+			fw_vf_id - bp->pf.first_vf_id,
+			rte_le_to_cpu_16(fwd_cmd->req_type));
+	}
+
+	return;
 }
 
 /* For the default completion ring only */
+int bnxt_alloc_def_cp_ring(struct bnxt *bp)
+{
+	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+	int rc;
+
+	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+				  0, HWRM_NA_SIGNATURE);
+	if (rc)
+		goto err_out;
+	cpr->cp_doorbell = bp->pdev->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;
+	if (BNXT_PF(bp))
+		rc = bnxt_hwrm_func_cfg_def_cp(bp);
+	else
+		rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
+
+err_out:
+	return rc;
+}
+
 void bnxt_free_def_cp_ring(struct bnxt *bp)
 {
 	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 83e5376..a6e8785 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -33,6 +33,7 @@
 
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_H_
+#include <stdbool.h>
 
 #include <rte_io.h>
 
@@ -56,6 +57,19 @@
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
 		    ((cpr)->cp_doorbell))
 
+#define B_CP_DB_ARM(cpr)	rte_write32((DB_KEY_CP), ((cpr)->cp_doorbell))
+#define B_CP_DB_DISARM(cpr)	(*(uint32_t *)((cpr)->cp_doorbell) = \
+				 DB_KEY_CP | DB_IRQ_DIS)
+
+#define B_CP_DB_IDX_ARM(cpr, cons)					\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+				(cons)))
+
+#define B_CP_DB_IDX_DISARM(cpr, cons)	do {				\
+		rte_smp_wmb();						\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS |	\
+				(cons));				\
+} while (0)
 #define B_CP_DIS_DB(cpr, raw_cons)					\
 	rte_write32((DB_CP_FLAGS |					\
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
@@ -75,6 +89,8 @@ struct bnxt_cp_ring_info {
 	uint32_t		hw_stats_ctx_id;
 
 	struct bnxt_ring	*cp_ring_struct;
+	uint16_t		cp_cons;
+	bool			v;
 };
 
 #define RX_CMP_L2_ERRORS						\
@@ -82,6 +98,7 @@ struct bnxt_cp_ring_info {
 
 
 struct bnxt;
+int bnxt_alloc_def_cp_ring(struct bnxt *bp);
 void bnxt_free_def_cp_ring(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);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index f127d3a..5240583 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -228,28 +228,31 @@ static int bnxt_init_chip(struct bnxt *bp)
 
 		rc = bnxt_hwrm_vnic_alloc(bp, vnic);
 		if (rc) {
-			RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
-				rc);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d alloc failure rc: %x\n",
+				i, 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);
+				"HWRM vnic %d ctx alloc failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d cfg failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD,
+				"HWRM vnic %d filter failure rc: %x\n",
+				i, rc);
 			goto err_out;
 		}
 		if (vnic->rss_table && vnic->hash_type) {
@@ -269,8 +272,8 @@ static int bnxt_init_chip(struct bnxt *bp)
 			rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
 			if (rc) {
 				RTE_LOG(ERR, PMD,
-					"HWRM vnic set RSS failure rc: %x\n",
-					rc);
+					"HWRM vnic %d set RSS failure rc: %x\n",
+					i, rc);
 				goto err_out;
 			}
 		}
@@ -638,7 +641,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
 			new.link_speed = ETH_LINK_SPEED_100M;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			RTE_LOG(ERR, PMD,
-				"Failed to retrieve link rc = 0x%x!", rc);
+				"Failed to retrieve link rc = 0x%x!\n", rc);
 			goto out;
 		}
 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
@@ -1010,7 +1013,8 @@ static bool bnxt_vf_pciid(uint16_t id)
 	if (id == BROADCOM_DEV_ID_57304_VF ||
 	    id == BROADCOM_DEV_ID_57406_VF ||
 	    id == BROADCOM_DEV_ID_5731X_VF ||
-	    id == BROADCOM_DEV_ID_5741X_VF)
+	    id == BROADCOM_DEV_ID_5741X_VF ||
+	    id == BROADCOM_DEV_ID_57414_VF)
 		return true;
 	return false;
 }
@@ -1066,7 +1070,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	if (version_printed++ == 0)
-		RTE_LOG(INFO, PMD, "%s", bnxt_version);
+		RTE_LOG(INFO, PMD, "%s\n", bnxt_version);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
@@ -1207,6 +1211,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (rc)
 		goto error_free_int;
 
+	rc = bnxt_alloc_def_cp_ring(bp);
+	if (rc)
+		goto error_free_int;
+
 	bnxt_enable_int(bp);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 137c7b7..0afde86 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -126,7 +126,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 				       "HWRM filter cannot be freed rc = %d\n",
 					rc);
 		}
-		filter->fw_l2_filter_id = -1;
+		filter->fw_l2_filter_id = UINT64_MAX;
 	}
 	STAILQ_INIT(&bp->free_filter_list);
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7aece5d..7c7c9ce 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -33,6 +33,8 @@
 
 #include <unistd.h>
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -286,24 +288,6 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	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_qcaps(struct bnxt *bp)
 {
 	int rc = 0;
@@ -905,12 +889,71 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+static int bnxt_hwrm_vnic_plcmodes_qcfg(struct bnxt *bp,
+					struct bnxt_vnic_info *vnic,
+					struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_QCFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	pmode->flags = rte_le_to_cpu_32(resp->flags);
+	/* dflt_vnic bit doesn't exist in the _cfg command */
+	pmode->flags &= ~(HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC);
+	pmode->jumbo_thresh = rte_le_to_cpu_16(resp->jumbo_thresh);
+	pmode->hds_offset = rte_le_to_cpu_16(resp->hds_offset);
+	pmode->hds_threshold = rte_le_to_cpu_16(resp->hds_threshold);
+
+	return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
+				       struct bnxt_vnic_info *vnic,
+				       struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+	req.flags = rte_cpu_to_le_32(pmode->flags);
+	req.jumbo_thresh = rte_cpu_to_le_16(pmode->jumbo_thresh);
+	req.hds_offset = rte_cpu_to_le_16(pmode->hds_offset);
+	req.hds_threshold = rte_cpu_to_le_16(pmode->hds_threshold);
+	req.enables = rte_cpu_to_le_32(
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID
+	);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	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;
 	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	struct bnxt_plcmodes_cfg pmodes;
+
+	rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
+	if (rc)
+		return rc;
 
 	HWRM_PREP(req, VNIC_CFG, -1, resp);
 
@@ -954,6 +997,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
+	rc = bnxt_hwrm_vnic_plcmodes_cfg(bp, vnic, &pmodes);
+
 	return rc;
 }
 
@@ -1773,6 +1818,25 @@ static void populate_vf_func_cfg_req(struct bnxt *bp,
 						 (num_vfs + 1));
 }
 
+static void add_random_mac_if_needed(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *cfg_req,
+				     int vf)
+{
+	struct ether_addr mac;
+
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac))
+		return;
+
+	if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) {
+		cfg_req->enables |=
+		rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+		eth_random_addr(cfg_req->dflt_mac_addr);
+		bp->pf.vf_info[vf].random_mac = true;
+	} else {
+		memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, ETHER_ADDR_LEN);
+	}
+}
+
 static void reserve_resources_from_vf(struct bnxt *bp,
 				      struct hwrm_func_cfg_input *cfg_req,
 				      int vf)
@@ -1914,6 +1978,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 
 	bp->pf.active_vfs = 0;
 	for (i = 0; i < num_vfs; i++) {
+		add_random_mac_if_needed(bp, &req, i);
+
 		HWRM_PREP(req, FUNC_CFG, -1, resp);
 		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
 		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
@@ -2019,6 +2085,23 @@ int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_vf_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_VF_CFG, -1, resp);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
@@ -2040,3 +2123,42 @@ int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	memcpy(mac->addr_bytes, resp->mac_address, ETHER_ADDR_LEN);
+	return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_exec_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, EXEC_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 0046ba4..1ea78b2 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,7 +51,8 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size);
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size);
 
@@ -62,6 +63,7 @@ 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_func_cfg_def_cp(struct bnxt *bp);
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index 20e17ff..a3d235d 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -66,16 +66,26 @@ static void bnxt_int_handler(void *param)
 			/* Handle any async event */
 			bnxt_handle_async_event(bp, cmp);
 			break;
-		case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+		case CMPL_BASE_TYPE_HWRM_FWD_REQ:
 			/* Handle HWRM forwarded responses */
 			bnxt_handle_fwd_req(bp, cmp);
 			break;
 		default:
 			/* Ignore any other events */
+			if (cmp->type & rte_cpu_to_le_16(0x01)) {
+				if (!CMP_VALID(cmp, raw_cons,
+					       cpr->cp_ring_struct))
+					goto no_more;
+			}
+			RTE_LOG(INFO, PMD,
+				"Ignoring %02x completion\n", CMP_TYPE(cmp));
 			break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
-	}
+
+	};
+no_more:
+	cpr->cp_raw_cons = raw_cons;
 	B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
 }
 
@@ -102,14 +112,15 @@ 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);
+	if (cpr != NULL && cpr->cp_doorbell != NULL)
+		B_CP_DB_DISARM(cpr);
 }
 
 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);
+	B_CP_DB_ARM(cpr);
 }
 
 int bnxt_setup_int(struct bnxt *bp)
@@ -136,7 +147,7 @@ int bnxt_setup_int(struct bnxt *bp)
 	return 0;
 
 setup_exit:
-	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed\n");
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 52fbd89..c1698ea 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -213,21 +213,6 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 	unsigned int i;
 	int rc = 0;
 
-	/* Default completion ring */
-	{
-		struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
-
-		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					0, HWRM_NA_SIGNATURE);
-		if (rc)
-			goto err_out;
-		cpr->cp_doorbell = 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;
@@ -259,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		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!");
+			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 04/25] bnxt: support lack of huge pages
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (2 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 03/25] bnxt: handle VF/PF initialization appropriately Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 05/25] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
                         ` (21 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

rte_malloc_virt2phy() does not return a physical address if huge pages
aren't in use.  Further, rte_memzone->phys_addr is not a physical address.

Use rte_mem_virt2phy() and manually lock pages to support lack of
huge pages.

Also check the return value of rte_mem_virt2phy()

Verify the function returns an address. Otherwise return an error and
log a message.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_hwrm.c | 17 +++++++++++++++--
 drivers/net/bnxt/bnxt_ring.c | 31 +++++++++++++++++++++++++------
 drivers/net/bnxt/bnxt_vnic.c | 16 +++++++++++++++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7c7c9ce..d2a8d8f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -489,8 +489,15 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto error;
 		}
+		rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 		bp->hwrm_cmd_resp_dma_addr =
-			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+			rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+		if (bp->hwrm_cmd_resp_dma_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"Unable to map response buffer to physical memory.\n");
+			rc = -ENOMEM;
+			goto error;
+		}
 		bp->max_resp_len = max_resp_len;
 	}
 
@@ -1363,10 +1370,16 @@ 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);
+	rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 	if (bp->hwrm_cmd_resp_addr == NULL)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
-		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+	if (bp->hwrm_cmd_resp_dma_addr == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map response address to physical memory\n");
+		return -ENOMEM;
+	}
 	rte_spinlock_init(&bp->hwrm_lock);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index c1698ea..5e4236a 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -32,6 +32,7 @@
  */
 
 #include <rte_memzone.h>
+#include <unistd.h>
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
@@ -96,6 +97,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	struct rte_pci_device *pdev = bp->pdev;
 	const struct rte_memzone *mz = NULL;
 	char mz_name[RTE_MEMZONE_NAMESIZE];
+	phys_addr_t mz_phys_addr;
+	int sz;
 
 	int stats_len = (tx_ring_info || rx_ring_info) ?
 	    RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats64)) : 0;
@@ -136,21 +139,37 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
 	mz = rte_memzone_lookup(mz_name);
 	if (!mz) {
-		mz = rte_memzone_reserve(mz_name, total_alloc_len,
+		mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
-					 RTE_MEMZONE_SIZE_HINT_ONLY);
+					 RTE_MEMZONE_SIZE_HINT_ONLY,
+					 getpagesize());
 		if (mz == NULL)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		for (sz = 0; sz < total_alloc_len; sz += getpagesize())
+			rte_mem_lock_page(((char *)mz->addr) + sz);
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map ring address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	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->bd_dma = mz_phys_addr + tx_ring_start;
 		tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
 		tx_ring->mem_zone = (const void *)mz;
 
@@ -170,7 +189,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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->bd_dma = mz_phys_addr + rx_ring_start;
 		rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
 		rx_ring->mem_zone = (const void *)mz;
 
@@ -185,7 +204,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
-	cp_ring->bd_dma = mz->phys_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;
 	cp_ring->mem_zone = (const void *)mz;
@@ -196,7 +215,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		*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_map = mz_phys_addr;
 	}
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 4e378a9..fe2244b 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -173,6 +173,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 				HW_HASH_KEY_SIZE);
 	uint16_t max_vnics;
 	int i;
+	phys_addr_t mz_phys_addr;
 
 	max_vnics = bp->max_vnics;
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
@@ -189,6 +190,19 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 		if (!mz)
 			return -ENOMEM;
 	}
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map vnic address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
@@ -198,7 +212,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 			(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_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));
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 05/25] bnxt: add additonal HWRM debug info to error messages
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (3 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 04/25] bnxt: support lack of huge pages Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 06/25] bnxt: add tunneling support Ajit Khaparde
                         ` (20 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

Add the cmd_err and opaque_0 and opaque_1 fields to HWRM error
messages.  These allow better debugging of some classes of HWRM
errors.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_hwrm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d2a8d8f..3c2f148 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -139,7 +139,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 	}
 
 	if (i >= HWRM_CMD_TIMEOUT) {
-		RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+		RTE_LOG(ERR, PMD, "Error sending msg 0x%04x\n",
 			req->req_type);
 		goto err_ret;
 	}
@@ -176,7 +176,22 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 		if (resp->error_code) { \
 			rc = rte_le_to_cpu_16(resp->error_code); \
-			RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \
+			if (resp->resp_len >= 16) { \
+				struct hwrm_err_output *tmp_hwrm_err_op = \
+							(void *)resp; \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d:%d:%08x:%04x\n", \
+					__func__, \
+					rc, tmp_hwrm_err_op->cmd_err, \
+					rte_le_to_cpu_32(\
+						tmp_hwrm_err_op->opaque_0), \
+					rte_le_to_cpu_16(\
+						tmp_hwrm_err_op->opaque_1)); \
+			} \
+			else { \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d\n", __func__, rc); \
+			} \
 			return rc; \
 		} \
 	}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 06/25] bnxt: add tunneling support
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (4 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 05/25] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 07/25] bnxt: add support for xstats get/reset Ajit Khaparde
                         ` (19 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for udp_tunnel_port_add/del dev_ops to configure a UDP port
for VXLAN and Geneve Tunnel protocols.
The HWRM supports only one global destination port for a tunnel type,
use a referene counter to keep track of its usage.
Cache the configured VXLAN/Geneve ports and use that value to check
if the right UDP port is being freed up.
Skip calling bnxt_hwrm_tunnel_dst_port_alloc if the same UDP port is
being programmed.
Skip calling bnxt_hwrm_tunnel_dst_port_free if no UDP port has been
configured.
Also update tx offload capabilities

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h        |   6 +++
 drivers/net/bnxt/bnxt_ethdev.c | 119 ++++++++++++++++++++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.c   |  56 +++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   5 ++
 drivers/net/bnxt/bnxt_txr.c    |   3 +-
 5 files changed, 187 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 0c59c66..3bc3f99 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -188,6 +188,12 @@ struct bnxt {
 	struct bnxt_pf_info		pf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint8_t			vxlan_port_cnt;
+	uint8_t			geneve_port_cnt;
+	uint16_t		vxlan_port;
+	uint16_t		geneve_port;
+	uint16_t		vxlan_fw_dst_port_id;
+	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5240583..e7288da 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -363,7 +363,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
+					DEV_TX_OFFLOAD_TCP_TSO |
+					DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+					DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+					DEV_TX_OFFLOAD_GRE_TNL_TSO |
+					DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+					DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
 
 	/* *INDENT-OFF* */
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -975,6 +980,116 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
 	return bnxt_set_hwrm_link_config(bp, true);
 }
 
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->vxlan_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->vxlan_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+		bp->vxlan_port_cnt++;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->geneve_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->geneve_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+		bp->geneve_port_cnt++;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+					     tunnel_type);
+	return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	uint16_t port = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (!bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->vxlan_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->vxlan_port);
+			return -EINVAL;
+		}
+		if (--bp->vxlan_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+		port = bp->vxlan_fw_dst_port_id;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (!bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->geneve_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->geneve_port);
+			return -EINVAL;
+		}
+		if (--bp->geneve_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+		port = bp->geneve_fw_dst_port_id;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+	if (!rc) {
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+			bp->vxlan_port = 0;
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+			bp->geneve_port = 0;
+	}
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1006,6 +1121,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.mac_addr_remove = bnxt_mac_addr_remove_op,
 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
+	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
+	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_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 3c2f148..dab4171 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1426,6 +1426,18 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+void bnxt_free_tunnel_ports(struct bnxt *bp)
+{
+	if (bp->vxlan_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN);
+	bp->vxlan_port = 0;
+	if (bp->geneve_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+	bp->geneve_port = 0;
+}
+
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 {
 	struct bnxt_vnic_info *vnic;
@@ -1451,6 +1463,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	bnxt_free_all_hwrm_rings(bp);
 	bnxt_free_all_hwrm_ring_grps(bp);
 	bnxt_free_all_hwrm_stat_ctxs(bp);
+	bnxt_free_tunnel_ports(bp);
 }
 
 static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
@@ -2051,6 +2064,49 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_alloc_input req = {0};
+	struct hwrm_tunnel_dst_port_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_val = port;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	switch (tunnel_type) {
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN:
+		bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->vxlan_port = port;
+		break;
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE:
+		bp->geneve_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->geneve_port = port;
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_free_input req = {0};
+	struct hwrm_tunnel_dst_port_free_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_FREE, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_id = rte_cpu_to_be_16(port);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
 
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1ea78b2..cee8fca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -114,5 +114,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+void bnxt_free_tunnel_ports(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 0d15bb1..6870b16 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -213,7 +213,8 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 			/* TSO */
 			txbd1->lflags = TX_BD_LONG_LFLAGS_LSO;
 			txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
-					tx_pkt->l4_len;
+					tx_pkt->l4_len + tx_pkt->outer_l2_len +
+					tx_pkt->outer_l3_len;
 			txbd1->mss = tx_pkt->tso_segsz;
 
 		} else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM |
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 07/25] bnxt: add support for xstats get/reset
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (5 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 06/25] bnxt: add tunneling support Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:42         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
                         ` (18 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to get and reset xstats dev_ops

dev_ops added:
xstats_get, xstats_get_name, xstats_reset

HWRM commands added:
hwrm_port_qstats, hwrm_port_clr_stats

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h        |   7 ++
 drivers/net/bnxt/bnxt_ethdev.c |  84 +++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   |  36 +++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   3 +-
 drivers/net/bnxt/bnxt_stats.c  | 207 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h  |  10 ++
 6 files changed, 346 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 3bc3f99..fde2202 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -130,6 +130,7 @@ struct bnxt {
 	uint32_t		flags;
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
+#define BNXT_FLAG_PORT_STATS	(1 << 2)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -138,10 +139,16 @@ struct bnxt {
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	struct bnxt_rx_queue **rx_queues;
+	const void		*rx_mem_zone;
+	struct rx_port_stats    *hw_rx_port_stats;
+	phys_addr_t		hw_rx_port_stats_map;
 
 	unsigned int		tx_nr_rings;
 	unsigned int		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
+	const void		*tx_mem_zone;
+	struct tx_port_stats    *hw_tx_port_stats;
+	phys_addr_t		hw_tx_port_stats_map;
 
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e7288da..5de7567 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -533,6 +533,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
+	bnxt_hwrm_port_clr_stats(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1123,6 +1124,9 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.xstats_get = bnxt_dev_xstats_get_op,
+	.xstats_get_names = bnxt_dev_xstats_get_names_op,
+	.xstats_reset = bnxt_dev_xstats_reset_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1182,7 +1186,11 @@ static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev = RTE_DEV_TO_PCI(eth_dev->device);
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	const struct rte_memzone *mz = NULL;
 	static int version_printed;
+	uint32_t total_alloc_len;
+	phys_addr_t mz_phys_addr;
 	struct bnxt *bp;
 	int rc;
 
@@ -1208,6 +1216,80 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
+	if (BNXT_PF(bp) && pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) {
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "rx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct rx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->rx_mem_zone = (const void *)mz;
+		bp->hw_rx_port_stats = mz->addr;
+		bp->hw_rx_port_stats_map = mz_phys_addr;
+
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "tx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct tx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->tx_mem_zone = (const void *)mz;
+		bp->hw_tx_port_stats = mz->addr;
+		bp->hw_tx_port_stats_map = mz_phys_addr;
+
+		bp->flags |= BNXT_FLAG_PORT_STATS;
+	}
+
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
@@ -1366,6 +1448,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	}
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
+	rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
+	rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
 	if (bp->pf.vf_info)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dab4171..d942648 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2246,3 +2246,39 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_port_qstats(struct bnxt *bp)
+{
+	struct hwrm_port_qstats_input req = {0};
+	struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_QSTATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	req.tx_stat_host_addr = rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+	req.rx_stat_host_addr = rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+	struct hwrm_port_clr_stats_input req = {0};
+	struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_CLR_STATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index cee8fca..8f7d103 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -119,5 +119,6 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
-
+int bnxt_hwrm_port_qstats(struct bnxt *bp);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 40c9cac..154dc0c 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -43,6 +43,128 @@
 #include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
+static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
+	{"rx_64b_frames", offsetof(struct rx_port_stats,
+				rx_64b_frames)},
+	{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
+				rx_65b_127b_frames)},
+	{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
+				rx_128b_255b_frames)},
+	{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
+				rx_256b_511b_frames)},
+	{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
+				rx_512b_1023b_frames)},
+	{"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
+				rx_1024b_1518_frames)},
+	{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
+				rx_good_vlan_frames)},
+	{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
+				rx_1519b_2047b_frames)},
+	{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
+				rx_2048b_4095b_frames)},
+	{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
+				rx_4096b_9216b_frames)},
+	{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
+				rx_9217b_16383b_frames)},
+	{"rx_total_frames", offsetof(struct rx_port_stats,
+				rx_total_frames)},
+	{"rx_ucast_frames", offsetof(struct rx_port_stats,
+				rx_ucast_frames)},
+	{"rx_mcast_frames", offsetof(struct rx_port_stats,
+				rx_mcast_frames)},
+	{"rx_bcast_frames", offsetof(struct rx_port_stats,
+				rx_bcast_frames)},
+	{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
+				rx_fcs_err_frames)},
+	{"rx_ctrl_frames", offsetof(struct rx_port_stats,
+				rx_ctrl_frames)},
+	{"rx_pause_frames", offsetof(struct rx_port_stats,
+				rx_pause_frames)},
+	{"rx_pfc_frames", offsetof(struct rx_port_stats,
+				rx_pfc_frames)},
+	{"rx_align_err_frames", offsetof(struct rx_port_stats,
+				rx_align_err_frames)},
+	{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
+				rx_ovrsz_frames)},
+	{"rx_jbr_frames", offsetof(struct rx_port_stats,
+				rx_jbr_frames)},
+	{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
+				rx_mtu_err_frames)},
+	{"rx_tagged_frames", offsetof(struct rx_port_stats,
+				rx_tagged_frames)},
+	{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
+				rx_double_tagged_frames)},
+	{"rx_good_frames", offsetof(struct rx_port_stats,
+				rx_good_frames)},
+	{"rx_undrsz_frames", offsetof(struct rx_port_stats,
+				rx_undrsz_frames)},
+	{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
+				rx_eee_lpi_events)},
+	{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
+				rx_eee_lpi_duration)},
+	{"rx_bytes", offsetof(struct rx_port_stats,
+				rx_bytes)},
+	{"rx_runt_bytes", offsetof(struct rx_port_stats,
+				rx_runt_bytes)},
+	{"rx_runt_frames", offsetof(struct rx_port_stats,
+				rx_runt_frames)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
+	{"tx_64b_frames", offsetof(struct tx_port_stats,
+				tx_64b_frames)},
+	{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
+				tx_65b_127b_frames)},
+	{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
+				tx_128b_255b_frames)},
+	{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
+				tx_256b_511b_frames)},
+	{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
+				tx_512b_1023b_frames)},
+	{"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
+				tx_1024b_1518_frames)},
+	{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
+				tx_good_vlan_frames)},
+	{"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
+				tx_1519b_2047_frames)},
+	{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
+				tx_2048b_4095b_frames)},
+	{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
+				tx_4096b_9216b_frames)},
+	{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
+				tx_9217b_16383b_frames)},
+	{"tx_good_frames", offsetof(struct tx_port_stats,
+				tx_good_frames)},
+	{"tx_total_frames", offsetof(struct tx_port_stats,
+				tx_total_frames)},
+	{"tx_ucast_frames", offsetof(struct tx_port_stats,
+				tx_ucast_frames)},
+	{"tx_mcast_frames", offsetof(struct tx_port_stats,
+				tx_mcast_frames)},
+	{"tx_bcast_frames", offsetof(struct tx_port_stats,
+				tx_bcast_frames)},
+	{"tx_pause_frames", offsetof(struct tx_port_stats,
+				tx_pause_frames)},
+	{"tx_pfc_frames", offsetof(struct tx_port_stats,
+				tx_pfc_frames)},
+	{"tx_jabber_frames", offsetof(struct tx_port_stats,
+				tx_jabber_frames)},
+	{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
+				tx_fcs_err_frames)},
+	{"tx_err", offsetof(struct tx_port_stats,
+				tx_err)},
+	{"tx_fifo_underruns", offsetof(struct tx_port_stats,
+				tx_fifo_underruns)},
+	{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
+				tx_eee_lpi_events)},
+	{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
+				tx_eee_lpi_duration)},
+	{"tx_total_collisions", offsetof(struct tx_port_stats,
+				tx_total_collisions)},
+	{"tx_bytes", offsetof(struct tx_port_stats,
+				tx_bytes)},
+};
+
 /*
  * Statistics functions
  */
@@ -140,3 +262,88 @@ void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
 
 	bnxt_clear_all_hwrm_stat_ctxs(bp);
 }
+
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	unsigned int count, i;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
+		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
+		return 0;
+	}
+
+	bnxt_hwrm_port_qstats(bp);
+
+	count = RTE_DIM(bnxt_rx_stats_strings) +
+		RTE_DIM(bnxt_tx_stats_strings);
+
+	if (n < count)
+		return count;
+
+	count = 0;
+	for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+		uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				*(uint64_t *)((char *)rx_stats +
+				bnxt_rx_stats_strings[i].offset));
+		count++;
+	}
+
+	for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+		uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				 *(uint64_t *)((char *)tx_stats +
+				bnxt_tx_stats_strings[i].offset));
+		count++;
+	}
+
+	return count;
+}
+
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit)
+{
+	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+				RTE_DIM(bnxt_tx_stats_strings);
+	unsigned int i, count;
+
+	if (xstats_names != NULL) {
+		count = 0;
+
+		for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_rx_stats_strings[i].name);
+			count++;
+		}
+
+		for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_tx_stats_strings[i].name);
+			count++;
+		}
+	}
+	return stat_cnt;
+}
+
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->flags & BNXT_FLAG_PORT_STATS && !BNXT_NPAR_PF(bp))
+		bnxt_hwrm_port_clr_stats(bp);
+
+	if (BNXT_VF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a VF device\n");
+	if (BNXT_NPAR_PF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a MF device\n");
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		RTE_LOG(ERR, PMD, "Operation not supported\n");
+}
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
index 65408a4..b6d133e 100644
--- a/drivers/net/bnxt/bnxt_stats.h
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -40,5 +40,15 @@ 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);
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit);
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n);
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev);
 
+struct bnxt_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	uint64_t offset;
+};
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (6 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 07/25] bnxt: add support for xstats get/reset Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:43         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
                         ` (17 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds VLAN strip and offload callbacks.
To add a VLAN filter:
    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

To remove a VLAN filter:
    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

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_ethdev.c    | 201 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 203 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 8fcabdb..78a738f 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -9,6 +9,8 @@ Queue start/stop     = Y
 Promiscuous mode     = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
+VLAN filter          = Y
+VLAN offload         = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5de7567..6e3ba79 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -141,6 +141,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_TCP |	\
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
+static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
 /***********************/
 
 /*
@@ -487,6 +488,7 @@ static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	int vlan_mask = 0;
 	int rc;
 
 	bp->dev_stopped = 0;
@@ -496,6 +498,13 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 		goto error;
 
 	bnxt_link_update_op(eth_dev, 0);
+
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter)
+		vlan_mask |= ETH_VLAN_FILTER_MASK;
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
+		vlan_mask |= ETH_VLAN_STRIP_MASK;
+	bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+
 	return 0;
 
 error:
@@ -1091,6 +1100,196 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
 	return rc;
 }
 
+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 int i;
+	int rc = 0;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk &&
+				    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 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->fw_vnic_id,
+							new_filter);
+					if (rc)
+						goto exit;
+					RTE_LOG(INFO, PMD,
+						"Del Vlan filter for %d\n",
+						vlan_id);
+				}
+				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 int i;
+	int rc = 0;
+	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
+		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk) {
+					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 |= en;
+				rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id,
+							  new_filter);
+				if (rc)
+					goto exit;
+				RTE_LOG(INFO, PMD,
+					"Added Vlan filter for %d\n", vlan_id);
+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_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	unsigned int i;
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (!dev->data->dev_conf.rxmode.hw_vlan_filter) {
+			/* Remove any VLAN filters programmed */
+			for (i = 0; i < 4095; i++)
+				bnxt_del_vlan_filter(bp, i);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Filtering: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_filter);
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		/* Enable or disable VLAN stripping */
+		for (i = 0; i < bp->nr_vnics; i++) {
+			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+			if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+				vnic->vlan_strip = true;
+			else
+				vnic->vlan_strip = false;
+			bnxt_hwrm_vnic_cfg(bp, vnic);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Strip Offload: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_strip);
+	}
+
+	if (mask & ETH_VLAN_EXTEND_MASK)
+		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
+}
+
 /*
  * Initialization
  */
@@ -1124,6 +1323,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.vlan_filter_set = bnxt_vlan_filter_set_op,
+	.vlan_offload_set = bnxt_vlan_offload_set_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (7 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:42         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 10/25] bnxt: add support for fw_version_get dev_op Ajit Khaparde
                         ` (16 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for set_mc_addr_list and
mac_addr_set dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 doc/guides/nics/features/bnxt.ini |  1 +
 drivers/net/bnxt/bnxt_ethdev.c    | 70 ++++++++++++++++++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.c      | 13 +++++---
 drivers/net/bnxt/bnxt_hwrm.h      |  2 +-
 drivers/net/bnxt/bnxt_vnic.c      |  7 +++-
 drivers/net/bnxt/bnxt_vnic.h      |  4 +++
 6 files changed, 90 insertions(+), 7 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 78a738f..9b3cd94 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -11,6 +11,7 @@ Unicast MAC filter   = Y
 Multicast MAC filter = Y
 VLAN filter          = Y
 VLAN offload         = Y
+Allmulticast mode    = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 6e3ba79..02d1749 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -638,7 +638,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
 	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
 	filter->mac_index = index;
 	memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
-	return bnxt_hwrm_set_filter(bp, vnic, filter);
+	return bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 }
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
@@ -1290,6 +1290,72 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
 }
 
+static void
+bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	/* Default Filter is tied to VNIC 0 */
+	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+	struct bnxt_filter_info *filter;
+	int rc;
+
+	if (BNXT_VF(bp))
+		return;
+
+	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
+	memcpy(&dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+	STAILQ_FOREACH(filter, &vnic->filter, next) {
+		/* Default Filter is at Index 0 */
+		if (filter->mac_index != 0)
+			continue;
+		rc = bnxt_hwrm_clear_filter(bp, filter);
+		if (rc)
+			break;
+		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
+		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+		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;
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
+		if (rc)
+			break;
+		filter->mac_index = 0;
+		RTE_LOG(DEBUG, PMD, "Set MAC addr\n");
+	}
+}
+
+static int
+bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
+			  struct ether_addr *mc_addr_set,
+			  uint32_t nb_mc_addr)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	char *mc_addr_list = (char *)mc_addr_set;
+	struct bnxt_vnic_info *vnic;
+	uint32_t off = 0, i = 0;
+
+	vnic = &bp->vnic_info[0];
+
+	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
+		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+		goto allmulti;
+	}
+
+	/* TODO Check for Duplicate mcast addresses */
+	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+	for (i = 0; i < nb_mc_addr; i++) {
+		memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN);
+		off += ETHER_ADDR_LEN;
+	}
+
+	vnic->mc_addr_cnt = i;
+
+allmulti:
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
 /*
  * Initialization
  */
@@ -1325,9 +1391,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_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 d942648..22e18d6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,7 +229,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+	if (vnic->mc_addr_cnt) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
+		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
+	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
 
@@ -261,7 +266,7 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 }
 
 int bnxt_hwrm_set_filter(struct bnxt *bp,
-			 struct bnxt_vnic_info *vnic,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter)
 {
 	int rc = 0;
@@ -275,7 +280,7 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 
 	enables = filter->enables |
 	      HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
-	req.dst_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.dst_id = rte_cpu_to_le_16(dst_id);
 
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
@@ -1419,7 +1424,7 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	int rc = 0;
 
 	STAILQ_FOREACH(filter, &vnic->filter, next) {
-		rc = bnxt_hwrm_set_filter(bp, vnic, filter);
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
 			break;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 8f7d103..c15404f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -49,7 +49,7 @@ 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,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter);
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			    void *encaped, size_t ec_size);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index fe2244b..db9fb07 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -170,7 +170,8 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	char mz_name[RTE_MEMZONE_NAMESIZE];
 	uint32_t entry_length = RTE_CACHE_LINE_ROUNDUP(
 				HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
-				HW_HASH_KEY_SIZE);
+				HW_HASH_KEY_SIZE +
+				BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN);
 	uint16_t max_vnics;
 	int i;
 	phys_addr_t mz_phys_addr;
@@ -218,6 +219,10 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 
 		vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
 			     HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+		vnic->mc_list = (void *)((char *)vnic->rss_hash_key +
+				HW_HASH_KEY_SIZE);
+		vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr +
+				HW_HASH_KEY_SIZE;
 	}
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index ca1c9cf..0d50224 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -57,6 +57,10 @@ struct bnxt_vnic_info {
 	uint16_t	*rss_table;
 	phys_addr_t	rss_hash_key_dma_addr;
 	void		*rss_hash_key;
+	phys_addr_t	mc_list_dma_addr;
+	char		*mc_list;
+	uint32_t	mc_addr_cnt;
+#define BNXT_MAX_MC_ADDRS		16
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 10/25] bnxt: add support for fw_version_get dev_op
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (8 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 11/25] bnxt: add support to set MTU Ajit Khaparde
                         ` (15 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for fw_version_get dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 doc/guides/nics/features/bnxt.ini |  1 +
 drivers/net/bnxt/bnxt_ethdev.c    | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 9b3cd94..b1be3fd 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -16,6 +16,7 @@ RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
+FW version           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 02d1749..e4fc362 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1356,6 +1356,25 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
 }
 
+static int
+bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
+	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
+	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
+	int ret;
+
+	ret = snprintf(fw_version, fw_size, "%d.%d.%d",
+			fw_major, fw_minor, fw_updt);
+
+	ret += 1; /* add the size of '\0' */
+	if (fw_size < (uint32_t)ret)
+		return ret;
+	else
+		return 0;
+}
+
 /*
  * Initialization
  */
@@ -1395,6 +1414,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 };
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 11/25] bnxt: add support to set MTU
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (9 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 10/25] bnxt: add support for fw_version_get dev_op Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 12/25] bnxt: add support for LRO Ajit Khaparde
                         ` (14 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to modify MTU using the set_mtu dev_op.
To support frames > 2k, the PMD creates an aggregator ring.
When a frame greater than 2k is received, it is fragmented
and the resulting fragments are DMA'ed to the aggregator ring.
Now the driver can support jumbo frames upto 9500 bytes.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 doc/guides/nics/features/bnxt.ini      |   2 +
 drivers/net/bnxt/bnxt.h                |   4 +-
 drivers/net/bnxt/bnxt_cpr.c            |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c         |  59 ++++++++++
 drivers/net/bnxt/bnxt_hwrm.c           | 121 ++++++++++++--------
 drivers/net/bnxt/bnxt_hwrm.h           |   4 +-
 drivers/net/bnxt/bnxt_ring.c           |  81 ++++++++++++--
 drivers/net/bnxt/bnxt_ring.h           |   2 +
 drivers/net/bnxt/bnxt_rxq.c            |  29 +++--
 drivers/net/bnxt/bnxt_rxq.h            |   1 +
 drivers/net/bnxt/bnxt_rxr.c            | 195 +++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_rxr.h            |   6 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h |   1 -
 13 files changed, 422 insertions(+), 86 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index b1be3fd..066cb01 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -17,6 +17,8 @@ Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
 FW version           = Y
+Jumbo frame          = Y
+MTU update           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index fde2202..8e6689f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,7 +45,7 @@
 
 #include "bnxt_cpr.h"
 
-#define BNXT_MAX_MTU		9000
+#define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
 
 enum bnxt_hw_context {
@@ -131,6 +131,7 @@ struct bnxt {
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
 #define BNXT_FLAG_PORT_STATS	(1 << 2)
+#define BNXT_FLAG_JUMBO		(1 << 3)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -233,4 +234,5 @@ struct rte_pmd_bnxt_mb_event_param {
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
+#define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index d13e6cc..f369cf6 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -159,7 +159,8 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
 
 	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-				  0, HWRM_NA_SIGNATURE);
+				  0, HWRM_NA_SIGNATURE,
+				  HWRM_NA_SIGNATURE);
 	if (rc)
 		goto err_out;
 	cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e4fc362..5755b80 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -199,6 +199,14 @@ static int bnxt_init_chip(struct bnxt *bp)
 	struct rte_eth_link new;
 	int rc;
 
+	if (bp->eth_dev->data->mtu > ETHER_MTU) {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+		bp->flags |= BNXT_FLAG_JUMBO;
+	} else {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
 	rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc);
@@ -1375,6 +1383,56 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+	struct bnxt *bp = eth_dev->data->dev_private;
+	struct rte_eth_dev_info dev_info;
+	uint32_t max_dev_mtu;
+	uint32_t rc = 0;
+	uint32_t i;
+
+	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 * 2;
+
+	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) {
+		bp->flags |= BNXT_FLAG_JUMBO;
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+	} else {
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
+	eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+		new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+
+	eth_dev->data->mtu = new_mtu;
+	RTE_LOG(INFO, PMD, "New MTU is %d\n", eth_dev->data->mtu);
+
+	for (i = 0; i < bp->nr_vnics; i++) {
+		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+		vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+		if (rc)
+			break;
+
+		rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1410,6 +1468,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 22e18d6..eb4f540 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -665,20 +665,20 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id)
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id)
 {
 	int rc = 0;
+	uint32_t enables = 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);
+	req.length = rte_cpu_to_le_32(ring->ring_size);
 
 	switch (ring_type) {
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
@@ -686,12 +686,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		/* FALLTHROUGH */
 	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.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id);
 		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);
+		if (stats_ctx_id != INVALID_STATS_CTX_ID)
+			enables |=
+			HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
@@ -700,13 +699,13 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		 * 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:
 		RTE_LOG(ERR, PMD, "hwrm alloc invalid ring type %d\n",
 			ring_type);
 		return -1;
 	}
+	req.enables = rte_cpu_to_le_32(enables);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -837,8 +836,8 @@ 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 int idx)
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
@@ -857,13 +856,12 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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_ctx_free(struct bnxt *bp,
-			    struct bnxt_cp_ring_info *cpr, unsigned int idx)
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
@@ -878,9 +876,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 
 	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;
 }
 
@@ -891,15 +886,10 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
-		}
+	RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
+		vnic->start_grp_id, vnic->end_grp_id);
+	for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++)
 		vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
-	}
 	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
 	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
 	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
@@ -1151,6 +1141,39 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t size;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.flags = rte_cpu_to_le_32(
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
+			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+	req.enables = rte_cpu_to_le_32(
+		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
+//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
+
+	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+	size -= RTE_PKTMBUF_HEADROOM;
+
+	req.jumbo_thresh = rte_cpu_to_le_16(size);
+//	req.hds_threshold = rte_cpu_to_le_16(size);
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1209,14 +1232,20 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
 	struct bnxt_cp_ring_info *cpr;
 
 	for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
-		unsigned int 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);
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
+			cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+			/*
+			 * TODO. Need a better way to reset grp_info.stats_ctx
+			 * for Rx rings only. stats_ctx is not saved for Tx
+			 * in grp_info.
+			 */
+			bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 			if (rc)
 				return rc;
 		}
@@ -1233,7 +1262,6 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 		struct bnxt_tx_queue *txq;
 		struct bnxt_rx_queue *rxq;
 		struct bnxt_cp_ring_info *cpr;
-		unsigned int idx = i + 1;
 
 		if (i >= bp->rx_cp_nr_rings) {
 			txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
@@ -1243,7 +1271,7 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 			cpr = rxq->cp_ring;
 		}
 
-		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, idx);
+		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i);
 
 		if (rc)
 			return rc;
@@ -1253,11 +1281,10 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 
 int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 {
-	uint16_t i;
+	uint16_t idx;
 	uint32_t rc = 0;
 
-	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int idx = i + 1;
+	for (idx = 0; idx < bp->rx_cp_nr_rings; idx++) {
 
 		if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) {
 			RTE_LOG(ERR, PMD,
@@ -1274,8 +1301,8 @@ 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 int idx)
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
@@ -1313,8 +1340,10 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 			txr->tx_prod = 0;
 			txr->tx_cons = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
@@ -1336,17 +1365,26 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 					rxr->rx_ring_struct->ring_size *
 					sizeof(*rxr->rx_buf_ring));
 			rxr->rx_prod = 0;
+			memset(rxr->ag_buf_ring, 0,
+					rxr->ag_ring_struct->ring_size *
+					sizeof(*rxr->ag_buf_ring));
+			rxr->ag_prod = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	/* 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)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, 0);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	return rc;
@@ -1358,14 +1396,7 @@ int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 	uint32_t rc = 0;
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int 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);
-
+		rc = bnxt_hwrm_ring_grp_alloc(bp, i);
 		if (rc)
 			return rc;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index c15404f..79b27ee 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -70,7 +70,7 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id);
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id);
 int bnxt_hwrm_ring_free(struct bnxt *bp,
 			struct bnxt_ring *ring, uint32_t ring_type);
 int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);
@@ -93,6 +93,8 @@ 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_hwrm_vnic_plcmode_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);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 5e4236a..a12c0aa 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -115,8 +115,15 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	int rx_vmem_len = rx_ring_info ?
 		RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
 						rx_ring_struct->vmem_size) : 0;
+	int ag_vmem_start = 0;
+	int ag_vmem_len = 0;
+	int cp_ring_start =  0;
+
+	ag_vmem_start = rx_vmem_start + rx_vmem_len;
+	ag_vmem_len = rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(
+				rx_ring_info->ag_ring_struct->vmem_size) : 0;
+	cp_ring_start = ag_vmem_start + ag_vmem_len;
 
-	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));
 
@@ -131,6 +138,10 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
+	int ag_ring_start = 0;
+
+	ag_ring_start = rx_ring_start + rx_ring_len;
+	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -201,6 +212,24 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->rx_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring = rx_ring_info->ag_ring_struct;
+
+		rx_ring->bd = ((char *)mz->addr + ag_ring_start);
+		rx_ring_info->ag_desc_ring =
+		    (struct rx_prod_pkt_bd *)rx_ring->bd;
+		rx_ring->bd_dma = mz->phys_addr + ag_ring_start;
+		rx_ring_info->ag_desc_mapping = rx_ring->bd_dma;
+		rx_ring->mem_zone = (const void *)mz;
+
+		if (!rx_ring->bd)
+			return -ENOMEM;
+		if (rx_ring->vmem_size) {
+			rx_ring->vmem =
+			    (void **)((char *)mz->addr + ag_vmem_start);
+			rx_ring_info->ag_buf_ring =
+			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+		}
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
@@ -239,35 +268,64 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
 		struct bnxt_ring *ring = rxr->rx_ring_struct;
 		unsigned int idx = i + 1;
+		unsigned int map_idx = idx + bp->rx_cp_nr_rings;
+
+		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+		bp->grp_info[i].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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 		rxr->rx_prod = 0;
 		rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
+		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+		ring = rxr->ag_ring_struct;
+		/* Agg ring */
+		if (ring == NULL)
+			RTE_LOG(ERR, PMD, "Alloc AGG Ring is NULL!\n");
+
+		rc = bnxt_hwrm_ring_alloc(bp, ring,
+				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+				map_idx, HWRM_NA_SIGNATURE,
+				cp_ring->fw_ring_id);
+		if (rc)
+			goto err_out;
+		RTE_LOG(DEBUG, PMD, "Alloc AGG Done!\n");
+		rxr->ag_prod = 0;
+		rxr->ag_doorbell =
+		    (char *)pci_dev->mem_resource[2].addr +
+		    map_idx * 0x80;
+		bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+		rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
 		if (bnxt_init_one_rx_ring(rxq)) {
 			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+		rxq->index = idx;
 	}
 
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
@@ -276,29 +334,34 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 		struct bnxt_tx_ring_info *txr = txq->tx_ring;
 		struct bnxt_ring *ring = txr->tx_ring_struct;
-		unsigned int idx = 1 + bp->rx_cp_nr_rings + i;
+		unsigned int idx = i + 1 + bp->rx_cp_nr_rings;
+
+		/* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
+		idx += bp->rx_cp_nr_rings;
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 
 		cpr->cp_doorbell = (char *)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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 
 		txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
+		txq->index = idx;
 	}
 
 err_out:
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 8656549..b5bd287 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -58,6 +58,7 @@
 #define DEFAULT_TX_RING_SIZE	256
 
 #define MAX_TPA		128
+#define AGG_RING_SIZE_FACTOR 2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
@@ -65,6 +66,7 @@
 #define MAX_CP_DESC_CNT (16 * 1024)
 
 #define INVALID_HW_RING_ID      ((uint16_t)-1)
+#define INVALID_STATS_CTX_ID		((uint16_t)-1)
 
 struct bnxt_ring {
 	void			*bd;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index cddf17d..5a5def5 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -84,9 +84,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 		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;
+		vnic->start_grp_id = 0;
+		vnic->end_grp_id = vnic->start_grp_id;
 		filter = bnxt_alloc_filter(bp);
 		if (!filter) {
 			RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -126,8 +125,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			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;
+		start_grp_id = 0;
+		end_grp_id = nb_q_per_grp;
 
 		ring_idx = 0;
 		for (i = 0; i < pools; i++) {
@@ -188,9 +187,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 	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;
+	vnic->start_grp_id = 0;
+	vnic->end_grp_id = bp->rx_cp_nr_rings;
 	filter = bnxt_alloc_filter(bp);
 	if (!filter) {
 		RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -228,6 +226,16 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 				}
 			}
 		}
+		/* Free up mbufs in Agg ring */
+		sw_ring = rxq->rx_ring->ag_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;
+				}
+			}
+		}
 	}
 }
 
@@ -251,6 +259,8 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 
 		/* Free RX ring hardware descriptors */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* Free RX Agg ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
 
 		/* Free RX completion ring hardware descriptors */
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -295,6 +305,9 @@ 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;
 
+	RTE_LOG(DEBUG, PMD, "RX Buf size is %d\n", rxq->rx_buf_use_size);
+	RTE_LOG(DEBUG, PMD, "RX Buf MTU %d\n", eth_dev->data->mtu);
+
 	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
 	if (rc)
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 9554329..0695214 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -52,6 +52,7 @@ struct bnxt_rx_queue {
 	uint8_t			crc_len; /* 0 if CRC stripped, 4 otherwise */
 
 	struct bnxt		*bp;
+	int			index;
 	struct bnxt_vnic_info	*vnic;
 
 	uint32_t			rx_buf_size;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 5d93de2..04ac673 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -77,6 +77,32 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
+static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
+				     struct bnxt_rx_ring_info *rxr,
+				     uint16_t prod)
+{
+	struct rx_prod_pkt_bd *rxbd = &rxr->ag_desc_ring[prod];
+	struct bnxt_sw_rx_bd *rx_buf = &rxr->ag_buf_ring[prod];
+	struct rte_mbuf *data;
+
+	data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	if (!data)
+		return -ENOMEM;
+
+	if (rxbd == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
+	if (rx_buf == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rx_buf is NULL\n");
+
+
+	rx_buf->mbuf = data;
+
+	rxbd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf));
+
+	return 0;
+}
+
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -94,6 +120,24 @@ static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 	prod_bd->addr = cons_bd->addr;
 }
 
+static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+			       struct rte_mbuf *mbuf)
+{
+	uint16_t prod = rxr->ag_prod;
+	struct bnxt_sw_rx_bd *prod_rx_buf;
+	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+	prod_rx_buf = &rxr->ag_buf_ring[prod];
+
+	prod_rx_buf->mbuf = mbuf;
+
+	prod_bd = &rxr->ag_desc_ring[prod];
+	cons_bd = &rxr->ag_desc_ring[cons];
+
+	prod_bd->addr = cons_bd->addr;
+}
+#endif
+
 static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 			    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -104,9 +148,12 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+	uint16_t ag_cons, ag_prod = rxr->ag_prod;
 	struct bnxt_sw_rx_bd *rx_buf;
 	struct rte_mbuf *mbuf;
 	int rc = 0;
+	uint8_t i;
+	uint8_t agg_buf = 0;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -126,6 +173,9 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	mbuf = rx_buf->mbuf;
 	rte_prefetch0(mbuf);
 
+	if (mbuf == NULL)
+		return -ENOMEM;
+
 	mbuf->nb_segs = 1;
 	mbuf->next = NULL;
 	mbuf->pkt_len = rxcmp->len;
@@ -139,6 +189,63 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->hash.fdir.id = rxcmp1->cfa_code;
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf) {
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
+			       cpr->cp_ring_struct))
+			return -EBUSY;
+		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
+			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
+	}
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		ag_cons = rxcmp->opaque;
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		ag_mbuf->nb_segs = 1;
+		ag_mbuf->data_len = rxcmp->len;
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+		if (mbuf->next == NULL) {
+			mbuf->next = ag_mbuf;
+		} else {
+			struct rte_mbuf *temp_mbuf = mbuf;
+
+			while (temp_mbuf->next != NULL)
+				temp_mbuf = temp_mbuf->next;
+			temp_mbuf->next = ag_mbuf;
+		}
+		ag_buf->mbuf = NULL;
+
+		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
+		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n",
+				ag_prod);
+			rc = -ENOMEM;
+		}
+		rxr->ag_prod = ag_prod;
+
+#ifdef BNXT_DEBUG
+		if (!CMP_VALID((struct cmpl_base *)
+			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
+			cpr->cp_ring_struct))
+			return -EBUSY;
+#endif
+	}
+
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
 			(RX_PKT_CMPL_METADATA_VID_MASK |
@@ -148,13 +255,17 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	}
 
 	rx_buf->mbuf = NULL;
+#ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
 		bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+		if (agg_buf)
+			bnxt_reuse_ag_mbuf(rxr, ag_cons, mbuf);
 
 		rc = -EIO;
 		goto next_rx;
 	}
+#endif
 	/*
 	 * TODO: Redesign this....
 	 * If the allocation fails, the packet does not get received.
@@ -170,24 +281,23 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 * calls in favour of a tight loop with the same function being called
 	 * in it.
 	 */
+	prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	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;
+		//goto next_rx;
 	}
-
+	rxr->rx_prod = prod;
 	/*
 	 * 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;
+#ifdef BNXT_DEBUG
 next_rx:
-	rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
+#endif
+	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -203,8 +313,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	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;
+	uint16_t prod = rxr->rx_prod;
+	uint16_t ag_prod = rxr->ag_prod;
 
 	/* Handle RX burst request */
 	while (1) {
@@ -224,13 +335,13 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 				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) {
+
+	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
 		 * the doorbell if there are no new completions
@@ -240,8 +351,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **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);
+	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+	/* Ring the AGG ring DB */
+	B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
 	return nb_rx_pkts;
 }
 
@@ -257,6 +369,12 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
 		rte_free(rxq->rx_ring->rx_ring_struct);
+
+		/* Free the Aggregator ring */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+		rte_free(rxq->rx_ring->ag_ring_struct);
+		rxq->rx_ring->ag_ring_struct = NULL;
+
 		rte_free(rxq->rx_ring);
 
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -270,13 +388,11 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 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;
 	struct bnxt_rx_ring_info *rxr;
 	struct bnxt_ring *ring;
 
-	rxq->rx_buf_use_size = bp->eth_dev->data->mtu +
-			       ETHER_HDR_LEN + ETHER_CRC_LEN +
+	rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN +
 			       (2 * VLAN_TAG_SIZE);
 	rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
 
@@ -313,13 +429,29 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 	if (ring == NULL)
 		return -ENOMEM;
 	cpr->cp_ring_struct = ring;
-	ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	ring->ring_size = rte_align32pow2(rxr->rx_ring_struct->ring_size *
+					  (2 + AGG_RING_SIZE_FACTOR));
 	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;
 
+	/* Allocate Aggregator rings */
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (ring == NULL)
+		return -ENOMEM;
+	rxr->ag_ring_struct = ring;
+	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc *
+					  AGG_RING_SIZE_FACTOR);
+	ring->ring_mask = ring->ring_size - 1;
+	ring->bd = (void *)rxr->ag_desc_ring;
+	ring->bd_dma = rxr->ag_desc_mapping;
+	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+	ring->vmem = (void **)&rxr->ag_buf_ring;
+
 	return 0;
 }
 
@@ -332,8 +464,8 @@ static void bnxt_init_rxbds(struct bnxt_ring *ring, uint32_t type,
 	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].flags_type = rte_cpu_to_le_16(type);
+		rx_bd_ring[j].len = rte_cpu_to_le_16(len);
 		rx_bd_ring[j].opaque = j;
 	}
 }
@@ -344,12 +476,17 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	struct bnxt_ring *ring;
 	uint32_t prod, type;
 	unsigned int i;
+	uint16_t size;
+
+	size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+	if (rxq->rx_buf_use_size <= size)
+		size = rxq->rx_buf_use_size;
 
-	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
 
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
-	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
+	bnxt_init_rxbds(ring, type, size);
 
 	prod = rxr->rx_prod;
 	for (i = 0; i < ring->ring_size; i++) {
@@ -362,6 +499,24 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		rxr->rx_prod = prod;
 		prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	}
+	RTE_LOG(DEBUG, PMD, "%s\n", __func__);
+
+	ring = rxr->ag_ring_struct;
+	type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
+	bnxt_init_rxbds(ring, type, size);
+	prod = rxr->ag_prod;
+
+	for (i = 0; i < ring->ring_size; i++) {
+		if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+			RTE_LOG(WARNING, PMD,
+			"init'ed AG ring %d with %d/%d mbufs only\n",
+			rxq->queue_id, i, ring->ring_size);
+			break;
+		}
+		rxr->ag_prod = prod;
+		prod = RING_NEXT(rxr->ag_ring_struct, prod);
+	}
+	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index f766b26..e104fbd 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -43,14 +43,20 @@ struct bnxt_sw_rx_bd {
 
 struct bnxt_rx_ring_info {
 	uint16_t		rx_prod;
+	uint16_t		ag_prod;
 	void			*rx_doorbell;
+	void			*ag_doorbell;
 
 	struct rx_prod_pkt_bd	*rx_desc_ring;
+	struct rx_prod_pkt_bd	*ag_desc_ring;
 	struct bnxt_sw_rx_bd	*rx_buf_ring; /* sw ring */
+	struct bnxt_sw_rx_bd	*ag_buf_ring; /* sw ring */
 
 	phys_addr_t		rx_desc_mapping;
+	phys_addr_t		ag_desc_mapping;
 
 	struct bnxt_ring	*rx_ring_struct;
+	struct bnxt_ring	*ag_ring_struct;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 518f16d..2fcfce6 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -7252,7 +7252,6 @@ struct hwrm_vnic_tpa_cfg_output {
 	 */
 } __attribute__((packed));
 
-
 /* hwrm_ring_alloc */
 /*
  * Description: This command allocates and does basic preparation for a ring.
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 12/25] bnxt: add support for LRO
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (10 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 11/25] bnxt: add support to set MTU Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 13/25] bnxt: add rxq/txq info_get dev_ops Ajit Khaparde
                         ` (13 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to enable and disable LRO
To support this feature, the driver creates an aggregrator ring.
When the hardware starts doing LRO, it sends a tpa_start completion.
When the driver receives a tpa_end completion, it indicates that the
LRO chaining is complete.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 doc/guides/nics/features/bnxt.ini |   1 +
 drivers/net/bnxt/bnxt_ethdev.c    |   7 +
 drivers/net/bnxt/bnxt_hwrm.c      |  44 +++++-
 drivers/net/bnxt/bnxt_hwrm.h      |   2 +
 drivers/net/bnxt/bnxt_ring.c      |  32 +++-
 drivers/net/bnxt/bnxt_ring.h      |   4 +-
 drivers/net/bnxt/bnxt_rxq.c       |  12 ++
 drivers/net/bnxt/bnxt_rxq.h       |   2 +
 drivers/net/bnxt/bnxt_rxr.c       | 315 +++++++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_rxr.h       |  40 +++++
 10 files changed, 374 insertions(+), 85 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 066cb01..4fd8abb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -19,6 +19,7 @@ SR-IOV               = Y
 FW version           = Y
 Jumbo frame          = Y
 MTU update           = Y
+LRO                  = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5755b80..410e86f 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -286,6 +286,13 @@ static int bnxt_init_chip(struct bnxt *bp)
 				goto err_out;
 			}
 		}
+
+		bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
+		else
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index eb4f540..dc4bb1b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1152,19 +1152,15 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
 
 	req.flags = rte_cpu_to_le_32(
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
 			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+
 	req.enables = rte_cpu_to_le_32(
 		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
-//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
 
 	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
 	size -= RTE_PKTMBUF_HEADROOM;
 
 	req.jumbo_thresh = rte_cpu_to_le_16(size);
-//	req.hds_threshold = rte_cpu_to_le_16(size);
 	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -1174,6 +1170,41 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic, bool enable)
+{
+	int rc = 0;
+	struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_TPA_CFG, -1, resp);
+
+	if (enable) {
+		req.enables = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+		req.flags = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+			HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
+		req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+		req.max_agg_segs = rte_cpu_to_le_16(5);
+		req.max_aggs =
+			rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+		req.min_agg_len = rte_cpu_to_le_32(512);
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1493,6 +1524,9 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		bnxt_clear_hwrm_vnic_filters(bp, vnic);
 
 		bnxt_hwrm_vnic_ctx_free(bp, vnic);
+
+		bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
+
 		bnxt_hwrm_vnic_free(bp, vnic);
 	}
 	/* Ring resources */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 79b27ee..6ce0bc3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -95,6 +95,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 				struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic, bool enable);
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index a12c0aa..9d0ae27 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bitmap.h>
 #include <rte_memzone.h>
 #include <unistd.h>
 
@@ -137,11 +138,23 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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;
-	int ag_ring_start = 0;
+	int ag_ring_start = rx_ring_start + rx_ring_len;
+	int ag_ring_len = rx_ring_len * AGG_RING_SIZE_FACTOR;
 
-	ag_ring_start = rx_ring_start + rx_ring_len;
-	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
+	int ag_bitmap_start = ag_ring_start + ag_ring_len;
+	int ag_bitmap_len =  rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(rte_bitmap_get_memory_footprint(
+			rx_ring_info->rx_ring_struct->ring_size *
+			AGG_RING_SIZE_FACTOR)) : 0;
+
+	int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
+	int tpa_info_len = rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
+				       sizeof(struct bnxt_tpa_info)) : 0;
+
+	int total_alloc_len = tpa_info_start;
+	if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+		total_alloc_len += tpa_info_len;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -230,6 +243,17 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->ag_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring_info->ag_bitmap =
+		    rte_bitmap_init(rx_ring_info->rx_ring_struct->ring_size *
+				    AGG_RING_SIZE_FACTOR, (uint8_t *)mz->addr +
+				    ag_bitmap_start, ag_bitmap_len);
+
+		/* TPA info */
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			rx_ring_info->tpa_info =
+				((struct bnxt_tpa_info *)((char *)mz->addr +
+							  tpa_info_start));
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index b5bd287..6d1eb58 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -57,8 +57,8 @@
 #define DEFAULT_RX_RING_SIZE	256
 #define DEFAULT_TX_RING_SIZE	256
 
-#define MAX_TPA		128
-#define AGG_RING_SIZE_FACTOR 2
+#define BNXT_TPA_MAX		64
+#define AGG_RING_SIZE_FACTOR	2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 5a5def5..b0bbed1 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -214,6 +214,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 {
 	struct bnxt_sw_rx_bd *sw_ring;
+	struct bnxt_tpa_info *tpa_info;
 	uint16_t i;
 
 	if (rxq) {
@@ -236,6 +237,17 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq __rte_unused)
 				}
 			}
 		}
+
+		/* Free up mbufs in TPA */
+		tpa_info = rxq->rx_ring->tpa_info;
+		if (tpa_info) {
+			for (i = 0; i < BNXT_TPA_MAX; i++) {
+				if (tpa_info[i].mbuf) {
+					rte_pktmbuf_free_seg(tpa_info[i].mbuf);
+					tpa_info[i].mbuf = NULL;
+				}
+			}
+		}
 	}
 }
 
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 0695214..01aaa00 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -59,6 +59,8 @@ struct bnxt_rx_queue {
 	uint32_t			rx_buf_use_size;  /* useable size */
 	struct bnxt_rx_ring_info	*rx_ring;
 	struct bnxt_cp_ring_info	*cp_ring;
+
+	struct bnxt_tpa_info		*rx_tpa;
 };
 
 void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 04ac673..1f0afcb 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -34,6 +34,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <rte_bitmap.h>
 #include <rte_byteorder.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
@@ -102,24 +103,28 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
-#ifdef BNXT_DEBUG
-static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+static inline void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr,
 			       struct rte_mbuf *mbuf)
 {
-	uint16_t prod = rxr->rx_prod;
+	uint16_t prod = RING_NEXT(rxr->rx_ring_struct, rxr->rx_prod);
 	struct bnxt_sw_rx_bd *prod_rx_buf;
-	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+	struct rx_prod_pkt_bd *prod_bd;
 
 	prod_rx_buf = &rxr->rx_buf_ring[prod];
 
+	RTE_ASSERT(prod_rx_buf->mbuf == NULL);
+	RTE_ASSERT(mbuf != NULL);
+
 	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;
+	prod_bd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(mbuf));
+
+	rxr->rx_prod = prod;
 }
 
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -138,7 +143,192 @@ static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 }
 #endif
 
-static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+static inline
+struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr,
+				     uint16_t cons)
+{
+	struct bnxt_sw_rx_bd *cons_rx_buf;
+	struct rte_mbuf *mbuf;
+
+	cons_rx_buf = &rxr->rx_buf_ring[cons];
+	RTE_ASSERT(cons_rx_buf->mbuf != NULL);
+	mbuf = cons_rx_buf->mbuf;
+	cons_rx_buf->mbuf = NULL;
+	return mbuf;
+}
+
+static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
+			   struct rx_tpa_start_cmpl *tpa_start,
+			   struct rx_tpa_start_cmpl_hi *tpa_start1)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
+		RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+	uint16_t data_cons;
+	struct bnxt_tpa_info *tpa_info;
+	struct rte_mbuf *mbuf;
+
+	data_cons = tpa_start->opaque;
+	tpa_info = &rxr->tpa_info[agg_id];
+
+	mbuf = bnxt_consume_rx_buf(rxr, data_cons);
+
+	bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
+
+	tpa_info->mbuf = mbuf;
+	tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
+
+	mbuf->nb_segs = 1;
+	mbuf->next = NULL;
+	mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len);
+	mbuf->data_len = mbuf->pkt_len;
+	mbuf->port = rxq->port_id;
+	mbuf->ol_flags = PKT_RX_LRO;
+	if (likely(tpa_start->flags_type &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS_RSS_VALID))) {
+		mbuf->hash.rss = rte_le_to_cpu_32(tpa_start->rss_hash);
+		mbuf->ol_flags |= PKT_RX_RSS_HASH;
+	} else {
+		mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code);
+		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+	}
+	if (tpa_start1->flags2 &
+	    rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) {
+		mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata);
+		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+	}
+	if (likely(tpa_start1->flags2 &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC)))
+		mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+
+	/* recycle next mbuf */
+	data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons);
+	bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons));
+}
+
+static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr,
+		uint8_t agg_bufs, uint32_t raw_cp_cons)
+{
+	uint16_t last_cp_cons;
+	struct rx_pkt_cmpl *agg_cmpl;
+
+	raw_cp_cons = ADV_RAW_CMP(raw_cp_cons, agg_bufs);
+	last_cp_cons = RING_CMP(cpr->cp_ring_struct, raw_cp_cons);
+	agg_cmpl = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[last_cp_cons];
+	return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct);
+}
+
+/* TPA consume agg buffer out of order, allocate connected data only */
+static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t next = RING_NEXT(rxr->ag_ring_struct, rxr->ag_prod);
+
+	/* TODO batch allocation for better performance */
+	while (rte_bitmap_get(rxr->ag_bitmap, next)) {
+		if (unlikely(bnxt_alloc_ag_data(rxq, rxr, next))) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n", next);
+			break;
+		}
+		rte_bitmap_clear(rxr->ag_bitmap, next);
+		rxr->ag_prod = next;
+		next = RING_NEXT(rxr->ag_ring_struct, next);
+	}
+
+	return 0;
+}
+
+static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
+			 struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
+			 uint8_t agg_buf)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	int i;
+	uint16_t cp_cons, ag_cons;
+	struct rx_pkt_cmpl *rxcmp;
+	struct rte_mbuf *last = mbuf;
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+		bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+		ag_cons = rxcmp->opaque;
+		RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		RTE_ASSERT(ag_mbuf != NULL);
+
+		ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+
+		last->next = ag_mbuf;
+		last = ag_mbuf;
+
+		ag_buf->mbuf = NULL;
+
+		/*
+		 * As aggregation buffer consumed out of order in TPA module,
+		 * use bitmap to track freed slots to be allocated and notified
+		 * to NIC
+		 */
+		rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+	}
+	bnxt_prod_ag_mbuf(rxq);
+	return 0;
+}
+
+static inline struct rte_mbuf *bnxt_tpa_end(
+		struct bnxt_rx_queue *rxq,
+		uint32_t *raw_cp_cons,
+		struct rx_tpa_end_cmpl *tpa_end,
+		struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
+			>> RX_TPA_END_CMPL_AGG_ID_SFT;
+	struct rte_mbuf *mbuf;
+	uint8_t agg_bufs;
+	//unsigned int len;
+	struct bnxt_tpa_info *tpa_info;
+
+	tpa_info = &rxr->tpa_info[agg_id];
+	mbuf = tpa_info->mbuf;
+	RTE_ASSERT(mbuf != NULL);
+
+	rte_prefetch0(mbuf);
+	//len = tpa_info->len;
+	agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
+		RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
+	if (agg_bufs) {
+		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+			return NULL;
+		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+	}
+	mbuf->l4_len = tpa_end->payload_offset;
+
+	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	RTE_ASSERT(new_data != NULL);
+	if (!new_data)
+		return NULL;
+	tpa_info->mbuf = new_data;
+
+	return mbuf;
+}
+
+static int 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;
@@ -148,12 +338,13 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-	uint16_t ag_cons, ag_prod = rxr->ag_prod;
-	struct bnxt_sw_rx_bd *rx_buf;
+#ifdef BNXT_DEBUG
+	uint16_t ag_cons;
+#endif
 	struct rte_mbuf *mbuf;
 	int rc = 0;
-	uint8_t i;
 	uint8_t agg_buf = 0;
+	uint16_t cmp_type;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -165,12 +356,34 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct))
 		return -EBUSY;
 
+	cmp_type = CMP_TYPE(rxcmp);
+	if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_START) {
+		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
+			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
+		rc = -EINVAL; /* Continue w/o new mbuf */
+		goto next_rx;
+	} else if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_END) {
+		mbuf = bnxt_tpa_end(rxq, &tmp_raw_cons,
+				   (struct rx_tpa_end_cmpl *)rxcmp,
+				   (struct rx_tpa_end_cmpl_hi *)rxcmp1);
+		if (unlikely(!mbuf))
+			return -EBUSY;
+		*rx_pkt = mbuf;
+		goto next_rx;
+	} else if (cmp_type != 0x11) {
+		rc = -EINVAL;
+		goto next_rx;
+	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+		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;
+	mbuf = bnxt_consume_rx_buf(rxr, cons);
 	rte_prefetch0(mbuf);
 
 	if (mbuf == NULL)
@@ -190,61 +403,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
 
-	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
-			>> RX_PKT_CMPL_AGG_BUFS_SFT;
-	if (agg_buf) {
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
-			       cpr->cp_ring_struct))
-			return -EBUSY;
-		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
-			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
-	}
-
-	for (i = 0; i < agg_buf; i++) {
-		struct bnxt_sw_rx_bd *ag_buf;
-		struct rte_mbuf *ag_mbuf;
-		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		ag_cons = rxcmp->opaque;
-		ag_buf = &rxr->ag_buf_ring[ag_cons];
-		ag_mbuf = ag_buf->mbuf;
-		ag_mbuf->nb_segs = 1;
-		ag_mbuf->data_len = rxcmp->len;
-
-		mbuf->nb_segs++;
-		mbuf->pkt_len += ag_mbuf->data_len;
-		if (mbuf->next == NULL) {
-			mbuf->next = ag_mbuf;
-		} else {
-			struct rte_mbuf *temp_mbuf = mbuf;
-
-			while (temp_mbuf->next != NULL)
-				temp_mbuf = temp_mbuf->next;
-			temp_mbuf->next = ag_mbuf;
-		}
-		ag_buf->mbuf = NULL;
-
-		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
-		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
-			RTE_LOG(ERR, PMD,
-				"agg mbuf alloc failed: prod=0x%x\n",
-				ag_prod);
-			rc = -ENOMEM;
-		}
-		rxr->ag_prod = ag_prod;
-
-#ifdef BNXT_DEBUG
-		if (!CMP_VALID((struct cmpl_base *)
-			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
-			cpr->cp_ring_struct))
-			return -EBUSY;
-#endif
-	}
+	if (agg_buf)
+		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
 
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
@@ -254,7 +414,6 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
 	}
 
-	rx_buf->mbuf = NULL;
 #ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
@@ -294,10 +453,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 */
 
 	*rx_pkt = mbuf;
-#ifdef BNXT_DEBUG
+
 next_rx:
-#endif
-	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -333,7 +490,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
 			if (likely(!rc))
 				nb_rx_pkts++;
-			else if (rc == -EBUSY)	/* partial completion */
+			if (rc == -EBUSY)	/* partial completion */
 				break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
@@ -341,6 +498,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			break;
 	}
 
+	cpr->cp_raw_cons = raw_cons;
 	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
@@ -348,7 +506,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		 */
 		return nb_rx_pkts;
 	}
-	cpr->cp_raw_cons = raw_cons;
 
 	B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -518,5 +675,15 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	}
 	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
+	if (rxr->tpa_info) {
+		for (i = 0; i < BNXT_TPA_MAX; i++) {
+			rxr->tpa_info[i].mbuf =
+				__bnxt_alloc_rx_data(rxq->mb_pool);
+			if (!rxr->tpa_info[i].mbuf)
+				return -ENOMEM;
+		}
+	}
+	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
+
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e104fbd..f8d6dc8 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -37,6 +37,39 @@
 #define B_RX_DB(db, prod)						\
 		(*(uint32_t *)db = (DB_KEY_RX | prod))
 
+#define BNXT_TPA_L4_SIZE(x)	\
+	{ \
+		typeof(x) hdr_info = (x); \
+		(((hdr_info) & 0xf8000000) ? ((hdr_info) >> 27) : 32) \
+	}
+
+#define BNXT_TPA_INNER_L3_OFF(hdr_info)	\
+	(((hdr_info) >> 18) & 0x1ff)
+
+#define BNXT_TPA_INNER_L2_OFF(hdr_info)	\
+	(((hdr_info) >> 9) & 0x1ff)
+
+#define BNXT_TPA_OUTER_L3_OFF(hdr_info)	\
+	((hdr_info) & 0x1ff)
+
+enum pkt_hash_types {
+	PKT_HASH_TYPE_NONE,	/* Undefined type */
+	PKT_HASH_TYPE_L2,	/* Input: src_MAC, dest_MAC */
+	PKT_HASH_TYPE_L3,	/* Input: src_IP, dst_IP */
+	PKT_HASH_TYPE_L4,	/* Input: src_IP, dst_IP, src_port, dst_port */
+};
+
+struct bnxt_tpa_info {
+	struct rte_mbuf		*mbuf;
+	uint16_t			len;
+	unsigned short		gso_type;
+	uint32_t			flags2;
+	uint32_t			metadata;
+	enum pkt_hash_types	hash_type;
+	uint32_t			rss_hash;
+	uint32_t			hdr_info;
+};
+
 struct bnxt_sw_rx_bd {
 	struct rte_mbuf		*mbuf; /* data associated with RX descriptor */
 };
@@ -57,6 +90,13 @@ struct bnxt_rx_ring_info {
 
 	struct bnxt_ring	*rx_ring_struct;
 	struct bnxt_ring	*ag_ring_struct;
+
+	/*
+	 * To deal with out of order return from TPA, use free buffer indicator
+	 */
+	struct rte_bitmap	*ag_bitmap;
+
+	struct bnxt_tpa_info *tpa_info;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 13/25] bnxt: add rxq/txq info_get dev_ops
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (11 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 12/25] bnxt: add support for LRO Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 14/25] bnxt: add code to support VLAN pvid set dev_op Ajit Khaparde
                         ` (12 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for txq_info_get and rxq_info_get dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 410e86f..8296e06 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1390,6 +1390,43 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static void
+bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_rxq_info *qinfo)
+{
+	struct bnxt_rx_queue *rxq;
+
+	rxq = dev->data->rx_queues[queue_id];
+
+	qinfo->mp = rxq->mb_pool;
+	qinfo->scattered_rx = dev->data->scattered_rx;
+	qinfo->nb_desc = rxq->nb_rx_desc;
+
+	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+	qinfo->conf.rx_drop_en = 0;
+	qinfo->conf.rx_deferred_start = 0;
+}
+
+static void
+bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_txq_info *qinfo)
+{
+	struct bnxt_tx_queue *txq;
+
+	txq = dev->data->tx_queues[queue_id];
+
+	qinfo->nb_desc = txq->nb_tx_desc;
+
+	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
+	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
+	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+
+	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
+	qinfo->conf.tx_rs_thresh = 0;
+	qinfo->conf.txq_flags = txq->txq_flags;
+	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
 static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
@@ -1482,6 +1519,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_reset = bnxt_dev_xstats_reset_op,
 	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
+	.rxq_info_get = bnxt_rxq_info_get_op,
+	.txq_info_get = bnxt_txq_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 14/25] bnxt: add code to support VLAN pvid set dev_op
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (12 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 13/25] bnxt: add rxq/txq info_get dev_ops Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 15/25] bnxt: reorg the query stats code Ajit Khaparde
                         ` (11 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds code to support vlan_pvid_set dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c | 21 +++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 31 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |  1 +
 4 files changed, 54 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8e6689f..adf0ab1 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -67,6 +67,7 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
+	uint16_t		dflt_vlan;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 8296e06..35e3066 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1477,6 +1477,26 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 	return rc;
 }
 
+static int
+bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint16_t vlan = bp->vlan;
+	int rc;
+
+	if (BNXT_NPAR_PF(bp) || BNXT_VF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"PVID cannot be modified for this function\n");
+		return -ENOTSUP;
+	}
+	bp->vlan = on ? pvid : 0;
+
+	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
+	if (rc)
+		bp->vlan = vlan;
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1512,6 +1532,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
 	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dc4bb1b..3e595c3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2256,6 +2256,37 @@ int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t dflt_vlan, fid;
+	uint32_t func_cfg_flags;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	if (is_vf) {
+		dflt_vlan = bp->pf.vf_info[vf].dflt_vlan;
+		fid = bp->pf.vf_info[vf].fid;
+		func_cfg_flags = bp->pf.vf_info[vf].func_cfg_flags;
+	} else {
+		fid = rte_cpu_to_le_16(0xffff);
+		func_cfg_flags = bp->pf.func_cfg_flags;
+		dflt_vlan = bp->vlan;
+	}
+
+	req.flags = rte_cpu_to_le_32(func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6ce0bc3..1759187 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -123,6 +123,7 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 15/25] bnxt: reorg the query stats code
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (13 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 14/25] bnxt: add code to support VLAN pvid set dev_op Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 16/25] bnxt: add support for led on/off Ajit Khaparde
                         ` (10 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

1) Use hwrm_stat_ctx_query command to query statistics
Using hwrm_stat_ctx_query command will allow polling
the statistics from hardware instead of using the current push
model from the hardware which does a DMA of the stats to the host
at fixed intervals.
2) Use the rx_mbuf_alloc_fail to track mbuf alloc failures.
3) We were wrongly incrementing hwrm_cmd_seq in bnxt_hwrm_stat_clear
and bnxt_hwrm_stat_ctx_alloc functions.  This patch fixes that.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c |  2 ++
 drivers/net/bnxt/bnxt_hwrm.c   | 82 ++++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  4 +++
 drivers/net/bnxt/bnxt_rxr.c    | 16 ++++++---
 drivers/net/bnxt/bnxt_stats.c  | 59 ++++--------------------------
 6 files changed, 102 insertions(+), 62 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index adf0ab1..e411704 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -204,6 +204,7 @@ struct bnxt {
 	uint16_t		vxlan_fw_dst_port_id;
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
+	rte_atomic64_t		rx_mbuf_alloc_fail;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 35e3066..0790cd4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1616,6 +1616,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+
+	rte_atomic64_init(&bp->rx_mbuf_alloc_fail);
 	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3e595c3..a1aa80e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -821,13 +821,12 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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;
 
+	HWRM_PREP(req, STAT_CTX_CLR_STATS, -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));
 
@@ -845,9 +844,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 
 	HWRM_PREP(req, STAT_CTX_ALLOC, -1, resp);
 
-	req.update_period_ms = rte_cpu_to_le_32(1000);
+	req.update_period_ms = rte_cpu_to_le_32(0);
 
-	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);
 
@@ -870,7 +868,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	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));
 
@@ -1227,6 +1224,43 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->ierrors = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->oerrors = rte_le_to_cpu_64(resp->tx_err_pkts);
+
+	stats->imissed = rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -2348,6 +2382,42 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 	return rc;
 }
 
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats)
+{
+	int rc = 0;
+	struct hwrm_stat_ctx_query_input req = {.req_type = 0};
+	struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, STAT_CTX_QUERY, -1, resp);
+
+	req.stat_ctx_id = rte_cpu_to_le_32(cid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->tx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_port_qstats(struct bnxt *bp)
 {
 	struct hwrm_port_qstats_input req = {0};
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1759187..ab42913 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -62,6 +62,8 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *stats);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
@@ -81,6 +83,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned int idx);
 int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 			    struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 1f0afcb..3001d81 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -68,8 +68,10 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	rx_buf->mbuf = data;
 
@@ -87,8 +89,10 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	if (rxbd == NULL)
 		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
@@ -321,8 +325,10 @@ static inline struct rte_mbuf *bnxt_tpa_end(
 
 	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
 	RTE_ASSERT(new_data != NULL);
-	if (!new_data)
+	if (!new_data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return NULL;
+	}
 	tpa_info->mbuf = new_data;
 
 	return mbuf;
@@ -679,8 +685,10 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		for (i = 0; i < BNXT_TPA_MAX; i++) {
 			rxr->tpa_info[i].mbuf =
 				__bnxt_alloc_rx_data(rxq->mb_pool);
-			if (!rxr->tpa_info[i].mbuf)
+			if (!rxr->tpa_info[i].mbuf) {
+				rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 				return -ENOMEM;
+			}
 		}
 	}
 	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 154dc0c..ade8195 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -196,64 +196,18 @@ void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
 
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
+	bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
+	bnxt_stats->rx_nombuf = rte_atomic64_read(&bp->rx_mbuf_alloc_fail);
 }
 
 void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
@@ -261,6 +215,7 @@ 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);
+	rte_atomic64_clear(&bp->rx_mbuf_alloc_fail);
 }
 
 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 16/25] bnxt: add support for led on/off
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (14 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 15/25] bnxt: reorg the query stats code Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:43         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
                         ` (9 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for dev_led_on/off dev_ops

HWRM calls added:
bnxt_hwrm_port_led_qcaps()
bnxt_hwrm_port_led_cfg()

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  39 ++
 drivers/net/bnxt/bnxt_ethdev.c         |  20 +
 drivers/net/bnxt/bnxt_hwrm.c           |  70 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 977 +++++++++++++++++++++++++++++++++
 5 files changed, 1108 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e411704..c23a836 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -47,6 +47,42 @@
 
 #define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
+#define BNXT_MAX_LED		4
+
+struct bnxt_led_info {
+	uint8_t      led_id;
+	uint8_t      led_type;
+	uint8_t      led_group_id;
+	uint8_t      unused;
+	uint16_t  led_state_caps;
+#define BNXT_LED_ALT_BLINK_CAP(x)       ((x) &  \
+	rte_cpu_to_le_16(HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT))
+
+	uint16_t  led_color_caps;
+};
+
+struct bnxt_led_cfg {
+	uint8_t led_id;
+	uint8_t led_state;
+	uint8_t led_color;
+	uint8_t unused;
+	uint16_t led_blink_on;
+	uint16_t led_blink_off;
+	uint8_t led_group_id;
+	uint8_t rsvd;
+};
+
+#define BNXT_LED_DFLT_ENA                               \
+	(HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID |             \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE |          \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON |       \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF |      \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID)
+
+#define BNXT_LED_DFLT_ENA_SHIFT		6
+
+#define BNXT_LED_DFLT_ENABLES(x)                        \
+	rte_cpu_to_le_32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
 
 enum bnxt_hw_context {
 	HW_CONTEXT_NONE     = 0,
@@ -205,6 +241,9 @@ struct bnxt {
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 	rte_atomic64_t		rx_mbuf_alloc_fail;
+
+	struct bnxt_led_info	leds[BNXT_MAX_LED];
+	uint8_t			num_leds;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 0790cd4..8ebae12 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1497,6 +1497,22 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
 	return rc;
 }
 
+static int
+bnxt_dev_led_on_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, true);
+}
+
+static int
+bnxt_dev_led_off_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, false);
+}
+
 /*
  * Initialization
  */
@@ -1542,6 +1558,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 	.rxq_info_get = bnxt_rxq_info_get_op,
 	.txq_info_get = bnxt_txq_info_get_op,
+	.dev_led_on = bnxt_dev_led_on_op,
+	.dev_led_off = bnxt_dev_led_off_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1815,6 +1833,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		}
 	}
 
+	bnxt_hwrm_port_led_qcaps(bp);
+
 	rc = bnxt_setup_int(bp);
 	if (rc)
 		goto error_free;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index a1aa80e..9a04885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2453,3 +2453,73 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
 	HWRM_CHECK_RESULT;
 	return rc;
 }
+
+int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
+{
+	struct hwrm_port_led_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_qcaps_input req = {0};
+	int rc;
+
+	if (BNXT_VF(bp))
+		return 0;
+
+	HWRM_PREP(req, PORT_LED_QCAPS, -1, resp);
+	req.port_id = bp->pf.port_id;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	if (resp->num_leds > 0 && resp->num_leds < BNXT_MAX_LED) {
+		unsigned int i;
+
+		bp->num_leds = resp->num_leds;
+		memcpy(bp->leds, &resp->led0_id,
+			sizeof(bp->leds[0]) * bp->num_leds);
+		for (i = 0; i < bp->num_leds; i++) {
+			struct bnxt_led_info *led = &bp->leds[i];
+
+			uint16_t caps = led->led_state_caps;
+
+			if (!led->led_group_id ||
+				!BNXT_LED_ALT_BLINK_CAP(caps)) {
+				bp->num_leds = 0;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
+{
+	struct hwrm_port_led_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_cfg_input req = {0};
+	struct bnxt_led_cfg *led_cfg;
+	uint8_t led_state = HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT;
+	uint16_t duration = 0;
+	int rc, i;
+
+	if (!bp->num_leds || BNXT_VF(bp))
+		return -EOPNOTSUPP;
+
+	HWRM_PREP(req, PORT_LED_CFG, -1, resp);
+	if (led_on) {
+		led_state = HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT;
+		duration = rte_cpu_to_le_16(500);
+	}
+	req.port_id = bp->pf.port_id;
+	req.num_leds = bp->num_leds;
+	led_cfg = (struct bnxt_led_cfg *)&req.led0_id;
+	for (i = 0; i < bp->num_leds; i++, led_cfg++) {
+		req.enables |= BNXT_LED_DFLT_ENABLES(i);
+		led_cfg->led_id = bp->leds[i].led_id;
+		led_cfg->led_state = led_state;
+		led_cfg->led_blink_on = duration;
+		led_cfg->led_blink_off = duration;
+		led_cfg->led_group_id = bp->leds[i].led_group_id;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index ab42913..3591917 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -130,4 +130,6 @@ void bnxt_free_tunnel_ports(struct bnxt *bp);
 int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
+int bnxt_hwrm_port_led_qcaps(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 2fcfce6..17a912f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -5743,6 +5743,983 @@ struct hwrm_port_clr_stats_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_port_led_cfg */
+/*
+ * Description: This function is used to configure LEDs on a given port. Each
+ * port has individual set of LEDs associated with it. These LEDs are used for
+ * speed/link configuration as well as activity indicator configuration. Up to
+ * three LEDs can be configured, one for activity and two for speeds.
+ */
+/* Input	(64 bytes) */
+struct hwrm_port_led_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the led0_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the led0_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE	UINT32_C(0x2)
+	/* This bit must be '1' for the led0_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_COLOR	UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the led0_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON	UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the led0_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF UINT32_C(0x10)
+	/*
+	 * This bit must be '1' for the led0_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID UINT32_C(0x20)
+	/* This bit must be '1' for the led1_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_ID	UINT32_C(0x40)
+	/* This bit must be '1' for the led1_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_STATE	UINT32_C(0x80)
+	/* This bit must be '1' for the led1_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_COLOR	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the led1_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_ON UINT32_C(0x200)
+	/*
+	 * This bit must be '1' for the led1_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_OFF UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the led1_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_GROUP_ID UINT32_C(0x800)
+	/* This bit must be '1' for the led2_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_ID	UINT32_C(0x1000)
+	/* This bit must be '1' for the led2_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_STATE	UINT32_C(0x2000)
+	/* This bit must be '1' for the led2_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_COLOR	UINT32_C(0x4000)
+	/*
+	 * This bit must be '1' for the led2_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_ON UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the led2_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_OFF UINT32_C(0x10000)
+	/*
+	 * This bit must be '1' for the led2_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_GROUP_ID UINT32_C(0x20000)
+	/* This bit must be '1' for the led3_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_ID	UINT32_C(0x40000)
+	/* This bit must be '1' for the led3_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_STATE  UINT32_C(0x80000)
+	/* This bit must be '1' for the led3_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_COLOR  UINT32_C(0x100000)
+	/*
+	 * This bit must be '1' for the led3_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_ON UINT32_C(0x200000)
+	/*
+	 * This bit must be '1' for the led3_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_OFF	\
+		UINT32_C(0x400000)
+	/*
+	 * This bit must be '1' for the led3_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_GROUP_ID UINT32_C(0x800000)
+	uint16_t port_id;
+	/* Port ID of port whose LEDs are configured. */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are being configured. Up to 4 LEDs
+	 * can be configured with this command.
+	 */
+	uint8_t rsvd;
+	/* Reserved field. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_state;
+	/* The requested state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The requested color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #0 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd0;
+	/* Reserved field. */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_state;
+	/* The requested state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The requested color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #1 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd1;
+	/* Reserved field. */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_state;
+	/* The requested state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The requested color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #2 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd2;
+	/* Reserved field. */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_state;
+	/* The requested state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The requested color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #3 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd3;
+	/* Reserved field. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_led_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcfg */
+/*
+ * Description: This function is used to query configuration of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration. Up to three LEDs can be configured, one for activity and two
+ * for speeds.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(56 bytes) */
+struct hwrm_port_led_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_state;
+	/* The current state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 is not grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_state;
+	/* The current state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 is not grouped. For all other
+	 * non-zero values of this field, LED #1 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_state;
+	/* The current state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 is not grouped. For all other
+	 * non-zero values of this field, LED #2 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_state;
+	/* The current state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 is not grouped. For all other
+	 * non-zero values of this field, LED #3 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t unused_8;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcaps */
+/*
+ * Description: This function is used to query capabilities of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcaps_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(48 bytes) */
+struct hwrm_port_led_qcaps_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t unused_0[3];
+	/* Reserved for future use. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_1;
+	uint16_t led0_state_caps;
+	/* The states supported by LED #0. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led0_color_caps;
+	/* The colors supported by LED #0. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_2;
+	uint16_t led1_state_caps;
+	/* The states supported by LED #1. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led1_color_caps;
+	/* The colors supported by LED #1. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_3;
+	uint16_t led2_state_caps;
+	/* The states supported by LED #2. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led2_color_caps;
+	/* The colors supported by LED #2. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t led3_state_caps;
+	/* The states supported by LED #3. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led3_color_caps;
+	/* The colors supported by LED #3. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_queue_qportcfg */
 /*
  * Description: This function is called by a driver to query queue configuration
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (15 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 16/25] bnxt: add support for led on/off Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:43         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 18/25] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
                         ` (8 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

Add functions rte_pmd_bnxt_set_tx_loopback,
rte_pmd_bnxt_set_all_queues_drop_en and
rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
queue_drop and VF MAC address setting in the hardware.
It also adds the necessary functions to send the HWRM commands
to the firmware.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/Makefile                 |   4 +
 drivers/net/bnxt/bnxt_hwrm.c              | 107 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |   4 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 163 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  87 ++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   9 ++
 6 files changed, 374 insertions(+)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0fffe35..b03f65d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -38,6 +38,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnxt.a
 
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
 LIBABIVER := 1
 
 CFLAGS += -O3
@@ -60,10 +62,12 @@ 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
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
 
 #
 # Export include files
 #
 SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include := rte_pmd_bnxt.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9a04885..64394b5 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2168,6 +2168,24 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+	req.evb_mode = bp->pf.evb_mode;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type)
 {
@@ -2523,3 +2541,92 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 
 	return rc;
 }
+
+static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
+					uint16_t *vnic_ids)
+{
+	struct hwrm_func_vf_vnic_ids_query_input req = {0};
+	struct hwrm_func_vf_vnic_ids_query_output *resp =
+						bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* First query all VNIC ids */
+	HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY, -1, resp_vf_vnic_ids);
+
+	req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+	req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+	req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2phy(vnic_ids));
+
+	if (req.vnic_id_tbl_addr == 0) {
+		RTE_LOG(ERR, PMD,
+		"unable to map VNIC ID table address to physical memory\n");
+		//rte_free(vnic_ids);
+		return -ENOMEM;
+	}
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query error %d\n", rc);
+		return -1;
+	}
+
+	return rte_le_to_cpu_32(resp->vnic_id_cnt);
+}
+
+/*
+ * This function queries the VNIC IDs  for a specified VF. It then calls
+ * the vnic_cb to update the necessary field in vnic_info with cbdata.
+ * Then it calls the hwrm_cb function to program this new vnic configuration.
+ */
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic))
+{
+	struct bnxt_vnic_info vnic;
+	int rc = 0;
+	int i, num_vnic_ids;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	size_t sz;
+
+	/* First query all VNIC ids */
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	num_vnic_ids = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+
+	if (num_vnic_ids < 0)
+		return num_vnic_ids;
+
+	/* Retrieve VNIC, update bd_stall then update */
+
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+		if (rc)
+			break;
+		if (vnic.mru == 4)	// Unallocated
+			continue;
+
+		vnic_cb(&vnic, cbdata);
+
+		rc = hwrm_cb(bp, &vnic);
+		if (rc)
+			break;
+	}
+
+	rte_free(vnic_ids);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 3591917..b79df9d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -120,6 +120,7 @@ int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
 int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -132,4 +133,7 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 0000000..667b24c
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,163 @@
+/*-
+ *   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>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set Tx loopback on non-PF port %d!\n",
+			port);
+		return -ENOTSUP;
+	}
+
+	if (on)
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+	else
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+	rc = bnxt_hwrm_pf_evb_mode(bp);
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->bd_stall = !(*on);
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	uint32_t i;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set all queues drop on non-PF port!\n");
+		return -ENOTSUP;
+	}
+
+	if (bp->vnic_info == NULL)
+		return -ENODEV;
+
+	/* Stall PF */
+	for (i = 0; i < bp->nr_vnics; i++) {
+		bp->vnic_info[i].bd_stall = !on;
+		rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update PF VNIC %d.\n", i);
+			return rc;
+		}
+	}
+
+	/* Stall all active VFs */
+	for (i = 0; i < bp->pf.active_vfs; i++) {
+		rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
+				rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", i);
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs || mac_addr == NULL)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d mac address on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 0000000..eec2313
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,87 @@
+/*-
+ *   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 _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+		struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+#endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 349c6e1..8b77163 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,13 @@
 DPDK_16.04 {
 
 	local: *;
+
+};
+
+DPDK_17.08 {
+	global:
+
+	rte_pmd_bnxt_set_tx_loopback;
+	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_set_vf_mac_addr;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 18/25] bnxt: add support for set VF QOS and MAC anti spoof
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (16 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 19/25] bnxt: add support for VLAN stripq, anti spoof and filtering for VFs Ajit Khaparde
                         ` (7 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to
1) enable VF MAC anti spoof.
2) QOS configuration for specified VF.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h                   |  2 +
 drivers/net/bnxt/bnxt_hwrm.c              | 33 +++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  3 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 95 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 37 ++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  2 +
 6 files changed, 172 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c23a836..8481413 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -104,6 +104,8 @@ struct bnxt_child_vf_info {
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
 	uint16_t		dflt_vlan;
+	uint16_t		max_tx_rate;
+	uint8_t			mac_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 64394b5..1997aa4 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2230,6 +2230,21 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 	return rc;
 }
 
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
@@ -2339,6 +2354,24 @@ int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
 	return rc;
 }
 
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(enables);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.max_bw = rte_cpu_to_le_32(max_bw);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b79df9d..42b071e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -121,6 +121,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -133,6 +135,7 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 667b24c..9d331eb 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -161,3 +161,98 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk)
+{
+	struct rte_eth_dev *eth_dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	uint16_t tot_rate = 0;
+	uint64_t idx;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	eth_dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!bp->pf.active_vfs)
+		return -EINVAL;
+
+	if (vf >= bp->pf.max_vfs)
+		return -EINVAL;
+
+	/* Add up the per queue BW and configure MAX BW of the VF */
+	for (idx = 0; idx < 64; idx++) {
+		if ((1ULL << idx) & q_msk)
+			tot_rate += tx_rate;
+	}
+
+	/* Requested BW can't be greater than link speed */
+	if (tot_rate > eth_dev->data->dev_link.link_speed) {
+		RTE_LOG(ERR, PMD, "Rate > Link speed. Set to %d\n", tot_rate);
+		return -EINVAL;
+	}
+
+	/* Requested BW already configured */
+	if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
+		return 0;
+
+	rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
+				HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
+
+	if (!rc)
+		bp->pf.vf_info[vf].max_tx_rate = tot_rate;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	uint32_t func_flags;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	/* Prev setting same as new setting. */
+	if (on == bp->pf.vf_info[vf].mac_spoof_en)
+		return 0;
+
+	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+	if (on)
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
+	else
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+
+	bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf);
+	if (!rc)
+		bp->pf.vf_info[vf].mac_spoof_en = on;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index eec2313..118acd2 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -37,6 +37,24 @@
 #include <rte_ethdev.h>
 
 /**
+ * Enable/Disable VF MAC anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF MAC anti spoof.
+ *    0 - Disable VF MAC anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
  * Set the VF MAC address.
  *
  * @param port
@@ -84,4 +102,23 @@ int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * Set the VF rate limit.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param tx_rate
+ *   Tx rate for the VF
+ * @param q_msk
+ *   Mask of the Tx queue
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 8b77163..4155640 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -10,4 +10,6 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
 	rte_pmd_bnxt_set_vf_mac_addr;
+	rte_pmd_bnxt_set_vf_mac_anti_spoof;
+	rte_pmd_bnxt_set_vf_rate_limit;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 19/25] bnxt: add support for VLAN stripq, anti spoof and filtering for VFs
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (17 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 18/25] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats Ajit Khaparde
                         ` (6 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support for VF VLAN stripq, VF VLAN anti spoof and
VF VLAN filtering.
The VF VLAN filtering needs the VLAN anti spoof setting to be set first
before the command to program the VLAN table is sent to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h                   |   2 +
 drivers/net/bnxt/bnxt_ethdev.c            |  12 +--
 drivers/net/bnxt/bnxt_filter.h            |   2 +
 drivers/net/bnxt/bnxt_hwrm.c              |  84 ++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   7 +-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 174 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  60 +++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   3 +
 8 files changed, 336 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8481413..192ba25 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -105,7 +105,9 @@ struct bnxt_child_vf_info {
 	uint16_t		fid;
 	uint16_t		dflt_vlan;
 	uint16_t		max_tx_rate;
+	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
+	uint8_t			vlan_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 8ebae12..d9331d0 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -294,7 +294,7 @@ static int bnxt_init_chip(struct bnxt *bp)
 		else
 			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
-	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"HWRM cfa l2 rx mask failure rc: %x\n", rc);
@@ -702,7 +702,7 @@ static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
@@ -716,7 +716,7 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
@@ -730,7 +730,7 @@ static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
@@ -744,7 +744,7 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
@@ -1368,7 +1368,7 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	vnic->mc_addr_cnt = i;
 
 allmulti:
-	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 06fe134..353b7f7 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -63,6 +63,8 @@ struct bnxt_filter_info {
 	uint32_t		vni;
 	uint8_t			pri_hint;
 	uint64_t		l2_filter_id_hint;
+	uint32_t		src_id;
+	uint8_t			src_type;
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1997aa4..820e0ab 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -213,7 +213,10 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
-int bnxt_hwrm_cfa_l2_set_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,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table)
 {
 	int rc = 0;
 	struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
@@ -237,6 +240,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
+	if (vlan_count && vlan_table) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
+			 rte_mem_virt2phy(vlan_table));
+		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
+	}
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -296,6 +305,10 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
 		req.l2_ovlan_mask = filter->l2_ovlan_mask;
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
+		req.src_id = rte_cpu_to_le_32(filter->src_id);
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
+		req.src_type = filter->src_type;
 
 	req.enables = rte_cpu_to_le_32(enables);
 
@@ -2663,3 +2676,72 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE);
+	req.vlan_antispoof_mode = on ?
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN :
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
+{
+	struct bnxt_vnic_info vnic;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	int num_vnic_ids, i;
+	size_t sz;
+	int rc;
+
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	rc = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+	if (rc <= 0)
+		goto exit;
+	num_vnic_ids = rc;
+
+	/*
+	 * Loop through to find the default VNIC ID.
+	 * TODO: The easier way would be to obtain the resp->dflt_vnic_id
+	 * by sending the hwrm_func_qcfg command to the firmware.
+	 */
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic,
+					bp->pf.first_vf_id + vf);
+		if (rc)
+			goto exit;
+		if (vnic.func_default) {
+			rte_free(vnic_ids);
+			return vnic.fw_vnic_id;
+		}
+	}
+	/* Could not find a default VNIC. */
+	RTE_LOG(ERR, PMD, "No default VNIC\n");
+exit:
+	rte_free(vnic_ids);
+	return -1;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 42b071e..f51ebcf 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -45,7 +45,9 @@ 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_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table);
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 int bnxt_hwrm_set_filter(struct bnxt *bp,
@@ -139,4 +141,7 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on);
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 9d331eb..1f71d3a 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -33,6 +33,7 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <unistd.h>
 
 #include <rte_dev.h>
 #include <rte_ethdev.h>
@@ -256,3 +257,176 @@ int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	struct bnxt *bp;
+	int rc;
+	int dflt_vnic;
+	struct bnxt_vnic_info vnic;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
+	if (!rc) {
+		bp->pf.vf_info[vf].vlan_spoof_en = on;
+		if (on) {
+			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+			if (dflt_vnic < 0) {
+				/*
+				 * This simply indicates there's no driver
+				 * loaded.  This is not an error.
+				 */
+				RTE_LOG(ERR, PMD,
+				      "Unable to get default VNIC for VF %d\n",
+					vf);
+			} else {
+				vnic.fw_vnic_id = dflt_vnic;
+				if (bnxt_hwrm_vnic_qcfg(bp,
+					&vnic, bp->pf.first_vf_id + vf) == 0) {
+					if (bnxt_hwrm_cfa_l2_set_rx_mask(bp,
+					   &vnic, bp->pf.vf_info[vf].vlan_count,
+					   bp->pf.vf_info[vf].vlan_table))
+						rc = -1;
+				}
+			}
+		}
+	} else {
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+	}
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->vlan_strip = *on;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d stripq on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+				rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+	if (rc)
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	int i, j;
+	int rc = 0;
+	struct bnxt_vlan_table_entry *ve;
+	uint16_t cnt;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	for (i = 0; vf_mask; i++, vf_mask >>= 1) {
+		cnt = bp->pf.vf_info[i].vlan_count;
+		if (vf_mask & 1) {
+			if (bp->pf.vf_info[i].vlan_table == NULL) {
+				rc = -1;
+				continue;
+			}
+			if (vlan_on) {
+				/* First, search for a duplicate... */
+				for (j = 0; j < cnt; j++) {
+					if (rte_be_to_cpu_16(
+					 bp->pf.vf_info[i].vlan_table[j].vid) ==
+					    vlan)
+						break;
+				}
+				if (j == cnt) {
+					/* Now check that there's space */
+					if (cnt == getpagesize() /
+					 sizeof(struct bnxt_vlan_table_entry)) {
+						RTE_LOG(ERR, PMD,
+						  "VF %d VLAN table is full\n",
+						  i);
+						RTE_LOG(ERR, PMD,
+							"cannot add VLAN %u\n",
+							vlan);
+						rc = -1;
+						continue;
+					}
+
+					cnt = bp->pf.vf_info[i].vlan_count++;
+					/*
+					 * And finally, add to the
+					 * end of the table
+					 */
+					ve = &bp->pf.vf_info[i].vlan_table[cnt];
+					// TODO: Hardcoded TPID
+					ve->tpid = rte_cpu_to_be_16(0x8100);
+					ve->vid = rte_cpu_to_be_16(vlan);
+				}
+			} else {
+				for (j = 0; cnt; j++) {
+					if (rte_be_to_cpu_16(
+					bp->pf.vf_info[i].vlan_table[j].vid) !=
+					    vlan)
+						continue;
+					memmove(
+					 &bp->pf.vf_info[i].vlan_table[j],
+					 &bp->pf.vf_info[i].vlan_table[j + 1],
+					 getpagesize() -
+					 ((j + 1) *
+					 sizeof(struct bnxt_vlan_table_entry)));
+					j--;
+					cnt = bp->pf.vf_info[i].vlan_count--;
+				}
+			}
+			rte_pmd_bnxt_set_vf_vlan_anti_spoof(dev->data->port_id,
+					 i, bp->pf.vf_info[i].vlan_spoof_en);
+		}
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 118acd2..87d1787 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -72,6 +72,48 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 		struct ether_addr *mac_addr);
 
 /**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
+ * received VLAN packets tagged with a given VLAN Tag Identifier.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vlan
+ *   The VLAN Tag Identifier whose filtering must be enabled or disabled.
+ * @param vf_mask
+ *    Bitmap listing which VFs participate in the VLAN filtering.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN filtering.
+ *    0 - Disable VFs VLAN filtering.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on);
+
+/**
  * Enable/Disable tx loopback
  *
  * @param port
@@ -121,4 +163,22 @@ int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
  */
 int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
+
+/**
+ * Enable/Disable VF VLAN anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF VLAN anti spoof.
+ *    0 - Disable VF VLAN anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 4155640..c98ed19 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -12,4 +12,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
+	rte_pmd_bnxt_set_vf_vlan_stripq;
+	rte_pmd_bnxt_set_vf_vlan_filter;
+	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (18 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 19/25] bnxt: add support for VLAN stripq, anti spoof and filtering for VFs Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:43         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF Ajit Khaparde
                         ` (5 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to get and clear VF stats.
It also adds the necessary HWRM structures to send the command
to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_hwrm.c    | 38 ++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h    |  3 ++
 drivers/net/bnxt/rte_pmd_bnxt.c | 87 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h | 64 ++++++++++++++++++++++++++++++
 4 files changed, 192 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 820e0ab..77c63a8 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1237,6 +1237,27 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (dropped)
+		*dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats)
 {
@@ -1274,6 +1295,23 @@ int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 	return rc;
 }
 
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	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 f51ebcf..5aaf947 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -66,6 +66,9 @@ int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 1f71d3a..f17b8c8 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -430,3 +430,90 @@ int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to get VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to reset VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d TX drops on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+					     count);
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 87d1787..2fa4786 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -165,6 +165,41 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
 
 /**
+ * Get VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param stats
+ *    A pointer to a structure of type *rte_eth_stats* to be filled with
+ *    the values of device counters supported statistics:
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id);
+
+/**
  * Enable/Disable VF VLAN anti spoof
  *
  * @param port
@@ -181,4 +216,33 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ */
+int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count);
 #endif /* _PMD_BNXT_H_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (19 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:43         ` Ferruh Yigit
  2017-05-26 18:39       ` [PATCH v2 22/25] bnxt: add support to add a VF MAC address Ajit Khaparde
                         ` (4 subsequent siblings)
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to determine the Rx status of a VF.
It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
the VNIC count of the function to get the Rx status.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 23 +++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 17 +++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  5 +++++
 5 files changed, 70 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 77c63a8..78daa93 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2626,6 +2626,30 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 	return rc;
 }
 
+static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
+{
+	uint32_t *count = cbdata;
+
+	if (vnic->func_default)
+		*count = *count + 1;
+}
+
+static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
+				     struct bnxt_vnic_info *vnic __rte_unused)
+{
+	return 0;
+}
+
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf)
+{
+	uint32_t count = 0;
+
+	bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, bnxt_vnic_count,
+	    &count, bnxt_vnic_count_hwrm_stub);
+
+	return count;
+}
+
 static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
 					uint16_t *vnic_ids)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 5aaf947..01e72fa 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -141,6 +141,7 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index f17b8c8..82fe313 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -480,6 +480,29 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
 	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
 }
 
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d RX stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_vf_default_vnic_count(bp, vf_id);
+}
+
 int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
 {
 	struct rte_eth_dev *dev;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 2fa4786..a35e577 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -217,6 +217,23 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+
+/**
+ * Returns the number of default RX queues on a VF
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @return
+ *   - Non-negative value - Number of default RX queues
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if on a function without VFs
+ *   - (-ENOMEM) on an allocation failure
+ *   - (-1) firmware interface error
+ */
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
+
 /**
  * Queries the TX drop counter for the function
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index c98ed19..7fb9a28 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -9,6 +9,11 @@ DPDK_17.08 {
 
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_get_vf_stats;
+	rte_pmd_bnxt_reset_vf_stats;
+	rte_pmd_bnxt_get_vf_rx_status;
+	rte_pmd_bnxt_get_vf_tx_drop_count;
+	rte_pmd_bnxt_get_tx_drop_count;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 22/25] bnxt: add support to add a VF MAC address
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (20 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 23/25] bnxt: add code to configure a default VF VLAN Ajit Khaparde
                         ` (3 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support to allocate a filter and program
it in the hardware for every MAC address added to the specified
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_filter.c            | 22 ++++++++++
 drivers/net/bnxt/bnxt_filter.h            |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 73 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 18 ++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 115 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 0afde86..e9aac27 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -68,6 +68,22 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
 	return filter;
 }
 
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+	struct bnxt_filter_info *filter;
+
+	filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+	if (!filter) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for VF %hu filters\n",
+			vf);
+		return NULL;
+	}
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+	return filter;
+}
+
 void bnxt_init_filters(struct bnxt *bp)
 {
 	struct bnxt_filter_info *filter;
@@ -102,6 +118,12 @@ void bnxt_free_all_filters(struct bnxt *bp)
 			STAILQ_INIT(&vnic->filter);
 		}
 	}
+
+	for (i = 0; i < bp->pf.max_vfs; i++) {
+		STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+			bnxt_hwrm_clear_filter(bp, filter);
+		}
+	}
 }
 
 void bnxt_free_filter_mem(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 353b7f7..613b2ee 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -68,6 +68,7 @@ struct bnxt_filter_info {
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
 void bnxt_init_filters(struct bnxt *bp);
 void bnxt_free_all_filters(struct bnxt *bp);
 void bnxt_free_filter_mem(struct bnxt *bp);
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 82fe313..a2bd39e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -540,3 +540,76 @@ int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
 					     count);
 }
+
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
+				uint32_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	struct bnxt_filter_info *filter;
+	struct bnxt_vnic_info vnic;
+	struct ether_addr dflt_mac;
+	int rc;
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to config VF %d MAC on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	/* If the VF currently uses a random MAC, update default to this one */
+	if (bp->pf.vf_info[vf_id].random_mac) {
+		if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+			rc = bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+	}
+
+	/* query the default VNIC id used by the function */
+	rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+	if (rc < 0)
+		goto exit;
+
+	memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+	vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+	rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+	if (rc < 0)
+		goto exit;
+
+	STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+		if (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) &&
+		    memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+			bnxt_hwrm_clear_filter(bp, filter);
+			break;
+		}
+	}
+
+	if (filter == NULL)
+		filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	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, addr, ETHER_ADDR_LEN);
+	memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+	/* Do not add a filter for the default MAC */
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+	    memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+		rc = bnxt_hwrm_set_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index a35e577..9b1777c 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -262,4 +262,22 @@ int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count);
  */
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param mac_addr
+ *    The MAC address to be programmed in the filter.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ *   - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
+				uint32_t vf_id);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 7fb9a28..17c8bd9 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -14,6 +14,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_rx_status;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_get_tx_drop_count;
+	rte_pmd_bnxt_mac_addr_add;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 23/25] bnxt: add code to configure a default VF VLAN
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (21 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 22/25] bnxt: add support to add a VF MAC address Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 24/25] bnxt: Add support to set VF rxmode Ajit Khaparde
                         ` (2 subsequent siblings)
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to insert a default VF VLAN.
Also track the current default VLAN per vnic for the VF.
When setting the default VLAN, avoid setting it to the current value.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt.h                   |  2 +-
 drivers/net/bnxt/bnxt_hwrm.c              | 39 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 35 +++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 20 ++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 6 files changed, 98 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 192ba25..eb2e9a8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -103,8 +103,8 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
-	uint16_t		dflt_vlan;
 	uint16_t		max_tx_rate;
+	uint16_t		dflt_vlan;
 	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
 	uint8_t			vlan_spoof_en;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 78daa93..a26906a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2069,6 +2069,27 @@ static void reserve_resources_from_vf(struct bnxt *bp,
 	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
 }
 
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Check for zero MAC address */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg error %d\n", rc);
+		return -1;
+	}
+	return rte_le_to_cpu_16(resp->vlan);
+}
+
 static int update_pf_resource_max(struct bnxt *bp)
 {
 	struct hwrm_func_qcfg_input req = {0};
@@ -2423,6 +2444,24 @@ int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(bp->pf.vf_info[vf].dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 01e72fa..33d2885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -128,8 +128,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 			uint16_t max_bw, uint16_t enables);
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index a2bd39e..ca14ff3 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -356,6 +356,41 @@ rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
 	return rc;
 }
 
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d vlan insert on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	bp->pf.vf_info[vf].dflt_vlan = vlan_id;
+	if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
+	    bp->pf.vf_info[vf].dflt_vlan)
+		return 0;
+
+	rc = bnxt_hwrm_set_vf_vlan(bp, vf);
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 9b1777c..d6cefc4 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -92,6 +92,26 @@ int
 rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
 
 /**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param vlan_id
+ *    0 - Disable VF's vlan insert.
+ *    n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id);
+
+/**
  * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
  * received VLAN packets tagged with a given VLAN Tag Identifier.
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 17c8bd9..04fce9a 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -21,4 +21,5 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_stripq;
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+	rte_pmd_bnxt_set_vf_vlan_insert;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 24/25] bnxt: Add support to set VF rxmode
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (22 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 23/25] bnxt: add code to configure a default VF VLAN Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-26 18:39       ` [PATCH v2 25/25] update release notes Ajit Khaparde
  2017-05-29 17:44       ` [PATCH v2 00/25] bnxt patchset Ferruh Yigit
  25 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to configure the VF L2 Rx settings.
The per VF setting is maintained in bnxt_child_vf_info.l2_rx_mask

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments
---
 drivers/net/bnxt/bnxt_hwrm.c              | 24 +++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/bnxt_rxq.c               | 13 ++++++--
 drivers/net/bnxt/bnxt_vnic.h              |  5 +++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 51 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 19 ++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 7 files changed, 109 insertions(+), 6 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index a26906a..2eefa76 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,23 +229,29 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
 	/* FIXME add multicast flag, when multicast adding options is supported
 	 * by ethtool.
 	 */
+	if (vnic->flags & BNXT_VNIC_INFO_BCAST)
+		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST;
+	if (vnic->flags & BNXT_VNIC_INFO_UNTAGGED)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN;
 	if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
-		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+		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;
+	if (vnic->flags & BNXT_VNIC_INFO_MCAST)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 	if (vnic->mc_addr_cnt) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
 		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
 	}
-	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
-				    mask);
 	if (vlan_count && vlan_table) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
 		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
 			 rte_mem_virt2phy(vlan_table));
 		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
 	}
+	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
+				    mask);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -2317,6 +2323,18 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
 	return rc;
 }
 
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp)
+{
+	uint32_t *flag = flagp;
+
+	vnic->flags = *flag;
+}
+
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 33d2885..a603dda 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -143,6 +143,8 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index b0bbed1..bef48df 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -76,6 +76,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto err_out;
 		}
+		vnic->flags |= BNXT_VNIC_INFO_BCAST;
 		STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
 		bp->nr_vnics++;
 
@@ -120,6 +121,9 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		}
 		/* For each pool, allocate MACVLAN CFA rule & VNIC */
 		if (!pools) {
+			pools = RTE_MIN(bp->max_vnics,
+			    RTE_MIN(bp->max_l2_ctx,
+			     RTE_MIN(bp->max_rsscos_ctx, ETH_64_POOLS)));
 			RTE_LOG(ERR, PMD,
 				"VMDq pool not set, defaulted to 64\n");
 			pools = ETH_64_POOLS;
@@ -137,6 +141,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 				rc = -ENOMEM;
 				goto err_out;
 			}
+			vnic->flags |= BNXT_VNIC_INFO_BCAST;
 			STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
 			bp->nr_vnics++;
 
@@ -177,6 +182,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		rc = -ENOMEM;
 		goto err_out;
 	}
+	vnic->flags |= BNXT_VNIC_INFO_BCAST;
 	/* 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];
@@ -295,7 +301,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
-		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+		RTE_LOG(ERR, PMD, "nb_desc %d is invalid\n", nb_desc);
 		rc = -EINVAL;
 		goto out;
 	}
@@ -308,7 +314,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	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!");
+		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -333,7 +339,8 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	/* Allocate RX ring hardware descriptors */
 	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
 			"rxr")) {
-		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
+		RTE_LOG(ERR, PMD,
+			"ring_dma_zone_reserve for rx_ring failed!\n");
 		bnxt_rx_queue_release_op(rxq);
 		rc = -ENOMEM;
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 0d50224..993f221 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -64,6 +64,11 @@ struct bnxt_vnic_info {
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
+#define BNXT_VNIC_INFO_BCAST			(1 << 2)
+#define BNXT_VNIC_INFO_UCAST			(1 << 3)
+#define BNXT_VNIC_INFO_MCAST			(1 << 4)
+#define BNXT_VNIC_INFO_TAGGED			(1 << 5)
+#define BNXT_VNIC_INFO_UNTAGGED			(1 << 6)
 
 	uint16_t	cos_rule;
 	uint16_t	lb_rule;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index ca14ff3..997173f 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -391,6 +391,57 @@ rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
 	return rc;
 }
 
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t flag = 0;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	if (vf >= bp->pdev->max_vfs)
+		return -EINVAL;
+
+	if (rx_mask & (ETH_VMDQ_ACCEPT_UNTAG | ETH_VMDQ_ACCEPT_HASH_MC)) {
+		RTE_LOG(ERR, PMD, "Currently cannot toggle this setting\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC && !on) {
+		RTE_LOG(ERR, PMD, "Currently cannot disable UC Rx\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
+		flag |= BNXT_VNIC_INFO_BCAST;
+	if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
+		flag |= BNXT_VNIC_INFO_ALLMULTI;
+
+	if (on)
+		bp->pf.vf_info[vf].l2_rx_mask |= flag;
+	else
+		bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+					vf_vnic_set_rxmask_cb,
+					&bp->pf.vf_info[vf].l2_rx_mask,
+					bnxt_set_rx_mask_no_vlan);
+	if (rc)
+		RTE_LOG(ERR, PMD, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index d6cefc4..e9f6cf2 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -237,6 +237,25 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+/**
+ * Set RX L2 Filtering mode of a VF of an Ethernet device.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param rx_mask
+ *    The RX mode mask
+ * @param on
+ *    1 - Enable a VF RX mode.
+ *    0 - Disable a VF RX mode.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on);
 
 /**
  * Returns the number of default RX queues on a VF
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 04fce9a..a0efa66 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -22,4 +22,5 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 	rte_pmd_bnxt_set_vf_vlan_insert;
+	rte_pmd_bnxt_set_vf_rxmode;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v2 25/25] update release notes
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (23 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 24/25] bnxt: Add support to set VF rxmode Ajit Khaparde
@ 2017-05-26 18:39       ` Ajit Khaparde
  2017-05-29 17:44         ` Ferruh Yigit
  2017-05-29 17:44       ` [PATCH v2 00/25] bnxt patchset Ferruh Yigit
  25 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-26 18:39 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Update release doc briefly describing updates to bnxt PMD.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/rel_notes/release_17_08.rst | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 74aae10..340c820 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -69,6 +69,14 @@ EAL
 Drivers
 ~~~~~~~
 
+* **Updated bnxt PMD.**
+
+  Major enhancements include:
+  * Support MTU modification.
+  * Support LRO.
+  * Support VLAN filter and strip functionality.
+  * Other enhancements to add support for more dev_ops.
+  * Add PMD specific APIs mainly to control VF from PF.
 
 Libraries
 ~~~~~~~~~
-- 
2.10.1 (Apple Git-78)

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

* Re: [PATCH v2 07/25] bnxt: add support for xstats get/reset
  2017-05-26 18:39       ` [PATCH v2 07/25] bnxt: add support for xstats get/reset Ajit Khaparde
@ 2017-05-29 17:42         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:42 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds support to get and reset xstats dev_ops
> 
> dev_ops added:
> xstats_get, xstats_get_name, xstats_reset
> 
> HWRM commands added:
> hwrm_port_qstats, hwrm_port_clr_stats
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> 
> --
> v1->v2: regroup related patches and incorporate other review comments
> ---
>  drivers/net/bnxt/bnxt.h        |   7 ++
>  drivers/net/bnxt/bnxt_ethdev.c |  84 +++++++++++++++++
>  drivers/net/bnxt/bnxt_hwrm.c   |  36 +++++++
>  drivers/net/bnxt/bnxt_hwrm.h   |   3 +-
>  drivers/net/bnxt/bnxt_stats.c  | 207 +++++++++++++++++++++++++++++++++++++++++
>  drivers/net/bnxt/bnxt_stats.h  |  10 ++

This patch should set "Extended stats       = Y" in bnxt.ini

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

* Re: [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set
  2017-05-26 18:39       ` [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
@ 2017-05-29 17:42         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:42 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds support for set_mc_addr_list and
> mac_addr_set dev_ops
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> 
> --
> v1->v2: regroup related patches and incorporate other review comments
> ---
>  doc/guides/nics/features/bnxt.ini |  1 +
>  drivers/net/bnxt/bnxt_ethdev.c    | 70 ++++++++++++++++++++++++++++++++++++++-
>  drivers/net/bnxt/bnxt_hwrm.c      | 13 +++++---
>  drivers/net/bnxt/bnxt_hwrm.h      |  2 +-
>  drivers/net/bnxt/bnxt_vnic.c      |  7 +++-
>  drivers/net/bnxt/bnxt_vnic.h      |  4 +++
>  6 files changed, 90 insertions(+), 7 deletions(-)
> 
> diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
> index 78a738f..9b3cd94 100644
> --- a/doc/guides/nics/features/bnxt.ini
> +++ b/doc/guides/nics/features/bnxt.ini
> @@ -11,6 +11,7 @@ Unicast MAC filter   = Y
>  Multicast MAC filter = Y
>  VLAN filter          = Y
>  VLAN offload         = Y
> +Allmulticast mode    = Y

To have this support, .allmulticast_enable and .allmulticast_disable
needs to implemented, these are already implemented in the PMD.

This PMD implements ".set_mc_addr_list", I think this is "Multicast MAC
filter", which seems already documented as supported.

So, it is possible to have a separate patch to document "Allmulticast mode"

>  RSS reta update      = Y
>  Basic stats          = Y
>  Extended stats       = Y
<...>

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

* Re: [PATCH v2 16/25] bnxt: add support for led on/off
  2017-05-26 18:39       ` [PATCH v2 16/25] bnxt: add support for led on/off Ajit Khaparde
@ 2017-05-29 17:43         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:43 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds support for dev_led_on/off dev_ops
> 
> HWRM calls added:
> bnxt_hwrm_port_led_qcaps()
> bnxt_hwrm_port_led_cfg()

Can you please add a LED feature in default.ini, and announce that
support in bnxt.ini?

> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> ---
<...>

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

* Re: [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops
  2017-05-26 18:39       ` [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
@ 2017-05-29 17:43         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:43 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds VLAN strip and offload callbacks.
> To add a VLAN filter:
>     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
> 
> To remove a VLAN filter:
>     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
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

This patch gives a build error [1] which seems fixed in next patch, can
you please move fix to this patch.


[1]
.../drivers/net/bnxt/bnxt_ethdev.c: In function ‘bnxt_del_vlan_filter’:
.../drivers/net/bnxt/bnxt_ethdev.c:1158:8: error: passing argument 2 of
‘bnxt_hwrm_set_filter’ makes pointer from integer without a cast
[-Werror=int-conversion]
        vnic->fw_vnic_id,
        ^~~~
In file included from .../drivers/net/bnxt/bnxt_ethdev.c:46:0:
.../drivers/net/bnxt/bnxt_hwrm.h:51:5: note: expected ‘struct
bnxt_vnic_info *’ but argument is of type ‘uint16_t {aka short unsigned
int}’
 int bnxt_hwrm_set_filter(struct bnxt *bp,
     ^~~~~~~~~~~~~~~~~~~~
.../drivers/net/bnxt/bnxt_ethdev.c: In function ‘bnxt_add_vlan_filter’:
.../drivers/net/bnxt/bnxt_ethdev.c:1232:35: error: passing argument 2 of
‘bnxt_hwrm_set_filter’ makes pointer from integer without a cast
[-Werror=int-conversion]
     rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id,
                                   ^~~~
In file included from .../drivers/net/bnxt/bnxt_ethdev.c:46:0:
.../drivers/net/bnxt/bnxt_hwrm.h:51:5: note: expected ‘struct
bnxt_vnic_info *’ but argument is of type ‘uint16_t {aka short unsigned
int}’
 int bnxt_hwrm_set_filter(struct bnxt *bp,
     ^~~~~~~~~~~~~~~~~~~~

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

* Re: [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop
  2017-05-26 18:39       ` [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
@ 2017-05-29 17:43         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:43 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Steeven Li

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> Add functions rte_pmd_bnxt_set_tx_loopback,
> rte_pmd_bnxt_set_all_queues_drop_en and
> rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
> queue_drop and VF MAC address setting in the hardware.
> It also adds the necessary functions to send the HWRM commands
> to the firmware.
> 
> Signed-off-by: Steeven Li <steeven.li@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> 
> --
> v1->v2: regroup related patches and incorporate other review comments
> ---
>  drivers/net/bnxt/Makefile                 |   4 +
>  drivers/net/bnxt/bnxt_hwrm.c              | 107 ++++++++++++++++++++
>  drivers/net/bnxt/bnxt_hwrm.h              |   4 +
>  drivers/net/bnxt/rte_pmd_bnxt.c           | 163 ++++++++++++++++++++++++++++++
>  drivers/net/bnxt/rte_pmd_bnxt.h           |  87 ++++++++++++++++
>  drivers/net/bnxt/rte_pmd_bnxt_version.map |   9 ++
>  6 files changed, 374 insertions(+)
>  create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
>  create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

How did you test these new PMD specific APIs?

In testpmd there are already functions for these APIs, can you please
update testpmd to use these APIs, this also makes them compiled so it
will be easy to find any issues.

<...>


> +	if (req.vnic_id_tbl_addr == 0) {
> +		RTE_LOG(ERR, PMD,
> +		"unable to map VNIC ID table address to physical memory\n");
> +		//rte_free(vnic_ids);

Please remove unused code.

<...>

> +		if (vnic.mru == 4)	// Unallocated

And please don't use // comment style.

<...>

> +/*-
> + *   BSD LICENSE
> + *
> + *   Copyright(c) Broadcom Limited.

Is year required here? I don't know what it is good for, but files tend
to have it.

<...>

> +int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
> +{
> +	struct rte_eth_dev *eth_dev;
> +	struct bnxt *bp;
> +	int rc;
> +
> +	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
> +
> +	if (on > 1)
> +		return -EINVAL;
> +
> +	eth_dev = &rte_eth_devices[port];

For PMD specific APIs, you need to add a protection against application
call the API with port_id of different vendor NIC.

Please check samples on ixgbe or i40e drivers.

<...>

> diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
> index 349c6e1..8b77163 100644
> --- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
> +++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
> @@ -1,4 +1,13 @@
>  DPDK_16.04 {
>  
>  	local: *;
> +
> +};
> +
> +DPDK_17.08 {
> +	global:
> +
> +	rte_pmd_bnxt_set_tx_loopback;
> +	rte_pmd_bnxt_set_all_queues_drop_en;
> +	rte_pmd_bnxt_set_vf_mac_addr;
>  };

Since DPDK_16.04 doesn't have any APIs, I think it can be removed
completely this one replace it (meaning moving local: *; to here)

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-26 18:39       ` [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats Ajit Khaparde
@ 2017-05-29 17:43         ` Ferruh Yigit
  2017-05-31  2:12           ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:43 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Stephen Hurd

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds code to get and clear VF stats.
> It also adds the necessary HWRM structures to send the command
> to the firmware.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> 
> --
> v1->v2: regroup related patches and incorporate other review comments
> ---
>  drivers/net/bnxt/bnxt_hwrm.c    | 38 ++++++++++++++++++
>  drivers/net/bnxt/bnxt_hwrm.h    |  3 ++
>  drivers/net/bnxt/rte_pmd_bnxt.c | 87 +++++++++++++++++++++++++++++++++++++++++
>  drivers/net/bnxt/rte_pmd_bnxt.h | 64 ++++++++++++++++++++++++++++++
>  4 files changed, 192 insertions(+)

It looks like new APIs not added into .map file.
This doesn't cause a build error because they are not used anywhere,
that is why using testpmd to implement them helps to find any issues.

<...>

> +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
> +{
> +	struct rte_eth_dev *dev;
> +	struct rte_eth_dev_info dev_info;
> +	struct bnxt *bp;
> +
> +	dev = &rte_eth_devices[port];
> +	rte_eth_dev_info_get(port, &dev_info);
> +	bp = (struct bnxt *)dev->data->dev_private;
> +
> +	return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> +}

This function is not to get VF stats from PF. As far as I can see this
just gets queue stats, does this really needs to be PMD specific API,
isn't this something generic?

<...>

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

* Re: [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF
  2017-05-26 18:39       ` [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-05-29 17:43         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:43 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Stephen Hurd

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patch adds code to determine the Rx status of a VF.
> It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
> the VNIC count of the function to get the Rx status.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

<..>

> diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
> index c98ed19..7fb9a28 100644
> --- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
> +++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
> @@ -9,6 +9,11 @@ DPDK_17.08 {
>  
>  	rte_pmd_bnxt_set_tx_loopback;
>  	rte_pmd_bnxt_set_all_queues_drop_en;
> +	rte_pmd_bnxt_get_vf_stats;
> +	rte_pmd_bnxt_reset_vf_stats;
> +	rte_pmd_bnxt_get_vf_rx_status;
> +	rte_pmd_bnxt_get_vf_tx_drop_count;
> +	rte_pmd_bnxt_get_tx_drop_count;

Some of these should go to previous patch.

>  	rte_pmd_bnxt_set_vf_mac_addr;
>  	rte_pmd_bnxt_set_vf_mac_anti_spoof;
>  	rte_pmd_bnxt_set_vf_rate_limit;
> 

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

* Re: [PATCH v2 25/25] update release notes
  2017-05-26 18:39       ` [PATCH v2 25/25] update release notes Ajit Khaparde
@ 2017-05-29 17:44         ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:44 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> Update release doc briefly describing updates to bnxt PMD.
> 
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> ---
>  doc/guides/rel_notes/release_17_08.rst | 8 ++++++++
>  1 file changed, 8 insertions(+)
> 
> diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
> index 74aae10..340c820 100644
> --- a/doc/guides/rel_notes/release_17_08.rst
> +++ b/doc/guides/rel_notes/release_17_08.rst
> @@ -69,6 +69,14 @@ EAL
>  Drivers
>  ~~~~~~~

This is "Resolved Issues" section of the document, please move following
to the "New Features" section.

>  
> +* **Updated bnxt PMD.**
> +
> +  Major enhancements include:
> +  * Support MTU modification.
> +  * Support LRO.
> +  * Support VLAN filter and strip functionality.
> +  * Other enhancements to add support for more dev_ops.
> +  * Add PMD specific APIs mainly to control VF from PF.

Update HWRM version to 1.7.7  ?

>  
>  Libraries
>  ~~~~~~~~~
> 

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

* Re: [PATCH v2 00/25] bnxt patchset
  2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
                         ` (24 preceding siblings ...)
  2017-05-26 18:39       ` [PATCH v2 25/25] update release notes Ajit Khaparde
@ 2017-05-29 17:44       ` Ferruh Yigit
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
  25 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-29 17:44 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 5/26/2017 7:39 PM, Ajit Khaparde wrote:
> This patchset amongst other changes adds support few more dev_ops,
> updates HWRM to version 1.7.7, switches to polling stats from the
> hardware, support for Jumbo MTU, LRO etc..
> As suggedted for the previous submission:
>  Grouped in the end, it also has PMD specific APIs to control VF from PF.
>  I have updated the release notes and the features file wherever possible.
> 
> --
>   bnxt: update to new HWRM version
>   bnxt: code reorg to properly allocate resources for PF/VF
>   bnxt: handle VF/PF initialization appropriately
>   bnxt: support lack of huge pages
>   bnxt: add additonal HWRM debug info to error messages
>   bnxt: add tunneling support
>   bnxt: add support for xstats get/reset
>   bnxt: Add support for VLAN filter and strip dev_ops
>   bnxt: add support for set multicast addr list and MAC addr set
>   bnxt: add support for fw_version_get dev_op
>   bnxt: add support to set MTU
>   bnxt: add support for LRO
>   bnxt: add rxq/txq info_get dev_ops
>   bnxt: add code to support VLAN pvid set dev_op
>   bnxt: reorg the query stats code
>   bnxt: add support for led on/off
>   bnxt: add support for tx loopback, set vf mac and queues drop
>   bnxt: add support for set VF QOS and MAC anti spoof
>   bnxt: add support for VLAN stripq, anti spoof and filtering for VFs
>   bnxt: add support to get and clear VF specific stats
>   bnxt: add code to determine the Rx status of VF
>   bnxt: add support to add a VF MAC address
>   bnxt: add code to configure a default VF VLAN
>   bnxt: Add support to set VF rxmode
>   update release notes

I have sent some comments for the patchset.

Also generic to the whole patchset, there are a few minor details it
would be helpful if you can apply in next version of the patchset
(otherwise maintainers have to fix them) :

- rebase patchset on top of latest next-net, there are two easy to fix
conflicts because of merged patches to next-net

- patch subject starts with "next/bnxt: " for driver and "doc: " for
document patch.

- in patch subject, after ":", sentences starts with lowercase char

- instead mentioning added dev_ops name in the patch subject, it would
be better to mention feature added.

Thanks,
ferruh

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-29 17:43         ` Ferruh Yigit
@ 2017-05-31  2:12           ` Ajit Khaparde
  2017-05-31  9:57             ` Ferruh Yigit
  0 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-31  2:12 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Stephen Hurd

On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <ferruh.yigit@intel.com>
wrote:

> > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
> > +{
> > +     struct rte_eth_dev *dev;
> > +     struct rte_eth_dev_info dev_info;
> > +     struct bnxt *bp;
> > +
> > +     dev = &rte_eth_devices[port];
> > +     rte_eth_dev_info_get(port, &dev_info);
> > +     bp = (struct bnxt *)dev->data->dev_private;
> > +
> > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> > +}
>
> This function is not to get VF stats from PF. As far as I can see this
> just gets queue stats, does this really needs to be PMD specific API,
> isn't this something generic?


​Yes. That is right. It returns a count of number of packets which were not
transmitted
because it did not pass the MAC/VLAN spoof check. It does not necessarily
mean "failure to transmit" and so I don't think it is right to map it to
oerrors.
So in the current form I don't see a way to make a generic function out of
it.​

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-31  2:12           ` Ajit Khaparde
@ 2017-05-31  9:57             ` Ferruh Yigit
  2017-05-31 14:27               ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-31  9:57 UTC (permalink / raw)
  To: Ajit Khaparde; +Cc: dev, Stephen Hurd

On 5/31/2017 3:12 AM, Ajit Khaparde wrote:
> 
> On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <ferruh.yigit@intel.com
> <mailto:ferruh.yigit@intel.com>> wrote:
> 
>     > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
>     > +{
>     > +     struct rte_eth_dev *dev;
>     > +     struct rte_eth_dev_info dev_info;
>     > +     struct bnxt *bp;
>     > +
>     > +     dev = &rte_eth_devices[port];
>     > +     rte_eth_dev_info_get(port, &dev_info);
>     > +     bp = (struct bnxt *)dev->data->dev_private;
>     > +
>     > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
>     > +}
> 
>     This function is not to get VF stats from PF. As far as I can see this
>     just gets queue stats, does this really needs to be PMD specific API,
>     isn't this something generic?
> 
> 
> ​Yes. That is right. It returns a count of number of packets which were
> not transmitted
> because it did not pass the MAC/VLAN spoof check. 
> It does not
> necessarily mean "failure to transmit" and so I don't think it is right
> to map it to oerrors.
> So in the current form I don't see a way to make a generic function out
> of it.​

I see, this is implemented because there is no place in basic stats to
put tx_drop_pkts.

Can xstats be used to get this value? Can new .xstats_get_by_id help here?

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-31  9:57             ` Ferruh Yigit
@ 2017-05-31 14:27               ` Ajit Khaparde
  2017-05-31 14:46                 ` Ferruh Yigit
  0 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-31 14:27 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Stephen Hurd

On Wed, May 31, 2017 at 4:57 AM, Ferruh Yigit <ferruh.yigit@intel.com>
wrote:

> On 5/31/2017 3:12 AM, Ajit Khaparde wrote:
> >
> > On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <ferruh.yigit@intel.com
> > <mailto:ferruh.yigit@intel.com>> wrote:
> >
> >     > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
> >     > +{
> >     > +     struct rte_eth_dev *dev;
> >     > +     struct rte_eth_dev_info dev_info;
> >     > +     struct bnxt *bp;
> >     > +
> >     > +     dev = &rte_eth_devices[port];
> >     > +     rte_eth_dev_info_get(port, &dev_info);
> >     > +     bp = (struct bnxt *)dev->data->dev_private;
> >     > +
> >     > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> >     > +}
> >
> >     This function is not to get VF stats from PF. As far as I can see
> this
> >     just gets queue stats, does this really needs to be PMD specific API,
> >     isn't this something generic?
> >
> >
> > ​Yes. That is right. It returns a count of number of packets which were
> > not transmitted
> > because it did not pass the MAC/VLAN spoof check.
> > It does not
> > necessarily mean "failure to transmit" and so I don't think it is right
> > to map it to oerrors.
> > So in the current form I don't see a way to make a generic function out
> > of it.​
>
> I see, this is implemented because there is no place in basic stats to
> put tx_drop_pkts.
>
> Can xstats be used to get this value? Can new .xstats_get_by_id help here?
>
​May be we could. Do we have time for that?​

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-31 14:27               ` Ajit Khaparde
@ 2017-05-31 14:46                 ` Ferruh Yigit
  2017-05-31 16:15                   ` Thomas Monjalon
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-05-31 14:46 UTC (permalink / raw)
  To: Ajit Khaparde; +Cc: dev, Stephen Hurd, Thomas Monjalon

On 5/31/2017 3:27 PM, Ajit Khaparde wrote:
> On Wed, May 31, 2017 at 4:57 AM, Ferruh Yigit <ferruh.yigit@intel.com
> <mailto:ferruh.yigit@intel.com>>wrote:
> 
>     On 5/31/2017 3:12 AM, Ajit Khaparde wrote:
>     >
>     > On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>
>     > <mailto:ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>>>
>     wrote:
>     >
>     >     > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t
>     *count)
>     >     > +{
>     >     > +     struct rte_eth_dev *dev;
>     >     > +     struct rte_eth_dev_info dev_info;
>     >     > +     struct bnxt *bp;
>     >     > +
>     >     > +     dev = &rte_eth_devices[port];
>     >     > +     rte_eth_dev_info_get(port, &dev_info);
>     >     > +     bp = (struct bnxt *)dev->data->dev_private;
>     >     > +
>     >     > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
>     >     > +}
>     >
>     >     This function is not to get VF stats from PF. As far as I can
>     see this
>     >     just gets queue stats, does this really needs to be PMD
>     specific API,
>     >     isn't this something generic?
>     >
>     >
>     > ​Yes. That is right. It returns a count of number of packets which
>     were
>     > not transmitted
>     > because it did not pass the MAC/VLAN spoof check.
>     > It does not
>     > necessarily mean "failure to transmit" and so I don't think it is
>     right
>     > to map it to oerrors.
>     > So in the current form I don't see a way to make a generic
>     function out
>     > of it.​
> 
>     I see, this is implemented because there is no place in basic stats to
>     put tx_drop_pkts.
> 
>     Can xstats be used to get this value? Can new .xstats_get_by_id help
>     here?
> 
> ​May be we could. Do we have time for that?​

Agreed that this may require effort, but I believe we should not use PMD
specific APIs as much as possible, and stick to ethdev abstraction layer.

PMD specific API kills the portability, and only should be used to
benefit from features that are available only for that PMD.

This was my concern to start implementing more thing in PMD layer, like
getting tx_drop stats..

Thanks,
ferruh

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-31 14:46                 ` Ferruh Yigit
@ 2017-05-31 16:15                   ` Thomas Monjalon
  2017-05-31 18:41                     ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Thomas Monjalon @ 2017-05-31 16:15 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: Ajit Khaparde, dev, Stephen Hurd

31/05/2017 16:46, Ferruh Yigit:
> On 5/31/2017 3:27 PM, Ajit Khaparde wrote:
> > On Wed, May 31, 2017 at 4:57 AM, Ferruh Yigit <ferruh.yigit@intel.com
> > <mailto:ferruh.yigit@intel.com>>wrote:
> > 
> >     On 5/31/2017 3:12 AM, Ajit Khaparde wrote:
> >     >
> >     > On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>
> >     > <mailto:ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>>>
> >     wrote:
> >     >
> >     >     > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t
> >     *count)
> >     >     > +{
> >     >     > +     struct rte_eth_dev *dev;
> >     >     > +     struct rte_eth_dev_info dev_info;
> >     >     > +     struct bnxt *bp;
> >     >     > +
> >     >     > +     dev = &rte_eth_devices[port];
> >     >     > +     rte_eth_dev_info_get(port, &dev_info);
> >     >     > +     bp = (struct bnxt *)dev->data->dev_private;
> >     >     > +
> >     >     > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> >     >     > +}
> >     >
> >     >     This function is not to get VF stats from PF. As far as I can
> >     see this
> >     >     just gets queue stats, does this really needs to be PMD
> >     specific API,
> >     >     isn't this something generic?
> >     >
> >     >
> >     > ​Yes. That is right. It returns a count of number of packets which
> >     were
> >     > not transmitted
> >     > because it did not pass the MAC/VLAN spoof check.
> >     > It does not
> >     > necessarily mean "failure to transmit" and so I don't think it is
> >     right
> >     > to map it to oerrors.
> >     > So in the current form I don't see a way to make a generic
> >     function out
> >     > of it.​
> > 
> >     I see, this is implemented because there is no place in basic stats to
> >     put tx_drop_pkts.
> > 
> >     Can xstats be used to get this value? Can new .xstats_get_by_id help
> >     here?
> > 
> > ​May be we could. Do we have time for that?​
> 
> Agreed that this may require effort, but I believe we should not use PMD
> specific APIs as much as possible, and stick to ethdev abstraction layer.
> 
> PMD specific API kills the portability, and only should be used to
> benefit from features that are available only for that PMD.
> 
> This was my concern to start implementing more thing in PMD layer, like
> getting tx_drop stats..

Yes I agree the specific statistics should be added in xstats.

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

* Re: [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats
  2017-05-31 16:15                   ` Thomas Monjalon
@ 2017-05-31 18:41                     ` Ajit Khaparde
  0 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-05-31 18:41 UTC (permalink / raw)
  To: Thomas Monjalon; +Cc: Ferruh Yigit, dev, Stephen Hurd

On Wed, May 31, 2017 at 11:15 AM, Thomas Monjalon <thomas@monjalon.net>
wrote:

> 31/05/2017 16:46, Ferruh Yigit:
> > On 5/31/2017 3:27 PM, Ajit Khaparde wrote:
> > > On Wed, May 31, 2017 at 4:57 AM, Ferruh Yigit <ferruh.yigit@intel.com
> > > <mailto:ferruh.yigit@intel.com>>wrote:
> > >
> > >     On 5/31/2017 3:12 AM, Ajit Khaparde wrote:
> > >     >
> > >     > On Mon, May 29, 2017 at 12:43 PM, Ferruh Yigit <
> ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>
> > >     > <mailto:ferruh.yigit@intel.com <mailto:ferruh.yigit@intel.com>>>
> > >     wrote:
> > >     >
> > >     >     > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t
> > >     *count)
> > >     >     > +{
> > >     >     > +     struct rte_eth_dev *dev;
> > >     >     > +     struct rte_eth_dev_info dev_info;
> > >     >     > +     struct bnxt *bp;
> > >     >     > +
> > >     >     > +     dev = &rte_eth_devices[port];
> > >     >     > +     rte_eth_dev_info_get(port, &dev_info);
> > >     >     > +     bp = (struct bnxt *)dev->data->dev_private;
> > >     >     > +
> > >     >     > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff,
> count);
> > >     >     > +}
> > >     >
> > >     >     This function is not to get VF stats from PF. As far as I can
> > >     see this
> > >     >     just gets queue stats, does this really needs to be PMD
> > >     specific API,
> > >     >     isn't this something generic?
> > >     >
> > >     >
> > >     > ​Yes. That is right. It returns a count of number of packets
> which
> > >     were
> > >     > not transmitted
> > >     > because it did not pass the MAC/VLAN spoof check.
> > >     > It does not
> > >     > necessarily mean "failure to transmit" and so I don't think it is
> > >     right
> > >     > to map it to oerrors.
> > >     > So in the current form I don't see a way to make a generic
> > >     function out
> > >     > of it.​
> > >
> > >     I see, this is implemented because there is no place in basic
> stats to
> > >     put tx_drop_pkts.
> > >
> > >     Can xstats be used to get this value? Can new .xstats_get_by_id
> help
> > >     here?
> > >
> > > ​May be we could. Do we have time for that?​
> >
> > Agreed that this may require effort, but I believe we should not use PMD
> > specific APIs as much as possible, and stick to ethdev abstraction layer.
> >
> > PMD specific API kills the portability, and only should be used to
> > benefit from features that are available only for that PMD.
> >
> > This was my concern to start implementing more thing in PMD layer, like
> > getting tx_drop stats..
>
> Yes I agree the specific statistics should be added in xstats.
>
​And I am already working on that.​ Thanks

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

* [PATCH v3 00/26] bnxt patchset
  2017-05-29 17:44       ` [PATCH v2 00/25] bnxt patchset Ferruh Yigit
@ 2017-06-01  3:02         ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
                             ` (26 more replies)
  0 siblings, 27 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patchset amongst other changes adds support few more dev_ops,
updates HWRM to version 1.7.7, switches to polling stats from the
hardware, support for Jumbo MTU, LRO etc..

v1->v2:
- Grouped in the end, it also has PMD specific APIs to control VF from PF.
- I have updated the release notes and the features file wherever possible.

v2->v3:
 - Rebasing to next-net tree
 - Use net/bnxt instead of just bnxt in patch subject
 - update testpmd to use the vendor specific APIs
 - Addressed other review comments as appropriate

--
  net/bnxt: update to new HWRM version
  net/bnxt: code reorg to properly allocate resources for PF/VF
  net/bnxt: handle VF/PF initialization appropriately
  net/bnxt: support lack of huge pages
  net/bnxt: add additonal HWRM debug info to error messages
  net/bnxt: add tunneling support
  net/bnxt: add support for xstats get/reset
  net/bnxt: add support for VLAN filter and strip
  net/bnxt: add support for set multicast addr list and MAC addr set
  doc: update bnxt.ini to document Allmulticast mode
  net/bnxt: add support to get fw version
  net/bnxt: add support to set MTU
  net/bnxt: add support for LRO
  net/bnxt: add rxq/txq info_get
  net/bnxt: add code to support VLAN pvid
  net/bnxt: reorg the query stats code
  doc: update default.ini to add LED support
  net/bnxt: add support for led on/off
  net/bnxt: add support for tx loopback, set vf mac and queues drop
  net/bnxt: add support for set VF QOS and MAC anti spoof
  net/bnxt: add support to get and clear VF specific stats
  net/bnxt: add code to determine the Rx status of VF
  net/bnxt: add support to add a VF MAC address
  net/bnxt: add code to configure a default VF VLAN
  net/bnxt: add support to set VF rxmode
  doc: update release notes

 app/test-pmd/Makefile                     |    4 +
 app/test-pmd/cmdline.c                    |   92 +-
 app/test-pmd/config.c                     |   20 +-
 doc/guides/nics/features/bnxt.ini         |   10 +
 doc/guides/nics/features/default.ini      |    1 +
 doc/guides/rel_notes/release_17_08.rst    |   10 +
 drivers/net/bnxt/Makefile                 |    4 +
 drivers/net/bnxt/bnxt.h                   |  144 +-
 drivers/net/bnxt/bnxt_cpr.c               |  132 +-
 drivers/net/bnxt/bnxt_cpr.h               |   17 +
 drivers/net/bnxt/bnxt_ethdev.c            |  852 ++-
 drivers/net/bnxt/bnxt_filter.c            |   54 +-
 drivers/net/bnxt/bnxt_filter.h            |    3 +
 drivers/net/bnxt/bnxt_hwrm.c              | 1605 ++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   66 +-
 drivers/net/bnxt/bnxt_irq.c               |   21 +-
 drivers/net/bnxt/bnxt_ring.c              |  159 +-
 drivers/net/bnxt/bnxt_ring.h              |    4 +-
 drivers/net/bnxt/bnxt_rxq.c               |   54 +-
 drivers/net/bnxt/bnxt_rxq.h               |    3 +
 drivers/net/bnxt/bnxt_rxr.c               |  396 +-
 drivers/net/bnxt/bnxt_rxr.h               |   46 +
 drivers/net/bnxt/bnxt_stats.c             |  322 +-
 drivers/net/bnxt/bnxt_stats.h             |   10 +
 drivers/net/bnxt/bnxt_txr.c               |    3 +-
 drivers/net/bnxt/bnxt_vnic.c              |   68 +-
 drivers/net/bnxt/bnxt_vnic.h              |   20 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h    | 9678 +++++++++++++++++++++--------
 drivers/net/bnxt/rte_pmd_bnxt.c           |  757 +++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  310 +
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   19 +-
 31 files changed, 11918 insertions(+), 2966 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 01/26] net/bnxt: update to new HWRM version
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
                             ` (25 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch updates the Broadcom bnxt PMD to version 1.7.7
Most of the changes in the patch are in the hsi_struct_def_dpdk.h - an
autogenerated file. The changes in the *.c files are because of changes
in the macro names.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches per review comment

v2->v3:
 - rebasing to next-net tree
 - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c           |   10 +-
 drivers/net/bnxt/bnxt_ring.c           |    8 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 8710 +++++++++++++++++++++++---------
 3 files changed, 6241 insertions(+), 2487 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3849d1a..9100b7b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -511,7 +511,7 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 		req.enables = rte_cpu_to_le_32(enables);
 	} else {
 		req.flags =
-		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN);
+		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
 		RTE_LOG(INFO, PMD, "Force Link Down\n");
 	}
 
@@ -618,7 +618,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
 		/*
 		 * TODO: Some HWRM versions crash with
@@ -639,7 +639,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD,
 				"hwrm_ring_alloc cp failed. rc:%d\n", rc);
 			return rc;
@@ -680,7 +680,7 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 			rc = rte_le_to_cpu_16(resp->error_code);
 
 		switch (ring_type) {
-		case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD, "hwrm_ring_free cp failed. rc:%d\n",
 				rc);
 			return rc;
@@ -1063,7 +1063,7 @@ static void bnxt_free_cp_ring(struct bnxt *bp,
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
 	bnxt_hwrm_ring_free(bp, cp_ring,
-			HWRM_RING_FREE_INPUT_RING_TYPE_CMPL);
+			HWRM_RING_FREE_INPUT_RING_TYPE_L2_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 *
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0fafa13..52fbd89 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -219,8 +219,8 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *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);
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+					0, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = pci_dev->mem_resource[2].addr;
@@ -238,7 +238,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
@@ -276,7 +276,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index f024837..518f16d 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) Broadcom Limited.
+ *   Copyright(c) 2001-2017 Broadcom Limited.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -31,74 +31,88 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
-#define _HSI_STRUCT_DEF_EXTERNAL_H_
-
-/*
- * per-context HW statistics -- chip view
- */
-
-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_discard_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_discard_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;
-} __attribute__((packed));
-
-/* HW Resource Manager Specification 1.5.1 */
+#ifndef _HSI_STRUCT_DEF_DPDK_
+#define _HSI_STRUCT_DEF_DPDK_
+/* HSI and HWRM Specification 1.7.7 */
 #define HWRM_VERSION_MAJOR	1
-#define HWRM_VERSION_MINOR	5
-#define HWRM_VERSION_UPDATE	1
-
-#define HWRM_VERSION_STR	"1.5.1"
+#define HWRM_VERSION_MINOR	7
+#define HWRM_VERSION_UPDATE	7
 
+#define HWRM_VERSION_STR	"1.7.7"
 /*
  * 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.
+ * applicable	(All F's). Need to cast it the size of the field if needed.
  */
-#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
+#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_MAX_RESP_LEN	(248)  /* hwrm_selftest_qlist */
+#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 */
+#define HWRM_ROCE_SP_HSI_VERSION_MAJOR	1
+#define HWRM_ROCE_SP_HSI_VERSION_MINOR	7
+#define HWRM_ROCE_SP_HSI_VERSION_UPDATE	4
 
 /*
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_BUF_UNRGTR		(UINT32_C(0xe))
+#define HWRM_FUNC_VF_CFG		(UINT32_C(0xf))
+    /* Reserved for future use */
+#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 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_PHY_QCFG		(UINT32_C(0x27))
+#define HWRM_PORT_MAC_QCFG		(UINT32_C(0x28))
+#define HWRM_PORT_PHY_QCAPS		(UINT32_C(0x2a))
+#define HWRM_PORT_LED_CFG		(UINT32_C(0x2d))
+#define HWRM_PORT_LED_QCFG		(UINT32_C(0x2e))
+#define HWRM_PORT_LED_QCAPS		(UINT32_C(0x2f))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_QUEUE_QCFG			(UINT32_C(0x31))
+#define HWRM_QUEUE_CFG			(UINT32_C(0x32))
+#define HWRM_FUNC_VLAN_CFG		(UINT32_C(0x33))
+#define HWRM_FUNC_VLAN_QCFG		(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_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_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_CFG_AGGINT_PARAM	(UINT32_C(0x53))
+#define HWRM_RING_RESET			(UINT32_C(0x5e))
+#define HWRM_RING_GRP_ALLOC		(UINT32_C(0x60))
 #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))
@@ -107,16 +121,69 @@ 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))
+    /* Reserved for future use */
+#define RESERVED4			(UINT32_C(0x94))
+#define HWRM_CFA_TUNNEL_FILTER_ALLOC	(UINT32_C(0x95))
+#define HWRM_CFA_TUNNEL_FILTER_FREE	(UINT32_C(0x96))
+#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_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_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_WOL_FILTER_ALLOC		(UINT32_C(0xf0))
+#define HWRM_WOL_FILTER_FREE		(UINT32_C(0xf1))
+#define HWRM_WOL_FILTER_QCFG		(UINT32_C(0xf2))
+#define HWRM_WOL_REASON_QCFG		(UINT32_C(0xf3))
+#define HWRM_DBG_DUMP			(UINT32_C(0xff14))
+#define HWRM_NVM_VALIDATE_OPTION	(UINT32_C(0xffef))
+#define HWRM_NVM_FLUSH			(UINT32_C(0xfff0))
+#define HWRM_NVM_GET_VARIABLE		(UINT32_C(0xfff1))
+#define HWRM_NVM_SET_VARIABLE		(UINT32_C(0xfff2))
+#define HWRM_NVM_INSTALL_UPDATE		(UINT32_C(0xfff3))
+#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_RAW_DUMP		(UINT32_C(0xfffc))
+#define HWRM_NVM_READ			(UINT32_C(0xfffd))
+#define HWRM_NVM_WRITE			(UINT32_C(0xfffe))
+#define HWRM_NVM_RAW_WRITE_BLK		(UINT32_C(0xffff))
 
-/* Return Codes */
-#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
-#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
-
-/* Short TX BD (16 bytes) */
+/*
+ * Note: The Host Software Interface (HSI) and Hardware Resource Manager (HWRM)
+ * specification describes the data structures used in Ethernet packet or RDMA
+ * message data transfers as well as an abstract interface for managing Ethernet
+ * NIC hardware resources.
+ */
+/* Ethernet Data path Host Structures */
+/*
+ * Description: The following three sections document the host structures used
+ * between device and software drivers for communicating Ethernet packets.
+ */
+/* BD Ring Structures */
+/*
+ * Description: This structure is used to inform the NIC of a location for and
+ * an aggregation buffer that will be used for packet data that is received. An
+ * aggregation buffer creates a different kind of completion operation for a
+ * packet where a variable number of BDs may be used to place the packet in the
+ * host. RX Rings that have aggregation buffers are known as aggregation rings
+ * and must contain only aggregation buffers.
+ */
+/* Short TX BD	(16 bytes) */
 struct tx_bd_short {
 	uint16_t flags_type;
 	/*
@@ -149,10 +216,10 @@ struct tx_bd_short {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -173,7 +240,8 @@ struct tx_bd_short {
 	#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
+	#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
@@ -213,7 +281,7 @@ struct tx_bd_short {
 	 */
 } __attribute__((packed));
 
-/* Long TX BD (32 bytes split to 2 16-byte struct) */
+/* Long TX BD	(32 bytes split to 2 16-byte struct) */
 struct tx_bd_long {
 	uint16_t flags_type;
 	/*
@@ -246,10 +314,10 @@ struct tx_bd_long {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -270,7 +338,8 @@ struct tx_bd_long {
 	#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
+	#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
@@ -360,7 +429,7 @@ struct tx_bd_long_hi {
 	 * bit is set, outer UDP checksum will be calculated for the
 	 * following cases: 1. Packets with tcp_udp_chksum flag set to
 	 * offload checksum for inner packet AND the inner packet is
-	 * TCP/UDP. If the inner packet is ICMP for example (non-
+	 * TCP/UDP. If the inner packet is ICMP for example	(non-
 	 * TCP/UDP), even if the tcp_udp_chksum is set, the outer UDP
 	 * checksum will not be calculated. 2. Packets with lso flag set
 	 * which implies inner TCP checksum calculation as part of LSO
@@ -392,7 +461,7 @@ struct tx_bd_long_hi {
 	 * 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. The flag is ignored if the LSO packet is a normal
-	 * (non-tunneled) TCP packet.
+	 *	(non-tunneled) TCP packet.
 	 */
 	#define TX_BD_LONG_LFLAGS_T_IPID	UINT32_C(0x80)
 	/*
@@ -460,7 +529,7 @@ struct tx_bd_long_hi {
 	#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	\
+	#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)
@@ -474,15 +543,16 @@ struct tx_bd_long_hi {
 	/* No editing */
 	#define TX_BD_LONG_CFA_META_KEY_NONE	(UINT32_C(0x0) << 28)
 	/*
-	 * - meta[17:16] - TPID select value (0 =
+	 * - 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
+	#define TX_BD_LONG_CFA_META_KEY_LAST \
+		TX_BD_LONG_CFA_META_KEY_VLAN_TAG
 } __attribute__((packed));
 
-/* RX Producer Packet BD (16 bytes) */
+/* RX Producer Packet BD	(16 bytes) */
 struct rx_prod_pkt_bd {
 	uint16_t flags_type;
 	/* This value identifies the type of buffer descriptor. */
@@ -490,7 +560,7 @@ struct rx_prod_pkt_bd {
 	#define RX_PROD_PKT_BD_TYPE_SFT	0
 	/*
 	 * Indicates that this BD is 16B long and is an
-	 * RX Producer (ie. empty) buffer descriptor.
+	 * RX Producer	(ie. empty) buffer descriptor.
 	 */
 	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT	UINT32_C(0x4)
 	/*
@@ -558,7 +628,7 @@ struct rx_prod_pkt_bd {
 
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
-/* Base Completion Record (16 bytes) */
+/* Base Completion Record	(16 bytes) */
 struct cmpl_base {
 	uint16_t type;
 	/* unused is 10 b */
@@ -637,7 +707,7 @@ struct cmpl_base {
 	/* info4 is 32 b */
 } __attribute__((packed));
 
-/* TX Completion Record (16 bytes) */
+/* TX Completion Record	(16 bytes) */
 struct tx_cmpl {
 	uint16_t flags_type;
 	/*
@@ -689,7 +759,7 @@ struct tx_cmpl {
 	#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	\
+	#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
@@ -726,7 +796,7 @@ struct tx_cmpl {
 	/* unused3 is 32 b */
 } __attribute__((packed));
 
-/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+/* RX Packet Completion Record	(32 bytes split to 2 16-byte struct) */
 struct rx_pkt_cmpl {
 	uint16_t flags_type;
 	/*
@@ -741,7 +811,9 @@ struct rx_pkt_cmpl {
 	 * RX L2 completion: Completion of and L2 RX
 	 * packet. Length = 32B
 	 */
-	#define RX_PKT_CMPL_TYPE_RX_L2	UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2			UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_START	UINT32_C(0x13)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_END		UINT32_C(0x15)
 	/*
 	 * When this bit is '1', it indicates a packet that has an error
 	 * of some type. Type of error is indicated in error_flags.
@@ -761,10 +833,12 @@ struct rx_pkt_cmpl {
 	 * 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
+	#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)
 	/* unused is 1 b */
+	#define RX_PKT_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
 	/*
 	 * This value indicates what the inner packet determined for the
 	 * packet was.
@@ -820,7 +894,8 @@ struct rx_pkt_cmpl {
 	 * 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_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 len;
@@ -938,7 +1013,7 @@ struct rx_pkt_cmpl_hi {
 	 * the vlan TPID value.
 	 */
 	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
-	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST	\
+	#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
@@ -988,15 +1063,18 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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	\
+	#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)
@@ -1037,39 +1115,45 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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
+	 * 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	\
+	#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
@@ -1089,15 +1173,17 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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
+	 * 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)
@@ -1106,18 +1192,21 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
@@ -1126,9 +1215,9 @@ struct rx_pkt_cmpl_hi {
 	 * 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	\
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
 		(UINT32_C(0x8) << 12)
-	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST	\
+	#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
@@ -1149,7 +1238,474 @@ struct rx_pkt_cmpl_hi {
 	#define RX_PKT_CMPL_REORDER_SFT	0
 } __attribute__((packed));
 
-/* HWRM Forwarded Request (16 bytes) */
+/* RX L2 TPA Start Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_start_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_START_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_START_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA Start Completion: Completion at the
+	 * beginning of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_START_CMPL_TYPE_RX_TPA_START	UINT32_C(0x13)
+	/* This bit will always be '0' for TPA start completions. */
+	#define RX_TPA_START_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+		(UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS (UINT32_C(0x6) << 7)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_TPA_START_CMPL_FLAGS_RSS_VALID	UINT32_C(0x400)
+	/* unused is 1 b */
+	#define RX_TPA_START_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_SFT	12
+	/* TCP Packet: Indicates that the packet was IP and TCP. */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_TCP	(UINT32_C(0x2) << 12)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_LAST \
+		RX_TPA_START_CMPL_FLAGS_ITYPE_TCP
+	#define RX_TPA_START_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_START_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value indicates the amount of packet data written to the
+	 * buffer the opaque field in this completion corresponds to.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t v1;
+	/* unused1 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 RX_TPA_START_CMPL_V1	UINT32_C(0x1)
+	/* unused1 is 7 b */
+	uint8_t rss_hash_type;
+	/*
+	 * 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]}
+	 * . The value of tuple_extrac_op provides the information about
+	 * what fields the hash was computed on. * 0: The RSS hash was
+	 * computed over source IP address, destination IP address,
+	 * source port, and destination port of inner IP and TCP or UDP
+	 * headers. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 1: The RSS hash was computed over
+	 * source IP address and destination IP address of inner IP
+	 * header. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 2: The RSS hash was computed over
+	 * source IP address, destination IP address, source port, and
+	 * destination port of IP and TCP or UDP headers of outer tunnel
+	 * headers. Note: For non-tunneled packets, this value is not
+	 * applicable. * 3: The RSS hash was computed over source IP
+	 * address and destination IP address of IP header of outer
+	 * tunnel headers. Note: For non-tunneled packets, this value is
+	 * not applicable. Note that 4-tuples values listed above are
+	 * applicable for layer 4 protocols supported and enabled for
+	 * RSS in the hardware, HWRM firmware, and drivers. For example,
+	 * if RSS hash is supported and enabled for TCP traffic only,
+	 * then the values of tuple_extract_op corresponding to 4-tuples
+	 * are only valid for TCP traffic.
+	 */
+	uint16_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 9 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_START_CMPL_AGG_ID_MASK	UINT32_C(0xfe00)
+	#define RX_TPA_START_CMPL_AGG_ID_SFT	9
+	uint32_t rss_hash;
+	/*
+	 * This value is the RSS hash value calculated for the packet
+	 * based on the mode bits and key value in the VNIC.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX L2 TPA Start Completion Record */
+struct rx_tpa_start_cmpl_hi {
+	uint32_t flags2;
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * inner packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_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 sum passed for
+	 * all segments included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC	UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * tunnel header and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_IP_CS_CALC	UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the
+	 * tunnel packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_L4_CS_CALC	UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_SFT	4
+	/* No metadata informtaion. Value is zero. */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_LAST \
+		RX_TPA_START_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.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_IP_TYPE	UINT32_C(0x100)
+	uint32_t metadata;
+	/*
+	 * 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_TPA_START_CMPL_METADATA_VID_MASK	UINT32_C(0xfff)
+	#define RX_TPA_START_CMPL_METADATA_VID_SFT	0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_TPA_START_CMPL_METADATA_DE	UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_TPA_START_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+	#define RX_TPA_START_CMPL_METADATA_PRI_SFT	13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_TPA_START_CMPL_METADATA_TPID_MASK	UINT32_C(0xffff0000)
+	#define RX_TPA_START_CMPL_METADATA_TPID_SFT	16
+	uint16_t v2;
+	/* unused4 is 15 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 RX_TPA_START_CMPL_V2	UINT32_C(0x1)
+	/* unused4 is 15 b */
+	uint16_t cfa_code;
+	/*
+	 * This field identifies the CFA action rule that was used for
+	 * this packet.
+	 */
+	uint32_t inner_l4_size_inner_l3_offset_inner_l2_offset_outer_l3_offset;
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the outer L3 header. If there is no outer L3 header, then
+	 * this value is zero.
+	 */
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_MASK	UINT32_C(0x1ff)
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_SFT	0
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L2 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_MASK	UINT32_C(0x3fe00)
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_SFT	9
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L3 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_MASK	UINT32_C(0x7fc0000)
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_SFT	18
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_MASK	UINT32_C(0xf8000000)
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_SFT	27
+} __attribute__((packed));
+
+/* RX TPA End Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_end_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_END_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_END_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA End Completion: Completion at the
+	 * end of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_END_CMPL_TYPE_RX_TPA_END	UINT32_C(0x15)
+	/*
+	 * 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_TPA_END_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_END_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_TPA_END_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_JUMBO (UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS	(UINT32_C(0x6) << 7)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* unused is 2 b */
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_MASK	UINT32_C(0xc00)
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_SFT	10
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was. - 2 TCP Packet Indicates that the packet was IP
+	 * and TCP. This indicates that the ip_cs field is valid and
+	 * that the tcp_udp_cs field is valid and contains the TCP
+	 * checksum. This also indicates that the payload_offset field
+	 * is valid.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_SFT	12
+	#define RX_TPA_END_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_END_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value is zero for TPA End completions. There is no data
+	 * in the buffer that corresponds to the opaque value in this
+	 * completion.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t agg_bufs_v1;
+	/* unused1 is 1 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 RX_TPA_END_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
+	 * aggregation packet. If the value is zero, then the packet is
+	 * completely contained in the buffer space provided in the
+	 * aggregation start completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_BUFS_MASK	UINT32_C(0x7e)
+	#define RX_TPA_END_CMPL_AGG_BUFS_SFT	1
+	/* unused1 is 1 b */
+	uint8_t tpa_segs;
+	/* This value is the number of segments in the TPA operation. */
+	uint8_t payload_offset;
+	/*
+	 * This value indicates the offset in bytes from the beginning
+	 * of the packet where the inner payload starts. This value is
+	 * valid for TCP, UDP, FCoE, and RoCE packets. A value of zero
+	 * indicates an offset of 256 bytes.
+	 */
+	uint8_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 1 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_ID_MASK	UINT32_C(0xfe)
+	#define RX_TPA_END_CMPL_AGG_ID_SFT	1
+	uint32_t tsdelta;
+	/*
+	 * For non-GRO packets, this value is the timestamp delta
+	 * between earliest and latest timestamp values for TPA packet.
+	 * If packets were not time stamped, then delta will be zero.
+	 * For GRO packets, this field is zero except for the following
+	 * sub-fields. - tsdelta[31] Timestamp present indication. When
+	 * '0', no Timestamp option is in the packet. When '1', then a
+	 * Timestamp option is present in the packet.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX TPA End Completion Record */
+struct rx_tpa_end_cmpl_hi {
+	uint32_t tpa_dup_acks;
+	/* unused3 is 28 b */
+	/*
+	 * This value is the number of duplicate ACKs that have been
+	 * received as part of the TPA operation.
+	 */
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_MASK	UINT32_C(0xf)
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_SFT	0
+	/* unused3 is 28 b */
+	uint16_t tpa_seg_len;
+	/*
+	 * This value is the valid when TPA completion is active. It
+	 * indicates the length of the longest segment of the TPA
+	 * operation for LRO mode and the length of the first segment in
+	 * GRO mode. This value may be used by GRO software to re-
+	 * construct the original packet stream from the TPA packet.
+	 * This is the length of all but the last segment for GRO. In
+	 * LRO mode this value may be used to indicate MSS size to the
+	 * stack.
+	 */
+	uint16_t unused_3;
+	/* unused4 is 16 b */
+	uint16_t errors_v2;
+	/*
+	 * 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_TPA_END_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_TPA_END_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+	/*
+	 * This error occurs when there is a fatal HW
+	 * problem in the chip only. It indicates that
+	 * there were not BDs on chip but that there was
+	 * adequate reservation. provided by the TPA
+	 * block.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+		(UINT32_C(0x2) << 1)
+	/*
+	 * This error occurs when TPA block was not
+	 * configured to reserve adequate BDs for TPA
+	 * operations on this RX ring. All data for the
+	 * TPA operation was not placed. This error can
+	 * also be generated when the number of segments
+	 * is not programmed correctly in TPA and the 33
+	 * total aggregation buffers allowed for the TPA
+	 * operation has been exceeded.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR \
+		(UINT32_C(0x4) << 1)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_LAST \
+		RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR
+	#define RX_TPA_END_CMPL_ERRORS_MASK	UINT32_C(0xfffe)
+	#define RX_TPA_END_CMPL_ERRORS_SFT	1
+	uint16_t unused_4;
+	/* unused5 is 16 b */
+	uint32_t start_opaque;
+	/*
+	 * This is the opaque value that was completed for the TPA start
+	 * completion that corresponds to this TPA end completion.
+	 */
+} __attribute__((packed));
+
+/* HWRM Forwarded Request	(16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	uint16_t req_len_type;
 	/* Length of forwarded request in bytes. */
@@ -1188,7 +1744,7 @@ struct hwrm_fwd_req_cmpl {
 	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
 } __attribute__((packed));
 
-/* HWRM Asynchronous Event Completion Record (16 bytes) */
+/* HWRM Asynchronous Event Completion Record	(16 bytes) */
 struct hwrm_async_event_cmpl {
 	uint16_t type;
 	/* unused1 is 10 b */
@@ -1210,19 +1766,20 @@ struct hwrm_async_event_cmpl {
 	/* Link MTU changed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE	UINT32_C(0x1)
 	/* Link speed changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE  UINT32_C(0x2)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE UINT32_C(0x2)
 	/* DCB Configuration changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE  UINT32_C(0x3)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE UINT32_C(0x3)
 	/* Port connection not allowed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED UINT32_C(0x4)
 	/* Link speed configuration was not allowed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED UINT32_C(0x5)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+		UINT32_C(0x5)
 	/* Link speed configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE UINT32_C(0x6)
 	/* Port PHY configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE UINT32_C(0x7)
 	/* Function driver unloaded */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD   UINT32_C(0x10)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD UINT32_C(0x10)
 	/* Function driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD	UINT32_C(0x11)
 	/* Function FLR related processing has completed */
@@ -1231,12 +1788,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD	UINT32_C(0x20)
 	/* PF driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD	UINT32_C(0x21)
-	/* VF Function Level Reset (FLR) */
+	/* VF Function Level Reset	(FLR) */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	UINT32_C(0x30)
 	/* VF MAC Address Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE UINT32_C(0x31)
 	/* PF-VF communication channel status change. */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE UINT32_C(0x32)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+		UINT32_C(0x32)
 	/* VF Configuration Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE	UINT32_C(0x33)
 	/* HWRM Error */
@@ -1255,69 +1813,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK	UINT32_C(0xfe)
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT	1
 	uint8_t timestamp_lo;
-	/* 8-lsb timestamp from POR (100-msec resolution) */
+	/* 8-lsb timestamp from POR	(100-msec resolution) */
 	uint16_t timestamp_hi;
-	/* 16-lsb timestamp from POR (100-msec resolution) */
+	/* 16-lsb timestamp from POR	(100-msec resolution) */
 	uint32_t event_data1;
 	/* Event specific data */
 } __attribute__((packed));
 
-/*
- * 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 service is vital part of the chip.
- * The chip can not be used by a driver or HWRM client without the HWRM.
- */
-
-/* Input (16 bytes) */
-struct input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
-/* Output (8 bytes) */
-struct output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
@@ -1327,7 +1829,7 @@ struct output {
  * interface or firmware version with major = 0, minor = 0, and update = 0 shall
  * be considered an invalid version.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ver_get_input {
 	uint16_t req_type;
 	/*
@@ -1384,7 +1886,7 @@ struct hwrm_ver_get_input {
 	uint8_t unused_0[5];
 } __attribute__((packed));
 
-/* Output (128 bytes) */
+/* Output	(128 bytes) */
 struct hwrm_ver_get_output {
 	uint16_t error_code;
 	/*
@@ -1454,7 +1956,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version of the HWRM
 	 * firmware.
 	 */
 	uint8_t mgmt_fw_maj;
@@ -1477,7 +1979,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint8_t netctrl_fw_maj;
 	/*
@@ -1500,7 +2002,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint32_t dev_caps_cfg;
 	/*
@@ -1512,13 +2014,27 @@ struct hwrm_ver_get_output {
 	 * supported. If set to 0, then secure firmware update behavior
 	 * is not supported.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  UINT32_C(0x1)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  \
+		UINT32_C(0x1)
 	/*
 	 * If set to 1, then firmware based DCBX agent is supported. If
 	 * set to 0, then firmware based DCBX agent capability is not
 	 * supported on this device.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, then HWRM short command format is supported. If
+	 * set to 0, then HWRM short command format is not supported.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED	 \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, then HWRM short command format is required. If
+	 * set to 0, then HWRM short command format is not required.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_INPUTUIRED	\
+		UINT32_C(0x8)
 	uint8_t roce_fw_maj;
 	/*
 	 * This field represents the major version of RoCE firmware. A
@@ -1539,22 +2055,22 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	char hwrm_fw_name[16];
 	/*
-	 * This field represents the name of HWRM FW (ASCII chars with
+	 * This field represents the name of HWRM FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char mgmt_fw_name[16];
 	/*
-	 * This field represents the name of mgmt FW (ASCII chars with
+	 * This field represents the name of mgmt FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char netctrl_fw_name[16];
 	/*
 	 * This field represents the name of network control firmware
-	 * (ASCII chars with NULL at the end).
+	 *	(ASCII chars with NULL at the end).
 	 */
 	uint32_t reserved2[4];
 	/*
@@ -1563,7 +2079,7 @@ struct hwrm_ver_get_output {
 	 */
 	char roce_fw_name[16];
 	/*
-	 * This field represents the name of RoCE FW (ASCII chars with
+	 * This field represents the name of RoCE FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	uint16_t chip_num;
@@ -1584,7 +2100,7 @@ struct hwrm_ver_get_output {
 	/* FPGA platform of the chip. */
 	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA	UINT32_C(0x1)
 	/* Palladium platform of the chip. */
-	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM	UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM UINT32_C(0x2)
 	uint16_t max_req_win_len;
 	/*
 	 * This field returns the maximum value of request window that
@@ -1614,7 +2130,7 @@ struct hwrm_ver_get_output {
 
 /* hwrm_func_reset */
 /*
- * Description: This command resets a hardware function (PCIe function) and
+ * 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
@@ -1626,7 +2142,7 @@ struct hwrm_ver_get_output {
  * idled. The command returns all the resources owned by the function so a new
  * driver may allocate and configure resources normally.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_reset_input {
 	uint16_t req_type;
 	/*
@@ -1668,7 +2184,7 @@ struct hwrm_func_reset_input {
 	/* This value indicates the level of a function reset. */
 	/*
 	 * Reset the caller function and its children
-	 * VFs (if any). If no children functions exist,
+	 * 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)
@@ -1681,7 +2197,8 @@ struct hwrm_func_reset_input {
 	 * 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)
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+		UINT32_C(0x2)
 	/*
 	 * Reset a specific VF of the caller function
 	 * driver if the caller is the parent PF driver.
@@ -1694,7 +2211,7 @@ struct hwrm_func_reset_input {
 	uint8_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_reset_output {
 	uint16_t error_code;
 	/*
@@ -1734,7 +2251,7 @@ struct hwrm_func_reset_output {
  * 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) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcaps_input {
 	uint16_t req_type;
 	/*
@@ -1765,12 +2282,12 @@ struct hwrm_func_qcaps_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (80 bytes) */
+/* Output	(80 bytes) */
 struct hwrm_func_qcaps_output {
 	uint16_t error_code;
 	/*
@@ -1795,54 +2312,56 @@ struct hwrm_func_qcaps_output {
 	uint16_t port_id;
 	/*
 	 * 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
+	 * 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.
 	 */
 	uint32_t flags;
 	/* If 1, then Push mode is supported on this function. */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED	UINT32_C(0x1)
+	#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)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING	 \
+		UINT32_C(0x2)
 	/*
-	 * If 1, then the Precision Time Protocol (PTP) processing is
+	 * 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.
+	 * only a single Physical Function	(PF) per port.
 	 */
 	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED	UINT32_C(0x4)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v1 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v1 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED	UINT32_C(0x8)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED UINT32_C(0x8)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v2 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v2 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED	UINT32_C(0x10)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED UINT32_C(0x10)
 	/*
 	 * If 1, then control and configuration of WoL magic packet are
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	UINT32_C(0x20)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	\
+		UINT32_C(0x20)
 	/*
 	 * If 1, then control and configuration of bitmap pattern packet
 	 * are supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED	UINT32_C(0x40)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED UINT32_C(0x40)
 	/*
 	 * If set to 1, then the control and configuration of rate limit
 	 * of an allocated TX ring on the queried function is supported.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED	UINT32_C(0x80)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED UINT32_C(0x80)
 	/*
 	 * If 1, then control and configuration of minimum and maximum
 	 * bandwidths are supported on the queried function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED	UINT32_C(0x100)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED UINT32_C(0x100)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1851,7 +2370,8 @@ struct hwrm_func_qcaps_output {
 	 * set to 0, then the PF does not have the capability to set the
 	 * rate limits on the TX rings of its children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	UINT32_C(0x200)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	 \
+		UINT32_C(0x200)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1861,7 +2381,17 @@ struct hwrm_func_qcaps_output {
 	 * capability to set the minimum or maximum bandwidths for its
 	 * children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED	UINT32_C(0x400)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED UINT32_C(0x400)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is supported on the
+	 * queried function. If set to 0, then standard TX ring mode is
+	 * not available on the queried function.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_STD_TX_RING_MODE_SUPPORTED   \
+		UINT32_C(0x800)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -1901,7 +2431,7 @@ struct hwrm_func_qcaps_output {
 	uint16_t first_vf_id;
 	/*
 	 * 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
+	 * 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.
 	 */
@@ -1909,7 +2439,7 @@ struct hwrm_func_qcaps_output {
 	/*
 	 * 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-
+	 * 0xFF...	(All Fs) if this command is called on a PF with SR-
 	 * IOV disabled or on a VF.
 	 */
 	uint16_t max_stat_ctx;
@@ -1929,22 +2459,22 @@ struct hwrm_func_qcaps_output {
 	 */
 	uint32_t max_tx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_tx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_rx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_rx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_mcast_filters;
@@ -1968,7 +2498,7 @@ struct hwrm_func_qcaps_output {
 	 * be allocated to the function. This number indicates the
 	 * maximum number of TX rings that can be assigned strict
 	 * priorities out of the maximum number of TX rings that can be
-	 * allocated (max_tx_rings) to the function.
+	 * allocated	(max_tx_rings) to the function.
 	 */
 	uint8_t unused_0;
 	uint8_t valid;
@@ -1989,9 +2519,13 @@ struct hwrm_func_qcaps_output {
  * 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.
+ * the PCI bus. This command should be called by every driver after
+ * 'hwrm_func_cfg' to get the actual number of resources allocated by the HWRM.
+ * The values returned by hwrm_func_qcfg are the values the driver shall use.
+ * These values may be different than what was originally requested in the
+ * 'hwrm_func_cfg' command.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcfg_input {
 	uint16_t req_type;
 	/*
@@ -2022,12 +2556,12 @@ struct hwrm_func_qcfg_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (72 bytes) */
+/* Output	(72 bytes) */
 struct hwrm_func_qcfg_output {
 	uint16_t error_code;
 	/*
@@ -2052,7 +2586,7 @@ struct hwrm_func_qcfg_output {
 	uint16_t port_id;
 	/*
 	 * Port ID of port that this function is associated with.
-	 * 0xFF... (All Fs) if this function is not associated with any
+	 * 0xFF...	(All Fs) if this function is not associated with any
 	 * port.
 	 */
 	uint16_t vlan;
@@ -2060,15 +2594,15 @@ struct hwrm_func_qcfg_output {
 	 * This value is the current VLAN setting for this function. The
 	 * value of 0 for this field indicates no priority tagging or
 	 * VLAN is used. This field's format is same as 802.1Q Tag's Tag
-	 * Control Information (TCI) format that includes both Priority
-	 * Code Point (PCP) and VLAN Identifier (VID).
+	 * Control Information	(TCI) format that includes both Priority
+	 * Code Point	(PCP) and VLAN Identifier	(VID).
 	 */
 	uint16_t flags;
 	/*
 	 * If 1, then magic packet based Out-Of-Box WoL is enabled on
 	 * the port associated with this function.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	 \
 		UINT32_C(0x1)
 	/*
 	 * If 1, then bitmap pattern based Out-Of-Box WoL packet is
@@ -2080,8 +2614,33 @@ struct hwrm_func_qcfg_output {
 	 * on the port associated with this function. If set to 0, then
 	 * DCBX agent is not running in the firmware.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED \
 		UINT32_C(0x4)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is enabled on the
+	 * queried function. If set to 0, then the standard TX ring mode
+	 * is disabled on the queried function. In this extended TX ring
+	 * resource mode, the minimum and maximum bandwidth settings are
+	 * not supported to allow the allocation of TX rings to span
+	 * multiple scheduler nodes.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_STD_TX_RING_MODE_ENABLED	 \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1 then FW based LLDP agent is enabled and running
+	 * on the port associated with this function. If set to 0 then
+	 * the LLDP agent is not running in the firmware.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED UINT32_C(0x10)
+	/*
+	 * If set to 1, then multi-host mode is active for this
+	 * function. If set to 0, then multi-host mode is inactive for
+	 * this function or not applicable for this device.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST		UINT32_C(0x20)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -2091,8 +2650,8 @@ struct hwrm_func_qcfg_output {
 	uint16_t pci_id;
 	/*
 	 * This value is current PCI ID of this function. If ARI is
-	 * enabled, then it is Bus Number (8b):Function Number(8b).
-	 * Otherwise, it is Bus Number (8b):Device Number (4b):Function
+	 * enabled, then it is Bus Number	(8b):Function Number(8b).
+	 * Otherwise, it is Bus Number	(8b):Device Number	(4b):Function
 	 * Number(4b).
 	 */
 	uint16_t alloc_rsscos_ctx;
@@ -2146,22 +2705,27 @@ struct hwrm_func_qcfg_output {
 	/* Multiple physical functions */
 	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS	UINT32_C(0x1)
 	/* Network Partitioning 1.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0	\
-		UINT32_C(0x2)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 UINT32_C(0x2)
 	/* Network Partitioning 1.5 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5	\
-		UINT32_C(0x3)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 UINT32_C(0x3)
 	/* Network Partitioning 2.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0	\
-		UINT32_C(0x4)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 UINT32_C(0x4)
 	/* Unknown */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN	\
-		UINT32_C(0xff)
-	uint8_t unused_0;
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN UINT32_C(0xff)
+	uint8_t port_pf_cnt;
+	/*
+	 * This field will indicate number of physical functions on this
+	 * port_partition. HWRM shall return unavail (i.e. value of 0)
+	 * for this field when this command is used to query VF's
+	 * configuration or from older firmware that doesn't support
+	 * this field.
+	 */
+	/* number of PFs is not available */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_UNAVAIL	UINT32_C(0x0)
 	uint16_t dflt_vnic_id;
 	/* The default VNIC ID assigned to a function that is being queried. */
+	uint8_t unused_0;
 	uint8_t unused_1;
-	uint8_t unused_2;
 	uint32_t min_bw;
 	/*
 	 * Minimum BW allocated for this function. The HWRM will
@@ -2169,26 +2733,41 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * the minimum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID
 	uint32_t max_bw;
 	/*
@@ -2197,43 +2776,58 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * that the maximum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID
 	uint8_t evb_mode;
 	/*
 	 * This value indicates the Edge virtual bridge mode for the
 	 * domain that this function belongs to.
 	 */
-	/* No Edge Virtual Bridging (EVB) */
+	/* No Edge Virtual Bridging	(EVB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
-	/* Virtual Ethernet Bridge (VEB) */
+	/* Virtual Ethernet Bridge	(VEB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB	UINT32_C(0x1)
-	/* Virtual Ethernet Port Aggregator (VEPA) */
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA	UINT32_C(0x2)
-	uint8_t unused_3;
+	uint8_t unused_2;
 	uint16_t alloc_vfs;
 	/*
 	 * The number of VFs that are allocated to the function. This is
-	 * valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if
+	 * 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.
 	 */
@@ -2247,9 +2841,9 @@ struct hwrm_func_qcfg_output {
 	uint16_t alloc_sp_tx_rings;
 	/*
 	 * The number of strict priority transmit rings out of currently
-	 * allocated TX rings to the function (alloc_tx_rings).
+	 * allocated TX rings to the function	(alloc_tx_rings).
 	 */
-	uint8_t unused_4;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -2261,15 +2855,14 @@ struct hwrm_func_qcfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_func_drv_rgtr */
+/* hwrm_func_vlan_qcfg */
 /*
- * 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.
+ * Description: This command should be called by PF driver to get the current
+ * C-TAG, S-TAG and correcponsing PCP and TPID values configured for the
+ * function.
  */
-/* Input (80 bytes) */
-struct hwrm_func_drv_rgtr_input {
+/* Input (24 bytes) */
+struct hwrm_func_vlan_qcfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2296,96 +2889,17 @@ struct hwrm_func_drv_rgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 enables;
-	/* 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_INPUT_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)
-	uint16_t os_type;
-	/* This value indicates the type of OS. */
-	/* Unknown */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Other OS not listed below. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
-	/* MSDOS OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
-	/* Windows OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
-	/* Solaris OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
-	/* Linux OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
-	/* FreeBSD OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
-	/* VMware ESXi OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
-	/* Microsoft Windows 8 64-bit OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
-	/* Microsoft Windows Server 2012 R2 OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
-	uint8_t ver_maj;
-	/* This is the major version of the driver. */
-	uint8_t ver_min;
-	/* This is the minor version of the driver. */
-	uint8_t ver_upd;
-	/* This is the update version of the driver. */
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint32_t timestamp;
-	/*
-	 * This is a 32-bit timestamp provided by the driver for keep
-	 * alive. The timestamp is in multiples of 1ms.
-	 */
-	uint32_t unused_2;
-	uint32_t vf_req_fwd[8];
-	/*
-	 * 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 async_event_fwd[8];
+	uint16_t fid;
 	/*
-	 * 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.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-} __attribute__((packed));
+	uint16_t unused_0[3];
+};
 
-/* Output (16 bytes) */
-struct hwrm_func_drv_rgtr_output {
+/* Output (40 bytes) */
+struct hwrm_func_vlan_qcfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2414,16 +2928,40 @@ struct hwrm_func_drv_rgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_4;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_5;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t rsvd3;
+	/* Future use. */
+	uint32_t unused_6;
+};
 
-/* hwrm_func_drv_unrgtr */
+/* hwrm_func_vlan_cfg */
 /*
- * 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.
+ * Description: This command allows PF driver to configure C-TAG, S-TAG and
+ * corresponding PCP and TPID values for a function.
  */
-/* Input (24 bytes) */
-struct hwrm_func_drv_unrgtr_input {
+/* Input (48 bytes) */
+struct hwrm_func_vlan_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2450,17 +2988,56 @@ struct hwrm_func_drv_unrgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint16_t fid;
 	/*
-	 * When this bit is '1', the function driver is notifying the
-	 * HWRM to prepare for the shutdown.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN	UINT32_C(0x1)
-	uint32_t unused_0;
-} __attribute__((packed));
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t enables;
+	/* This bit must be '1' for the stag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_VID	UINT32_C(0x1)
+	/* This bit must be '1' for the ctag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_VID	UINT32_C(0x2)
+	/* This bit must be '1' for the stag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_PCP	UINT32_C(0x4)
+	/* This bit must be '1' for the ctag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_PCP	UINT32_C(0x8)
+	/* This bit must be '1' for the stag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_TPID	UINT32_C(0x10)
+	/* This bit must be '1' for the ctag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_TPID	UINT32_C(0x20)
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_2;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_3;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd1;
+	/* Future use. */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t unused_4;
+};
 
 /* Output (16 bytes) */
-struct hwrm_func_drv_unrgtr_output {
+struct hwrm_func_vlan_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2489,19 +3066,45 @@ struct hwrm_func_drv_unrgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+};
 
-/* hwrm_port_phy_cfg */
+/* hwrm_func_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.
+ * Description: This command allows configuration of a PF by the corresponding
+ * PF driver. This command also allows configuration of a child VF by its parent
+ * PF driver. The input FID value is used to indicate what function is being
+ * configured. This allows a PF driver to configure the PF owned by itself or a
+ * virtual function that is a child of the PF. This command allows to reserve
+ * resources for a VF by its parent PF. To reverse the process, the command
+ * should be called with all enables flags cleared for resources. This will free
+ * allocated resources for the VF and return them to the resource pool. If this
+ * command is requested by a VF driver to configure or reserve resources, then
+ * the HWRM shall fail this command. If default MAC address and/or VLAN are
+ * provided in this command, then the HWRM shall set up appropriate MAC/VLAN
+ * filters for the function that is being configured. If source properties
+ * checks are enabled and default MAC address and/or IP address are provided in
+ * this command, then the HWRM shall set appropriate source property checks
+ * based on provided MAC and/or IP addresses. The parent PF driver should not
+ * set MTU/MRU for a VF using this command. This is to allow MTU/MRU setting by
+ * the VF driver. If the MTU or MRU for a VF is set by the PF driver, then the
+ * HWRM should ignore it. A function's MTU/MRU should be set prior to allocating
+ * RX VNICs or TX rings. A PF driver calls hwrm_func_cfg to allocate resources
+ * for itself or its children VFs. All function drivers shall call hwrm_func_cfg
+ * to reserve resources. A request to hwrm_func_cfg may not be fully granted;
+ * that is, a request for resources may be larger than what can be supported by
+ * the device and the HWRM will allocate the best set of resources available,
+ * but that may be less than requested. If all the amounts requested could not
+ * be fulfilled, the HWRM shall allocate what it could and return a status code
+ * of success. A function driver should call hwrm_func_qcfg immediately after
+ * hwrm_func_cfg to determine what resources were assigned to the configured
+ * function. A call by a PF driver to hwrm_func_cfg to allocate resources for
+ * itself shall only allocate resources for the PF driver to use, not for its
+ * children VFs. Likewise, a call to hwrm_func_qcfg shall return the resources
+ * available for the PF driver to use, not what is available to its children
+ * VFs.
  */
-/* Input (56 bytes) */
-struct hwrm_port_phy_cfg_input {
+/* Input	(88 bytes) */
+struct hwrm_func_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2528,397 +3131,560 @@ struct hwrm_port_phy_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF...	(All Fs), then the the configuration is for the
+	 * requesting function.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
 	uint32_t flags;
 	/*
-	 * 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.
+	 * When this bit is '1', the function is disabled with source
+	 * MAC address check. This is an anti-spoofing check. If this
+	 * flag is set, then the function shall be configured to
+	 * disallow transmission of frames with the source MAC address
+	 * that is configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY	UINT32_C(0x1)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE	 \
+		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.
+	 * When this bit is '1', the function is enabled with source MAC
+	 * address check. This is an anti-spoofing check. If this flag
+	 * is set, then the function shall be configured to allow
+	 * transmission of frames with the source MAC address that is
+	 * configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN	UINT32_C(0x2)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE	\
+		UINT32_C(0x2)
+	/* reserved */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_MASK	UINT32_C(0x1fc)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_SFT	2
 	/*
-	 * 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.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is requested to be
+	 * enabled on the function being configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE	UINT32_C(0x4)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE	\
+		UINT32_C(0x200)
 	/*
-	 * When this bit is set to '1', the auto-negotiation process
-	 * shall be restarted on the link.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then the standard TX ring mode is requested to be
+	 * disabled on the function being configured. In this extended
+	 * TX ring resource mode, the minimum and maximum bandwidth
+	 * settings are not supported to allow the allocation of TX
+	 * rings to span multiple scheduler nodes.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG	UINT32_C(0x8)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE	\
+		UINT32_C(0x400)
 	/*
-	 * 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.
+	 * If this bit is set, virtual mac address configured in this
+	 * command will be persistent over warm boot.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_VIRT_MAC_PERSIST	UINT32_C(0x800)
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MTU	UINT32_C(0x1)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MRU	UINT32_C(0x2)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_rsscos_ctxs field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS	UINT32_C(0x4)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_cmpl_rings field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_ENABLE	UINT32_C(0x40)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS	UINT32_C(0x8)
+	/* This bit must be '1' for the num_tx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS	UINT32_C(0x10)
+	/* This bit must be '1' for the num_rx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS	UINT32_C(0x20)
+	/* This bit must be '1' for the num_l2_ctxs field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS	UINT32_C(0x40)
+	/* This bit must be '1' for the num_vnics field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS	UINT32_C(0x80)
+	/*
+	 * This bit must be '1' for the num_stat_ctxs field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS	UINT32_C(0x100)
 	/*
-	 * When this bit is set to '1' and EEE is enabled on this link,
-	 * then TX LPI is requested to be disabled 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.
+	 * This bit must be '1' for the dflt_mac_addr field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR	UINT32_C(0x200)
+	/* This bit must be '1' for the dflt_vlan field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN	UINT32_C(0x400)
+	/* This bit must be '1' for the dflt_ip_addr field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_IP_ADDR	UINT32_C(0x800)
+	/* This bit must be '1' for the min_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MIN_BW	UINT32_C(0x1000)
+	/* This bit must be '1' for the max_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW	UINT32_C(0x2000)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_DISABLE	UINT32_C(0x80)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR	UINT32_C(0x4000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC
-	 * autonegotitation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the vlan_antispoof_mode field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE	UINT32_C(0x100)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE	UINT32_C(0x8000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC
-	 * autonegotiation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the allowed_vlan_pris field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	UINT32_C(0x200)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ALLOWED_VLAN_PRIS UINT32_C(0x10000)
+	/* This bit must be '1' for the evb_mode field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE	UINT32_C(0x20000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74 (Fire
-	 * Code) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_mcast_filters field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	UINT32_C(0x400)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MCAST_FILTERS UINT32_C(0x40000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
-	 * (Fire Code) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 74 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_hw_ring_grps field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	UINT32_C(0x800)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS UINT32_C(0x80000)
+	uint16_t mtu;
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91 (Reed
-	 * Solomon) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * The maximum transmission unit of the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed
+	 * the mtu of the physical port that this function is associated
+	 * with. In addition to configuring mtu per function, it is
+	 * possible to configure mtu per transmit ring. By default, the
+	 * mtu of each transmit ring associated with a function is equal
+	 * to the mtu of the function. The HWRM should make sure that
+	 * the mtu of each transmit ring that is assigned to a function
+	 * has a valid mtu.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	UINT32_C(0x1000)
+	uint16_t mru;
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
-	 * (Reed Solomon) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 91 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * The maximum receive unit of the function. The HWRM should
+	 * make sure that the mru of the function does not exceed the
+	 * mru of the physical port that this function is associated
+	 * with. In addition to configuring mru per function, it is
+	 * possible to configure mru per vnic. By default, the mru of
+	 * each vnic associated with a function is equal to the mru of
+	 * the function. The HWRM should make sure that the mru of each
+	 * vnic that is assigned to a function has a valid mru.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	UINT32_C(0x2000)
-	uint32_t enables;
-	/* 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)
+	uint16_t num_rsscos_ctxs;
+	/* The number of RSS/COS contexts requested for the function. */
+	uint16_t num_cmpl_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed field to be
-	 * configured.
+	 * The number of completion rings requested for the function.
+	 * This does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED	UINT32_C(0x8)
+	uint16_t num_tx_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed_mask field to be
-	 * configured.
+	 * The number of transmit rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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_WIOUTPUTEED	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)
+	uint16_t num_rx_rings;
 	/*
-	 * This bit must be '1' for the eee_link_speed_mask field to be
-	 * configured.
+	 * The number of receive rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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)
-	uint16_t port_id;
-	/* Port ID of port that is to be configured. */
-	uint16_t force_link_speed;
+	uint16_t num_l2_ctxs;
+	/* The requested number of L2 contexts for the function. */
+	uint16_t num_vnics;
+	/* The requested number of vnics for the function. */
+	uint16_t num_stat_ctxs;
+	/* The requested number of statistic contexts for the function. */
+	uint16_t num_hw_ring_grps;
 	/*
-	 * This is the speed that will be used if the force bit is '1'.
-	 * If unsupported speed is selected, an error will be generated.
+	 * The number of HW ring groups that should be reserved for this
+	 * function.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
+	uint8_t dflt_mac_addr[6];
+	/* The default MAC address for the function being configured. */
+	uint16_t dflt_vlan;
 	/*
-	 * This value is used to identify what autoneg mode is used when
-	 * the link speed is not being forced.
+	 * The default VLAN for the function being configured. This
+	 * field's format is same as 802.1Q Tag's Tag Control
+	 * Information	(TCI) format that includes both Priority Code
+	 * Point	(PCP) and VLAN Identifier	(VID).
 	 */
+	uint32_t dflt_ip_addr[4];
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * The default IP address for the function being configured.
+	 * This address is only used in enabling source property check.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	uint32_t min_bw;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Minimum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+	uint32_t max_bw;
+	/*
+	 * Maximum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK \
+		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous
+	 * event completions. If this field is not valid, then the HWRM
+	 * shall use the default completion ring of the function that is
+	 * being configured as the target completion ring for providing
+	 * any asynchronous event completions for that function. If this
+	 * field is valid, then the HWRM shall use the completion ring
+	 * identified by this ID as the target completion ring for
+	 * providing any asynchronous event completions for the function
+	 * that is being configured.
+	 */
+	uint8_t vlan_antispoof_mode;
+	/* VLAN Anti-spoofing mode. */
+	/* No VLAN anti-spoofing checks are enabled */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK	UINT32_C(0x0)
+	/* Validate VLAN against the configured VLAN(s) */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN \
+		UINT32_C(0x1)
+	/* Insert VLAN if it does not exist, otherwise discard */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_IF_VLANDNE \
+		UINT32_C(0x2)
 	/*
-	 * 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.
+	 * Insert VLAN if it does not exist, override
+	 * VLAN if it exists
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW	UINT32_C(0x3)
+	#define \
+	HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN \
+		UINT32_C(0x3)
+	uint8_t allowed_vlan_pris;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * This bit field defines VLAN PRIs that are allowed on this
+	 * function. If nth bit is set, then VLAN PRI n is allowed on
+	 * this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_duplex;
+	uint8_t evb_mode;
 	/*
-	 * This is the duplex setting that will be used if the
-	 * autoneg_mode is "one_speed" or "one_or_below".
+	 * The HWRM shall allow a PF driver to change EVB mode for the
+	 * partition it belongs to. The HWRM shall not allow a VF driver
+	 * to change the EVB mode. The HWRM shall take into account the
+	 * switching of EVB mode from one to another and reconfigure
+	 * hardware resources as appropriately. The switching from VEB
+	 * to VEPA mode requires the disabling of the loopback traffic.
+	 * Additionally, source knock outs are handled differently in
+	 * VEB and VEPA modes.
+	 */
+	/* No Edge Virtual Bridging	(EVB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
+	/* Virtual Ethernet Bridge	(VEB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEB	UINT32_C(0x1)
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA	UINT32_C(0x2)
+	uint8_t unused_2;
+	uint16_t num_mcast_filters;
+	/*
+	 * The number of multicast filters that should be reserved for
+	 * this function on the RX side.
 	 */
-	/* Half Duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
-	/* Both Half and Full dupex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
-	uint8_t auto_pause;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_cfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+} __attribute__((packed));
+
+/* hwrm_func_qstats */
+/*
+ * Description: This command returns statistics 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 HWRM shall return any unsupported counter with a value
+ * of 0xFFFFFFFF for 32-bit counters and 0xFFFFFFFFFFFFFFFF for 64-bit counters.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_qstats_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE	UINT32_C(0x4)
-	uint8_t unused_0;
-	uint16_t auto_link_speed;
+	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* This value controls the wirespeed feature. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* 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)
+	uint64_t resp_addr;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t fid;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Function ID of the function that is being queried. 0xFF...
+	 *	(All Fs) if the query is for the requesting function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(176 bytes) */
+struct hwrm_func_qstats_output {
+	uint16_t error_code;
 	/*
-	 * This value is used to configure the pause that will be used
-	 * for force mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
 	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets on the function. */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets on the function. */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets on the function. */
+	uint64_t tx_err_pkts;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of transmitted packets that were discarded due to
+	 * internal NIC resource problems. For transmit, this can only
+	 * happen if TMP is configured to allow dropping in HOL blocking
+	 * conditions, which is not a normal configuration.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	uint64_t tx_drop_pkts;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of dropped packets on transmit path on the function.
+	 * These are packets that have been marked for drop by the TE
+	 * CFA block or are packets that exceeded the transmit MTU limit
+	 * for the function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t unused_1;
-	uint32_t preemphasis;
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic on the function. */
+	uint64_t tx_mcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for multicast traffic on the
+	 * function.
 	 */
-	uint16_t eee_link_speed_mask;
+	uint64_t tx_bcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for broadcast traffic on the
+	 * function.
 	 */
-	/* 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)
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets on the function. */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets on the function. */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets on the function. */
+	uint64_t rx_err_pkts;
+	/*
+	 * Number of received packets that were discarded on the
+	 * function due to resource limitations. This can happen for 3
+	 * reasons. # The BD used for the packet has a bad format. #
+	 * There were no BDs available in the ring for the packet. #
+	 * There were no BDs available on-chip for the packet.
+	 */
+	uint64_t rx_drop_pkts;
+	/*
+	 * Number of dropped packets on received path on the function.
+	 * These are packets that have been marked for drop by the RE
+	 * CFA.
+	 */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic on the function. */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic on the function. */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic on the function. */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets on the function. */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes on the function. */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events on the function. */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations on the function. */
+	uint32_t unused_0;
+	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint32_t tx_lpi_timer;
-	uint32_t unused_4;
+	uint8_t valid;
 	/*
-	 * Reuested setting of TX LPI timer in microseconds. This field
-	 * is valid only when EEE is enabled and TX LPI is enabled.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK	UINT32_C(0xffffff)
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT	0
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_port_phy_cfg_output {
+/* hwrm_func_clr_stats */
+/*
+ * Description: This command clears statistics of a function. The input FID
+ * value is used to indicate what function's statistics is being cleared. This
+ * allows a physical function driver to clear statistics of virtual functions
+ * that are children of the physical function.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function. 0xFF...	(All Fs) if the query is
+	 * for the requesting function.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2949,10 +3715,10 @@ struct hwrm_port_phy_cfg_output {
 	 */
 } __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 {
+/* hwrm_func_vf_vnic_ids_query */
+/* Description: This command is used to query vf vnic ids. */
+/* Input	(32 bytes) */
+struct hwrm_func_vf_vnic_ids_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2979,13 +3745,21 @@ struct hwrm_port_phy_qcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint16_t port_id;
-	/* Port ID of port that is to be queried. */
-	uint16_t unused_0[3];
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_vnic_id_cnt;
+	/* Max number of vnic ids in vnic id table */
+	uint64_t vnic_id_tbl_addr;
+	/* This is the address for VF VNIC ID table */
 } __attribute__((packed));
 
-/* Output (96 bytes) */
-struct hwrm_port_phy_qcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_func_vf_vnic_ids_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3001,698 +3775,2769 @@ struct hwrm_port_phy_qcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t link;
-	/* 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)
-	/* There is no link, but a cable has been detected. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
-	/* There is a link. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t link_speed;
-	/* 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)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t duplex;
-	/* This value is indicates the duplex of the current connection. */
-	/* Half Duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
-	uint8_t pause;
+	uint32_t vnic_id_cnt;
 	/*
-	 * This value is used to indicate the current pause
-	 * configuration. When autoneg is enabled, this value represents
-	 * the autoneg results of pause configuration.
+	 * Actual number of vnic ids Each VNIC ID is written as a 32-bit
+	 * number.
 	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX	UINT32_C(0x1)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX	UINT32_C(0x2)
-	uint16_t support_speeds;
+	uint16_t cmpl_ring;
 	/*
-	 * 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)
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 enables;
+	/* 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_INPUT_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)
+	uint16_t os_type;
+	/*
+	 * This value indicates the type of OS. The values are based on
+	 * CIM_OperatingSystem.mof file as published by the DMTF.
+	 */
+	/* Unknown */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Other OS not listed below. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
+	/* MSDOS OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
+	/* Windows OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
+	/* Solaris OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
+	/* Linux OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
+	/* FreeBSD OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
+	/* VMware ESXi OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
+	/* Microsoft Windows 8 64-bit OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
+	/* Microsoft Windows Server 2012 R2 OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
+	uint8_t ver_maj;
+	/* This is the major version of the driver. */
+	uint8_t ver_min;
+	/* This is the minor version of the driver. */
+	uint8_t ver_upd;
+	/* This is the update version of the driver. */
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint32_t timestamp;
+	/*
+	 * This is a 32-bit timestamp provided by the driver for keep
+	 * alive. The timestamp is in multiples of 1ms.
+	 */
+	uint32_t unused_2;
+	uint32_t vf_req_fwd[8];
+	/*
+	 * 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 async_event_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.
+	 */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_rgtr */
+/*
+ * Description: This command is used by the PF driver to register buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * register buffers for each PF-VF channel. A parent PF may issue this command
+ * per child VF. If VF ID is not valid, then this command is used to register
+ * buffers for all children VFs of the PF.
+ */
+/* Input	(128 bytes) */
+struct hwrm_func_buf_rgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the err_buf_addr field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR	UINT32_C(0x2)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t req_buf_num_pages;
+	/*
+	 * This field represents the number of pages used for request
+	 * buffer(s).
+	 */
+	uint16_t req_buf_page_size;
+	/* This field represents the page size used for request buffer(s). */
+	/* 16 bytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_16B UINT32_C(0x4)
+	/* 4 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4K	UINT32_C(0xc)
+	/* 8 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_8K	UINT32_C(0xd)
+	/* 64 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_64K UINT32_C(0x10)
+	/* 2 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_2M	UINT32_C(0x15)
+	/* 4 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4M	UINT32_C(0x16)
+	/* 1 Gbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_1G	UINT32_C(0x1e)
+	uint16_t req_buf_len;
+	/* The length of the request buffer per VF in bytes. */
+	uint16_t resp_buf_len;
+	/* The length of the response buffer in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint64_t req_buf_page_addr[10];
+	/* This field represents the page address of req buffer. */
+	uint64_t error_buf_addr;
+	/*
+	 * This field is used to receive the error reporting from the
+	 * chipset. Only applicable for PFs.
+	 */
+	uint64_t resp_buf_addr;
+	/* This field is used to receive the response forwarded by the HWRM. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_unrgtr */
+/*
+ * Description: This command is used by the PF driver to unregister buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * unregister buffers for PF-VF communication. A parent PF may issue this
+ * command to unregister buffers for communication between the PF and a specific
+ * VF. If the VF ID is not valid, then this command is used to unregister
+ * buffers used for communications with all children VFs of the PF.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_buf_unrgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_UNRGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_vf_cfg */
+/*
+ * Description: This command allows configuration of a VF by its driver. If this
+ * function is called by a PF driver, then the HWRM shall fail this command. If
+ * guest VLAN and/or MAC address are provided in this command, then the HWRM
+ * shall set up appropriate MAC/VLAN filters for the VF that is being
+ * configured. A VF driver should set VF MTU/MRU using this command prior to
+ * allocating RX VNICs or TX rings for the corresponding VF.
+ */
+/* Input (32 bytes) */
+
+struct hwrm_func_vf_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_MTU                 UINT32_C(0x1)
+	/* This bit must be '1' for the guest_vlan field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_GUEST_VLAN          UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be configured.
+	 */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR      UINT32_C(0x4)
+	/* This bit must be '1' for the dflt_mac_addr field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR       UINT32_C(0x8)
+	uint16_t mtu;
+	/*
+	 * The maximum transmission unit requested on the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed the mtu
+	 * of the physical port that this function is associated with. In
+	 * addition to requesting mtu per function, it is possible to configure
+	 * mtu per transmit ring. By default, the mtu of each transmit ring
+	 * associated with a function is equal to the mtu of the function. The
+	 * HWRM should make sure that the mtu of each transmit ring that is
+	 * assigned to a function has a valid mtu.
+	 */
+	uint16_t guest_vlan;
+	/*
+	 * The guest VLAN for the function being configured. This field's format
+	 * is same as 802.1Q Tag's Tag Control Information (TCI) format that
+	 * includes both Priority Code Point (PCP) and VLAN Identifier (VID).
+	 */
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous event
+	 * completions. If this field is not valid, then the HWRM shall use the
+	 * default completion ring of the function that is being configured as
+	 * the target completion ring for providing any asynchronous event
+	 * completions for that function. If this field is valid, then the HWRM
+	 * shall use the completion ring identified by this ID as the target
+	 * completion ring for providing any asynchronous event completions for
+	 * the function that is being configured.
+	 */
+	uint8_t dflt_mac_addr[6];
+	/*
+	 * This value is the current MAC address requested by the VF driver to
+	 * be configured on this VF. A value of 00-00-00-00-00-00 indicates no
+	 * MAC address configuration is requested by the VF driver. The parent
+	 * PF driver may reject or overwrite this MAC address.
+	 */
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_vf_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* deprecated bit. Do not use!!! */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_DEPRECATED	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_ENABLE	UINT32_C(0x40)
+	/*
+	 * When this bit is set to '1' and EEE is enabled on this link,
+	 * then TX LPI is requested to be disabled 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_DISABLE UINT32_C(0x80)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC
+	 * autonegotitation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE UINT32_C(0x100)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC
+	 * autonegotiation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	\
+		UINT32_C(0x200)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74	(Fire
+	 * Code) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	\
+		UINT32_C(0x400)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
+	 *	(Fire Code) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 74 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	\
+		UINT32_C(0x800)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91	(Reed
+	 * Solomon) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	\
+		UINT32_C(0x1000)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
+	 *	(Reed Solomon) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 91 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	\
+		UINT32_C(0x2000)
+	/*
+	 * 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_DWN UINT32_C(0x4000)
+	uint32_t enables;
+	/* 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_WIOUTPUTEED	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)
+	uint16_t port_id;
+	/* Port ID of port that is to be configured. */
+	uint16_t force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_duplex;
+	/*
+	 * 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)
+	/* Full duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
+	/* Both Half and Full dupex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
+	uint8_t auto_pause;
+	/*
+	 * 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 unused_0;
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* This value controls the wirespeed feature. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 unused_1;
+	uint32_t preemphasis;
+	/*
+	 * 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.
+	 */
+	uint16_t eee_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t tx_lpi_timer;
+	uint32_t unused_4;
+	/*
+	 * 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
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_phy_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is to be queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(96 bytes) */
+struct hwrm_port_phy_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t link;
+	/* 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)
+	/* There is no link, but a cable has been detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
+	/* There is a link. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
+	uint8_t unused_0;
+	uint16_t link_speed;
+	/* 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t duplex;
+	/* This value is indicates the duplex of the current connection. */
+	/* Half Duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
+	/* Full duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
+	uint8_t pause;
+	/*
+	 * 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)
+	uint16_t support_speeds;
+	/*
+	 * 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 force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/* 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_pause;
+	/*
+	 * 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)
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* Current setting for wirespeed. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* Current setting for loopback. */
+	/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 module_status;
+	/*
+	 * 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)
+	/* Module is rejected and transmit side Laser is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX UINT32_C(0x1)
+	/* Module mismatch warning. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG UINT32_C(0x2)
+	/* Module is rejected and powered down. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
+	/* Module is not inserted. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+		UINT32_C(0x4)
+	/* Module status is not applicable. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+		UINT32_C(0xff)
+	uint32_t preemphasis;
+	/* Current setting for preemphasis. */
+	uint8_t phy_maj;
+	/* This field represents the major version of the PHY. */
+	uint8_t phy_min;
+	/* This field represents the minor version of the PHY. */
+	uint8_t phy_bld;
+	/* This field represents the build version of the PHY. */
+	uint8_t phy_type;
+	/* This value represents a PHY type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* BASE-CR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
+	/* BASE-KR4	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
+	/* BASE-LR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
+	/* BASE-SR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
+	/* BASE-KR2	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
+	/* BASE-KX */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
+	/* BASE-KR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
+	/* BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
+	/* EEE capable BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
+	/* SGMII connected external PHY */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
+	/* 25G_BASECR_CA_L */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L UINT32_C(0xb)
+	/* 25G_BASECR_CA_S */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S UINT32_C(0xc)
+	/* 25G_BASECR_CA_N */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N UINT32_C(0xd)
+	/* 25G_BASESR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR	UINT32_C(0xe)
+	/* 100G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4	UINT32_C(0xf)
+	/* 100G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4	UINT32_C(0x10)
+	/* 100G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4	UINT32_C(0x11)
+	/* 100G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4	UINT32_C(0x12)
+	/* 100G_BASESR10 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10 UINT32_C(0x13)
+	/* 40G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4	UINT32_C(0x14)
+	/* 40G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4	UINT32_C(0x15)
+	/* 40G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4	UINT32_C(0x16)
+	/* 40G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4	UINT32_C(0x17)
+	/* 40G_ACTIVE_CABLE */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE \
+		UINT32_C(0x18)
+	uint8_t media_type;
+	/* This value represents a media type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Twisted Pair */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
+	/* Direct Attached Copper */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
+	/* Fiber */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
+	uint8_t xcvr_pkg_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)
+	/* PHY and MAC are in different packages */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+		UINT32_C(0x2)
+	uint8_t eee_config_phy_addr;
+	/*
+	 * 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 parallel_detect;
+	/* 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
+	uint16_t link_partner_adv_speeds;
+	/*
+	 * 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_SUPPORT_SPEEDS_2GB	UINT32_C(0x10)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB	\
+		UINT32_C(0x10)
 	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB	UINT32_C(0x20)
+	#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)
+	uint8_t link_partner_adv_auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t link_partner_adv_pause;
+	/* 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)
+	uint16_t adv_eee_link_speed_mask;
+	/*
+	 * 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 link_partner_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_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 force_link_speed;
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+		UINT32_C(0x40)
+	uint32_t xcvr_identifier_type_tx_lpi_timer;
+	/* 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)
+	uint16_t fec_cfg;
+	/*
+	 * This value represents the current configuration of Forward
+	 * Error Correction	(FEC) on the port.
+	 */
+	/*
+	 * When set to 1, then FEC is not supported on this port. If
+	 * this flag is set to 1, then all other FEC configuration flags
+	 * shall be ignored. When set to 0, then FEC is supported as
+	 * indicated by other configuration flags. If no cable is
+	 * attached and the HWRM does not yet know the FEC capability,
+	 * then the HWRM shall set this flag to 1 when reporting FEC
+	 * capability.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	 \
+		UINT32_C(0x1)
+	/*
+	 * When set to 1, then FEC autonegotiation is supported on this
+	 * port. When set to 0, then FEC autonegotiation is not
+	 * supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
+		UINT32_C(0x2)
+	/*
+	 * When set to 1, then FEC autonegotiation is enabled on this
+	 * port. When set to 0, then FEC autonegotiation is disabled if
+	 * supported. This flag should be ignored if FEC autonegotiation
+	 * is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
+		UINT32_C(0x4)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is supported on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
+		UINT32_C(0x8)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is enabled on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * disabled if supported. This flag should be ignored if FEC
+	 * CLAUSE 74 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
+		UINT32_C(0x10)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is supported
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
+		UINT32_C(0x20)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is enabled
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is disabled if supported. This flag should be
+	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
+		UINT32_C(0x40)
+	uint8_t unused_1;
+	uint8_t unused_2;
+	char phy_vendor_name[16];
+	/*
+	 * 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_partnumber[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.
+	 */
+	uint32_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_qstats */
+/* Description: This function returns per port Ethernet statistics. */
+/* Input	(40 bytes) */
+struct hwrm_port_qstats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2[3];
+	uint8_t unused_3;
+	uint64_t tx_stat_host_addr;
+	/* This is the host address where Tx port statistics will be stored */
+	uint64_t rx_stat_host_addr;
+	/* This is the host address where Rx port statistics will be stored */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_qstats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tx_stat_size;
+	/* The size of TX port statistics block in bytes. */
+	uint16_t rx_stat_size;
+	/* The size of RX port statistics block in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_clr_stats */
+/*
+ * Description: This function clears per port statistics. The HWRM shall not
+ * allow a VF driver to clear port statistics. The HWRM shall not allow a PF
+ * driver to clear port statistics in a partitioning mode. The HWRM may allow a
+ * PF driver to clear port statistics in the non-partitioning mode.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* rx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+	uint16_t port_id;
+	/*
+	 * Port ID of port for which the queue configuration is being
+	 * queried. This field is only required when sent by IPC.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_queue_qportcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t max_configurable_queues;
+	/*
+	 * The maximum number of queues that can be configured on this
+	 * port. Valid values range from 1 through 8.
+	 */
+	uint8_t max_configurable_lossless_queues;
+	/*
+	 * The maximum number of lossless queues that can be configured
+	 * on this port. Valid values range from 0 through 8.
+	 */
+	uint8_t queue_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_cfg command. Each bit represents a specific queue
+	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
+	 * # A value of 0 indicates that the queue is not configurable
+	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
+	 * the queue is configurable. # A hwrm_queue_cfg command shall
+	 * return error when trying to configure a queue not
+	 * configurable.
+	 */
+	uint8_t queue_cfg_info;
+	/* Information about queue configuration. */
+	/*
+	 * If this flag is set to '1', then the queues are configured
+	 * asymmetrically on TX and RX sides. If this flag is set to
+	 * '0', then the queues are configured symmetrically on TX and
+	 * RX sides. For symmetric configuration, the queue
+	 * configuration including queue ids and service profiles on the
+	 * TX side is the same as the corresponding queue configuration
+	 * on the RX side.
+	 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG UINT32_C(0x1)
+	uint8_t queue_pfcenable_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
+	 * specific priority where bit 0 represents priority 0 and bit 7
+	 * represents priority 7. # A value of 0 indicates that the
+	 * priority is not configurable by the hwrm_queue_pfcenable_cfg
+	 * command. # A value of 1 indicates that the priority is
+	 * configurable. # A hwrm_queue_pfcenable_cfg command shall
+	 * return error when trying to configure a priority that is not
+	 * configurable.
+	 */
+	uint8_t queue_pri2cos_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue that is not configurable.
+	 */
+	uint8_t queue_cos2bw_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue not configurable.
+	 */
+	uint8_t queue_id0;
+	/*
+	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id0_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id1;
+	/*
+	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id1_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id2;
+	/*
+	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id2_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id3;
+	/*
+	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id3_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id4;
+	/*
+	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id4_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id5;
+	/*
+	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id5_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * Current setting of forced link speed. When the link speed is
-	 * not being forced, this value shall be set to 0.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB	\
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id6;
+	/*
+	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	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)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB	\
-		UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB	\
-		UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
-	/* Current setting of auto negotiation mode. */
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id7;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	uint8_t queue_id7_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * 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.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW	\
-		UINT32_C(0x3)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_pause;
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Current setting of pause autonegotiation. Move autoneg_pause
-	 * flag here.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE	\
-		UINT32_C(0x4)
-	uint16_t auto_link_speed;
+	uint32_t flags;
 	/*
-	 * Current setting for auto_link_speed. This field is only valid
-	 * when auto_mode is set to "one_speed" or "one_or_below".
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_free_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+} __attribute__((packed));
+
+/* hwrm_vnic_cfg */
+/* Description: Configure the RX VNIC structure. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_cfg_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* Current setting for wirespeed. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* Current setting for loopback. */
-	/* No loopback is selected. Normal operation. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	uint16_t cmpl_ring;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint64_t resp_addr;
 	/*
-	 * Current setting of forced pause. When the pause configuration
-	 * is not being forced, then this value shall be set to 0.
+	 * 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.
 	 */
+	uint32_t flags;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * When this bit is '1', the VNIC is requested to be the default
+	 * VNIC for the function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t module_status;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * This value indicates the current status of the optics module
-	 * on this port.
+	 * 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.
 	 */
-	/* Module is inserted and accepted */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE	UINT32_C(0x0)
-	/* Module is rejected and transmit side Laser is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX	\
-		UINT32_C(0x1)
-	/* Module mismatch warning. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG	\
-		UINT32_C(0x2)
-	/* Module is rejected and powered down. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
-	/* Module is not inserted. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED	\
-		UINT32_C(0x4)
-	/* Module status is not applicable. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE	\
-		UINT32_C(0xff)
-	uint32_t preemphasis;
-	/* Current setting for preemphasis. */
-	uint8_t phy_maj;
-	/* This field represents the major version of the PHY. */
-	uint8_t phy_min;
-	/* This field represents the minor version of the PHY. */
-	uint8_t phy_bld;
-	/* This field represents the build version of the PHY. */
-	uint8_t phy_type;
-	/* This value represents a PHY type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* BASE-CR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
-	/* BASE-KR4 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
-	/* BASE-LR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
-	/* BASE-SR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
-	/* BASE-KR2 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
-	/* BASE-KX */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
-	/* BASE-KR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
-	/* BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
-	/* EEE capable BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
-	/* SGMII connected external PHY */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
-	uint8_t media_type;
-	/* This value represents a media type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Twisted Pair */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
-	/* Direct Attached Copper */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
-	/* Fiber */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
-	uint8_t xcvr_pkg_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)
-	/* PHY and MAC are in different packages */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL	\
-		UINT32_C(0x2)
-	uint8_t eee_config_phy_addr;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * 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).
+	 * 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.
 	 */
-	/* 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
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * 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_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED	\
-		UINT32_C(0x20)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. This flag is used to enable a mode where RSS is enabled
+	 * in the VNIC using a RSS context for computing RSS hash but
+	 * the RSS indirection table is not configured using
+	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
+	 * should not program RSS indirection table for the RSS context
+	 * that is used for computing RSS hash only.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE	UINT32_C(0x40)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t enables;
 	/*
-	 * 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.
+	 * This bit must be '1' for the dflt_ring_grp field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI	UINT32_C(0x80)
+	#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)
+	uint16_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t dflt_ring_grp;
 	/*
-	 * 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).
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK	UINT32_C(0xe0)
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT	5
-	uint8_t parallel_detect;
-	/* Reserved field, set to 0 */
+	uint16_t rss_rule;
 	/*
-	 * 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.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#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
-	uint16_t link_partner_adv_speeds;
+	uint16_t cos_rule;
 	/*
-	 * The advertised speeds for the port by the link partner. Each
-	 * advertised speed will be set to '1'.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	/* 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)
-	uint8_t link_partner_adv_auto_mode;
+	uint16_t lb_rule;
 	/*
-	 * The advertised autoneg for the port by the link partner. This
-	 * field is deprecated and should be set to 0.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
+	uint16_t mru;
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
-		UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
-	UINT32_C(0x1)
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_cfg_output {
+	uint16_t error_code;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
-		UINT32_C(0x2)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
-	UINT32_C(0x3)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK \
-	UINT32_C(0x4)
-	uint8_t link_partner_adv_pause;
-	/* The advertised pause settings on the port by the link partner. */
+} __attribute__((packed));
+
+/* hwrm_vnic_qcfg */
+/*
+ * Description: Query the RX VNIC structure. This function can be used by a PF
+ * driver to query its own VNIC resource or VNIC resource of its child VF. This
+ * function can also be used by a VF driver to query its own VNIC resource.
+ */
+/* Input	(32 bytes) */
+struct hwrm_vnic_qcfg_input {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX	\
-		UINT32_C(0x1)
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX	\
-		UINT32_C(0x2)
-	uint16_t adv_eee_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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 link_partner_adv_eee_link_speed_mask;
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 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)
-	uint32_t xcvr_identifier_type_tx_lpi_timer;
-	/* This value represents transceiver identifier type. */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID	UINT32_C(0x1)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t vf_id;
+	/* ID of Virtual Function whose VNIC resource is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_vnic_qcfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#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)
-	uint16_t fec_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This value represents the current configuration of Forward
-	 * Error Correction (FEC) on the port.
+	 * 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 dflt_ring_grp;
+	/* Default Completion ring for the VNIC. */
+	uint16_t rss_rule;
 	/*
-	 * When set to 1, then FEC is not supported on this port. If
-	 * this flag is set to 1, then all other FEC configuration flags
-	 * shall be ignored. When set to 0, then FEC is supported as
-	 * indicated by other configuration flags. If no cable is
-	 * attached and the HWRM does not yet know the FEC capability,
-	 * then the HWRM shall set this flag to 1 when reporting FEC
-	 * capability.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	\
-		UINT32_C(0x1)
+	uint16_t cos_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is supported on this
-	 * port. When set to 0, then FEC autonegotiation is not
-	 * supported on this port.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
-		UINT32_C(0x2)
+	uint16_t lb_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is enabled on this
-	 * port. When set to 0, then FEC autonegotiation is disabled if
-	 * supported. This flag should be ignored if FEC autonegotiation
-	 * is not supported on this port.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
-		UINT32_C(0x4)
+	uint16_t mru;
+	/* The maximum receive unit of the vnic. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t flags;
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is supported on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * not supported on this port.
+	 * When this bit is '1', the VNIC is the default VNIC for the
+	 * function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
-		UINT32_C(0x8)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is enabled on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * disabled if supported. This flag should be ignored if FEC
-	 * CLAUSE 74 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled
+	 * on this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
-		UINT32_C(0x10)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is supported
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to buffer
+	 * receive packets in the hardware until the host posts new
+	 * receive buffers. If set to '0', then bd_stall is disabled on
+	 * this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
-		UINT32_C(0x20)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is enabled
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is disabled if supported. This flag should be
-	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is
+	 * not configured to operate in dual VNIC mode.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
-		UINT32_C(0x40)
-	uint8_t unused_1;
-	uint8_t unused_2;
-	char phy_vendor_name[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * When this flag is set to '1', the VNIC is configured to
+	 * receive only RoCE traffic. When this flag is set to '0', the
+	 * VNIC is not configured to receive only RoCE traffic. If
+	 * roce_dual_vnic_mode flag and this flag both are set to '1',
+	 * then it is an invalid configuration of the VNIC. The HWRM
+	 * should not allow that type of mis-configuration by HWRM
+	 * clients.
 	 */
-	char phy_vendor_partnumber[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. When this bit is set to '1', then the VNIC is enabled
+	 * in a mode where RSS is enabled in the VNIC using a RSS
+	 * context for computing RSS hash but the RSS indirection table
+	 * is not configured.
 	 */
-	uint32_t unused_3;
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t unused_2;
+	uint8_t unused_3;
 	uint8_t unused_4;
 	uint8_t unused_5;
-	uint8_t unused_6;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -3704,19 +6549,10 @@ struct hwrm_port_phy_qcfg_output {
 	 */
 } __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 {
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+/* Input	(48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -3743,29 +6579,53 @@ struct hwrm_queue_qportcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t hash_type;
 	/*
-	 * 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.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source and destination IPv4 addresses of IPv4 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX	UINT32_C(0x0)
-	/* rx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST	\
-		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
-	uint16_t port_id;
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4	UINT32_C(0x1)
 	/*
-	 * Port ID of port for which the queue configuration is being
-	 * queried. This field is only required when sent by IPC.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination
+	 * ports of TCP/IPv4 packets.
 	 */
-	uint16_t unused_0;
+	#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 unused_0;
+	uint64_t ring_grp_tbl_addr;
+	/* This is the address for rss ring group table */
+	uint64_t hash_key_tbl_addr;
+	/* This is the address for rss hash key table */
+	uint16_t rss_ctx_idx;
+	/* Index to the rss indirection table. */
+	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (32 bytes) */
-struct hwrm_queue_qportcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3781,265 +6641,363 @@ struct hwrm_queue_qportcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t max_configurable_queues;
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * The maximum number of queues that can be configured on this
-	 * port. Valid values range from 1 through 8.
+	 * 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 max_configurable_lossless_queues;
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_cfg */
+/*
+ * Description: This function can be used to set placement mode configuration of
+ * the VNIC.
+ */
+/* Input (40 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_input {
+	uint16_t req_type;
 	/*
-	 * The maximum number of lossless queues that can be configured
-	 * on this port. Valid values range from 0 through 8.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
-	uint8_t queue_cfg_allowed;
+	uint16_t cmpl_ring;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_cfg command. Each bit represents a specific queue
-	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
-	 * # A value of 0 indicates that the queue is not configurable
-	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
-	 * the queue is configurable. # A hwrm_queue_cfg command shall
-	 * return error when trying to configure a queue not
-	 * configurable.
+	 * 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.
 	 */
-	uint8_t queue_cfg_info;
-	/* Information about queue configuration. */
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * If this flag is set to '1', then the queues are configured
-	 * asymmetrically on TX and RX sides. If this flag is set to
-	 * '0', then the queues are configured symmetrically on TX and
-	 * RX sides. For symmetric configuration, the queue
-	 * configuration including queue ids and service profiles on the
-	 * TX side is the same as the corresponding queue configuration
-	 * on the RX side.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to use regular
+	 * placement algorithm. By default, the regular placement algorithm
+	 * shall be enabled on the VNIC.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG	\
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
-	uint8_t queue_pfcenable_cfg_allowed;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pfcenable_cfg command.
-	 * # A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pfcenable_cfg command shall return error when
-	 * trying to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured use the jumbo
+	 * placement algorithm.
 	 */
-	uint8_t queue_pri2cos_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv4 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv4, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv4, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv4 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv4 packet.
 	 */
-	uint8_t queue_cos2bw_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4        UINT32_C(0x4)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv6 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv6, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv6, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv6 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv6 packet.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6        UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for FCoE packets at the beginning of FC payload.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_FCOE       UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for RoCE packets at the beginning of RoCE payload (after
+	 * BTH/GRH headers).
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_ROCE       UINT32_C(0x20)
+	uint32_t enables;
+	/*
+	 * This bit must be '1' for the jumbo_thresh_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID \
+		UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the hds_offset_valid field to be configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID \
+		UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the hds_threshold_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID \
+		UINT32_C(0x4)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t jumbo_thresh;
+	/*
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
+	 */
+	uint16_t hds_offset;
+	/*
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
+	 */
+	uint16_t hds_threshold;
+	/*
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_qcfg */
+/*
+ * Description: This function can be used to query placement mode configuration
+ * of the VNIC.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
-	uint8_t queue_id0;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id0_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC is configured to use regular placement
+	 * algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to use the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id1;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv4 packets.
 	 */
-	uint8_t queue_id1_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV4      UINT32_C(0x4)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv6 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id2;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV6      UINT32_C(0x8)
 	/*
-	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for FCoE packets.
 	 */
-	uint8_t queue_id2_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_FCOE     UINT32_C(0x10)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for RoCE packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id3;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_ROCE     UINT32_C(0x20)
 	/*
-	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to be the default VNIC
+	 * of the requesting function.
 	 */
-	uint8_t queue_id3_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC    UINT32_C(0x40)
+	uint16_t jumbo_thresh;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id4;
+	uint16_t hds_offset;
 	/*
-	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
 	 */
-	uint8_t queue_id4_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t hds_threshold;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id5;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t valid;
 	/*
-	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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 queue_id5_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_alloc */
+/* Description: This function is used to allocate COS/Load Balance context. */
+/* Input	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+	uint16_t req_type;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id6;
+	uint16_t cmpl_ring;
 	/*
-	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	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)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id7;
+	uint64_t resp_addr;
 	/*
-	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id7_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+	uint16_t error_code;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4051,25 +7009,10 @@ struct hwrm_queue_qportcfg_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4096,17 +7039,13 @@ struct hwrm_vnic_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 unused_0;
+	uint16_t rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4122,11 +7061,10 @@ struct hwrm_vnic_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t vnic_id;
-	/* Logical vnic ID */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4134,18 +7072,14 @@ struct hwrm_vnic_alloc_output {
 	 * 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.
-	 */
-} __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 field is written last.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_tpa_cfg */
+/* Description: This function is used to enable/configure TPA on the VNIC. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_tpa_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4172,13 +7106,122 @@ struct hwrm_vnic_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of non-tunneled TCP
+	 * packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of tunneled TCP packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Windows
+	 * Receive Segment Coalescing	(RSC) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Linux
+	 * Generic Receive Offload	(GRO) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for TCP packets with IP
+	 * ECN set to non-zero.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for GRE tunneled TCP
+	 * packets only if all packets have the same GRE sequence.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ	\
+		UINT32_C(0x20)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP/IPv4 packets with consecutively increasing
+	 * IPIDs. In other words, the last packet that is being
+	 * aggregated to an already existing aggregation context shall
+	 * have IPID 1 more than the IPID of the last packet that was
+	 * aggregated in that aggregation context.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_IPID_CHECK	UINT32_C(0x40)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP packets with the same TTL	(IPv4) or Hop limit
+	 *	(IPv6) value.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_TTL_CHECK	UINT32_C(0x80)
+	uint32_t enables;
+	/* This bit must be '1' for the max_agg_segs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS	UINT32_C(0x1)
+	/* This bit must be '1' for the max_aggs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS	UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the max_agg_timer field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER	UINT32_C(0x4)
+	/* This bit must be '1' for the min_agg_len field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN	UINT32_C(0x8)
+	uint16_t vnic_id;
 	/* Logical vnic ID */
-	uint32_t unused_0;
+	uint16_t max_agg_segs;
+	/*
+	 * This is the maximum number of TCP segments that can be
+	 * aggregated	(unit is Log2). Max value is 31.
+	 */
+	/* 1 segment */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1	UINT32_C(0x0)
+	/* 2 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2	UINT32_C(0x1)
+	/* 4 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4	UINT32_C(0x2)
+	/* 8 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8	UINT32_C(0x3)
+	/* Any segment size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX	UINT32_C(0x1f)
+	uint16_t max_aggs;
+	/*
+	 * This is the maximum number of aggregations this VNIC is
+	 * allowed	(unit is Log2). Max value is 7
+	 */
+	/* 1 aggregation */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1	UINT32_C(0x0)
+	/* 2 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2	UINT32_C(0x1)
+	/* 4 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4	UINT32_C(0x2)
+	/* 8 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8	UINT32_C(0x3)
+	/* 16 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16	UINT32_C(0x4)
+	/* Any aggregation size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX	UINT32_C(0x7)
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_agg_timer;
+	/*
+	 * This is the maximum amount of time allowed for an aggregation
+	 * context to complete after it was initiated.
+	 */
+	uint32_t min_agg_len;
+	/*
+	 * This is the minimum amount of payload length required to
+	 * start an aggregation context.
+	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_free_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_tpa_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4209,10 +7252,13 @@ struct hwrm_vnic_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_cfg */
-/* Description: Configure the RX VNIC structure. */
-/* Input (40 bytes) */
-struct hwrm_vnic_cfg_input {
+
+/* hwrm_ring_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a ring.
+ */
+/* Input	(80 bytes) */
+struct hwrm_ring_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4239,103 +7285,295 @@ struct hwrm_vnic_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t enables;
+	/* 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 ring_arb_cfg field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
 	/*
-	 * When this bit is '1', the VNIC is requested to be the default
-	 * VNIC for the function.
+	 * This bit must be '1' for the stat_ctx_id_valid field to be
+	 * configured.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
+	#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)
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint64_t page_tbl_addr;
+	/* This value is a pointer to the page table for the Ring. */
+	uint32_t fbo;
+	/* First Byte Offset of the first entry in the first page. */
+	uint8_t page_size;
 	/*
-	 * 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.
+	 * 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. - 21 = 2
+	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
+	 * GB Page size is 1 GB.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	uint8_t page_tbl_depth;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t length;
 	/*
-	 * 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.
+	 * Number of 16B units in the ring. Minimum size for a ring is
+	 * 16 16B entries.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	uint16_t logical_id;
 	/*
-	 * 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'.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	uint16_t cmpl_ring_id;
 	/*
-	 * When a VNIC uses one destination ring group for certain
-	 * application (e.g. Receive Flow Steering) where exact match is
-	 * used to direct packets to a VNIC with one destination ring
-	 * group only, there is no need to configure RSS indirection
-	 * table for that VNIC as only one destination ring group is
-	 * used. This flag is used to enable a mode where RSS is enabled
-	 * in the VNIC using a RSS context for computing RSS hash but
-	 * the RSS indirection table is not configured using
-	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
-	 * should not program RSS indirection table for the RSS context
-	 * that is used for computing RSS hash only.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what completion ring the TX ring is
+	 * associated with.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
-	uint32_t enables;
+	uint16_t queue_id;
 	/*
-	 * This bit must be '1' for the dflt_ring_grp field to be
-	 * configured.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what CoS queue the TX ring is associated
+	 * with.
 	 */
-	#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)
-	uint16_t vnic_id;
-	/* Logical vnic ID */
-	uint16_t dflt_ring_grp;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint32_t reserved1;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint16_t ring_arb_cfg;
+	/*
+	 * This field is used only when ring_type is a TX ring. This
+	 * field is used to configure arbitration related parameters for
+	 * a TX ring.
+	 */
+	/* Arbitration policy used for the ring. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK UINT32_C(0xf)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	/*
+	 * Use strict priority for the TX ring. Priority
+	 * value is specified in arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP \
+		(UINT32_C(0x1) << 0)
+	/*
+	 * Use weighted fair queue arbitration for the
+	 * TX ring. Weight is specified in
+	 * arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ \
+		(UINT32_C(0x2) << 0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST \
+		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
+	/* Reserved field. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	/*
+	 * Arbitration policy specific parameter. # For strict priority
+	 * arbitration policy, this field represents a priority value.
+	 * If set to 0, then the priority is not specified and the HWRM
+	 * is allowed to select any priority for this TX ring. # For
+	 * weighted fair queue arbitration policy, this field represents
+	 * a weight value. If set to 0, then the weight is not specified
+	 * and the HWRM is allowed to select any weight for this TX
+	 * ring.
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
+		UINT32_C(0xff00)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT	8
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint32_t reserved3;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t stat_ctx_id;
+	/*
+	 * 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 reserved4;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t max_bw;
+	/*
+	 * This field is used only when ring_type is a TX ring to
+	 * specify maximum BW allocated to the TX ring. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for this ring inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES (UINT32_C(0x1) << 28)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_LAST \
+		RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
+		UINT32_C(0xe0000000)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint8_t int_mode;
+	/*
+	 * 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)
+	/* Reserved */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
+	/* MSI-X */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
+	/* No Interrupt - Polled mode */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
+	uint8_t unused_8[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_ring_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 ring_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.
+	 * Physical number of ring allocated. This value shall be unique
+	 * for a ring type.
 	 */
-	uint16_t rss_rule;
+	uint16_t logical_ring_id;
+	/* Logical number of ring allocated. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
-	 * there is no RSS rule.
+	 * 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.
 	 */
-	uint16_t cos_rule;
+} __attribute__((packed));
+
+/* hwrm_ring_free */
+/*
+ * Description: This command is used to free a ring and associated resources.
+ * With QoS and DCBx agents, it is possible the traffic classes will be moved
+ * from one CoS queue to another. When this occurs, the driver shall call
+ * 'hwrm_ring_free' to free the allocated rings and then call 'hwrm_ring_alloc'
+ * to re-allocate each ring and assign it to a new CoS queue. hwrm_ring_free
+ * shall be called on a ring only after it has been idle for 500ms or more and
+ * no frames have been posted to the ring during this time. All frames queued
+ * for transmission shall be completed and at least 500ms time elapsed from the
+ * last completion before calling this command.
+ */
+/* Input	(24 bytes) */
+struct hwrm_ring_free_input {
+	uint16_t req_type;
 	/*
-	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
-	 * there is no COS rule.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	uint16_t lb_rule;
+	uint16_t cmpl_ring;
 	/*
-	 * RSS ID for load balancing rule/table structure. 0xFF... (All
-	 * Fs) if there is no LB rule.
+	 * 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 mru;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t unused_0;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t ring_id;
+	/* Physical number of ring allocated. */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4366,10 +7604,12 @@ struct hwrm_vnic_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cfg */
-/* Description: This function is used to enable RSS configuration. */
-/* Input (48 bytes) */
-struct hwrm_vnic_rss_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4396,53 +7636,25 @@ struct hwrm_vnic_rss_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t hash_type;
-	/*
-	 * 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)
+	uint16_t cr;
+	/* This value identifies the CR associated with the ring group. */
+	uint16_t rr;
+	/* This value identifies the main RR associated with the ring group. */
+	uint16_t ar;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of TCP/IPv6 packets.
+	 * 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.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
+	uint16_t sc;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of UDP/IPv6 packets.
+	 * This value identifies the statistics context associated with
+	 * the ring group.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6	UINT32_C(0x20)
-	uint32_t unused_0;
-	uint64_t ring_grp_tbl_addr;
-	/* This is the address for rss ring group table */
-	uint64_t hash_key_tbl_addr;
-	/* This is the address for rss hash key table */
-	uint16_t rss_ctx_idx;
-	/* Index to the rss indirection table. */
-	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4458,10 +7670,15 @@ struct hwrm_vnic_rss_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t ring_group_id;
+	/*
+	 * 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.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4473,10 +7690,17 @@ struct hwrm_vnic_rss_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cos_lb_ctx_alloc */
-/* Description: This function is used to allocate COS/Load Balance context. */
-/* Input (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4503,10 +7727,13 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint32_t ring_group_id;
+	/* This is the ring group ID value. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4522,13 +7749,10 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4540,10 +7764,64 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4556,269 +7834,355 @@ struct hwrm_vnic_rss_cos_lb_ctx_free_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 \
+		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 enables;
+	/* 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)
+	uint8_t l2_addr[6];
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the match value for the L2 MAC address.
+	 * Destination MAC address for RX path. Source MAC address for
+	 * TX path.
 	 */
-	uint64_t resp_addr;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t l2_addr_mask[6];
 	/*
-	 * 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.
+	 * This value sets the mask value for the L2 address. A value of
+	 * 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint16_t unused_0[3];
-} __attribute__((packed));
-
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_free_output {
-	uint16_t error_code;
+	uint16_t l2_ovlan;
+	/* This value sets VLAN ID value for outer VLAN. */
+	uint16_t l2_ovlan_mask;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * This value sets the mask value for the ovlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
+	uint16_t l2_ivlan;
+	/* This value sets VLAN ID value for inner VLAN. */
+	uint16_t l2_ivlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the ivlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t valid;
+	uint8_t t_l2_addr[6];
 	/*
-	 * 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.
+	 * This value sets the match value for the tunnel L2 MAC
+	 * address. Destination MAC address for RX path. Source MAC
+	 * address for TX path.
 	 */
-} __attribute__((packed));
-
-/* hwrm_ring_alloc */
-/*
- * Description: This command allocates and does basic preparation for a ring.
- */
-/* Input (80 bytes) */
-struct hwrm_ring_alloc_input {
-	uint16_t req_type;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t t_l2_addr_mask[6];
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value sets the mask value for the tunnel L2 address. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t cmpl_ring;
+	uint16_t t_l2_ovlan;
+	/* This value sets VLAN ID value for tunnel outer VLAN. */
+	uint16_t t_l2_ovlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the tunnel ovlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t t_l2_ivlan;
+	/* This value sets VLAN ID value for tunnel inner VLAN. */
+	uint16_t t_l2_ivlan_mask;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the mask value for the tunnel ivlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint64_t resp_addr;
+	uint8_t src_type;
+	/* 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)
+	/* Physical function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
+	/* Virtual function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
+	/* Virtual NIC of a function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
+	/* Embedded processor for CFA management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
+	/* Embedded processor for OOB management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
+	/* Embedded processor for RoCE */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
+	/* Embedded processor for network proxy functions */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
+	uint8_t unused_6;
+	uint32_t src_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.
+	 * 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 enables;
-	/* 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 ring_arb_cfg field to be configured. */
-	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Non-tunnel */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+		UINT32_C(0x0)
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
 	/*
-	 * This bit must be '1' for the stat_ctx_id_valid field to be
-	 * configured.
+	 * Network Virtualization Generic Routing
+	 * Encapsulation	(NVGRE)
 	 */
-	#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)
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint64_t page_tbl_addr;
-	/* This value is a pointer to the page table for the Ring. */
-	uint32_t fbo;
-	/* First Byte Offset of the first entry in the first page. */
-	uint8_t page_size;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+		UINT32_C(0x2)
 	/*
-	 * 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. - 21 = 2
-	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
-	 * GB Page size is 1 GB.
+	 * Generic Routing Encapsulation	(GRE) inside
+	 * Ethernet payload
 	 */
-	uint8_t page_tbl_depth;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE UINT32_C(0x3)
+	/* IP in IP */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	/* Multi-Protocol Lable Switching	(MPLS) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
+	/* Stateless Transport Tunnel	(STT) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
 	/*
-	 * 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.
+	 * Generic Routing Encapsulation	(GRE) inside IP
+	 * datagram payload
 	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint32_t length;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE UINT32_C(0x8)
+	/* Any tunneled traffic */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+		UINT32_C(0xff)
+	uint8_t unused_7;
+	uint16_t dst_id;
 	/*
-	 * Number of 16B units in the ring. Minimum size for a ring is
-	 * 16 16B entries.
+	 * 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 logical_id;
+	uint16_t mirror_vnic_id;
+	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
+	uint8_t pri_hint;
 	/*
-	 * 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.
+	 * This hint is provided to help in placing the filter in the
+	 * filter table.
 	 */
-	uint16_t cmpl_ring_id;
+	/* No preference */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+		UINT32_C(0x0)
+	/* Above the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+		UINT32_C(0x1)
+	/* Below the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+		UINT32_C(0x2)
+	/* As high as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
+	/* As low as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
+	uint8_t unused_8;
+	uint32_t unused_9;
+	uint64_t l2_filter_id_hint;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what completion ring the TX ring is
-	 * associated with.
+	 * 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
 	 */
-	uint16_t queue_id;
+} __attribute__((packed));
+
+/* Output	(24 bytes) */
+struct hwrm_cfa_l2_filter_alloc_output {
+	uint16_t error_code;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what CoS queue the TX ring is associated
-	 * with.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint8_t unused_4;
-	uint8_t unused_5;
-	uint32_t reserved1;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint16_t ring_arb_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * field is used to configure arbitration related parameters for
-	 * a TX ring.
+	 * 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.
+	 */
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t flow_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.
 	 */
-	/* Arbitration policy used for the ring. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK	\
-		UINT32_C(0xf)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * Use strict priority for the TX ring. Priority
-	 * value is specified in arb_policy_param
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP	\
-		(UINT32_C(0x1) << 0)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Use weighted fair queue arbitration for the
-	 * TX ring. Weight is specified in
-	 * arb_policy_param
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ	\
-		(UINT32_C(0x2) << 0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST	\
-		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
-	/* Reserved field. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	uint16_t cmpl_ring;
 	/*
-	 * Arbitration policy specific parameter. # For strict priority
-	 * arbitration policy, this field represents a priority value.
-	 * If set to 0, then the priority is not specified and the HWRM
-	 * is allowed to select any priority for this TX ring. # For
-	 * weighted fair queue arbitration policy, this field represents
-	 * a weight value. If set to 0, then the weight is not specified
-	 * and the HWRM is allowed to select any weight for this TX
-	 * ring.
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
-		UINT32_C(0xff00)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT   8
-	uint8_t unused_6;
-	uint8_t unused_7;
-	uint32_t reserved3;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t stat_ctx_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * input indicates what statistics context this ring should be
-	 * associated with.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t reserved4;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t max_bw;
+	uint64_t resp_addr;
 	/*
-	 * This field is used only when ring_type is a TX ring to
-	 * specify maximum BW allocated to the TX ring. The HWRM will
-	 * translate this value into byte counter and time interval used
-	 * for this ring inside the device.
+	 * 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.
 	 */
-	/* Bandwidth value */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
-	/* bw_value_unit is 3 b */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
-		UINT32_C(0xe0000000)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
-		(UINT32_C(0x0) << 29)
-	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
-		(UINT32_C(0x1) << 29)
-	/* Invalid unit */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
-		(UINT32_C(0x7) << 29)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
-		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
-	uint8_t int_mode;
+	uint64_t l2_filter_id;
 	/*
-	 * 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.
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
 	 */
-	/* Legacy INTA */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY	UINT32_C(0x0)
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
-	/* MSI-X */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
-	/* No Interrupt - Polled mode */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
-	uint8_t unused_8[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4834,16 +8198,10 @@ struct hwrm_ring_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t ring_id;
-	/*
-	 * Physical number of ring allocated. This value shall be unique
-	 * for a ring type.
-	 */
-	uint16_t logical_ring_id;
-	/* Logical number of ring allocated. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4855,12 +8213,10 @@ struct hwrm_ring_alloc_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_filter_cfg */
+/* Description: Change the configuration of an existing L2 filter */
+/* Input	(40 bytes) */
+struct hwrm_cfa_l2_filter_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4887,22 +8243,52 @@ struct hwrm_ring_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t ring_id;
-	/* Physical number of ring allocated. */
-	uint32_t unused_1;
+	uint32_t flags;
+	/*
+	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
+	/* tx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX \
+		(UINT32_C(0x0) << 0)
+	/* rx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX \
+		(UINT32_C(0x1) << 0)
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST \
+		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
+	/*
+	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
+	uint32_t enables;
+	/* This bit must be '1' for the dst_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the new_mirror_vnic_id field to be
+	 * configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   \
+		UINT32_C(0x2)
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t dst_id;
+	/*
+	 * 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.
+	 */
+	uint32_t new_mirror_vnic_id;
+	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_free_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4933,12 +8319,10 @@ struct hwrm_ring_free_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_set_rx_mask */
+/* Description: This command will set rx mask of the function. */
+/* Input	(56 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4959,31 +8343,116 @@ struct hwrm_ring_grp_alloc_input {
 	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
 	 * - HWRM
 	 */
-	uint64_t resp_addr;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* VNIC ID */
+	uint32_t mask;
+	/* 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)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for the VLAN-
+	 * tagged packets that match the TPID and VID fields of VLAN
+	 * tags in the VLAN tag table specified in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets that match the TPID
+	 * and VID fields of VLAN tags in the VLAN tag table specified
+	 * in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
+	 * If this flag is set, then the HWRM shall ignore VLAN tags
+	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
+	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
+	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
+	 * set at most one flag out of vlanonly, vlan_nonvlan, and
+	 * anyvlan_nonvlan.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	\
+		UINT32_C(0x100)
+	uint64_t mc_tbl_addr;
+	/* This is the address for mcast address tbl. */
+	uint32_t num_mc_entries;
 	/*
-	 * 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.
+	 * This value indicates how many entries in mc_tbl are valid.
+	 * Each entry is 6 bytes.
 	 */
-	uint16_t cr;
-	/* This value identifies the CR associated with the ring group. */
-	uint16_t rr;
-	/* This value identifies the main RR associated with the ring group. */
-	uint16_t ar;
+	uint32_t unused_0;
+	uint64_t vlan_tag_tbl_addr;
 	/*
-	 * 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.
+	 * This is the address for VLAN tag table. Each VLAN entry in
+	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
+	 * and VID fields in network byte order.
 	 */
-	uint16_t sc;
+	uint32_t num_vlan_tags;
 	/*
-	 * This value identifies the statistics context associated with
-	 * the ring group.
+	 * This value indicates how many entries in vlan_tag_tbl are
+	 * valid. Each entry is 4 bytes.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4999,15 +8468,10 @@ struct hwrm_ring_grp_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t ring_group_id;
-	/*
-	 * 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.
-	 */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5019,17 +8483,13 @@ struct hwrm_ring_grp_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_ring_grp_free */
+/* hwrm_tunnel_dst_port_query */
 /*
- * 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.
+ * Description: This function is called by a driver to query tunnel type
+ * specific destination port configuration.
  */
-/* Input (24 bytes) */
-struct hwrm_ring_grp_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5056,13 +8516,19 @@ struct hwrm_ring_grp_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t ring_group_id;
-	/* This is the ring group ID value. */
-	uint32_t unused_0;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0[7];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5078,10 +8544,24 @@ struct hwrm_ring_grp_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint16_t tunnel_dst_port_id;
+	/*
+	 * This field represents the identifier of L4 destination port
+	 * used for the given tunnel type. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling.
+	 */
+	uint16_t tunnel_dst_port_val;
+	/*
+	 * This field represents the value of L4 destination port
+	 * identified by tunnel_dst_port_id. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling. This field is in network byte order. A value
+	 * of 0 means that the destination port is not configured.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5093,15 +8573,24 @@ struct hwrm_ring_grp_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_alloc */
+/* hwrm_tunnel_dst_port_alloc */
 /*
- * A filter is used to identify traffic that contains a matching set of
- * parameters like unicast or broadcast MAC address or a VLAN tag amongst
- * other things which then allows the ASIC to direct the  incoming traffic
- * to an appropriate VNIC or Rx ring.
+ * Description: This function is called by a driver to allocate l4 destination
+ * port for a specific tunnel type. The destination port value is provided in
+ * the input. If the HWRM supports only one global destination port for a tunnel
+ * type, then the HWRM shall keep track of its usage as described below. # The
+ * first caller that allocates a destination port shall always succeed and the
+ * HWRM shall save the destination port configuration for that tunnel type and
+ * increment the usage count to 1. # Subsequent callers allocating the same
+ * destination port for that tunnel type shall succeed and the HWRM shall
+ * increment the usage count for that port for each subsequent caller that
+ * succeeds. # Any subsequent caller trying to allocate a different destination
+ * port for that tunnel type shall fail until the usage count for the original
+ * destination port goes to zero. # A caller that frees a port will cause the
+ * usage count for that port to decrement.
  */
-/* Input (96 bytes) */
-struct hwrm_cfa_l2_filter_alloc_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5114,253 +8603,41 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint32_t flags;
-	/*
-	 * 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	\
-		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 enables;
-	/* 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)
-	uint8_t l2_addr[6];
-	/*
-	 * 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 unused_0;
-	uint8_t unused_1;
-	uint8_t l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the L2 address. A value of
-	 * 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ovlan;
-	/* This value sets VLAN ID value for outer VLAN. */
-	uint16_t l2_ovlan_mask;
-	/*
-	 * This value sets the mask value for the ovlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ivlan;
-	/* This value sets VLAN ID value for inner VLAN. */
-	uint16_t l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the ivlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t t_l2_addr[6];
-	/*
-	 * 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 unused_4;
-	uint8_t unused_5;
-	uint8_t t_l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the tunnel L2 address. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t t_l2_ovlan;
-	/* This value sets VLAN ID value for tunnel outer VLAN. */
-	uint16_t t_l2_ovlan_mask;
-	/*
-	 * 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_ivlan;
-	/* This value sets VLAN ID value for tunnel inner VLAN. */
-	uint16_t t_l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the tunnel ivlan id. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint8_t src_type;
-	/* 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)
-	/* Physical function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
-	/* Virtual function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
-	/* Virtual NIC of a function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
-	/* Embedded processor for CFA management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
-	/* Embedded processor for OOB management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
-	/* Embedded processor for RoCE */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
-	/* Embedded processor for network proxy functions */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
-	uint8_t unused_6;
-	uint32_t src_id;
-	/*
-	 * 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
-	 */
-	uint8_t tunnel_type;
-	/* Tunnel Type. */
-	/* Non-tunnel */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL	UINT32_C(0x0)
-	/* Virtual eXtensible Local Area Network (VXLAN) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN	UINT32_C(0x1)
-	/*
-	 * Network Virtualization Generic Routing
-	 * Encapsulation (NVGRE)
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE	UINT32_C(0x2)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside
-	 * Ethernet payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE	UINT32_C(0x3)
-	/* IP in IP */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
-	/* Generic Network Virtualization Encapsulation (Geneve) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE	UINT32_C(0x5)
-	/* Multi-Protocol Lable Switching (MPLS) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
-	/* Stateless Transport Tunnel (STT) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside IP
-	 * datagram payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE	UINT32_C(0x8)
-	/* Any tunneled traffic */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL	UINT32_C(0xff)
-	uint8_t unused_7;
-	uint16_t dst_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint16_t mirror_vnic_id;
-	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
-	uint8_t pri_hint;
+	uint64_t resp_addr;
 	/*
-	 * This hint is provided to help in placing the filter in the
-	 * filter table.
+	 * 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.
 	 */
-	/* No preference */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER	UINT32_C(0x0)
-	/* Above the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER	UINT32_C(0x1)
-	/* Below the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER	UINT32_C(0x2)
-	/* As high as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
-	/* As low as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
-	uint8_t unused_8;
-	uint32_t unused_9;
-	uint64_t l2_filter_id_hint;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_val;
 	/*
-	 * 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
+	 * This field represents the value of L4 destination port used
+	 * for the given tunnel type. This field is valid for specific
+	 * tunnel types that use layer 4	(e.g. UDP) transports for
+	 * tunneling. This field is in network byte order. A value of 0
+	 * shall fail the command.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (24 bytes) */
-struct hwrm_cfa_l2_filter_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5376,21 +8653,17 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint64_t l2_filter_id;
-	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
-	 */
-	uint32_t flow_id;
+	uint16_t tunnel_dst_port_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.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
 	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5402,13 +8675,13 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_free */
+/* hwrm_tunnel_dst_port_free */
 /*
- * Description: Free a L2 filter. The HWRM shall free all associated filter
- * resources with the L2 filter.
+ * Description: This function is called by a driver to free l4 destination port
+ * for a specific tunnel type.
  */
-/* Input (24 bytes) */
-struct hwrm_cfa_l2_filter_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5435,15 +8708,24 @@ struct hwrm_cfa_l2_filter_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint64_t l2_filter_id;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_id;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5474,10 +8756,13 @@ struct hwrm_cfa_l2_filter_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_cfg */
-/* Description: Change the configuration of an existing L2 filter */
-/* Input (40 bytes) */
-struct hwrm_cfa_l2_filter_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5504,49 +8789,35 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX	(UINT32_C(0x0) << 0)
-	/* rx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX	(UINT32_C(0x1) << 0)
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST	\
-		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
-	/*
-	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
-	uint32_t enables;
-	/* This bit must be '1' for the dst_id field to be configured. */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	uint64_t stats_dma_addr;
+	/* This is the address for statistic block. */
+	uint32_t update_period_ms;
 	/*
-	 * This bit must be '1' for the new_mirror_vnic_id field to be
-	 * configured.
+	 * The statistic block update period in ms. e.g. 250ms, 500ms,
+	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
+	 * update shall be never done and the DMA address shall not be
+	 * used. In this case, the stat block can only be read by
+	 * hwrm_stat_ctx_query command.
 	 */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   UINT32_C(0x2)
-	uint64_t l2_filter_id;
+	uint8_t stat_ctx_flags;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * This field is used to specify statistics context specific
+	 * configuration flags.
 	 */
-	uint32_t dst_id;
 	/*
-	 * 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.
+	 * When this bit is set to '1', the statistics context shall be
+	 * allocated for RoCE traffic only. In this case, traffic other
+	 * than offloaded RoCE traffic shall not be included in this
+	 * statistic context. When this bit is set to '0', the
+	 * statistics context shall be used for the network traffic
+	 * other than offloaded RoCE traffic.
 	 */
-	uint32_t new_mirror_vnic_id;
-	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
+	#define HWRM_STAT_CTX_ALLOC_INPUT_STAT_CTX_FLAGS_ROCE	UINT32_C(0x1)
+	uint8_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5562,10 +8833,11 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5577,10 +8849,10 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_set_rx_mask */
-/* Description: This command will set rx mask of the function. */
-/* Input (56 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_input {
+/* hwrm_stat_ctx_free */
+/* Description: This command is used to free a stat context. */
+/* Input	(24 bytes) */
+struct hwrm_stat_ctx_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5607,109 +8879,81 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
-	/* VNIC ID */
-	uint32_t mask;
-	/* 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)
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_free_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST	UINT32_C(0x20)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for the VLAN-
-	 * tagged packets that match the TPID and VID fields of VLAN
-	 * tags in the VLAN tag table specified in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets that match the TPID
-	 * and VID fields of VLAN tags in the VLAN tag table specified
-	 * in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
-	 * If this flag is set, then the HWRM shall ignore VLAN tags
-	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
-	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
-	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
-	 * set at most one flag out of vlanonly, vlan_nonvlan, and
-	 * anyvlan_nonvlan.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	UINT32_C(0x100)
-	uint64_t mc_tbl_addr;
-	/* This is the address for mcast address tbl. */
-	uint32_t num_mc_entries;
+	uint16_t cmpl_ring;
 	/*
-	 * This value indicates how many entries in mc_tbl are valid.
-	 * Each entry is 6 bytes.
+	 * 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.
 	 */
-	uint32_t unused_0;
-	uint64_t vlan_tag_tbl_addr;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This is the address for VLAN tag table. Each VLAN entry in
-	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
-	 * and VID fields in network byte order.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t num_vlan_tags;
-	/*
-	 * This value indicates how many entries in vlan_tag_tbl are
-	 * valid. Each entry is 4 bytes.
+	uint64_t resp_addr;
+	/*
+	 * 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.
 	 */
-	uint32_t unused_1;
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5740,58 +8984,48 @@ struct hwrm_cfa_l2_set_rx_mask_output {
 	 */
 } __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 {
+/* hwrm_stat_ctx_query */
+/* Description: This command returns statistics of a context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_query_input {
 	uint16_t req_type;
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
 	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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 seq_id;
 	/* This value indicates the command sequence number. */
 	uint16_t target_id;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
 	 */
 	uint64_t resp_addr;
 	/*
-	 * 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 stats_dma_addr;
-	/* This is the address for statistic block. */
-	uint32_t update_period_ms;
-	/*
-	 * The statistic block update period in ms. e.g. 250ms, 500ms,
-	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
-	 * update shall be never done and the DMA address shall not be
-	 * used. In this case, the stat block can only be read by
-	 * hwrm_stat_ctx_query command.
+	 * 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.
 	 */
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_alloc_output {
+/* Output (176 bytes) */
+
+struct hwrm_stat_ctx_query_output {
 	uint16_t error_code;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
 	uint16_t req_type;
 	/* This field returns the type of original request. */
@@ -5799,30 +9033,76 @@ struct hwrm_stat_ctx_alloc_output {
 	/* This field provides original sequence number of the command. */
 	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t tx_err_pkts;
+	/* Number of transmitted packets with error */
+	uint64_t tx_drop_pkts;
+	/* Number of dropped packets on transmit path */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t tx_mcast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t tx_bcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t rx_err_pkts;
+	/* Number of received packets with error */
+	uint64_t rx_drop_pkts;
+	/* Number of dropped packets on received path */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations */
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
-	 * 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.
+	 * 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.
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5849,13 +9129,24 @@ struct hwrm_stat_ctx_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * 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.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_free_output {
+/* Output	(16 bytes) */
+struct hwrm_exec_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5871,11 +9162,10 @@ struct hwrm_stat_ctx_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5887,10 +9177,18 @@ struct hwrm_stat_ctx_free_output {
 	 */
 } __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 {
+/* hwrm_reject_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to reject the request and forward the
+ * error 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_reject_fwd_resp_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5917,13 +9215,25 @@ struct hwrm_stat_ctx_clr_stats_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * This is an encapsulated request. This request should be
+	 * rejected by the HWRM and the error response should be
+	 * provided in the response buffer inside the encapsulated
+	 * request.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_clr_stats_output {
+/* Output	(16 bytes) */
+struct hwrm_reject_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5954,18 +9264,16 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_exec_fwd_resp */
+/* Hardware Resource Manager Specification */
+/* Description: This structure is used to specify port description. */
 /*
- * 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.
+ * 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 service is vital part of the chip.
+ * The chip can not be used by a driver or HWRM client without the HWRM.
  */
-/* Input (128 bytes) */
-struct hwrm_exec_fwd_resp_input {
+/* Input	(16 bytes) */
+struct input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5992,24 +9300,91 @@ struct hwrm_exec_fwd_resp_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t encap_request[26];
+} __attribute__((packed));
+
+/* Output	(8 bytes) */
+struct output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint16_t encap_resp_target_id;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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
+	 * 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.
+	 */
+} __attribute__((packed));
+
+#define HWRM_GET_HWRM_ERROR_CODE(arg) \
+	{ \
+		typeof(arg) x = (arg); \
+	((x) == 0xf ? "HWRM_ERROR" : \
+	((x) == 0xffff ? "CMD_NOT_SUPPORTED" : \
+	((x) == 0xfffe ? "UNKNOWN_ERR" : \
+	((x) == 0x4 ? "RESOURCE_ALLOC_ERROR" : \
+	((x) == 0x5 ? "INVALID_FLAGS" : \
+	((x) == 0x6 ? "INVALID_ENABLES" : \
+	((x) == 0x0 ? "SUCCESS" : \
+	((x) == 0x1 ? "FAIL" : \
+	((x) == 0x2 ? "INVALID_PARAMS" : \
+	((x) == 0x3 ? "RESOURCE_ACCESS_DENIED" : \
+	"Unknown error_code")))))))))) \
+	}
+
+/* Return Codes	(8 bytes) */
+struct ret_codes {
+	uint16_t error_code;
+	/* These are numbers assigned to return/error codes. */
+	/* Request was successfully executed by the HWRM. */
+	#define HWRM_ERR_CODE_SUCCESS	(UINT32_C(0x0))
+	/* THe HWRM failed to execute the request. */
+	#define HWRM_ERR_CODE_FAIL	(UINT32_C(0x1))
+	/*
+	 * The request contains invalid argument(s) or
+	 * input parameters.
+	 */
+	#define HWRM_ERR_CODE_INVALID_PARAMS	(UINT32_C(0x2))
+	/*
+	 * The requester is not allowed to access the
+	 * requested resource. This error code shall be
+	 * provided in a response to a request to query
+	 * or modify an existing resource that is not
+	 * accessible by the requester.
+	 */
+	#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED	(UINT32_C(0x3))
+	/*
+	 * The HWRM is unable to allocate the requested
+	 * resource. This code only applies to requests
+	 * for HWRM resource allocations.
 	 */
+	#define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR	(UINT32_C(0x4))
+	/* Invalid combination of flags is specified in the request. */
+	#define HWRM_ERR_CODE_INVALID_FLAGS	(UINT32_C(0x5))
+	/*
+	 * Invalid combination of enables fields is
+	 * specified in the request.
+	 */
+	#define HWRM_ERR_CODE_INVALID_ENABLES	(UINT32_C(0x6))
+	/*
+	 * Generic HWRM execution error that represents
+	 * an internal error.
+	 */
+	#define HWRM_ERR_CODE_HWRM_ERROR	(UINT32_C(0xf))
+	/* Unknown error */
+	#define HWRM_ERR_CODE_UNKNOWN_ERR	(UINT32_C(0xfffe))
+	/* Unsupported or invalid command */
+	#define HWRM_ERR_CODE_CMD_NOT_SUPPORTED	(UINT32_C(0xffff))
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_exec_fwd_resp_output {
+/* Output	(16 bytes) */
+struct hwrm_err_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -6025,10 +9400,15 @@ struct hwrm_exec_fwd_resp_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
+	uint32_t opaque_0;
+	/* debug info for this error response. */
+	uint16_t opaque_1;
+	/* debug info for this error response. */
+	uint8_t cmd_err;
+	/*
+	 * In the case of an error response, command specific error code
+	 * is returned in this field.
+	 */
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -6040,4 +9420,378 @@ struct hwrm_exec_fwd_resp_output {
 	 */
 } __attribute__((packed));
 
-#endif
+/* Port Tx Statistics Formats	(408 bytes) */
+struct tx_port_stats {
+	uint64_t tx_64b_frames;
+	/* Total Number of 64 Bytes frames transmitted */
+	uint64_t tx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames transmitted */
+	uint64_t tx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames transmitted */
+	uint64_t tx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames transmitted */
+	uint64_t tx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames transmitted */
+	uint64_t tx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames transmitted */
+	uint64_t tx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * transmitted which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t tx_1519b_2047_frames;
+	/* Total Number of 1519-2047 Bytes frames transmitted */
+	uint64_t tx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames transmitted */
+	uint64_t tx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames transmitted */
+	uint64_t tx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames transmitted */
+	uint64_t tx_good_frames;
+	/* Total Number of good frames transmitted */
+	uint64_t tx_total_frames;
+	/* Total Number of frames transmitted */
+	uint64_t tx_ucast_frames;
+	/* Total number of unicast frames transmitted */
+	uint64_t tx_mcast_frames;
+	/* Total number of multicast frames transmitted */
+	uint64_t tx_bcast_frames;
+	/* Total number of broadcast frames transmitted */
+	uint64_t tx_pause_frames;
+	/* Total number of PAUSE control frames transmitted */
+	uint64_t tx_pfc_frames;
+	/* Total number of PFC/per-priority PAUSE control frames transmitted */
+	uint64_t tx_jabber_frames;
+	/* Total number of jabber frames transmitted */
+	uint64_t tx_fcs_err_frames;
+	/* Total number of frames transmitted with FCS error */
+	uint64_t tx_control_frames;
+	/* Total number of control frames transmitted */
+	uint64_t tx_oversz_frames;
+	/* Total number of over-sized frames transmitted */
+	uint64_t tx_single_dfrl_frames;
+	/* Total number of frames with single deferral */
+	uint64_t tx_multi_dfrl_frames;
+	/* Total number of frames with multiple deferrals */
+	uint64_t tx_single_coll_frames;
+	/* Total number of frames with single collision */
+	uint64_t tx_multi_coll_frames;
+	/* Total number of frames with multiple collisions */
+	uint64_t tx_late_coll_frames;
+	/* Total number of frames with late collisions */
+	uint64_t tx_excessive_coll_frames;
+	/* Total number of frames with excessive collisions */
+	uint64_t tx_frag_frames;
+	/* Total number of fragmented frames transmitted */
+	uint64_t tx_err;
+	/* Total number of transmit errors */
+	uint64_t tx_tagged_frames;
+	/* Total number of single VLAN tagged frames transmitted */
+	uint64_t tx_dbl_tagged_frames;
+	/* Total number of double VLAN tagged frames transmitted */
+	uint64_t tx_runt_frames;
+	/* Total number of runt frames transmitted */
+	uint64_t tx_fifo_underruns;
+	/* Total number of TX FIFO under runs */
+	uint64_t tx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 0
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 1
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 2
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 3
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 4
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 5
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 6
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 7
+	 * transmitted
+	 */
+	uint64_t tx_eee_lpi_events;
+	/* Total number of EEE LPI Events on TX */
+	uint64_t tx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on TX */
+	uint64_t tx_llfc_logical_msgs;
+	/*
+	 * Total number of Link Level Flow Control	(LLFC) messages
+	 * transmitted
+	 */
+	uint64_t tx_hcfc_msgs;
+	/* Total number of HCFC messages transmitted */
+	uint64_t tx_total_collisions;
+	/* Total number of TX collisions */
+	uint64_t tx_bytes;
+	/* Total number of transmitted bytes */
+	uint64_t tx_xthol_frames;
+	/* Total number of end-to-end HOL frames */
+	uint64_t tx_stat_discard;
+	/* Total Tx Drops per Port reported by STATS block */
+	uint64_t tx_stat_error;
+	/* Total Tx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Port Rx Statistics Formats	(528 bytes) */
+struct rx_port_stats {
+	uint64_t rx_64b_frames;
+	/* Total Number of 64 Bytes frames received */
+	uint64_t rx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames received */
+	uint64_t rx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames received */
+	uint64_t rx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames received */
+	uint64_t rx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames received */
+	uint64_t rx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames received */
+	uint64_t rx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * received which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t rx_1519b_2047b_frames;
+	/* Total Number of 1519-2047 Bytes frames received */
+	uint64_t rx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames received */
+	uint64_t rx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames received */
+	uint64_t rx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames received */
+	uint64_t rx_total_frames;
+	/* Total number of frames received */
+	uint64_t rx_ucast_frames;
+	/* Total number of unicast frames received */
+	uint64_t rx_mcast_frames;
+	/* Total number of multicast frames received */
+	uint64_t rx_bcast_frames;
+	/* Total number of broadcast frames received */
+	uint64_t rx_fcs_err_frames;
+	/* Total number of received frames with FCS error */
+	uint64_t rx_ctrl_frames;
+	/* Total number of control frames received */
+	uint64_t rx_pause_frames;
+	/* Total number of PAUSE frames received */
+	uint64_t rx_pfc_frames;
+	/* Total number of PFC frames received */
+	uint64_t rx_unsupported_opcode_frames;
+	/* Total number of frames received with an unsupported opcode */
+	uint64_t rx_unsupported_da_pausepfc_frames;
+	/*
+	 * Total number of frames received with an unsupported DA for
+	 * pause and PFC
+	 */
+	uint64_t rx_wrong_sa_frames;
+	/* Total number of frames received with an unsupported SA */
+	uint64_t rx_align_err_frames;
+	/* Total number of received packets with alignment error */
+	uint64_t rx_oor_len_frames;
+	/* Total number of received frames with out-of-range length */
+	uint64_t rx_code_err_frames;
+	/* Total number of received frames with error termination */
+	uint64_t rx_false_carrier_frames;
+	/*
+	 * Total number of received frames with a false carrier is
+	 * detected during idle, as defined by RX_ER samples active and
+	 * RXD is 0xE. The event is reported along with the statistics
+	 * generated on the next received frame. Only one false carrier
+	 * condition can be detected and logged between frames. Carrier
+	 * event, valid for 10M/100M speed modes only.
+	 */
+	uint64_t rx_ovrsz_frames;
+	/* Total number of over-sized frames received */
+	uint64_t rx_jbr_frames;
+	/* Total number of jabber packets received */
+	uint64_t rx_mtu_err_frames;
+	/* Total number of received frames with MTU error */
+	uint64_t rx_match_crc_frames;
+	/* Total number of received frames with CRC match */
+	uint64_t rx_promiscuous_frames;
+	/* Total number of frames received promiscuously */
+	uint64_t rx_tagged_frames;
+	/* Total number of received frames with one or two VLAN tags */
+	uint64_t rx_double_tagged_frames;
+	/* Total number of received frames with two VLAN tags */
+	uint64_t rx_trunc_frames;
+	/* Total number of truncated frames received */
+	uint64_t rx_good_frames;
+	/* Total number of good frames	(without errors) received */
+	uint64_t rx_pfc_xon2xoff_frames_pri0;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 0
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri1;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 1
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri2;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 2
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri3;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 3
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri4;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 4
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri5;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 5
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri6;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 6
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri7;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 7
+	 */
+	uint64_t rx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 0
+	 */
+	uint64_t rx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 1
+	 */
+	uint64_t rx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 2
+	 */
+	uint64_t rx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 3
+	 */
+	uint64_t rx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 4
+	 */
+	uint64_t rx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 5
+	 */
+	uint64_t rx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 6
+	 */
+	uint64_t rx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 7
+	 */
+	uint64_t rx_sch_crc_err_frames;
+	/* Total Number of frames received with SCH CRC error */
+	uint64_t rx_undrsz_frames;
+	/* Total Number of under-sized frames received */
+	uint64_t rx_frag_frames;
+	/* Total Number of fragmented frames received */
+	uint64_t rx_eee_lpi_events;
+	/* Total number of RX EEE LPI Events */
+	uint64_t rx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on RX */
+	uint64_t rx_llfc_physical_msgs;
+	/*
+	 * Total number of physical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_logical_msgs;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_msgs_with_crc_err;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received with CRC error
+	 */
+	uint64_t rx_hcfc_msgs;
+	/* Total number of HCFC messages received */
+	uint64_t rx_hcfc_msgs_with_crc_err;
+	/* Total number of HCFC messages received with CRC error */
+	uint64_t rx_bytes;
+	/* Total number of received bytes */
+	uint64_t rx_runt_bytes;
+	/* Total number of bytes received in runt frames */
+	uint64_t rx_runt_frames;
+	/* Total number of runt frames received */
+	uint64_t rx_stat_discard;
+	/* Total Rx Discards per Port reported by STATS block */
+	uint64_t rx_stat_err;
+	/* Total Rx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Periodic Statistics Context DMA to host	(160 bytes) */
+/*
+ * per-context HW statistics -- chip view
+ */
+
+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_discard_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_discard_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;
+} __attribute__((packed));
+
+#endif /* _HSI_STRUCT_DEF_DPDK_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
                             ` (24 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) Move the function reset to bnxt_dev_init.
On the same lines, setup, enable and request interrupt to init path.
Memory allocation is also being done in the init path.
2) After a function reset, configure the VFs.  Distribute resources
evenly between all functions (PF and VF) for now. In the future, this
should be controllable.
3) The bnxt_vf_info and bnxt_pf_info had lot of duplication. Move the
common items to struct bnxt. And only unique items specific to PF remain
in the struct bnxt_pf_info.
4) Program the firmware to allow certain commands sent by a VF.
Disallowing these will prevent clean VF driver cleanup.
5) Since PF/VF need to allocate resources from a pool in the hardware,
use func_qcaps and func_qcfg to appropriately query the capabilities
and available resources.
6) If a PF is being initialized and no VFs are allocated, explicitly
call func_cfg to allocate the resources.
7) Once resources are requested from the firmware, update local copy
of resource count in struct bnxt only after sending the func_qcfg to
make sure the allocation request in the firmware went through.

The changes in this patch will be used by the subsequent patches
to allow proper initialization of PF/VF instance.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: Regroup related patches per review comment
  Also split bigger patch into smaller patches if possible.

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |  80 ++++--
 drivers/net/bnxt/bnxt_ethdev.c | 155 ++++++++---
 drivers/net/bnxt/bnxt_filter.c |  30 +-
 drivers/net/bnxt/bnxt_hwrm.c   | 614 +++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  17 +-
 drivers/net/bnxt/bnxt_vnic.c   |  45 +--
 drivers/net/bnxt/bnxt_vnic.h   |  11 +-
 7 files changed, 764 insertions(+), 188 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4418c7f..0c59c66 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -35,6 +35,7 @@
 #define _BNXT_H_
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <sys/queue.h>
 
 #include <rte_ethdev.h>
@@ -54,17 +55,19 @@ enum bnxt_hw_context {
 	HW_CONTEXT_IS_LB    = 3,
 };
 
-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;
-	uint16_t		vlan;
-	struct bnxt_pf_info	*pf;
+struct bnxt_vlan_table_entry {
+	uint16_t		tpid;
+	uint16_t		vid;
+} __attribute__((packed));
+
+struct bnxt_child_vf_info {
+	void			*req_buf;
+	struct bnxt_vlan_table_entry	*vlan_table;
+	STAILQ_HEAD(, bnxt_filter_info)	filter;
+	uint32_t		func_cfg_flags;
+	uint32_t		l2_rx_mask;
+	uint16_t		fid;
+	bool			random_mac;
 };
 
 struct bnxt_pf_info {
@@ -73,22 +76,20 @@ struct bnxt_pf_info {
 #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;
+	uint32_t		func_cfg_flags;
 	void			*vf_req_buf;
 	phys_addr_t		vf_req_buf_dma_addr;
 	uint32_t		vf_req_fwd[8];
-	struct bnxt_vf_info	*vf;
+	uint16_t		total_vnics;
+	struct bnxt_child_vf_info	*vf_info;
+#define BNXT_EVB_MODE_NONE	0
+#define BNXT_EVB_MODE_VEB	1
+#define BNXT_EVB_MODE_VEPA	2
+	uint8_t			evb_mode;
 };
 
 /* Max wait time is 10 * 100ms = 1s */
@@ -174,12 +175,49 @@ struct bnxt {
 	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
+	uint16_t		fw_fid;
+	uint8_t			dflt_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		max_stat_ctx;
+	uint16_t		vlan;
 	struct bnxt_pf_info		pf;
-	struct bnxt_vf_info		vf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint32_t		fw_ver;
+};
+
+/*
+ * Response sent back to the caller after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+	RTE_PMD_BNXT_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_PMD_BNXT_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_PMD_BNXT_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET			0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR	0x02 /* VF requests PF to set MAC addr */
+#define BNXT_VF_SET_VLAN		0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU			0x04 /* VF requests PF to set MTU */
+#define BNXT_VF_SET_MRU			0x05 /* VF requests PF to set MRU */
+
+/*
+ * Data sent to the caller when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+	uint16_t vf_id;	/* Virtual Function number */
+	int	retval;	/* return value */
+	void	*msg;	/* pointer to message */
 };
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index c230394..6e7e4f6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -345,18 +345,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
-	}
+	if (BNXT_PF(bp))
+		dev_info->max_vfs = bp->pdev->max_vfs;
+	dev_info->max_rx_queues = bp->max_rx_rings;
+	dev_info->max_tx_queues = bp->max_tx_rings;
+	dev_info->reta_size = bp->max_rsscos_ctx;
+	max_vnics = bp->max_vnics;
 
 	/* Fast path specifics */
 	dev_info->min_rx_bufsize = 1;
@@ -488,41 +482,18 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	bp->dev_stopped = 0;
-	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);
-
 	bnxt_link_update_op(eth_dev, 0);
 	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;
 }
 
@@ -554,8 +525,6 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
-	bnxt_disable_int(bp);
-	bnxt_free_int(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1082,6 +1051,12 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 
 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
 
+#define ALLOW_FUNC(x)	\
+	{ \
+		typeof(x) arg = (x); \
+		bp->pf.vf_req_fwd[((arg) >> 5)] &= \
+		~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
+	}
 static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1097,6 +1072,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
 		bp->flags |= BNXT_FLAG_VF;
@@ -1130,6 +1106,11 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
 		goto error_free;
 	}
+	if (bp->max_tx_rings == 0) {
+		RTE_LOG(ERR, PMD, "No TX rings available!\n");
+		rc = -EBUSY;
+		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) {
@@ -1140,10 +1121,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		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(bp->mac_addr, bp->dflt_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);
@@ -1155,8 +1133,29 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error_free;
 	}
 
-	rc = bnxt_hwrm_func_driver_register(bp, 0,
-					    bp->pf.vf_req_fwd);
+	/* Forward all requests if firmware is new enough */
+	if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
+	    (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
+	    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
+		memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
+	} else {
+		RTE_LOG(WARNING, PMD,
+			"Firmware too old for VF mailbox functionality\n");
+		memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
+	}
+
+	/*
+	 * The following are used for driver cleanup.  If we disallow these,
+	 * VF drivers can't clean up cleanly.
+	 */
+	ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
+	ALLOW_FUNC(HWRM_VNIC_FREE);
+	ALLOW_FUNC(HWRM_RING_FREE);
+	ALLOW_FUNC(HWRM_RING_GRP_FREE);
+	ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
+	ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
+	ALLOW_FUNC(HWRM_STAT_CTX_FREE);
+	rc = bnxt_hwrm_func_driver_register(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"Failed to register driver");
@@ -1169,10 +1168,55 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		pci_dev->mem_resource[0].phys_addr,
 		pci_dev->mem_resource[0].addr);
 
-	bp->dev_stopped = 0;
+	rc = bnxt_hwrm_func_reset(bp);
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc);
+		rc = -1;
+		goto error_free;
+	}
+
+	if (BNXT_PF(bp)) {
+		//if (bp->pf.active_vfs) {
+			// TODO: Deallocate VF resources?
+		//}
+		if (bp->pdev->max_vfs) {
+			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
+			if (rc) {
+				RTE_LOG(ERR, PMD, "Failed to allocate VFs\n");
+				goto error_free;
+			}
+		} else {
+			rc = bnxt_hwrm_allocate_pf_only(bp);
+			if (rc) {
+				RTE_LOG(ERR, PMD,
+					"Failed to allocate PF resources\n");
+				goto error_free;
+			}
+		}
+	}
+
+	rc = bnxt_setup_int(bp);
+	if (rc)
+		goto error_free;
+
+	rc = bnxt_alloc_mem(bp);
+	if (rc)
+		goto error_free_int;
+
+	rc = bnxt_request_int(bp);
+	if (rc)
+		goto error_free_int;
+
+	bnxt_enable_int(bp);
 
 	return 0;
 
+error_free_int:
+	bnxt_disable_int(bp);
+	bnxt_free_def_cp_ring(bp);
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 error_free:
 	bnxt_dev_uninit(eth_dev);
 error:
@@ -1184,6 +1228,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	int rc;
 
+	bnxt_disable_int(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 	if (eth_dev->data->mac_addrs != NULL) {
 		rte_free(eth_dev->data->mac_addrs);
 		eth_dev->data->mac_addrs = NULL;
@@ -1196,6 +1243,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	bnxt_free_hwrm_resources(bp);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
+	if (bp->pf.vf_info)
+		rte_free(bp->pf.vf_info);
 	eth_dev->dev_ops = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 	eth_dev->tx_pkt_burst = NULL;
@@ -1203,6 +1252,24 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	return rc;
 }
 
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+	struct rte_pmd_bnxt_mb_event_param cb_param;
+
+	cb_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+	cb_param.vf_id = vf_id;
+	cb_param.msg = msg;
+
+	_rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+			&cb_param);
+
+	/* Default to approve */
+	if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+		cb_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+	return cb_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? true : false;
+}
+
 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index df1042c..137c7b7 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -73,15 +73,7 @@ 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	STAILQ_INIT(&bp->free_filter_list);
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
@@ -122,15 +114,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 		return;
 
 	/* 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
 		if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
@@ -155,15 +139,7 @@ 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;
-	}
+	max_filters = bp->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),
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9100b7b..7aece5d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -54,6 +56,38 @@
 
 #define HWRM_CMD_TIMEOUT		2000
 
+struct bnxt_plcmodes_cfg {
+	uint32_t	flags;
+	uint16_t	jumbo_thresh;
+	uint16_t	hds_offset;
+	uint16_t	hds_threshold;
+};
+
+static int page_getenum(size_t size)
+{
+	if (size <= 1 << 4)
+		return 4;
+	if (size <= 1 << 12)
+		return 12;
+	if (size <= 1 << 13)
+		return 13;
+	if (size <= 1 << 16)
+		return 16;
+	if (size <= 1 << 21)
+		return 21;
+	if (size <= 1 << 22)
+		return 22;
+	if (size <= 1 << 30)
+		return 30;
+	RTE_LOG(ERR, PMD, "Page size %zu out of range\n", size);
+	return sizeof(void *) * 8 - 1;
+}
+
+static int page_roundup(size_t size)
+{
+	return 1 << page_getenum(size);
+}
+
 /*
  * HWRM Functions (sent to HWRM)
  * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message()
@@ -275,6 +309,8 @@ 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;
+	uint16_t new_max_vfs;
+	int i;
 
 	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
 
@@ -286,31 +322,52 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	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;
-
-		pf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		pf->port_id = resp->port_id;
-		memcpy(pf->mac_addr, resp->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);
+		bp->pf.port_id = resp->port_id;
+		bp->pf.first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+		new_max_vfs = bp->pdev->max_vfs;
+		if (new_max_vfs != bp->pf.max_vfs) {
+			if (bp->pf.vf_info)
+				rte_free(bp->pf.vf_info);
+			bp->pf.vf_info = rte_malloc("bnxt_vf_info",
+			    sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0);
+			bp->pf.max_vfs = new_max_vfs;
+			for (i = 0; i < new_max_vfs; i++) {
+				bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i;
+				bp->pf.vf_info[i].vlan_table =
+					rte_zmalloc("VF VLAN table",
+						    getpagesize(),
+						    getpagesize());
+				if (bp->pf.vf_info[i].vlan_table == NULL)
+					RTE_LOG(ERR, PMD,
+					"Fail to alloc VLAN table for VF %d\n",
+					i);
+				else
+					rte_mem_lock_page(
+						bp->pf.vf_info[i].vlan_table);
+				STAILQ_INIT(&bp->pf.vf_info[i].filter);
+			}
+		}
+	}
+
+	bp->fw_fid = rte_le_to_cpu_32(resp->fid);
+	memcpy(bp->dflt_mac_addr, &resp->mac_address, ETHER_ADDR_LEN);
+	bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	if (BNXT_PF(bp)) {
+		if (bp->pf.max_vfs)
+			bp->max_vnics = 1;
+		else
+			bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
 	} else {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		vf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		memcpy(vf->mac_addr, &resp->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);
+		bp->max_vnics = 1;
 	}
+	bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+	if (BNXT_PF(bp))
+		bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
 
 	return rc;
 }
@@ -332,8 +389,7 @@ int bnxt_hwrm_func_reset(struct bnxt *bp)
 	return rc;
 }
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd)
+int bnxt_hwrm_func_driver_register(struct bnxt *bp)
 {
 	int rc;
 	struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
@@ -343,16 +399,22 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 		return 0;
 
 	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
-	req.flags = flags;
-	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
-			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD;
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
 	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));
+	if (BNXT_PF(bp)) {
+		req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_INPUT_FWD);
+		memcpy(req.vf_req_fwd, bp->pf.vf_req_fwd,
+		       RTE_MIN(sizeof(req.vf_req_fwd),
+			       sizeof(bp->pf.vf_req_fwd)));
+	}
 
 	req.async_event_fwd[0] |= rte_cpu_to_le_32(0x1);   /* TODO: Use MACRO */
+	memset(req.async_event_fwd, 0xff, sizeof(req.async_event_fwd));
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -391,6 +453,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		resp->hwrm_intf_maj, resp->hwrm_intf_min,
 		resp->hwrm_intf_upd,
 		resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
+	bp->fw_ver = (resp->hwrm_fw_maj << 24) | (resp->hwrm_fw_min << 16) |
+			(resp->hwrm_fw_bld << 8) | resp->hwrm_fw_rsvd;
 	RTE_LOG(INFO, PMD, "Driver HWRM version: %d.%d.%d\n",
 		HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);
 
@@ -825,10 +889,12 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		}
 		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;
-
+	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
+	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				ETHER_CRC_LEN + VLAN_TAG_SIZE;
 	HWRM_PREP(req, VNIC_ALLOC, -1, resp);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -844,27 +910,45 @@ 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;
+	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
 
 	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);
+	if (vnic->lb_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE;
+	if (vnic->cos_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE;
+	if (vnic->rss_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	req.enables |= rte_cpu_to_le_32(ctx_enable_flag);
 	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);
+	req.dflt_ring_grp = rte_cpu_to_le_16(vnic->dflt_ring_grp);
+	req.rss_rule = rte_cpu_to_le_16(vnic->rss_rule);
+	req.cos_rule = rte_cpu_to_le_16(vnic->cos_rule);
+	req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
+	req.mru = rte_cpu_to_le_16(vnic->mru);
 	if (vnic->func_default)
-		req.flags = 1;
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
 	if (vnic->vlan_strip)
 		req.flags |=
 		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+	if (vnic->bd_stall)
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+	if (vnic->roce_dual)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE);
+	if (vnic->roce_only)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE);
+	if (vnic->rss_dflt_cr)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -873,6 +957,45 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+		int16_t fw_vf_id)
+{
+	int rc = 0;
+	struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_QCFG, -1, resp);
+
+	req.enables =
+		rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.vf_id = rte_cpu_to_le_16(fw_vf_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_rule);
+	vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+	vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+	vnic->mru = rte_le_to_cpu_16(resp->mru);
+	vnic->func_default = rte_le_to_cpu_32(
+			resp->flags) & HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+	vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+	vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+	vnic->roce_dual = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE;
+	vnic->roce_only = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE;
+	vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE;
+
+	return rc;
+}
+
 int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0;
@@ -886,7 +1009,7 @@ int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
 
 	return rc;
 }
@@ -900,13 +1023,13 @@ int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	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);
+	req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+	vnic->rss_rule = INVALID_HW_RING_ID;
 
 	return rc;
 }
@@ -947,7 +1070,7 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	    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);
+	req.rss_ctx_idx = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -956,6 +1079,28 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+	memcpy(req.dflt_mac_addr, mac_addr, sizeof(req.dflt_mac_addr));
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	bp->pf.vf_info[vf].random_mac = false;
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -1217,7 +1362,8 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		return;
 
 	vnic = &bp->vnic_info[0];
-	bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
+	if (BNXT_PF(bp))
+		bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
 
 	/* VNIC resources */
 	for (i = 0; i < bp->nr_vnics; i++) {
@@ -1512,12 +1658,8 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
-	if (BNXT_VF(bp)) {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		/* Hard Coded.. 0xfff VLAN ID mask */
-		vf->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
-	}
+	/* Hard Coded.. 0xfff VLAN ID mask */
+	bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
 
 	switch (resp->port_partition_type) {
 	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
@@ -1532,3 +1674,369 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	return rc;
 }
+
+static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg,
+				   struct hwrm_func_qcaps_output *qcaps)
+{
+	qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs;
+	memcpy(qcaps->mac_address, fcfg->dflt_mac_addr,
+	       sizeof(qcaps->mac_address));
+	qcaps->max_l2_ctxs = fcfg->num_l2_ctxs;
+	qcaps->max_rx_rings = fcfg->num_rx_rings;
+	qcaps->max_tx_rings = fcfg->num_tx_rings;
+	qcaps->max_cmpl_rings = fcfg->num_cmpl_rings;
+	qcaps->max_stat_ctx = fcfg->num_stat_ctxs;
+	qcaps->max_vfs = 0;
+	qcaps->first_vf_id = 0;
+	qcaps->max_vnics = fcfg->num_vnics;
+	qcaps->max_decap_records = 0;
+	qcaps->max_encap_records = 0;
+	qcaps->max_tx_wm_flows = 0;
+	qcaps->max_tx_em_flows = 0;
+	qcaps->max_rx_wm_flows = 0;
+	qcaps->max_rx_em_flows = 0;
+	qcaps->max_flow_id = 0;
+	qcaps->max_mcast_filters = fcfg->num_mcast_filters;
+	qcaps->max_sp_tx_rings = 0;
+	qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps;
+}
+
+static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
+	req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx);
+	req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings);
+	req.num_tx_rings = rte_cpu_to_le_16(tx_rings);
+	req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings);
+	req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx);
+	req.num_vnics = rte_cpu_to_le_16(bp->max_vnics);
+	req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps);
+	req.fid = rte_cpu_to_le_16(0xffff);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+static void populate_vf_func_cfg_req(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *req,
+				     int num_vfs)
+{
+	req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+
+	req->mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx /
+						(num_vfs + 1));
+	req->num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1));
+	req->num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings /
+					       (num_vfs + 1));
+	req->num_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1));
+	req->num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1));
+	req->num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1));
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	req->num_vnics = rte_cpu_to_le_16(1);
+	req->num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps /
+						 (num_vfs + 1));
+}
+
+static void reserve_resources_from_vf(struct bnxt *bp,
+				      struct hwrm_func_cfg_input *cfg_req,
+				      int vf)
+{
+	struct hwrm_func_qcaps_input req = {0};
+	struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Get the actual allocated values now */
+	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps failed rc:%d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps error %d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	}
+
+	bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx);
+	bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/*
+	 * TODO: While not supporting VMDq with VFs, max_vnics is always
+	 * forced to 1 in this case
+	 */
+	//bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics);
+	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
+}
+
+static int update_pf_resource_max(struct bnxt *bp)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* And copy the allocated numbers into the pf struct */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	/* Only TX ring value reflects actual allocation? TODO */
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+	bp->pf.evb_mode = resp->evb_mode;
+
+	return rc;
+}
+
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
+{
+	int rc;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+	if (rc)
+		return rc;
+
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	return rc;
+}
+
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int i;
+	size_t sz;
+	int rc = 0;
+	size_t req_buf_sz;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+
+	if (rc)
+		return rc;
+
+	bp->pf.active_vfs = num_vfs;
+
+	/*
+	 * First, configure the PF to only use one TX ring.  This ensures that
+	 * there are enough rings for all VFs.
+	 *
+	 * If we don't do this, when we call func_alloc() later, we will lock
+	 * extra rings to the PF that won't be available during func_cfg() of
+	 * the VFs.
+	 *
+	 * This has been fixed with firmware versions above 20.6.54
+	 */
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, 1);
+	if (rc)
+		return rc;
+
+	/*
+	 * Now, create and register a buffer to hold forwarded VF requests
+	 */
+	req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN;
+	bp->pf.vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz,
+		page_roundup(num_vfs * HWRM_MAX_REQ_LEN));
+	if (bp->pf.vf_req_buf == NULL) {
+		rc = -ENOMEM;
+		goto error_free;
+	}
+	for (sz = 0; sz < req_buf_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)bp->pf.vf_req_buf) + sz);
+	for (i = 0; i < num_vfs; i++)
+		bp->pf.vf_info[i].req_buf = ((char *)bp->pf.vf_req_buf) +
+					(i * HWRM_MAX_REQ_LEN);
+
+	rc = bnxt_hwrm_func_buf_rgtr(bp);
+	if (rc)
+		goto error_free;
+
+	populate_vf_func_cfg_req(bp, &req, num_vfs);
+
+	bp->pf.active_vfs = 0;
+	for (i = 0; i < num_vfs; i++) {
+		HWRM_PREP(req, FUNC_CFG, -1, resp);
+		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
+		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
+		rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+		/* Clear enable flag for next pass */
+		req.enables &= ~rte_cpu_to_le_32(
+				HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+
+		if (rc || resp->error_code) {
+			RTE_LOG(ERR, PMD,
+				"Failed to initizlie VF %d\n", i);
+			RTE_LOG(ERR, PMD,
+				"Not all VFs available. (%d, %d)\n",
+				rc, resp->error_code);
+			break;
+		}
+
+		reserve_resources_from_vf(bp, &req, i);
+		bp->pf.active_vfs++;
+	}
+
+	/*
+	 * Now configure the PF to use "the rest" of the resources
+	 * We're using STD_TX_RING_MODE here though which will limit the TX
+	 * rings.  This will allow QoS to function properly.  Not setting this
+	 * will cause PF rings to break bandwidth settings.
+	 */
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	if (rc)
+		goto error_free;
+
+	rc = update_pf_resource_max(bp);
+	if (rc)
+		goto error_free;
+
+	return rc;
+
+error_free:
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	return rc;
+}
+
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	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);
+
+	req.req_buf_num_pages = rte_cpu_to_le_16(1);
+	req.req_buf_page_size = rte_cpu_to_le_16(
+			 page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN));
+	req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
+	req.req_buf_page_addr[0] =
+		rte_cpu_to_le_64(rte_mem_virt2phy(bp->pf.vf_req_buf));
+	if (req.req_buf_page_addr[0] == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map buffer address to physical memory\n");
+		return -ENOMEM;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
+	struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_BUF_UNRGTR, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_reject_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_reject_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, REJECT_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6519ef2..0046ba4 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,14 +51,17 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size);
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd);
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp);
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
@@ -81,6 +84,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_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				int16_t fw_vf_id);
 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);
@@ -101,5 +106,11 @@ 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);
 int bnxt_hwrm_func_qcfg(struct bnxt *bp);
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
+			  const uint8_t *mac_addr);
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 33fdde2..4e378a9 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -69,21 +69,14 @@ void bnxt_init_vnics(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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;
+		vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
 		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
 			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
@@ -181,15 +174,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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);
@@ -232,15 +217,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp)
 	if (bp->vnic_info == NULL)
 		return;
 
-	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;
-	}
+	max_vnics = bp->max_vnics;
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
 		if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
@@ -258,15 +235,7 @@ 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;
-	}
+	max_vnics = bp->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);
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 9671ba4..ca1c9cf 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -42,8 +42,7 @@ struct bnxt_vnic_info {
 	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;
+	uint16_t	rss_rule;
 #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 + \
@@ -51,6 +50,8 @@ struct bnxt_vnic_info {
 	uint16_t	start_grp_id;
 	uint16_t	end_grp_id;
 	uint16_t	fw_grp_ids[MAX_QUEUES_PER_VNIC];
+	uint16_t	dflt_ring_grp;
+	uint16_t	mru;
 	uint16_t	hash_type;
 	phys_addr_t	rss_table_dma_addr;
 	uint16_t	*rss_table;
@@ -60,8 +61,14 @@ struct bnxt_vnic_info {
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
 
+	uint16_t	cos_rule;
+	uint16_t	lb_rule;
 	bool		vlan_strip;
 	bool		func_default;
+	bool		bd_stall;
+	bool		roce_dual;
+	bool		roce_only;
+	bool		rss_dflt_cr;
 
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 03/26] net/bnxt: handle VF/PF initialization appropriately
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
                             ` (23 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) For a VF, query the firmware to determine if a MAC address is
already configured. If not configure a random default MAC address.
2) Do not initialize the default completion ring in
bnxt_alloc_hwrm_rings().
3) While registering for async events with the firmware,
use func_vf_cfg for a VF and use func_cfg for a PF.
4) Query the VNIC plcmode config using the bnxt_hwrm_vnic_plcmodes_qcfg
before a VNIC is updated. Reconfigure the VNIC with the plcmode
configuration queried earlier. Not doing this could overwrite
the plcmodes in some cases.
5) Reorg the bnxt_handle_fwd_req to properly handle the forwarded
requests. The previous code did not handle it completely.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other
  review comments.

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_cpr.c       | 131 ++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_cpr.h       |  17 ++++
 drivers/net/bnxt/bnxt_ethdev.c    |  30 +++++---
 drivers/net/bnxt/bnxt_filter.c    |   2 +-
 drivers/net/bnxt/bnxt_hwrm.c      | 158 +++++++++++++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_hwrm.h      |   4 +-
 drivers/net/bnxt/bnxt_irq.c       |  21 +++--
 drivers/net/bnxt/bnxt_ring.c      |  17 +---
 9 files changed, 294 insertions(+), 88 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 013a9cd..8fcabdb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -12,5 +12,7 @@ Multicast MAC filter = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
+SR-IOV               = Y
+Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 3aedcb8..d13e6cc 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -65,56 +65,115 @@ void bnxt_handle_async_event(struct bnxt *bp,
 
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
 {
+	struct hwrm_exec_fwd_resp_input *fwreq;
 	struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
 	struct input *fwd_cmd;
-	uint16_t logical_vf_id, error_code;
+	uint16_t fw_vf_id;
+	uint16_t vf_id;
+	uint16_t req_len;
+	int rc;
 
-	/* 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;
+	if (bp->pf.active_vfs <= 0) {
+		RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
+		return;
 	}
 
+	/* Qualify the fwd request */
+	fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+	vf_id = fw_vf_id - bp->pf.first_vf_id;
+
+	req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+		   HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+		HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+	if (req_len > sizeof(fwreq->encap_request))
+		req_len = sizeof(fwreq->encap_request);
+
 	/* 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;
+	fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
+
+	if (fw_vf_id < bp->pf.first_vf_id ||
+	    fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+		RTE_LOG(ERR, PMD,
+		"FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
+			fw_vf_id, bp->pf.first_vf_id,
+			(bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
+			bp->pf.first_vf_id, bp->pf.active_vfs);
 		goto reject;
 	}
 
-	/* Forward */
-	fwd_cmd->target_id = fwd_cmpl->source_id;
-	bnxt_hwrm_exec_fwd_resp(bp, fwd_cmd);
-	return;
+	if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
+		/*
+		 * In older firmware versions, the MAC had to be all zeros for
+		 * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
+		 * zeros if it's being configured and has been ok'd by caller.
+		 */
+		if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
+			struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
+
+			if (vfc->enables &
+			    HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
+				bnxt_hwrm_func_vf_mac(bp, vf_id,
+				(const uint8_t *)"\x00\x00\x00\x00\x00");
+			}
+		}
+		if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
+			struct hwrm_cfa_l2_set_rx_mask_input *srm =
+							(void *)fwd_cmd;
+
+			srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
+			srm->num_vlan_tags = rte_cpu_to_le_32(0);
+			srm->mask &= ~rte_cpu_to_le_32(
+				HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
+		}
+		/* Forward */
+		rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+		if (rc) {
+			RTE_LOG(ERR, PMD,
+				"Failed to send FWD req VF 0x%x, type 0x%x.\n",
+				fw_vf_id - bp->pf.first_vf_id,
+				rte_le_to_cpu_16(fwd_cmd->req_type));
+		}
+		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);
+	rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+	if (rc) {
+		RTE_LOG(ERR, PMD,
+			"Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+			fw_vf_id - bp->pf.first_vf_id,
+			rte_le_to_cpu_16(fwd_cmd->req_type));
+	}
+
+	return;
 }
 
 /* For the default completion ring only */
+int bnxt_alloc_def_cp_ring(struct bnxt *bp)
+{
+	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+	int rc;
+
+	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+				  0, HWRM_NA_SIGNATURE);
+	if (rc)
+		goto err_out;
+	cpr->cp_doorbell = bp->pdev->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;
+	if (BNXT_PF(bp))
+		rc = bnxt_hwrm_func_cfg_def_cp(bp);
+	else
+		rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
+
+err_out:
+	return rc;
+}
+
 void bnxt_free_def_cp_ring(struct bnxt *bp)
 {
 	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 83e5376..a6e8785 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -33,6 +33,7 @@
 
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_H_
+#include <stdbool.h>
 
 #include <rte_io.h>
 
@@ -56,6 +57,19 @@
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
 		    ((cpr)->cp_doorbell))
 
+#define B_CP_DB_ARM(cpr)	rte_write32((DB_KEY_CP), ((cpr)->cp_doorbell))
+#define B_CP_DB_DISARM(cpr)	(*(uint32_t *)((cpr)->cp_doorbell) = \
+				 DB_KEY_CP | DB_IRQ_DIS)
+
+#define B_CP_DB_IDX_ARM(cpr, cons)					\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+				(cons)))
+
+#define B_CP_DB_IDX_DISARM(cpr, cons)	do {				\
+		rte_smp_wmb();						\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS |	\
+				(cons));				\
+} while (0)
 #define B_CP_DIS_DB(cpr, raw_cons)					\
 	rte_write32((DB_CP_FLAGS |					\
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
@@ -75,6 +89,8 @@ struct bnxt_cp_ring_info {
 	uint32_t		hw_stats_ctx_id;
 
 	struct bnxt_ring	*cp_ring_struct;
+	uint16_t		cp_cons;
+	bool			v;
 };
 
 #define RX_CMP_L2_ERRORS						\
@@ -82,6 +98,7 @@ struct bnxt_cp_ring_info {
 
 
 struct bnxt;
+int bnxt_alloc_def_cp_ring(struct bnxt *bp);
 void bnxt_free_def_cp_ring(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);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 6e7e4f6..7fe6969 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -228,28 +228,31 @@ static int bnxt_init_chip(struct bnxt *bp)
 
 		rc = bnxt_hwrm_vnic_alloc(bp, vnic);
 		if (rc) {
-			RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
-				rc);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d alloc failure rc: %x\n",
+				i, 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);
+				"HWRM vnic %d ctx alloc failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d cfg failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD,
+				"HWRM vnic %d filter failure rc: %x\n",
+				i, rc);
 			goto err_out;
 		}
 		if (vnic->rss_table && vnic->hash_type) {
@@ -269,8 +272,8 @@ static int bnxt_init_chip(struct bnxt *bp)
 			rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
 			if (rc) {
 				RTE_LOG(ERR, PMD,
-					"HWRM vnic set RSS failure rc: %x\n",
-					rc);
+					"HWRM vnic %d set RSS failure rc: %x\n",
+					i, rc);
 				goto err_out;
 			}
 		}
@@ -638,7 +641,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
 			new.link_speed = ETH_LINK_SPEED_100M;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			RTE_LOG(ERR, PMD,
-				"Failed to retrieve link rc = 0x%x!", rc);
+				"Failed to retrieve link rc = 0x%x!\n", rc);
 			goto out;
 		}
 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
@@ -1010,7 +1013,8 @@ static bool bnxt_vf_pciid(uint16_t id)
 	if (id == BROADCOM_DEV_ID_57304_VF ||
 	    id == BROADCOM_DEV_ID_57406_VF ||
 	    id == BROADCOM_DEV_ID_5731X_VF ||
-	    id == BROADCOM_DEV_ID_5741X_VF)
+	    id == BROADCOM_DEV_ID_5741X_VF ||
+	    id == BROADCOM_DEV_ID_57414_VF)
 		return true;
 	return false;
 }
@@ -1066,7 +1070,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	if (version_printed++ == 0)
-		RTE_LOG(INFO, PMD, "%s", bnxt_version);
+		RTE_LOG(INFO, PMD, "%s\n", bnxt_version);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
@@ -1207,6 +1211,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (rc)
 		goto error_free_int;
 
+	rc = bnxt_alloc_def_cp_ring(bp);
+	if (rc)
+		goto error_free_int;
+
 	bnxt_enable_int(bp);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 137c7b7..0afde86 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -126,7 +126,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 				       "HWRM filter cannot be freed rc = %d\n",
 					rc);
 		}
-		filter->fw_l2_filter_id = -1;
+		filter->fw_l2_filter_id = UINT64_MAX;
 	}
 	STAILQ_INIT(&bp->free_filter_list);
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7aece5d..7c7c9ce 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -33,6 +33,8 @@
 
 #include <unistd.h>
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -286,24 +288,6 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	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_qcaps(struct bnxt *bp)
 {
 	int rc = 0;
@@ -905,12 +889,71 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+static int bnxt_hwrm_vnic_plcmodes_qcfg(struct bnxt *bp,
+					struct bnxt_vnic_info *vnic,
+					struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_QCFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	pmode->flags = rte_le_to_cpu_32(resp->flags);
+	/* dflt_vnic bit doesn't exist in the _cfg command */
+	pmode->flags &= ~(HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC);
+	pmode->jumbo_thresh = rte_le_to_cpu_16(resp->jumbo_thresh);
+	pmode->hds_offset = rte_le_to_cpu_16(resp->hds_offset);
+	pmode->hds_threshold = rte_le_to_cpu_16(resp->hds_threshold);
+
+	return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
+				       struct bnxt_vnic_info *vnic,
+				       struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+	req.flags = rte_cpu_to_le_32(pmode->flags);
+	req.jumbo_thresh = rte_cpu_to_le_16(pmode->jumbo_thresh);
+	req.hds_offset = rte_cpu_to_le_16(pmode->hds_offset);
+	req.hds_threshold = rte_cpu_to_le_16(pmode->hds_threshold);
+	req.enables = rte_cpu_to_le_32(
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID
+	);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	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;
 	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	struct bnxt_plcmodes_cfg pmodes;
+
+	rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
+	if (rc)
+		return rc;
 
 	HWRM_PREP(req, VNIC_CFG, -1, resp);
 
@@ -954,6 +997,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
+	rc = bnxt_hwrm_vnic_plcmodes_cfg(bp, vnic, &pmodes);
+
 	return rc;
 }
 
@@ -1773,6 +1818,25 @@ static void populate_vf_func_cfg_req(struct bnxt *bp,
 						 (num_vfs + 1));
 }
 
+static void add_random_mac_if_needed(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *cfg_req,
+				     int vf)
+{
+	struct ether_addr mac;
+
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac))
+		return;
+
+	if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) {
+		cfg_req->enables |=
+		rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+		eth_random_addr(cfg_req->dflt_mac_addr);
+		bp->pf.vf_info[vf].random_mac = true;
+	} else {
+		memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, ETHER_ADDR_LEN);
+	}
+}
+
 static void reserve_resources_from_vf(struct bnxt *bp,
 				      struct hwrm_func_cfg_input *cfg_req,
 				      int vf)
@@ -1914,6 +1978,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 
 	bp->pf.active_vfs = 0;
 	for (i = 0; i < num_vfs; i++) {
+		add_random_mac_if_needed(bp, &req, i);
+
 		HWRM_PREP(req, FUNC_CFG, -1, resp);
 		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
 		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
@@ -2019,6 +2085,23 @@ int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_vf_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_VF_CFG, -1, resp);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
@@ -2040,3 +2123,42 @@ int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	memcpy(mac->addr_bytes, resp->mac_address, ETHER_ADDR_LEN);
+	return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_exec_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, EXEC_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 0046ba4..1ea78b2 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,7 +51,8 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size);
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size);
 
@@ -62,6 +63,7 @@ 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_func_cfg_def_cp(struct bnxt *bp);
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index 20e17ff..a3d235d 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -66,16 +66,26 @@ static void bnxt_int_handler(void *param)
 			/* Handle any async event */
 			bnxt_handle_async_event(bp, cmp);
 			break;
-		case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+		case CMPL_BASE_TYPE_HWRM_FWD_REQ:
 			/* Handle HWRM forwarded responses */
 			bnxt_handle_fwd_req(bp, cmp);
 			break;
 		default:
 			/* Ignore any other events */
+			if (cmp->type & rte_cpu_to_le_16(0x01)) {
+				if (!CMP_VALID(cmp, raw_cons,
+					       cpr->cp_ring_struct))
+					goto no_more;
+			}
+			RTE_LOG(INFO, PMD,
+				"Ignoring %02x completion\n", CMP_TYPE(cmp));
 			break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
-	}
+
+	};
+no_more:
+	cpr->cp_raw_cons = raw_cons;
 	B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
 }
 
@@ -102,14 +112,15 @@ 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);
+	if (cpr != NULL && cpr->cp_doorbell != NULL)
+		B_CP_DB_DISARM(cpr);
 }
 
 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);
+	B_CP_DB_ARM(cpr);
 }
 
 int bnxt_setup_int(struct bnxt *bp)
@@ -136,7 +147,7 @@ int bnxt_setup_int(struct bnxt *bp)
 	return 0;
 
 setup_exit:
-	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed\n");
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 52fbd89..c1698ea 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -213,21 +213,6 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 	unsigned int i;
 	int rc = 0;
 
-	/* Default completion ring */
-	{
-		struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
-
-		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					0, HWRM_NA_SIGNATURE);
-		if (rc)
-			goto err_out;
-		cpr->cp_doorbell = 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;
@@ -259,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		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!");
+			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 04/26] net/bnxt: support lack of huge pages
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (2 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
                             ` (22 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

rte_malloc_virt2phy() does not return a physical address if huge pages
aren't in use.  Further, rte_memzone->phys_addr is not a physical address.

Use rte_mem_virt2phy() and manually lock pages to support lack of
huge pages.

Also check the return value of rte_mem_virt2phy()

Verify the function returns an address. Otherwise return an error and
log a message.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c | 17 +++++++++++++++--
 drivers/net/bnxt/bnxt_ring.c | 31 +++++++++++++++++++++++++------
 drivers/net/bnxt/bnxt_vnic.c | 16 +++++++++++++++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7c7c9ce..d2a8d8f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -489,8 +489,15 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto error;
 		}
+		rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 		bp->hwrm_cmd_resp_dma_addr =
-			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+			rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+		if (bp->hwrm_cmd_resp_dma_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"Unable to map response buffer to physical memory.\n");
+			rc = -ENOMEM;
+			goto error;
+		}
 		bp->max_resp_len = max_resp_len;
 	}
 
@@ -1363,10 +1370,16 @@ 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);
+	rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 	if (bp->hwrm_cmd_resp_addr == NULL)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
-		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+	if (bp->hwrm_cmd_resp_dma_addr == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map response address to physical memory\n");
+		return -ENOMEM;
+	}
 	rte_spinlock_init(&bp->hwrm_lock);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index c1698ea..5e4236a 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -32,6 +32,7 @@
  */
 
 #include <rte_memzone.h>
+#include <unistd.h>
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
@@ -96,6 +97,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	struct rte_pci_device *pdev = bp->pdev;
 	const struct rte_memzone *mz = NULL;
 	char mz_name[RTE_MEMZONE_NAMESIZE];
+	phys_addr_t mz_phys_addr;
+	int sz;
 
 	int stats_len = (tx_ring_info || rx_ring_info) ?
 	    RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats64)) : 0;
@@ -136,21 +139,37 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
 	mz = rte_memzone_lookup(mz_name);
 	if (!mz) {
-		mz = rte_memzone_reserve(mz_name, total_alloc_len,
+		mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
-					 RTE_MEMZONE_SIZE_HINT_ONLY);
+					 RTE_MEMZONE_SIZE_HINT_ONLY,
+					 getpagesize());
 		if (mz == NULL)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		for (sz = 0; sz < total_alloc_len; sz += getpagesize())
+			rte_mem_lock_page(((char *)mz->addr) + sz);
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map ring address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	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->bd_dma = mz_phys_addr + tx_ring_start;
 		tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
 		tx_ring->mem_zone = (const void *)mz;
 
@@ -170,7 +189,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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->bd_dma = mz_phys_addr + rx_ring_start;
 		rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
 		rx_ring->mem_zone = (const void *)mz;
 
@@ -185,7 +204,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
-	cp_ring->bd_dma = mz->phys_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;
 	cp_ring->mem_zone = (const void *)mz;
@@ -196,7 +215,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		*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_map = mz_phys_addr;
 	}
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 4e378a9..fe2244b 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -173,6 +173,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 				HW_HASH_KEY_SIZE);
 	uint16_t max_vnics;
 	int i;
+	phys_addr_t mz_phys_addr;
 
 	max_vnics = bp->max_vnics;
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
@@ -189,6 +190,19 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 		if (!mz)
 			return -ENOMEM;
 	}
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map vnic address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
@@ -198,7 +212,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 			(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_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));
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 05/26] net/bnxt: add additonal HWRM debug info to error messages
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (3 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 06/26] net/bnxt: add tunneling support Ajit Khaparde
                             ` (21 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

Add the cmd_err and opaque_0 and opaque_1 fields to HWRM error
messages.  These allow better debugging of some classes of HWRM
errors.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d2a8d8f..3c2f148 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -139,7 +139,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 	}
 
 	if (i >= HWRM_CMD_TIMEOUT) {
-		RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+		RTE_LOG(ERR, PMD, "Error sending msg 0x%04x\n",
 			req->req_type);
 		goto err_ret;
 	}
@@ -176,7 +176,22 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 		if (resp->error_code) { \
 			rc = rte_le_to_cpu_16(resp->error_code); \
-			RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \
+			if (resp->resp_len >= 16) { \
+				struct hwrm_err_output *tmp_hwrm_err_op = \
+							(void *)resp; \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d:%d:%08x:%04x\n", \
+					__func__, \
+					rc, tmp_hwrm_err_op->cmd_err, \
+					rte_le_to_cpu_32(\
+						tmp_hwrm_err_op->opaque_0), \
+					rte_le_to_cpu_16(\
+						tmp_hwrm_err_op->opaque_1)); \
+			} \
+			else { \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d\n", __func__, rc); \
+			} \
 			return rc; \
 		} \
 	}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 06/26] net/bnxt: add tunneling support
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (4 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
                             ` (20 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for udp_tunnel_port_add/del dev_ops to configure a UDP port
for VXLAN and Geneve Tunnel protocols.
The HWRM supports only one global destination port for a tunnel type,
use a referene counter to keep track of its usage.
Cache the configured VXLAN/Geneve ports and use that value to check
if the right UDP port is being freed up.
Skip calling bnxt_hwrm_tunnel_dst_port_alloc if the same UDP port is
being programmed.
Skip calling bnxt_hwrm_tunnel_dst_port_free if no UDP port has been
configured.
Also update tx offload capabilities

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |   6 +++
 drivers/net/bnxt/bnxt_ethdev.c | 119 ++++++++++++++++++++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.c   |  56 +++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   5 ++
 drivers/net/bnxt/bnxt_txr.c    |   3 +-
 5 files changed, 187 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 0c59c66..3bc3f99 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -188,6 +188,12 @@ struct bnxt {
 	struct bnxt_pf_info		pf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint8_t			vxlan_port_cnt;
+	uint8_t			geneve_port_cnt;
+	uint16_t		vxlan_port;
+	uint16_t		geneve_port;
+	uint16_t		vxlan_fw_dst_port_id;
+	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7fe6969..076c4ce 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -363,7 +363,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
+					DEV_TX_OFFLOAD_TCP_TSO |
+					DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+					DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+					DEV_TX_OFFLOAD_GRE_TNL_TSO |
+					DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+					DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
 
 	/* *INDENT-OFF* */
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -975,6 +980,116 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
 	return bnxt_set_hwrm_link_config(bp, true);
 }
 
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->vxlan_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->vxlan_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+		bp->vxlan_port_cnt++;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->geneve_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->geneve_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+		bp->geneve_port_cnt++;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+					     tunnel_type);
+	return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	uint16_t port = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (!bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->vxlan_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->vxlan_port);
+			return -EINVAL;
+		}
+		if (--bp->vxlan_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+		port = bp->vxlan_fw_dst_port_id;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (!bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->geneve_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->geneve_port);
+			return -EINVAL;
+		}
+		if (--bp->geneve_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+		port = bp->geneve_fw_dst_port_id;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+	if (!rc) {
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+			bp->vxlan_port = 0;
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+			bp->geneve_port = 0;
+	}
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1006,6 +1121,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.mac_addr_remove = bnxt_mac_addr_remove_op,
 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
+	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
+	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_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 3c2f148..dab4171 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1426,6 +1426,18 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+void bnxt_free_tunnel_ports(struct bnxt *bp)
+{
+	if (bp->vxlan_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN);
+	bp->vxlan_port = 0;
+	if (bp->geneve_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+	bp->geneve_port = 0;
+}
+
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 {
 	struct bnxt_vnic_info *vnic;
@@ -1451,6 +1463,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	bnxt_free_all_hwrm_rings(bp);
 	bnxt_free_all_hwrm_ring_grps(bp);
 	bnxt_free_all_hwrm_stat_ctxs(bp);
+	bnxt_free_tunnel_ports(bp);
 }
 
 static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
@@ -2051,6 +2064,49 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_alloc_input req = {0};
+	struct hwrm_tunnel_dst_port_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_val = port;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	switch (tunnel_type) {
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN:
+		bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->vxlan_port = port;
+		break;
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE:
+		bp->geneve_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->geneve_port = port;
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_free_input req = {0};
+	struct hwrm_tunnel_dst_port_free_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_FREE, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_id = rte_cpu_to_be_16(port);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
 
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1ea78b2..cee8fca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -114,5 +114,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+void bnxt_free_tunnel_ports(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 0d15bb1..6870b16 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -213,7 +213,8 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 			/* TSO */
 			txbd1->lflags = TX_BD_LONG_LFLAGS_LSO;
 			txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
-					tx_pkt->l4_len;
+					tx_pkt->l4_len + tx_pkt->outer_l2_len +
+					tx_pkt->outer_l3_len;
 			txbd1->mss = tx_pkt->tso_segsz;
 
 		} else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM |
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 07/26] net/bnxt: add support for xstats get/reset
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (5 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 06/26] net/bnxt: add tunneling support Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
                             ` (19 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to get and reset xstats dev_ops

dev_ops added:
xstats_get, xstats_get_name, xstats_reset

HWRM commands added:
hwrm_port_qstats, hwrm_port_clr_stats

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |   7 ++
 drivers/net/bnxt/bnxt_ethdev.c |  84 +++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   |  36 +++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   3 +-
 drivers/net/bnxt/bnxt_stats.c  | 207 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h  |  10 ++
 6 files changed, 346 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 3bc3f99..fde2202 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -130,6 +130,7 @@ struct bnxt {
 	uint32_t		flags;
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
+#define BNXT_FLAG_PORT_STATS	(1 << 2)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -138,10 +139,16 @@ struct bnxt {
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	struct bnxt_rx_queue **rx_queues;
+	const void		*rx_mem_zone;
+	struct rx_port_stats    *hw_rx_port_stats;
+	phys_addr_t		hw_rx_port_stats_map;
 
 	unsigned int		tx_nr_rings;
 	unsigned int		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
+	const void		*tx_mem_zone;
+	struct tx_port_stats    *hw_tx_port_stats;
+	phys_addr_t		hw_tx_port_stats_map;
 
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 076c4ce..1e2a8de 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -533,6 +533,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
+	bnxt_hwrm_port_clr_stats(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1123,6 +1124,9 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.xstats_get = bnxt_dev_xstats_get_op,
+	.xstats_get_names = bnxt_dev_xstats_get_names_op,
+	.xstats_reset = bnxt_dev_xstats_reset_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1182,7 +1186,11 @@ static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	const struct rte_memzone *mz = NULL;
 	static int version_printed;
+	uint32_t total_alloc_len;
+	phys_addr_t mz_phys_addr;
 	struct bnxt *bp;
 	int rc;
 
@@ -1208,6 +1216,80 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
+	if (BNXT_PF(bp) && pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) {
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "rx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct rx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->rx_mem_zone = (const void *)mz;
+		bp->hw_rx_port_stats = mz->addr;
+		bp->hw_rx_port_stats_map = mz_phys_addr;
+
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "tx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct tx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->tx_mem_zone = (const void *)mz;
+		bp->hw_tx_port_stats = mz->addr;
+		bp->hw_tx_port_stats_map = mz_phys_addr;
+
+		bp->flags |= BNXT_FLAG_PORT_STATS;
+	}
+
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
@@ -1366,6 +1448,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	}
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
+	rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
+	rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
 	if (bp->pf.vf_info)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dab4171..d942648 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2246,3 +2246,39 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_port_qstats(struct bnxt *bp)
+{
+	struct hwrm_port_qstats_input req = {0};
+	struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_QSTATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	req.tx_stat_host_addr = rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+	req.rx_stat_host_addr = rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+	struct hwrm_port_clr_stats_input req = {0};
+	struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_CLR_STATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index cee8fca..8f7d103 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -119,5 +119,6 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
-
+int bnxt_hwrm_port_qstats(struct bnxt *bp);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 40c9cac..154dc0c 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -43,6 +43,128 @@
 #include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
+static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
+	{"rx_64b_frames", offsetof(struct rx_port_stats,
+				rx_64b_frames)},
+	{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
+				rx_65b_127b_frames)},
+	{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
+				rx_128b_255b_frames)},
+	{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
+				rx_256b_511b_frames)},
+	{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
+				rx_512b_1023b_frames)},
+	{"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
+				rx_1024b_1518_frames)},
+	{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
+				rx_good_vlan_frames)},
+	{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
+				rx_1519b_2047b_frames)},
+	{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
+				rx_2048b_4095b_frames)},
+	{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
+				rx_4096b_9216b_frames)},
+	{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
+				rx_9217b_16383b_frames)},
+	{"rx_total_frames", offsetof(struct rx_port_stats,
+				rx_total_frames)},
+	{"rx_ucast_frames", offsetof(struct rx_port_stats,
+				rx_ucast_frames)},
+	{"rx_mcast_frames", offsetof(struct rx_port_stats,
+				rx_mcast_frames)},
+	{"rx_bcast_frames", offsetof(struct rx_port_stats,
+				rx_bcast_frames)},
+	{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
+				rx_fcs_err_frames)},
+	{"rx_ctrl_frames", offsetof(struct rx_port_stats,
+				rx_ctrl_frames)},
+	{"rx_pause_frames", offsetof(struct rx_port_stats,
+				rx_pause_frames)},
+	{"rx_pfc_frames", offsetof(struct rx_port_stats,
+				rx_pfc_frames)},
+	{"rx_align_err_frames", offsetof(struct rx_port_stats,
+				rx_align_err_frames)},
+	{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
+				rx_ovrsz_frames)},
+	{"rx_jbr_frames", offsetof(struct rx_port_stats,
+				rx_jbr_frames)},
+	{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
+				rx_mtu_err_frames)},
+	{"rx_tagged_frames", offsetof(struct rx_port_stats,
+				rx_tagged_frames)},
+	{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
+				rx_double_tagged_frames)},
+	{"rx_good_frames", offsetof(struct rx_port_stats,
+				rx_good_frames)},
+	{"rx_undrsz_frames", offsetof(struct rx_port_stats,
+				rx_undrsz_frames)},
+	{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
+				rx_eee_lpi_events)},
+	{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
+				rx_eee_lpi_duration)},
+	{"rx_bytes", offsetof(struct rx_port_stats,
+				rx_bytes)},
+	{"rx_runt_bytes", offsetof(struct rx_port_stats,
+				rx_runt_bytes)},
+	{"rx_runt_frames", offsetof(struct rx_port_stats,
+				rx_runt_frames)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
+	{"tx_64b_frames", offsetof(struct tx_port_stats,
+				tx_64b_frames)},
+	{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
+				tx_65b_127b_frames)},
+	{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
+				tx_128b_255b_frames)},
+	{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
+				tx_256b_511b_frames)},
+	{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
+				tx_512b_1023b_frames)},
+	{"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
+				tx_1024b_1518_frames)},
+	{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
+				tx_good_vlan_frames)},
+	{"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
+				tx_1519b_2047_frames)},
+	{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
+				tx_2048b_4095b_frames)},
+	{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
+				tx_4096b_9216b_frames)},
+	{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
+				tx_9217b_16383b_frames)},
+	{"tx_good_frames", offsetof(struct tx_port_stats,
+				tx_good_frames)},
+	{"tx_total_frames", offsetof(struct tx_port_stats,
+				tx_total_frames)},
+	{"tx_ucast_frames", offsetof(struct tx_port_stats,
+				tx_ucast_frames)},
+	{"tx_mcast_frames", offsetof(struct tx_port_stats,
+				tx_mcast_frames)},
+	{"tx_bcast_frames", offsetof(struct tx_port_stats,
+				tx_bcast_frames)},
+	{"tx_pause_frames", offsetof(struct tx_port_stats,
+				tx_pause_frames)},
+	{"tx_pfc_frames", offsetof(struct tx_port_stats,
+				tx_pfc_frames)},
+	{"tx_jabber_frames", offsetof(struct tx_port_stats,
+				tx_jabber_frames)},
+	{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
+				tx_fcs_err_frames)},
+	{"tx_err", offsetof(struct tx_port_stats,
+				tx_err)},
+	{"tx_fifo_underruns", offsetof(struct tx_port_stats,
+				tx_fifo_underruns)},
+	{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
+				tx_eee_lpi_events)},
+	{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
+				tx_eee_lpi_duration)},
+	{"tx_total_collisions", offsetof(struct tx_port_stats,
+				tx_total_collisions)},
+	{"tx_bytes", offsetof(struct tx_port_stats,
+				tx_bytes)},
+};
+
 /*
  * Statistics functions
  */
@@ -140,3 +262,88 @@ void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
 
 	bnxt_clear_all_hwrm_stat_ctxs(bp);
 }
+
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	unsigned int count, i;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
+		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
+		return 0;
+	}
+
+	bnxt_hwrm_port_qstats(bp);
+
+	count = RTE_DIM(bnxt_rx_stats_strings) +
+		RTE_DIM(bnxt_tx_stats_strings);
+
+	if (n < count)
+		return count;
+
+	count = 0;
+	for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+		uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				*(uint64_t *)((char *)rx_stats +
+				bnxt_rx_stats_strings[i].offset));
+		count++;
+	}
+
+	for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+		uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				 *(uint64_t *)((char *)tx_stats +
+				bnxt_tx_stats_strings[i].offset));
+		count++;
+	}
+
+	return count;
+}
+
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit)
+{
+	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+				RTE_DIM(bnxt_tx_stats_strings);
+	unsigned int i, count;
+
+	if (xstats_names != NULL) {
+		count = 0;
+
+		for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_rx_stats_strings[i].name);
+			count++;
+		}
+
+		for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_tx_stats_strings[i].name);
+			count++;
+		}
+	}
+	return stat_cnt;
+}
+
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->flags & BNXT_FLAG_PORT_STATS && !BNXT_NPAR_PF(bp))
+		bnxt_hwrm_port_clr_stats(bp);
+
+	if (BNXT_VF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a VF device\n");
+	if (BNXT_NPAR_PF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a MF device\n");
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		RTE_LOG(ERR, PMD, "Operation not supported\n");
+}
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
index 65408a4..b6d133e 100644
--- a/drivers/net/bnxt/bnxt_stats.h
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -40,5 +40,15 @@ 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);
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit);
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n);
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev);
 
+struct bnxt_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	uint64_t offset;
+};
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 08/26] net/bnxt: add support for VLAN filter and strip
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (6 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
                             ` (18 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds VLAN strip and offload callbacks.
To add a VLAN filter:
    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

To remove a VLAN filter:
    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

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Fix a "pointer from integer" warning seen during compilation
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_ethdev.c    | 201 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 203 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 8fcabdb..78a738f 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -9,6 +9,8 @@ Queue start/stop     = Y
 Promiscuous mode     = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
+VLAN filter          = Y
+VLAN offload         = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1e2a8de..5073cd8 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -141,6 +141,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_TCP |	\
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
+static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
 /***********************/
 
 /*
@@ -487,6 +488,7 @@ static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	int vlan_mask = 0;
 	int rc;
 
 	bp->dev_stopped = 0;
@@ -496,6 +498,13 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 		goto error;
 
 	bnxt_link_update_op(eth_dev, 0);
+
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter)
+		vlan_mask |= ETH_VLAN_FILTER_MASK;
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
+		vlan_mask |= ETH_VLAN_STRIP_MASK;
+	bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+
 	return 0;
 
 error:
@@ -1091,6 +1100,196 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
 	return rc;
 }
 
+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 int i;
+	int rc = 0;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk &&
+				    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 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;
+					RTE_LOG(INFO, PMD,
+						"Del Vlan filter for %d\n",
+						vlan_id);
+				}
+				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 int i;
+	int rc = 0;
+	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
+		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk) {
+					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 |= en;
+				rc = bnxt_hwrm_set_filter(bp, vnic,
+							  new_filter);
+				if (rc)
+					goto exit;
+				RTE_LOG(INFO, PMD,
+					"Added Vlan filter for %d\n", vlan_id);
+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_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	unsigned int i;
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (!dev->data->dev_conf.rxmode.hw_vlan_filter) {
+			/* Remove any VLAN filters programmed */
+			for (i = 0; i < 4095; i++)
+				bnxt_del_vlan_filter(bp, i);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Filtering: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_filter);
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		/* Enable or disable VLAN stripping */
+		for (i = 0; i < bp->nr_vnics; i++) {
+			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+			if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+				vnic->vlan_strip = true;
+			else
+				vnic->vlan_strip = false;
+			bnxt_hwrm_vnic_cfg(bp, vnic);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Strip Offload: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_strip);
+	}
+
+	if (mask & ETH_VLAN_EXTEND_MASK)
+		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
+}
+
 /*
  * Initialization
  */
@@ -1124,6 +1323,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.vlan_filter_set = bnxt_vlan_filter_set_op,
+	.vlan_offload_set = bnxt_vlan_offload_set_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 09/26] net/bnxt: add support for set multicast addr list and MAC addr set
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (7 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
                             ` (17 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for set_mc_addr_list and
mac_addr_set dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Split the patch to document "Allmulticast mode" in bnxt.ini
---
 drivers/net/bnxt/bnxt_ethdev.c | 74 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.c   | 13 +++++---
 drivers/net/bnxt/bnxt_hwrm.h   |  2 +-
 drivers/net/bnxt/bnxt_vnic.c   |  7 +++-
 drivers/net/bnxt/bnxt_vnic.h   |  4 +++
 5 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5073cd8..ef14fb9 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -638,7 +638,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
 	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
 	filter->mac_index = index;
 	memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
-	return bnxt_hwrm_set_filter(bp, vnic, filter);
+	return bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 }
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
@@ -1155,7 +1155,7 @@ static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
 					       filter->l2_addr, ETHER_ADDR_LEN);
 					/* MAC only filter */
 					rc = bnxt_hwrm_set_filter(bp,
-							vnic,
+							vnic->fw_vnic_id,
 							new_filter);
 					if (rc)
 						goto exit;
@@ -1229,7 +1229,7 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
 				new_filter->l2_ovlan = vlan_id;
 				new_filter->l2_ovlan_mask = 0xF000;
 				new_filter->enables |= en;
-				rc = bnxt_hwrm_set_filter(bp, vnic,
+				rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id,
 							  new_filter);
 				if (rc)
 					goto exit;
@@ -1290,6 +1290,72 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
 }
 
+static void
+bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	/* Default Filter is tied to VNIC 0 */
+	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+	struct bnxt_filter_info *filter;
+	int rc;
+
+	if (BNXT_VF(bp))
+		return;
+
+	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
+	memcpy(&dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+	STAILQ_FOREACH(filter, &vnic->filter, next) {
+		/* Default Filter is at Index 0 */
+		if (filter->mac_index != 0)
+			continue;
+		rc = bnxt_hwrm_clear_filter(bp, filter);
+		if (rc)
+			break;
+		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
+		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+		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;
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
+		if (rc)
+			break;
+		filter->mac_index = 0;
+		RTE_LOG(DEBUG, PMD, "Set MAC addr\n");
+	}
+}
+
+static int
+bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
+			  struct ether_addr *mc_addr_set,
+			  uint32_t nb_mc_addr)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	char *mc_addr_list = (char *)mc_addr_set;
+	struct bnxt_vnic_info *vnic;
+	uint32_t off = 0, i = 0;
+
+	vnic = &bp->vnic_info[0];
+
+	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
+		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+		goto allmulti;
+	}
+
+	/* TODO Check for Duplicate mcast addresses */
+	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+	for (i = 0; i < nb_mc_addr; i++) {
+		memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN);
+		off += ETHER_ADDR_LEN;
+	}
+
+	vnic->mc_addr_cnt = i;
+
+allmulti:
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
 /*
  * Initialization
  */
@@ -1325,9 +1391,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_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 d942648..22e18d6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,7 +229,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+	if (vnic->mc_addr_cnt) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
+		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
+	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
 
@@ -261,7 +266,7 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 }
 
 int bnxt_hwrm_set_filter(struct bnxt *bp,
-			 struct bnxt_vnic_info *vnic,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter)
 {
 	int rc = 0;
@@ -275,7 +280,7 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 
 	enables = filter->enables |
 	      HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
-	req.dst_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.dst_id = rte_cpu_to_le_16(dst_id);
 
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
@@ -1419,7 +1424,7 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	int rc = 0;
 
 	STAILQ_FOREACH(filter, &vnic->filter, next) {
-		rc = bnxt_hwrm_set_filter(bp, vnic, filter);
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
 			break;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 8f7d103..c15404f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -49,7 +49,7 @@ 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,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter);
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			    void *encaped, size_t ec_size);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index fe2244b..db9fb07 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -170,7 +170,8 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	char mz_name[RTE_MEMZONE_NAMESIZE];
 	uint32_t entry_length = RTE_CACHE_LINE_ROUNDUP(
 				HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
-				HW_HASH_KEY_SIZE);
+				HW_HASH_KEY_SIZE +
+				BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN);
 	uint16_t max_vnics;
 	int i;
 	phys_addr_t mz_phys_addr;
@@ -218,6 +219,10 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 
 		vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
 			     HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+		vnic->mc_list = (void *)((char *)vnic->rss_hash_key +
+				HW_HASH_KEY_SIZE);
+		vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr +
+				HW_HASH_KEY_SIZE;
 	}
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index ca1c9cf..0d50224 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -57,6 +57,10 @@ struct bnxt_vnic_info {
 	uint16_t	*rss_table;
 	phys_addr_t	rss_hash_key_dma_addr;
 	void		*rss_hash_key;
+	phys_addr_t	mc_list_dma_addr;
+	char		*mc_list;
+	uint32_t	mc_addr_cnt;
+#define BNXT_MAX_MC_ADDRS		16
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 10/26] doc: update bnxt.ini to document Allmulticast mode
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (8 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 11/26] net/bnxt: add support to get fw version Ajit Khaparde
                             ` (16 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch update bnxt.int to document Allmulticast mode
which is already supported by the PMD.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/nics/features/bnxt.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 78a738f..9b3cd94 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -11,6 +11,7 @@ Unicast MAC filter   = Y
 Multicast MAC filter = Y
 VLAN filter          = Y
 VLAN offload         = Y
+Allmulticast mode    = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 11/26] net/bnxt: add support to get fw version
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (9 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 12/26] net/bnxt: add support to set MTU Ajit Khaparde
                             ` (15 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for fw_version_get dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 doc/guides/nics/features/bnxt.ini |  1 +
 drivers/net/bnxt/bnxt_ethdev.c    | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 9b3cd94..b1be3fd 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -16,6 +16,7 @@ RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
+FW version           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index ef14fb9..e987732 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1356,6 +1356,25 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
 }
 
+static int
+bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
+	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
+	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
+	int ret;
+
+	ret = snprintf(fw_version, fw_size, "%d.%d.%d",
+			fw_major, fw_minor, fw_updt);
+
+	ret += 1; /* add the size of '\0' */
+	if (fw_size < (uint32_t)ret)
+		return ret;
+	else
+		return 0;
+}
+
 /*
  * Initialization
  */
@@ -1395,6 +1414,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 };
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 12/26] net/bnxt: add support to set MTU
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (10 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 11/26] net/bnxt: add support to get fw version Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 13/26] net/bnxt: add support for LRO Ajit Khaparde
                             ` (14 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to modify MTU using the set_mtu dev_op.
To support frames > 2k, the PMD creates an aggregator ring.
When a frame greater than 2k is received, it is fragmented
and the resulting fragments are DMA'ed to the aggregator ring.
Now the driver can support jumbo frames upto 9500 bytes.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini      |   2 +
 drivers/net/bnxt/bnxt.h                |   4 +-
 drivers/net/bnxt/bnxt_cpr.c            |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c         |  59 ++++++++++
 drivers/net/bnxt/bnxt_hwrm.c           | 121 ++++++++++++--------
 drivers/net/bnxt/bnxt_hwrm.h           |   4 +-
 drivers/net/bnxt/bnxt_ring.c           |  81 ++++++++++++--
 drivers/net/bnxt/bnxt_ring.h           |   2 +
 drivers/net/bnxt/bnxt_rxq.c            |  29 +++--
 drivers/net/bnxt/bnxt_rxq.h            |   1 +
 drivers/net/bnxt/bnxt_rxr.c            | 195 +++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_rxr.h            |   6 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h |   1 -
 13 files changed, 422 insertions(+), 86 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index b1be3fd..066cb01 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -17,6 +17,8 @@ Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
 FW version           = Y
+Jumbo frame          = Y
+MTU update           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index fde2202..8e6689f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,7 +45,7 @@
 
 #include "bnxt_cpr.h"
 
-#define BNXT_MAX_MTU		9000
+#define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
 
 enum bnxt_hw_context {
@@ -131,6 +131,7 @@ struct bnxt {
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
 #define BNXT_FLAG_PORT_STATS	(1 << 2)
+#define BNXT_FLAG_JUMBO		(1 << 3)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -233,4 +234,5 @@ struct rte_pmd_bnxt_mb_event_param {
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
+#define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index d13e6cc..f369cf6 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -159,7 +159,8 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
 
 	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-				  0, HWRM_NA_SIGNATURE);
+				  0, HWRM_NA_SIGNATURE,
+				  HWRM_NA_SIGNATURE);
 	if (rc)
 		goto err_out;
 	cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e987732..6197be1 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -199,6 +199,14 @@ static int bnxt_init_chip(struct bnxt *bp)
 	struct rte_eth_link new;
 	int rc;
 
+	if (bp->eth_dev->data->mtu > ETHER_MTU) {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+		bp->flags |= BNXT_FLAG_JUMBO;
+	} else {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
 	rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc);
@@ -1375,6 +1383,56 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+	struct bnxt *bp = eth_dev->data->dev_private;
+	struct rte_eth_dev_info dev_info;
+	uint32_t max_dev_mtu;
+	uint32_t rc = 0;
+	uint32_t i;
+
+	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 * 2;
+
+	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) {
+		bp->flags |= BNXT_FLAG_JUMBO;
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+	} else {
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
+	eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+		new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+
+	eth_dev->data->mtu = new_mtu;
+	RTE_LOG(INFO, PMD, "New MTU is %d\n", eth_dev->data->mtu);
+
+	for (i = 0; i < bp->nr_vnics; i++) {
+		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+		vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+		if (rc)
+			break;
+
+		rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1410,6 +1468,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 22e18d6..eb4f540 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -665,20 +665,20 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id)
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id)
 {
 	int rc = 0;
+	uint32_t enables = 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);
+	req.length = rte_cpu_to_le_32(ring->ring_size);
 
 	switch (ring_type) {
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
@@ -686,12 +686,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		/* FALLTHROUGH */
 	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.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id);
 		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);
+		if (stats_ctx_id != INVALID_STATS_CTX_ID)
+			enables |=
+			HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
@@ -700,13 +699,13 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		 * 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:
 		RTE_LOG(ERR, PMD, "hwrm alloc invalid ring type %d\n",
 			ring_type);
 		return -1;
 	}
+	req.enables = rte_cpu_to_le_32(enables);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -837,8 +836,8 @@ 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 int idx)
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
@@ -857,13 +856,12 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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_ctx_free(struct bnxt *bp,
-			    struct bnxt_cp_ring_info *cpr, unsigned int idx)
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
@@ -878,9 +876,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 
 	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;
 }
 
@@ -891,15 +886,10 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
-		}
+	RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
+		vnic->start_grp_id, vnic->end_grp_id);
+	for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++)
 		vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
-	}
 	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
 	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
 	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
@@ -1151,6 +1141,39 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t size;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.flags = rte_cpu_to_le_32(
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
+			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+	req.enables = rte_cpu_to_le_32(
+		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
+//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
+
+	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+	size -= RTE_PKTMBUF_HEADROOM;
+
+	req.jumbo_thresh = rte_cpu_to_le_16(size);
+//	req.hds_threshold = rte_cpu_to_le_16(size);
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1209,14 +1232,20 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
 	struct bnxt_cp_ring_info *cpr;
 
 	for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
-		unsigned int 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);
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
+			cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+			/*
+			 * TODO. Need a better way to reset grp_info.stats_ctx
+			 * for Rx rings only. stats_ctx is not saved for Tx
+			 * in grp_info.
+			 */
+			bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 			if (rc)
 				return rc;
 		}
@@ -1233,7 +1262,6 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 		struct bnxt_tx_queue *txq;
 		struct bnxt_rx_queue *rxq;
 		struct bnxt_cp_ring_info *cpr;
-		unsigned int idx = i + 1;
 
 		if (i >= bp->rx_cp_nr_rings) {
 			txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
@@ -1243,7 +1271,7 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 			cpr = rxq->cp_ring;
 		}
 
-		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, idx);
+		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i);
 
 		if (rc)
 			return rc;
@@ -1253,11 +1281,10 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 
 int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 {
-	uint16_t i;
+	uint16_t idx;
 	uint32_t rc = 0;
 
-	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int idx = i + 1;
+	for (idx = 0; idx < bp->rx_cp_nr_rings; idx++) {
 
 		if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) {
 			RTE_LOG(ERR, PMD,
@@ -1274,8 +1301,8 @@ 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 int idx)
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
@@ -1313,8 +1340,10 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 			txr->tx_prod = 0;
 			txr->tx_cons = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
@@ -1336,17 +1365,26 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 					rxr->rx_ring_struct->ring_size *
 					sizeof(*rxr->rx_buf_ring));
 			rxr->rx_prod = 0;
+			memset(rxr->ag_buf_ring, 0,
+					rxr->ag_ring_struct->ring_size *
+					sizeof(*rxr->ag_buf_ring));
+			rxr->ag_prod = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	/* 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)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, 0);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	return rc;
@@ -1358,14 +1396,7 @@ int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 	uint32_t rc = 0;
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int 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);
-
+		rc = bnxt_hwrm_ring_grp_alloc(bp, i);
 		if (rc)
 			return rc;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index c15404f..79b27ee 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -70,7 +70,7 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id);
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id);
 int bnxt_hwrm_ring_free(struct bnxt *bp,
 			struct bnxt_ring *ring, uint32_t ring_type);
 int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);
@@ -93,6 +93,8 @@ 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_hwrm_vnic_plcmode_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);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 5e4236a..a12c0aa 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -115,8 +115,15 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	int rx_vmem_len = rx_ring_info ?
 		RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
 						rx_ring_struct->vmem_size) : 0;
+	int ag_vmem_start = 0;
+	int ag_vmem_len = 0;
+	int cp_ring_start =  0;
+
+	ag_vmem_start = rx_vmem_start + rx_vmem_len;
+	ag_vmem_len = rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(
+				rx_ring_info->ag_ring_struct->vmem_size) : 0;
+	cp_ring_start = ag_vmem_start + ag_vmem_len;
 
-	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));
 
@@ -131,6 +138,10 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
+	int ag_ring_start = 0;
+
+	ag_ring_start = rx_ring_start + rx_ring_len;
+	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -201,6 +212,24 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->rx_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring = rx_ring_info->ag_ring_struct;
+
+		rx_ring->bd = ((char *)mz->addr + ag_ring_start);
+		rx_ring_info->ag_desc_ring =
+		    (struct rx_prod_pkt_bd *)rx_ring->bd;
+		rx_ring->bd_dma = mz->phys_addr + ag_ring_start;
+		rx_ring_info->ag_desc_mapping = rx_ring->bd_dma;
+		rx_ring->mem_zone = (const void *)mz;
+
+		if (!rx_ring->bd)
+			return -ENOMEM;
+		if (rx_ring->vmem_size) {
+			rx_ring->vmem =
+			    (void **)((char *)mz->addr + ag_vmem_start);
+			rx_ring_info->ag_buf_ring =
+			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+		}
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
@@ -239,35 +268,64 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
 		struct bnxt_ring *ring = rxr->rx_ring_struct;
 		unsigned int idx = i + 1;
+		unsigned int map_idx = idx + bp->rx_cp_nr_rings;
+
+		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+		bp->grp_info[i].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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 		rxr->rx_prod = 0;
 		rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
+		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+		ring = rxr->ag_ring_struct;
+		/* Agg ring */
+		if (ring == NULL)
+			RTE_LOG(ERR, PMD, "Alloc AGG Ring is NULL!\n");
+
+		rc = bnxt_hwrm_ring_alloc(bp, ring,
+				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+				map_idx, HWRM_NA_SIGNATURE,
+				cp_ring->fw_ring_id);
+		if (rc)
+			goto err_out;
+		RTE_LOG(DEBUG, PMD, "Alloc AGG Done!\n");
+		rxr->ag_prod = 0;
+		rxr->ag_doorbell =
+		    (char *)pci_dev->mem_resource[2].addr +
+		    map_idx * 0x80;
+		bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+		rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
 		if (bnxt_init_one_rx_ring(rxq)) {
 			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+		rxq->index = idx;
 	}
 
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
@@ -276,29 +334,34 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 		struct bnxt_tx_ring_info *txr = txq->tx_ring;
 		struct bnxt_ring *ring = txr->tx_ring_struct;
-		unsigned int idx = 1 + bp->rx_cp_nr_rings + i;
+		unsigned int idx = i + 1 + bp->rx_cp_nr_rings;
+
+		/* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
+		idx += bp->rx_cp_nr_rings;
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 
 		cpr->cp_doorbell = (char *)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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 
 		txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
+		txq->index = idx;
 	}
 
 err_out:
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 8656549..b5bd287 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -58,6 +58,7 @@
 #define DEFAULT_TX_RING_SIZE	256
 
 #define MAX_TPA		128
+#define AGG_RING_SIZE_FACTOR 2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
@@ -65,6 +66,7 @@
 #define MAX_CP_DESC_CNT (16 * 1024)
 
 #define INVALID_HW_RING_ID      ((uint16_t)-1)
+#define INVALID_STATS_CTX_ID		((uint16_t)-1)
 
 struct bnxt_ring {
 	void			*bd;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 7625fb1..0d7d708 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -84,9 +84,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 		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;
+		vnic->start_grp_id = 0;
+		vnic->end_grp_id = vnic->start_grp_id;
 		filter = bnxt_alloc_filter(bp);
 		if (!filter) {
 			RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -126,8 +125,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			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;
+		start_grp_id = 0;
+		end_grp_id = nb_q_per_grp;
 
 		ring_idx = 0;
 		for (i = 0; i < pools; i++) {
@@ -188,9 +187,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 	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;
+	vnic->start_grp_id = 0;
+	vnic->end_grp_id = bp->rx_cp_nr_rings;
 	filter = bnxt_alloc_filter(bp);
 	if (!filter) {
 		RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -228,6 +226,16 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 				}
 			}
 		}
+		/* Free up mbufs in Agg ring */
+		sw_ring = rxq->rx_ring->ag_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;
+				}
+			}
+		}
 	}
 }
 
@@ -251,6 +259,8 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 
 		/* Free RX ring hardware descriptors */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* Free RX Agg ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
 
 		/* Free RX completion ring hardware descriptors */
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -295,6 +305,9 @@ 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;
 
+	RTE_LOG(DEBUG, PMD, "RX Buf size is %d\n", rxq->rx_buf_use_size);
+	RTE_LOG(DEBUG, PMD, "RX Buf MTU %d\n", eth_dev->data->mtu);
+
 	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
 	if (rc)
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 9554329..0695214 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -52,6 +52,7 @@ struct bnxt_rx_queue {
 	uint8_t			crc_len; /* 0 if CRC stripped, 4 otherwise */
 
 	struct bnxt		*bp;
+	int			index;
 	struct bnxt_vnic_info	*vnic;
 
 	uint32_t			rx_buf_size;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 5d93de2..04ac673 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -77,6 +77,32 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
+static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
+				     struct bnxt_rx_ring_info *rxr,
+				     uint16_t prod)
+{
+	struct rx_prod_pkt_bd *rxbd = &rxr->ag_desc_ring[prod];
+	struct bnxt_sw_rx_bd *rx_buf = &rxr->ag_buf_ring[prod];
+	struct rte_mbuf *data;
+
+	data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	if (!data)
+		return -ENOMEM;
+
+	if (rxbd == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
+	if (rx_buf == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rx_buf is NULL\n");
+
+
+	rx_buf->mbuf = data;
+
+	rxbd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf));
+
+	return 0;
+}
+
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -94,6 +120,24 @@ static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 	prod_bd->addr = cons_bd->addr;
 }
 
+static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+			       struct rte_mbuf *mbuf)
+{
+	uint16_t prod = rxr->ag_prod;
+	struct bnxt_sw_rx_bd *prod_rx_buf;
+	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+	prod_rx_buf = &rxr->ag_buf_ring[prod];
+
+	prod_rx_buf->mbuf = mbuf;
+
+	prod_bd = &rxr->ag_desc_ring[prod];
+	cons_bd = &rxr->ag_desc_ring[cons];
+
+	prod_bd->addr = cons_bd->addr;
+}
+#endif
+
 static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 			    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -104,9 +148,12 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+	uint16_t ag_cons, ag_prod = rxr->ag_prod;
 	struct bnxt_sw_rx_bd *rx_buf;
 	struct rte_mbuf *mbuf;
 	int rc = 0;
+	uint8_t i;
+	uint8_t agg_buf = 0;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -126,6 +173,9 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	mbuf = rx_buf->mbuf;
 	rte_prefetch0(mbuf);
 
+	if (mbuf == NULL)
+		return -ENOMEM;
+
 	mbuf->nb_segs = 1;
 	mbuf->next = NULL;
 	mbuf->pkt_len = rxcmp->len;
@@ -139,6 +189,63 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->hash.fdir.id = rxcmp1->cfa_code;
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf) {
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
+			       cpr->cp_ring_struct))
+			return -EBUSY;
+		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
+			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
+	}
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		ag_cons = rxcmp->opaque;
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		ag_mbuf->nb_segs = 1;
+		ag_mbuf->data_len = rxcmp->len;
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+		if (mbuf->next == NULL) {
+			mbuf->next = ag_mbuf;
+		} else {
+			struct rte_mbuf *temp_mbuf = mbuf;
+
+			while (temp_mbuf->next != NULL)
+				temp_mbuf = temp_mbuf->next;
+			temp_mbuf->next = ag_mbuf;
+		}
+		ag_buf->mbuf = NULL;
+
+		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
+		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n",
+				ag_prod);
+			rc = -ENOMEM;
+		}
+		rxr->ag_prod = ag_prod;
+
+#ifdef BNXT_DEBUG
+		if (!CMP_VALID((struct cmpl_base *)
+			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
+			cpr->cp_ring_struct))
+			return -EBUSY;
+#endif
+	}
+
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
 			(RX_PKT_CMPL_METADATA_VID_MASK |
@@ -148,13 +255,17 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	}
 
 	rx_buf->mbuf = NULL;
+#ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
 		bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+		if (agg_buf)
+			bnxt_reuse_ag_mbuf(rxr, ag_cons, mbuf);
 
 		rc = -EIO;
 		goto next_rx;
 	}
+#endif
 	/*
 	 * TODO: Redesign this....
 	 * If the allocation fails, the packet does not get received.
@@ -170,24 +281,23 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 * calls in favour of a tight loop with the same function being called
 	 * in it.
 	 */
+	prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	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;
+		//goto next_rx;
 	}
-
+	rxr->rx_prod = prod;
 	/*
 	 * 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;
+#ifdef BNXT_DEBUG
 next_rx:
-	rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
+#endif
+	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -203,8 +313,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	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;
+	uint16_t prod = rxr->rx_prod;
+	uint16_t ag_prod = rxr->ag_prod;
 
 	/* Handle RX burst request */
 	while (1) {
@@ -224,13 +335,13 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 				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) {
+
+	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
 		 * the doorbell if there are no new completions
@@ -240,8 +351,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **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);
+	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+	/* Ring the AGG ring DB */
+	B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
 	return nb_rx_pkts;
 }
 
@@ -257,6 +369,12 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
 		rte_free(rxq->rx_ring->rx_ring_struct);
+
+		/* Free the Aggregator ring */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+		rte_free(rxq->rx_ring->ag_ring_struct);
+		rxq->rx_ring->ag_ring_struct = NULL;
+
 		rte_free(rxq->rx_ring);
 
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -270,13 +388,11 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 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;
 	struct bnxt_rx_ring_info *rxr;
 	struct bnxt_ring *ring;
 
-	rxq->rx_buf_use_size = bp->eth_dev->data->mtu +
-			       ETHER_HDR_LEN + ETHER_CRC_LEN +
+	rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN +
 			       (2 * VLAN_TAG_SIZE);
 	rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
 
@@ -313,13 +429,29 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 	if (ring == NULL)
 		return -ENOMEM;
 	cpr->cp_ring_struct = ring;
-	ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	ring->ring_size = rte_align32pow2(rxr->rx_ring_struct->ring_size *
+					  (2 + AGG_RING_SIZE_FACTOR));
 	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;
 
+	/* Allocate Aggregator rings */
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (ring == NULL)
+		return -ENOMEM;
+	rxr->ag_ring_struct = ring;
+	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc *
+					  AGG_RING_SIZE_FACTOR);
+	ring->ring_mask = ring->ring_size - 1;
+	ring->bd = (void *)rxr->ag_desc_ring;
+	ring->bd_dma = rxr->ag_desc_mapping;
+	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+	ring->vmem = (void **)&rxr->ag_buf_ring;
+
 	return 0;
 }
 
@@ -332,8 +464,8 @@ static void bnxt_init_rxbds(struct bnxt_ring *ring, uint32_t type,
 	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].flags_type = rte_cpu_to_le_16(type);
+		rx_bd_ring[j].len = rte_cpu_to_le_16(len);
 		rx_bd_ring[j].opaque = j;
 	}
 }
@@ -344,12 +476,17 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	struct bnxt_ring *ring;
 	uint32_t prod, type;
 	unsigned int i;
+	uint16_t size;
+
+	size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+	if (rxq->rx_buf_use_size <= size)
+		size = rxq->rx_buf_use_size;
 
-	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
 
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
-	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
+	bnxt_init_rxbds(ring, type, size);
 
 	prod = rxr->rx_prod;
 	for (i = 0; i < ring->ring_size; i++) {
@@ -362,6 +499,24 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		rxr->rx_prod = prod;
 		prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	}
+	RTE_LOG(DEBUG, PMD, "%s\n", __func__);
+
+	ring = rxr->ag_ring_struct;
+	type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
+	bnxt_init_rxbds(ring, type, size);
+	prod = rxr->ag_prod;
+
+	for (i = 0; i < ring->ring_size; i++) {
+		if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+			RTE_LOG(WARNING, PMD,
+			"init'ed AG ring %d with %d/%d mbufs only\n",
+			rxq->queue_id, i, ring->ring_size);
+			break;
+		}
+		rxr->ag_prod = prod;
+		prod = RING_NEXT(rxr->ag_ring_struct, prod);
+	}
+	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index f766b26..e104fbd 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -43,14 +43,20 @@ struct bnxt_sw_rx_bd {
 
 struct bnxt_rx_ring_info {
 	uint16_t		rx_prod;
+	uint16_t		ag_prod;
 	void			*rx_doorbell;
+	void			*ag_doorbell;
 
 	struct rx_prod_pkt_bd	*rx_desc_ring;
+	struct rx_prod_pkt_bd	*ag_desc_ring;
 	struct bnxt_sw_rx_bd	*rx_buf_ring; /* sw ring */
+	struct bnxt_sw_rx_bd	*ag_buf_ring; /* sw ring */
 
 	phys_addr_t		rx_desc_mapping;
+	phys_addr_t		ag_desc_mapping;
 
 	struct bnxt_ring	*rx_ring_struct;
+	struct bnxt_ring	*ag_ring_struct;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 518f16d..2fcfce6 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -7252,7 +7252,6 @@ struct hwrm_vnic_tpa_cfg_output {
 	 */
 } __attribute__((packed));
 
-
 /* hwrm_ring_alloc */
 /*
  * Description: This command allocates and does basic preparation for a ring.
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 13/26] net/bnxt: add support for LRO
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (11 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 12/26] net/bnxt: add support to set MTU Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
                             ` (13 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to enable and disable LRO
To support this feature, the driver creates an aggregrator ring.
When the hardware starts doing LRO, it sends a tpa_start completion.
When the driver receives a tpa_end completion, it indicates that the
LRO chaining is complete.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini |   1 +
 drivers/net/bnxt/bnxt_ethdev.c    |   7 +
 drivers/net/bnxt/bnxt_hwrm.c      |  44 +++++-
 drivers/net/bnxt/bnxt_hwrm.h      |   2 +
 drivers/net/bnxt/bnxt_ring.c      |  32 +++-
 drivers/net/bnxt/bnxt_ring.h      |   4 +-
 drivers/net/bnxt/bnxt_rxq.c       |  12 ++
 drivers/net/bnxt/bnxt_rxq.h       |   2 +
 drivers/net/bnxt/bnxt_rxr.c       | 315 +++++++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_rxr.h       |  40 +++++
 10 files changed, 374 insertions(+), 85 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 066cb01..4fd8abb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -19,6 +19,7 @@ SR-IOV               = Y
 FW version           = Y
 Jumbo frame          = Y
 MTU update           = Y
+LRO                  = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 6197be1..8f8024c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -286,6 +286,13 @@ static int bnxt_init_chip(struct bnxt *bp)
 				goto err_out;
 			}
 		}
+
+		bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
+		else
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index eb4f540..dc4bb1b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1152,19 +1152,15 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
 
 	req.flags = rte_cpu_to_le_32(
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
 			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+
 	req.enables = rte_cpu_to_le_32(
 		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
-//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
 
 	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
 	size -= RTE_PKTMBUF_HEADROOM;
 
 	req.jumbo_thresh = rte_cpu_to_le_16(size);
-//	req.hds_threshold = rte_cpu_to_le_16(size);
 	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -1174,6 +1170,41 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic, bool enable)
+{
+	int rc = 0;
+	struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_TPA_CFG, -1, resp);
+
+	if (enable) {
+		req.enables = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+		req.flags = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+			HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
+		req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+		req.max_agg_segs = rte_cpu_to_le_16(5);
+		req.max_aggs =
+			rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+		req.min_agg_len = rte_cpu_to_le_32(512);
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1493,6 +1524,9 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		bnxt_clear_hwrm_vnic_filters(bp, vnic);
 
 		bnxt_hwrm_vnic_ctx_free(bp, vnic);
+
+		bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
+
 		bnxt_hwrm_vnic_free(bp, vnic);
 	}
 	/* Ring resources */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 79b27ee..6ce0bc3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -95,6 +95,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 				struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic, bool enable);
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index a12c0aa..9d0ae27 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bitmap.h>
 #include <rte_memzone.h>
 #include <unistd.h>
 
@@ -137,11 +138,23 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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;
-	int ag_ring_start = 0;
+	int ag_ring_start = rx_ring_start + rx_ring_len;
+	int ag_ring_len = rx_ring_len * AGG_RING_SIZE_FACTOR;
 
-	ag_ring_start = rx_ring_start + rx_ring_len;
-	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
+	int ag_bitmap_start = ag_ring_start + ag_ring_len;
+	int ag_bitmap_len =  rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(rte_bitmap_get_memory_footprint(
+			rx_ring_info->rx_ring_struct->ring_size *
+			AGG_RING_SIZE_FACTOR)) : 0;
+
+	int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
+	int tpa_info_len = rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
+				       sizeof(struct bnxt_tpa_info)) : 0;
+
+	int total_alloc_len = tpa_info_start;
+	if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+		total_alloc_len += tpa_info_len;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -230,6 +243,17 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->ag_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring_info->ag_bitmap =
+		    rte_bitmap_init(rx_ring_info->rx_ring_struct->ring_size *
+				    AGG_RING_SIZE_FACTOR, (uint8_t *)mz->addr +
+				    ag_bitmap_start, ag_bitmap_len);
+
+		/* TPA info */
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			rx_ring_info->tpa_info =
+				((struct bnxt_tpa_info *)((char *)mz->addr +
+							  tpa_info_start));
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index b5bd287..6d1eb58 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -57,8 +57,8 @@
 #define DEFAULT_RX_RING_SIZE	256
 #define DEFAULT_TX_RING_SIZE	256
 
-#define MAX_TPA		128
-#define AGG_RING_SIZE_FACTOR 2
+#define BNXT_TPA_MAX		64
+#define AGG_RING_SIZE_FACTOR	2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 0d7d708..d8b970e 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -214,6 +214,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 {
 	struct bnxt_sw_rx_bd *sw_ring;
+	struct bnxt_tpa_info *tpa_info;
 	uint16_t i;
 
 	if (rxq) {
@@ -236,6 +237,17 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 				}
 			}
 		}
+
+		/* Free up mbufs in TPA */
+		tpa_info = rxq->rx_ring->tpa_info;
+		if (tpa_info) {
+			for (i = 0; i < BNXT_TPA_MAX; i++) {
+				if (tpa_info[i].mbuf) {
+					rte_pktmbuf_free_seg(tpa_info[i].mbuf);
+					tpa_info[i].mbuf = NULL;
+				}
+			}
+		}
 	}
 }
 
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 0695214..01aaa00 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -59,6 +59,8 @@ struct bnxt_rx_queue {
 	uint32_t			rx_buf_use_size;  /* useable size */
 	struct bnxt_rx_ring_info	*rx_ring;
 	struct bnxt_cp_ring_info	*cp_ring;
+
+	struct bnxt_tpa_info		*rx_tpa;
 };
 
 void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 04ac673..1f0afcb 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -34,6 +34,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <rte_bitmap.h>
 #include <rte_byteorder.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
@@ -102,24 +103,28 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
-#ifdef BNXT_DEBUG
-static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+static inline void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr,
 			       struct rte_mbuf *mbuf)
 {
-	uint16_t prod = rxr->rx_prod;
+	uint16_t prod = RING_NEXT(rxr->rx_ring_struct, rxr->rx_prod);
 	struct bnxt_sw_rx_bd *prod_rx_buf;
-	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+	struct rx_prod_pkt_bd *prod_bd;
 
 	prod_rx_buf = &rxr->rx_buf_ring[prod];
 
+	RTE_ASSERT(prod_rx_buf->mbuf == NULL);
+	RTE_ASSERT(mbuf != NULL);
+
 	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;
+	prod_bd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(mbuf));
+
+	rxr->rx_prod = prod;
 }
 
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -138,7 +143,192 @@ static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 }
 #endif
 
-static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+static inline
+struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr,
+				     uint16_t cons)
+{
+	struct bnxt_sw_rx_bd *cons_rx_buf;
+	struct rte_mbuf *mbuf;
+
+	cons_rx_buf = &rxr->rx_buf_ring[cons];
+	RTE_ASSERT(cons_rx_buf->mbuf != NULL);
+	mbuf = cons_rx_buf->mbuf;
+	cons_rx_buf->mbuf = NULL;
+	return mbuf;
+}
+
+static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
+			   struct rx_tpa_start_cmpl *tpa_start,
+			   struct rx_tpa_start_cmpl_hi *tpa_start1)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
+		RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+	uint16_t data_cons;
+	struct bnxt_tpa_info *tpa_info;
+	struct rte_mbuf *mbuf;
+
+	data_cons = tpa_start->opaque;
+	tpa_info = &rxr->tpa_info[agg_id];
+
+	mbuf = bnxt_consume_rx_buf(rxr, data_cons);
+
+	bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
+
+	tpa_info->mbuf = mbuf;
+	tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
+
+	mbuf->nb_segs = 1;
+	mbuf->next = NULL;
+	mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len);
+	mbuf->data_len = mbuf->pkt_len;
+	mbuf->port = rxq->port_id;
+	mbuf->ol_flags = PKT_RX_LRO;
+	if (likely(tpa_start->flags_type &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS_RSS_VALID))) {
+		mbuf->hash.rss = rte_le_to_cpu_32(tpa_start->rss_hash);
+		mbuf->ol_flags |= PKT_RX_RSS_HASH;
+	} else {
+		mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code);
+		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+	}
+	if (tpa_start1->flags2 &
+	    rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) {
+		mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata);
+		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+	}
+	if (likely(tpa_start1->flags2 &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC)))
+		mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+
+	/* recycle next mbuf */
+	data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons);
+	bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons));
+}
+
+static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr,
+		uint8_t agg_bufs, uint32_t raw_cp_cons)
+{
+	uint16_t last_cp_cons;
+	struct rx_pkt_cmpl *agg_cmpl;
+
+	raw_cp_cons = ADV_RAW_CMP(raw_cp_cons, agg_bufs);
+	last_cp_cons = RING_CMP(cpr->cp_ring_struct, raw_cp_cons);
+	agg_cmpl = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[last_cp_cons];
+	return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct);
+}
+
+/* TPA consume agg buffer out of order, allocate connected data only */
+static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t next = RING_NEXT(rxr->ag_ring_struct, rxr->ag_prod);
+
+	/* TODO batch allocation for better performance */
+	while (rte_bitmap_get(rxr->ag_bitmap, next)) {
+		if (unlikely(bnxt_alloc_ag_data(rxq, rxr, next))) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n", next);
+			break;
+		}
+		rte_bitmap_clear(rxr->ag_bitmap, next);
+		rxr->ag_prod = next;
+		next = RING_NEXT(rxr->ag_ring_struct, next);
+	}
+
+	return 0;
+}
+
+static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
+			 struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
+			 uint8_t agg_buf)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	int i;
+	uint16_t cp_cons, ag_cons;
+	struct rx_pkt_cmpl *rxcmp;
+	struct rte_mbuf *last = mbuf;
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+		bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+		ag_cons = rxcmp->opaque;
+		RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		RTE_ASSERT(ag_mbuf != NULL);
+
+		ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+
+		last->next = ag_mbuf;
+		last = ag_mbuf;
+
+		ag_buf->mbuf = NULL;
+
+		/*
+		 * As aggregation buffer consumed out of order in TPA module,
+		 * use bitmap to track freed slots to be allocated and notified
+		 * to NIC
+		 */
+		rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+	}
+	bnxt_prod_ag_mbuf(rxq);
+	return 0;
+}
+
+static inline struct rte_mbuf *bnxt_tpa_end(
+		struct bnxt_rx_queue *rxq,
+		uint32_t *raw_cp_cons,
+		struct rx_tpa_end_cmpl *tpa_end,
+		struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
+			>> RX_TPA_END_CMPL_AGG_ID_SFT;
+	struct rte_mbuf *mbuf;
+	uint8_t agg_bufs;
+	//unsigned int len;
+	struct bnxt_tpa_info *tpa_info;
+
+	tpa_info = &rxr->tpa_info[agg_id];
+	mbuf = tpa_info->mbuf;
+	RTE_ASSERT(mbuf != NULL);
+
+	rte_prefetch0(mbuf);
+	//len = tpa_info->len;
+	agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
+		RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
+	if (agg_bufs) {
+		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+			return NULL;
+		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+	}
+	mbuf->l4_len = tpa_end->payload_offset;
+
+	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	RTE_ASSERT(new_data != NULL);
+	if (!new_data)
+		return NULL;
+	tpa_info->mbuf = new_data;
+
+	return mbuf;
+}
+
+static int 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;
@@ -148,12 +338,13 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-	uint16_t ag_cons, ag_prod = rxr->ag_prod;
-	struct bnxt_sw_rx_bd *rx_buf;
+#ifdef BNXT_DEBUG
+	uint16_t ag_cons;
+#endif
 	struct rte_mbuf *mbuf;
 	int rc = 0;
-	uint8_t i;
 	uint8_t agg_buf = 0;
+	uint16_t cmp_type;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -165,12 +356,34 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct))
 		return -EBUSY;
 
+	cmp_type = CMP_TYPE(rxcmp);
+	if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_START) {
+		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
+			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
+		rc = -EINVAL; /* Continue w/o new mbuf */
+		goto next_rx;
+	} else if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_END) {
+		mbuf = bnxt_tpa_end(rxq, &tmp_raw_cons,
+				   (struct rx_tpa_end_cmpl *)rxcmp,
+				   (struct rx_tpa_end_cmpl_hi *)rxcmp1);
+		if (unlikely(!mbuf))
+			return -EBUSY;
+		*rx_pkt = mbuf;
+		goto next_rx;
+	} else if (cmp_type != 0x11) {
+		rc = -EINVAL;
+		goto next_rx;
+	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+		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;
+	mbuf = bnxt_consume_rx_buf(rxr, cons);
 	rte_prefetch0(mbuf);
 
 	if (mbuf == NULL)
@@ -190,61 +403,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
 
-	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
-			>> RX_PKT_CMPL_AGG_BUFS_SFT;
-	if (agg_buf) {
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
-			       cpr->cp_ring_struct))
-			return -EBUSY;
-		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
-			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
-	}
-
-	for (i = 0; i < agg_buf; i++) {
-		struct bnxt_sw_rx_bd *ag_buf;
-		struct rte_mbuf *ag_mbuf;
-		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		ag_cons = rxcmp->opaque;
-		ag_buf = &rxr->ag_buf_ring[ag_cons];
-		ag_mbuf = ag_buf->mbuf;
-		ag_mbuf->nb_segs = 1;
-		ag_mbuf->data_len = rxcmp->len;
-
-		mbuf->nb_segs++;
-		mbuf->pkt_len += ag_mbuf->data_len;
-		if (mbuf->next == NULL) {
-			mbuf->next = ag_mbuf;
-		} else {
-			struct rte_mbuf *temp_mbuf = mbuf;
-
-			while (temp_mbuf->next != NULL)
-				temp_mbuf = temp_mbuf->next;
-			temp_mbuf->next = ag_mbuf;
-		}
-		ag_buf->mbuf = NULL;
-
-		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
-		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
-			RTE_LOG(ERR, PMD,
-				"agg mbuf alloc failed: prod=0x%x\n",
-				ag_prod);
-			rc = -ENOMEM;
-		}
-		rxr->ag_prod = ag_prod;
-
-#ifdef BNXT_DEBUG
-		if (!CMP_VALID((struct cmpl_base *)
-			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
-			cpr->cp_ring_struct))
-			return -EBUSY;
-#endif
-	}
+	if (agg_buf)
+		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
 
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
@@ -254,7 +414,6 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
 	}
 
-	rx_buf->mbuf = NULL;
 #ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
@@ -294,10 +453,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 */
 
 	*rx_pkt = mbuf;
-#ifdef BNXT_DEBUG
+
 next_rx:
-#endif
-	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -333,7 +490,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
 			if (likely(!rc))
 				nb_rx_pkts++;
-			else if (rc == -EBUSY)	/* partial completion */
+			if (rc == -EBUSY)	/* partial completion */
 				break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
@@ -341,6 +498,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			break;
 	}
 
+	cpr->cp_raw_cons = raw_cons;
 	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
@@ -348,7 +506,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		 */
 		return nb_rx_pkts;
 	}
-	cpr->cp_raw_cons = raw_cons;
 
 	B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -518,5 +675,15 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	}
 	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
+	if (rxr->tpa_info) {
+		for (i = 0; i < BNXT_TPA_MAX; i++) {
+			rxr->tpa_info[i].mbuf =
+				__bnxt_alloc_rx_data(rxq->mb_pool);
+			if (!rxr->tpa_info[i].mbuf)
+				return -ENOMEM;
+		}
+	}
+	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
+
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e104fbd..f8d6dc8 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -37,6 +37,39 @@
 #define B_RX_DB(db, prod)						\
 		(*(uint32_t *)db = (DB_KEY_RX | prod))
 
+#define BNXT_TPA_L4_SIZE(x)	\
+	{ \
+		typeof(x) hdr_info = (x); \
+		(((hdr_info) & 0xf8000000) ? ((hdr_info) >> 27) : 32) \
+	}
+
+#define BNXT_TPA_INNER_L3_OFF(hdr_info)	\
+	(((hdr_info) >> 18) & 0x1ff)
+
+#define BNXT_TPA_INNER_L2_OFF(hdr_info)	\
+	(((hdr_info) >> 9) & 0x1ff)
+
+#define BNXT_TPA_OUTER_L3_OFF(hdr_info)	\
+	((hdr_info) & 0x1ff)
+
+enum pkt_hash_types {
+	PKT_HASH_TYPE_NONE,	/* Undefined type */
+	PKT_HASH_TYPE_L2,	/* Input: src_MAC, dest_MAC */
+	PKT_HASH_TYPE_L3,	/* Input: src_IP, dst_IP */
+	PKT_HASH_TYPE_L4,	/* Input: src_IP, dst_IP, src_port, dst_port */
+};
+
+struct bnxt_tpa_info {
+	struct rte_mbuf		*mbuf;
+	uint16_t			len;
+	unsigned short		gso_type;
+	uint32_t			flags2;
+	uint32_t			metadata;
+	enum pkt_hash_types	hash_type;
+	uint32_t			rss_hash;
+	uint32_t			hdr_info;
+};
+
 struct bnxt_sw_rx_bd {
 	struct rte_mbuf		*mbuf; /* data associated with RX descriptor */
 };
@@ -57,6 +90,13 @@ struct bnxt_rx_ring_info {
 
 	struct bnxt_ring	*rx_ring_struct;
 	struct bnxt_ring	*ag_ring_struct;
+
+	/*
+	 * To deal with out of order return from TPA, use free buffer indicator
+	 */
+	struct rte_bitmap	*ag_bitmap;
+
+	struct bnxt_tpa_info *tpa_info;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 14/26] net/bnxt: add rxq/txq info_get
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (12 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 13/26] net/bnxt: add support for LRO Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
                             ` (12 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for txq_info_get and rxq_info_get dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 drivers/net/bnxt/bnxt_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 8f8024c..d884c7e 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1390,6 +1390,43 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static void
+bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_rxq_info *qinfo)
+{
+	struct bnxt_rx_queue *rxq;
+
+	rxq = dev->data->rx_queues[queue_id];
+
+	qinfo->mp = rxq->mb_pool;
+	qinfo->scattered_rx = dev->data->scattered_rx;
+	qinfo->nb_desc = rxq->nb_rx_desc;
+
+	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+	qinfo->conf.rx_drop_en = 0;
+	qinfo->conf.rx_deferred_start = 0;
+}
+
+static void
+bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_txq_info *qinfo)
+{
+	struct bnxt_tx_queue *txq;
+
+	txq = dev->data->tx_queues[queue_id];
+
+	qinfo->nb_desc = txq->nb_tx_desc;
+
+	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
+	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
+	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+
+	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
+	qinfo->conf.tx_rs_thresh = 0;
+	qinfo->conf.txq_flags = txq->txq_flags;
+	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
 static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
@@ -1482,6 +1519,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_reset = bnxt_dev_xstats_reset_op,
 	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
+	.rxq_info_get = bnxt_rxq_info_get_op,
+	.txq_info_get = bnxt_txq_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 15/26] net/bnxt: add code to support VLAN pvid
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (13 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
                             ` (11 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds code to support vlan_pvid_set dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c | 21 +++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 31 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |  1 +
 4 files changed, 54 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8e6689f..adf0ab1 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -67,6 +67,7 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
+	uint16_t		dflt_vlan;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d884c7e..178e581 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1477,6 +1477,26 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 	return rc;
 }
 
+static int
+bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint16_t vlan = bp->vlan;
+	int rc;
+
+	if (BNXT_NPAR_PF(bp) || BNXT_VF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"PVID cannot be modified for this function\n");
+		return -ENOTSUP;
+	}
+	bp->vlan = on ? pvid : 0;
+
+	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
+	if (rc)
+		bp->vlan = vlan;
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1512,6 +1532,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
 	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dc4bb1b..3e595c3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2256,6 +2256,37 @@ int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t dflt_vlan, fid;
+	uint32_t func_cfg_flags;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	if (is_vf) {
+		dflt_vlan = bp->pf.vf_info[vf].dflt_vlan;
+		fid = bp->pf.vf_info[vf].fid;
+		func_cfg_flags = bp->pf.vf_info[vf].func_cfg_flags;
+	} else {
+		fid = rte_cpu_to_le_16(0xffff);
+		func_cfg_flags = bp->pf.func_cfg_flags;
+		dflt_vlan = bp->vlan;
+	}
+
+	req.flags = rte_cpu_to_le_32(func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6ce0bc3..1759187 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -123,6 +123,7 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 16/26] net/bnxt: reorg the query stats code
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (14 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 17/26] doc: update default.ini to add LED support Ajit Khaparde
                             ` (10 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

1) Use hwrm_stat_ctx_query command to query statistics
Using hwrm_stat_ctx_query command will allow polling
the statistics from hardware instead of using the current push
model from the hardware which does a DMA of the stats to the host
at fixed intervals.
2) Use the rx_mbuf_alloc_fail to track mbuf alloc failures.
3) We were wrongly incrementing hwrm_cmd_seq in bnxt_hwrm_stat_clear
and bnxt_hwrm_stat_ctx_alloc functions.  This patch fixes that.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c |  2 ++
 drivers/net/bnxt/bnxt_hwrm.c   | 82 ++++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  4 +++
 drivers/net/bnxt/bnxt_rxr.c    | 16 ++++++---
 drivers/net/bnxt/bnxt_stats.c  | 59 ++++--------------------------
 6 files changed, 102 insertions(+), 62 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index adf0ab1..e411704 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -204,6 +204,7 @@ struct bnxt {
 	uint16_t		vxlan_fw_dst_port_id;
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
+	rte_atomic64_t		rx_mbuf_alloc_fail;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 178e581..4576156 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1616,6 +1616,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+
+	rte_atomic64_init(&bp->rx_mbuf_alloc_fail);
 	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3e595c3..a1aa80e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -821,13 +821,12 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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;
 
+	HWRM_PREP(req, STAT_CTX_CLR_STATS, -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));
 
@@ -845,9 +844,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 
 	HWRM_PREP(req, STAT_CTX_ALLOC, -1, resp);
 
-	req.update_period_ms = rte_cpu_to_le_32(1000);
+	req.update_period_ms = rte_cpu_to_le_32(0);
 
-	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);
 
@@ -870,7 +868,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	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));
 
@@ -1227,6 +1224,43 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->ierrors = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->oerrors = rte_le_to_cpu_64(resp->tx_err_pkts);
+
+	stats->imissed = rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -2348,6 +2382,42 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 	return rc;
 }
 
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats)
+{
+	int rc = 0;
+	struct hwrm_stat_ctx_query_input req = {.req_type = 0};
+	struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, STAT_CTX_QUERY, -1, resp);
+
+	req.stat_ctx_id = rte_cpu_to_le_32(cid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->tx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_port_qstats(struct bnxt *bp)
 {
 	struct hwrm_port_qstats_input req = {0};
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1759187..ab42913 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -62,6 +62,8 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *stats);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
@@ -81,6 +83,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned int idx);
 int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 			    struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 1f0afcb..3001d81 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -68,8 +68,10 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	rx_buf->mbuf = data;
 
@@ -87,8 +89,10 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	if (rxbd == NULL)
 		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
@@ -321,8 +325,10 @@ static inline struct rte_mbuf *bnxt_tpa_end(
 
 	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
 	RTE_ASSERT(new_data != NULL);
-	if (!new_data)
+	if (!new_data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return NULL;
+	}
 	tpa_info->mbuf = new_data;
 
 	return mbuf;
@@ -679,8 +685,10 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		for (i = 0; i < BNXT_TPA_MAX; i++) {
 			rxr->tpa_info[i].mbuf =
 				__bnxt_alloc_rx_data(rxq->mb_pool);
-			if (!rxr->tpa_info[i].mbuf)
+			if (!rxr->tpa_info[i].mbuf) {
+				rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 				return -ENOMEM;
+			}
 		}
 	}
 	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 154dc0c..ade8195 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -196,64 +196,18 @@ void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
 
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
+	bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
+	bnxt_stats->rx_nombuf = rte_atomic64_read(&bp->rx_mbuf_alloc_fail);
 }
 
 void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
@@ -261,6 +215,7 @@ 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);
+	rte_atomic64_clear(&bp->rx_mbuf_alloc_fail);
 }
 
 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 17/26] doc: update default.ini to add LED support
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (15 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 18/26] net/bnxt: add support for led on/off Ajit Khaparde
                             ` (9 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Update default.ini to indicate LED on/off support
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/nics/features/default.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index cafc6c7..5549acd 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -60,6 +60,7 @@ Stats per queue      =
 FW version           =
 EEPROM dump          =
 Registers dump       =
+LED                  =
 Multiprocess aware   =
 BSD nic_uio          =
 Linux UIO            =
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 18/26] net/bnxt: add support for led on/off
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (16 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 17/26] doc: update default.ini to add LED support Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
                             ` (8 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for dev_led_on/off dev_ops

HWRM calls added:
bnxt_hwrm_port_led_qcaps()
bnxt_hwrm_port_led_cfg()

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1-v2:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Update bnxt.ini indicating support for LED on/off
---
 doc/guides/nics/features/bnxt.ini      |   1 +
 drivers/net/bnxt/bnxt.h                |  39 ++
 drivers/net/bnxt/bnxt_ethdev.c         |  20 +
 drivers/net/bnxt/bnxt_hwrm.c           |  70 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 977 +++++++++++++++++++++++++++++++++
 6 files changed, 1109 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 4fd8abb..f582836 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -20,6 +20,7 @@ FW version           = Y
 Jumbo frame          = Y
 MTU update           = Y
 LRO                  = Y
+LED                  = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e411704..c23a836 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -47,6 +47,42 @@
 
 #define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
+#define BNXT_MAX_LED		4
+
+struct bnxt_led_info {
+	uint8_t      led_id;
+	uint8_t      led_type;
+	uint8_t      led_group_id;
+	uint8_t      unused;
+	uint16_t  led_state_caps;
+#define BNXT_LED_ALT_BLINK_CAP(x)       ((x) &  \
+	rte_cpu_to_le_16(HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT))
+
+	uint16_t  led_color_caps;
+};
+
+struct bnxt_led_cfg {
+	uint8_t led_id;
+	uint8_t led_state;
+	uint8_t led_color;
+	uint8_t unused;
+	uint16_t led_blink_on;
+	uint16_t led_blink_off;
+	uint8_t led_group_id;
+	uint8_t rsvd;
+};
+
+#define BNXT_LED_DFLT_ENA                               \
+	(HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID |             \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE |          \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON |       \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF |      \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID)
+
+#define BNXT_LED_DFLT_ENA_SHIFT		6
+
+#define BNXT_LED_DFLT_ENABLES(x)                        \
+	rte_cpu_to_le_32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
 
 enum bnxt_hw_context {
 	HW_CONTEXT_NONE     = 0,
@@ -205,6 +241,9 @@ struct bnxt {
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 	rte_atomic64_t		rx_mbuf_alloc_fail;
+
+	struct bnxt_led_info	leds[BNXT_MAX_LED];
+	uint8_t			num_leds;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 4576156..de901eb 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1497,6 +1497,22 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
 	return rc;
 }
 
+static int
+bnxt_dev_led_on_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, true);
+}
+
+static int
+bnxt_dev_led_off_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, false);
+}
+
 /*
  * Initialization
  */
@@ -1542,6 +1558,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 	.rxq_info_get = bnxt_rxq_info_get_op,
 	.txq_info_get = bnxt_txq_info_get_op,
+	.dev_led_on = bnxt_dev_led_on_op,
+	.dev_led_off = bnxt_dev_led_off_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1815,6 +1833,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		}
 	}
 
+	bnxt_hwrm_port_led_qcaps(bp);
+
 	rc = bnxt_setup_int(bp);
 	if (rc)
 		goto error_free;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index a1aa80e..9a04885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2453,3 +2453,73 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
 	HWRM_CHECK_RESULT;
 	return rc;
 }
+
+int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
+{
+	struct hwrm_port_led_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_qcaps_input req = {0};
+	int rc;
+
+	if (BNXT_VF(bp))
+		return 0;
+
+	HWRM_PREP(req, PORT_LED_QCAPS, -1, resp);
+	req.port_id = bp->pf.port_id;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	if (resp->num_leds > 0 && resp->num_leds < BNXT_MAX_LED) {
+		unsigned int i;
+
+		bp->num_leds = resp->num_leds;
+		memcpy(bp->leds, &resp->led0_id,
+			sizeof(bp->leds[0]) * bp->num_leds);
+		for (i = 0; i < bp->num_leds; i++) {
+			struct bnxt_led_info *led = &bp->leds[i];
+
+			uint16_t caps = led->led_state_caps;
+
+			if (!led->led_group_id ||
+				!BNXT_LED_ALT_BLINK_CAP(caps)) {
+				bp->num_leds = 0;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
+{
+	struct hwrm_port_led_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_cfg_input req = {0};
+	struct bnxt_led_cfg *led_cfg;
+	uint8_t led_state = HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT;
+	uint16_t duration = 0;
+	int rc, i;
+
+	if (!bp->num_leds || BNXT_VF(bp))
+		return -EOPNOTSUPP;
+
+	HWRM_PREP(req, PORT_LED_CFG, -1, resp);
+	if (led_on) {
+		led_state = HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT;
+		duration = rte_cpu_to_le_16(500);
+	}
+	req.port_id = bp->pf.port_id;
+	req.num_leds = bp->num_leds;
+	led_cfg = (struct bnxt_led_cfg *)&req.led0_id;
+	for (i = 0; i < bp->num_leds; i++, led_cfg++) {
+		req.enables |= BNXT_LED_DFLT_ENABLES(i);
+		led_cfg->led_id = bp->leds[i].led_id;
+		led_cfg->led_state = led_state;
+		led_cfg->led_blink_on = duration;
+		led_cfg->led_blink_off = duration;
+		led_cfg->led_group_id = bp->leds[i].led_group_id;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index ab42913..3591917 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -130,4 +130,6 @@ void bnxt_free_tunnel_ports(struct bnxt *bp);
 int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
+int bnxt_hwrm_port_led_qcaps(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 2fcfce6..17a912f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -5743,6 +5743,983 @@ struct hwrm_port_clr_stats_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_port_led_cfg */
+/*
+ * Description: This function is used to configure LEDs on a given port. Each
+ * port has individual set of LEDs associated with it. These LEDs are used for
+ * speed/link configuration as well as activity indicator configuration. Up to
+ * three LEDs can be configured, one for activity and two for speeds.
+ */
+/* Input	(64 bytes) */
+struct hwrm_port_led_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the led0_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the led0_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE	UINT32_C(0x2)
+	/* This bit must be '1' for the led0_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_COLOR	UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the led0_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON	UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the led0_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF UINT32_C(0x10)
+	/*
+	 * This bit must be '1' for the led0_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID UINT32_C(0x20)
+	/* This bit must be '1' for the led1_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_ID	UINT32_C(0x40)
+	/* This bit must be '1' for the led1_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_STATE	UINT32_C(0x80)
+	/* This bit must be '1' for the led1_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_COLOR	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the led1_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_ON UINT32_C(0x200)
+	/*
+	 * This bit must be '1' for the led1_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_OFF UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the led1_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_GROUP_ID UINT32_C(0x800)
+	/* This bit must be '1' for the led2_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_ID	UINT32_C(0x1000)
+	/* This bit must be '1' for the led2_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_STATE	UINT32_C(0x2000)
+	/* This bit must be '1' for the led2_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_COLOR	UINT32_C(0x4000)
+	/*
+	 * This bit must be '1' for the led2_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_ON UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the led2_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_OFF UINT32_C(0x10000)
+	/*
+	 * This bit must be '1' for the led2_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_GROUP_ID UINT32_C(0x20000)
+	/* This bit must be '1' for the led3_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_ID	UINT32_C(0x40000)
+	/* This bit must be '1' for the led3_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_STATE  UINT32_C(0x80000)
+	/* This bit must be '1' for the led3_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_COLOR  UINT32_C(0x100000)
+	/*
+	 * This bit must be '1' for the led3_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_ON UINT32_C(0x200000)
+	/*
+	 * This bit must be '1' for the led3_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_OFF	\
+		UINT32_C(0x400000)
+	/*
+	 * This bit must be '1' for the led3_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_GROUP_ID UINT32_C(0x800000)
+	uint16_t port_id;
+	/* Port ID of port whose LEDs are configured. */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are being configured. Up to 4 LEDs
+	 * can be configured with this command.
+	 */
+	uint8_t rsvd;
+	/* Reserved field. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_state;
+	/* The requested state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The requested color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #0 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd0;
+	/* Reserved field. */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_state;
+	/* The requested state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The requested color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #1 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd1;
+	/* Reserved field. */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_state;
+	/* The requested state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The requested color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #2 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd2;
+	/* Reserved field. */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_state;
+	/* The requested state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The requested color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #3 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd3;
+	/* Reserved field. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_led_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcfg */
+/*
+ * Description: This function is used to query configuration of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration. Up to three LEDs can be configured, one for activity and two
+ * for speeds.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(56 bytes) */
+struct hwrm_port_led_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_state;
+	/* The current state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 is not grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_state;
+	/* The current state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 is not grouped. For all other
+	 * non-zero values of this field, LED #1 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_state;
+	/* The current state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 is not grouped. For all other
+	 * non-zero values of this field, LED #2 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_state;
+	/* The current state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 is not grouped. For all other
+	 * non-zero values of this field, LED #3 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t unused_8;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcaps */
+/*
+ * Description: This function is used to query capabilities of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcaps_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(48 bytes) */
+struct hwrm_port_led_qcaps_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t unused_0[3];
+	/* Reserved for future use. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_1;
+	uint16_t led0_state_caps;
+	/* The states supported by LED #0. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led0_color_caps;
+	/* The colors supported by LED #0. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_2;
+	uint16_t led1_state_caps;
+	/* The states supported by LED #1. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led1_color_caps;
+	/* The colors supported by LED #1. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_3;
+	uint16_t led2_state_caps;
+	/* The states supported by LED #2. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led2_color_caps;
+	/* The colors supported by LED #2. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t led3_state_caps;
+	/* The states supported by LED #3. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led3_color_caps;
+	/* The colors supported by LED #3. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_queue_qportcfg */
 /*
  * Description: This function is called by a driver to query queue configuration
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (17 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 18/26] net/bnxt: add support for led on/off Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
                             ` (7 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

Add functions rte_pmd_bnxt_set_tx_loopback,
rte_pmd_bnxt_set_all_queues_drop_en and
rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
queue_drop and VF MAC address setting in the hardware.
It also adds the necessary functions to send the HWRM commands
to the firmware.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add the copyright year.
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/Makefile                     |   4 +
 app/test-pmd/cmdline.c                    |  25 ++++-
 drivers/net/bnxt/Makefile                 |   4 +
 drivers/net/bnxt/bnxt.h                   |   2 +
 drivers/net/bnxt/bnxt_ethdev.c            |  15 +++
 drivers/net/bnxt/bnxt_hwrm.c              | 106 ++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |   4 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 172 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  87 +++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   7 +-
 10 files changed, 422 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 35ecee9..c36be19 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -73,6 +73,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_I40E_PMD),y)
 LDLIBS += -lrte_pmd_i40e
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
+LDLIBS += -lrte_pmd_bnxt
+endif
+
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
 LDLIBS += -lrte_pmd_xenvirt
 endif
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0afac68..26b0da1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -94,6 +94,9 @@
 #ifdef RTE_LIBRTE_I40E_PMD
 #include <rte_pmd_i40e.h>
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
 #include "testpmd.h"
 
 static struct cmdline *testpmd_cl;
@@ -11402,6 +11405,10 @@ cmd_set_tx_loopback_parsed(
 	if (ret == -ENOTSUP)
 		ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_tx_loopback(res->port_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11434,7 +11441,6 @@ cmdline_parse_inst_t cmd_set_tx_loopback = {
 	},
 };
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 /* all queues drop enable configuration */
 
 /* Common result structure for all queues drop enable */
@@ -11480,13 +11486,20 @@ cmd_set_all_queues_drop_en_parsed(
 	__attribute__((unused)) void *data)
 {
 	struct cmd_all_queues_drop_en_result *res = parsed_result;
-	int ret = 0;
+	int ret = -ENOTSUP;
 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
 
 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
 		return;
 
-	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_all_queues_drop_en(res->port_id, is_on);
+#endif
 	switch (ret) {
 	case 0:
 		break;
@@ -11519,6 +11532,7 @@ cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
 	},
 };
 
+#ifdef RTE_LIBRTE_IXGBE_PMD
 /* vf split drop enable configuration */
 
 /* Common result structure for vf split drop enable */
@@ -11673,6 +11687,11 @@ cmd_set_vf_mac_addr_parsed(
 		ret = rte_pmd_i40e_set_vf_mac_addr(res->port_id, res->vf_id,
 				&res->mac_addr);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_mac_addr(res->port_id, res->vf_id,
+				&res->mac_addr);
+#endif
 
 	switch (ret) {
 	case 0:
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0fffe35..b03f65d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -38,6 +38,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnxt.a
 
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
 LIBABIVER := 1
 
 CFLAGS += -O3
@@ -60,10 +62,12 @@ 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
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
 
 #
 # Export include files
 #
 SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include := rte_pmd_bnxt.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c23a836..e918517 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -276,4 +276,6 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
+
+bool is_bnxt_supported(struct rte_eth_dev *dev);
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index de901eb..57f9064 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -142,6 +142,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
 static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
+
 /***********************/
 
 /*
@@ -1936,6 +1937,20 @@ static struct rte_pci_driver bnxt_rte_pmd = {
 	.remove = bnxt_pci_remove,
 };
 
+static bool
+is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
+{
+	if (strcmp(dev->data->drv_name, drv->driver.name))
+		return false;
+
+	return true;
+}
+
+bool is_bnxt_supported(struct rte_eth_dev *dev)
+{
+	return is_device_supported(dev, &bnxt_rte_pmd);
+}
+
 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio");
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9a04885..79c5ca8 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2168,6 +2168,24 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+	req.evb_mode = bp->pf.evb_mode;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type)
 {
@@ -2523,3 +2541,91 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 
 	return rc;
 }
+
+static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
+					uint16_t *vnic_ids)
+{
+	struct hwrm_func_vf_vnic_ids_query_input req = {0};
+	struct hwrm_func_vf_vnic_ids_query_output *resp =
+						bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* First query all VNIC ids */
+	HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY, -1, resp_vf_vnic_ids);
+
+	req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+	req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+	req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2phy(vnic_ids));
+
+	if (req.vnic_id_tbl_addr == 0) {
+		RTE_LOG(ERR, PMD,
+		"unable to map VNIC ID table address to physical memory\n");
+		return -ENOMEM;
+	}
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query error %d\n", rc);
+		return -1;
+	}
+
+	return rte_le_to_cpu_32(resp->vnic_id_cnt);
+}
+
+/*
+ * This function queries the VNIC IDs  for a specified VF. It then calls
+ * the vnic_cb to update the necessary field in vnic_info with cbdata.
+ * Then it calls the hwrm_cb function to program this new vnic configuration.
+ */
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic))
+{
+	struct bnxt_vnic_info vnic;
+	int rc = 0;
+	int i, num_vnic_ids;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	size_t sz;
+
+	/* First query all VNIC ids */
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	num_vnic_ids = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+
+	if (num_vnic_ids < 0)
+		return num_vnic_ids;
+
+	/* Retrieve VNIC, update bd_stall then update */
+
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+		if (rc)
+			break;
+		if (vnic.mru == 4)	/* Indicates unallocated */
+			continue;
+
+		vnic_cb(&vnic, cbdata);
+
+		rc = hwrm_cb(bp, &vnic);
+		if (rc)
+			break;
+	}
+
+	rte_free(vnic_ids);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 3591917..b79df9d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -120,6 +120,7 @@ int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
 int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -132,4 +133,7 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 0000000..57a11a4
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,172 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set Tx loopback on non-PF port %d!\n",
+			port);
+		return -ENOTSUP;
+	}
+
+	if (on)
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+	else
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+	rc = bnxt_hwrm_pf_evb_mode(bp);
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->bd_stall = !(*on);
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	uint32_t i;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set all queues drop on non-PF port!\n");
+		return -ENOTSUP;
+	}
+
+	if (bp->vnic_info == NULL)
+		return -ENODEV;
+
+	/* Stall PF */
+	for (i = 0; i < bp->nr_vnics; i++) {
+		bp->vnic_info[i].bd_stall = !on;
+		rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update PF VNIC %d.\n", i);
+			return rc;
+		}
+	}
+
+	/* Stall all active VFs */
+	for (i = 0; i < bp->pf.active_vfs; i++) {
+		rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
+				rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", i);
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs || mac_addr == NULL)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d mac address on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 0000000..292976d
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,87 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+		struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+#endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 349c6e1..fa291cb 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,9 @@
-DPDK_16.04 {
+DPDK_17.08 {
+	global:
+
+	rte_pmd_bnxt_set_tx_loopback;
+	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_set_vf_mac_addr;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (18 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
                             ` (6 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to
1) enable VF MAC anti spoof.
2) QOS configuration for specified VF.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    |  24 ++-
 app/test-pmd/config.c                     |  20 ++-
 drivers/net/bnxt/bnxt.h                   |   4 +
 drivers/net/bnxt/bnxt_ethdev.c            |  12 +-
 drivers/net/bnxt/bnxt_filter.h            |   2 +
 drivers/net/bnxt/bnxt_hwrm.c              | 117 +++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |  10 +-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 284 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  97 ++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   5 +
 10 files changed, 559 insertions(+), 16 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 26b0da1..90e4a27 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6964,6 +6964,11 @@ cmd_vf_rx_vlan_filter_parsed(void *parsed_result,
 		ret = rte_pmd_i40e_set_vf_vlan_filter(res->port_id,
 				res->vlan_id, res->vf_mask, is_add);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_filter(res->port_id,
+				res->vlan_id, res->vf_mask, is_add);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -7089,7 +7094,6 @@ cmdline_parse_inst_t cmd_queue_rate_limit = {
 	},
 };
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 /* *** SET RATE LIMIT FOR A VF OF A PORT *** */
 struct cmd_vf_rate_limit_result {
 	cmdline_fixed_string_t set;
@@ -7168,7 +7172,6 @@ cmdline_parse_inst_t cmd_vf_rate_limit = {
 		NULL,
 	},
 };
-#endif
 
 /* *** ADD TUNNEL FILTER OF A PORT *** */
 struct cmd_tunnel_filter_result {
@@ -11015,6 +11018,11 @@ cmd_set_vf_vlan_anti_spoof_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_anti_spoof(res->port_id,
 				res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_anti_spoof(res->port_id,
+				res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11116,6 +11124,11 @@ cmd_set_vf_mac_anti_spoof_parsed(
 		ret = rte_pmd_i40e_set_vf_mac_anti_spoof(res->port_id,
 			res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_mac_anti_spoof(res->port_id,
+			res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11217,6 +11230,11 @@ cmd_set_vf_vlan_stripq_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_stripq(res->port_id,
 			res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_stripq(res->port_id,
+			res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -13752,8 +13770,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sa,
 	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
-	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 #endif
+	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 	(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4d873cd..35eddc9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -97,6 +97,9 @@
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
 
 #include "testpmd.h"
 
@@ -3053,20 +3056,27 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	return diag;
 }
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 int
 set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
 {
-	int diag;
+	int diag = -ENOTSUP;
 
-	diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate, q_msk);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (diag == -ENOTSUP)
+		diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate,
+						       q_msk);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (diag == -ENOTSUP)
+		diag = rte_pmd_bnxt_set_vf_rate_limit(port_id, vf, rate, q_msk);
+#endif
 	if (diag == 0)
 		return diag;
-	printf("rte_pmd_ixgbe_set_vf_rate_limit for port_id=%d failed diag=%d\n",
+
+	printf("set_vf_rate_limit for port_id=%d failed diag=%d\n",
 		port_id, diag);
 	return diag;
 }
-#endif
 
 /*
  * Functions to manage the set of filtered Multicast MAC addresses.
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e918517..c1f9095 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -104,6 +104,10 @@ struct bnxt_child_vf_info {
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
 	uint16_t		dflt_vlan;
+	uint16_t		max_tx_rate;
+	uint16_t		vlan_count;
+	uint8_t			mac_spoof_en;
+	uint8_t			vlan_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 57f9064..a710c41 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -295,7 +295,7 @@ static int bnxt_init_chip(struct bnxt *bp)
 		else
 			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
-	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"HWRM cfa l2 rx mask failure rc: %x\n", rc);
@@ -703,7 +703,7 @@ static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
@@ -717,7 +717,7 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
@@ -731,7 +731,7 @@ static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
@@ -745,7 +745,7 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
@@ -1369,7 +1369,7 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	vnic->mc_addr_cnt = i;
 
 allmulti:
-	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 06fe134..353b7f7 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -63,6 +63,8 @@ struct bnxt_filter_info {
 	uint32_t		vni;
 	uint8_t			pri_hint;
 	uint64_t		l2_filter_id_hint;
+	uint32_t		src_id;
+	uint8_t			src_type;
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 79c5ca8..f143541 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -213,7 +213,10 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
-int bnxt_hwrm_cfa_l2_set_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,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table)
 {
 	int rc = 0;
 	struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
@@ -237,6 +240,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
+	if (vlan_count && vlan_table) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
+			 rte_mem_virt2phy(vlan_table));
+		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
+	}
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -296,6 +305,10 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
 		req.l2_ovlan_mask = filter->l2_ovlan_mask;
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
+		req.src_id = rte_cpu_to_le_32(filter->src_id);
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
+		req.src_type = filter->src_type;
 
 	req.enables = rte_cpu_to_le_32(enables);
 
@@ -2230,6 +2243,21 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 	return rc;
 }
 
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
@@ -2339,6 +2367,24 @@ int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
 	return rc;
 }
 
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(enables);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.max_bw = rte_cpu_to_le_32(max_bw);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
@@ -2629,3 +2675,72 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE);
+	req.vlan_antispoof_mode = on ?
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN :
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
+{
+	struct bnxt_vnic_info vnic;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	int num_vnic_ids, i;
+	size_t sz;
+	int rc;
+
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	rc = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+	if (rc <= 0)
+		goto exit;
+	num_vnic_ids = rc;
+
+	/*
+	 * Loop through to find the default VNIC ID.
+	 * TODO: The easier way would be to obtain the resp->dflt_vnic_id
+	 * by sending the hwrm_func_qcfg command to the firmware.
+	 */
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic,
+					bp->pf.first_vf_id + vf);
+		if (rc)
+			goto exit;
+		if (vnic.func_default) {
+			rte_free(vnic_ids);
+			return vnic.fw_vnic_id;
+		}
+	}
+	/* Could not find a default VNIC. */
+	RTE_LOG(ERR, PMD, "No default VNIC\n");
+exit:
+	rte_free(vnic_ids);
+	return -1;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b79df9d..f51ebcf 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -45,7 +45,9 @@ 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_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table);
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 int bnxt_hwrm_set_filter(struct bnxt *bp,
@@ -121,6 +123,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -133,7 +137,11 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on);
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 57a11a4..4a714b1 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -33,6 +33,7 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <unistd.h>
 
 #include <rte_dev.h>
 #include <rte_ethdev.h>
@@ -170,3 +171,286 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk)
+{
+	struct rte_eth_dev *eth_dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	uint16_t tot_rate = 0;
+	uint64_t idx;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!bp->pf.active_vfs)
+		return -EINVAL;
+
+	if (vf >= bp->pf.max_vfs)
+		return -EINVAL;
+
+	/* Add up the per queue BW and configure MAX BW of the VF */
+	for (idx = 0; idx < 64; idx++) {
+		if ((1ULL << idx) & q_msk)
+			tot_rate += tx_rate;
+	}
+
+	/* Requested BW can't be greater than link speed */
+	if (tot_rate > eth_dev->data->dev_link.link_speed) {
+		RTE_LOG(ERR, PMD, "Rate > Link speed. Set to %d\n", tot_rate);
+		return -EINVAL;
+	}
+
+	/* Requested BW already configured */
+	if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
+		return 0;
+
+	rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
+				HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
+
+	if (!rc)
+		bp->pf.vf_info[vf].max_tx_rate = tot_rate;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	uint32_t func_flags;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	/* Prev setting same as new setting. */
+	if (on == bp->pf.vf_info[vf].mac_spoof_en)
+		return 0;
+
+	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+	if (on)
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
+	else
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+
+	bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf);
+	if (!rc)
+		bp->pf.vf_info[vf].mac_spoof_en = on;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	struct bnxt *bp;
+	int rc;
+	int dflt_vnic;
+	struct bnxt_vnic_info vnic;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
+	if (!rc) {
+		bp->pf.vf_info[vf].vlan_spoof_en = on;
+		if (on) {
+			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+			if (dflt_vnic < 0) {
+				/*
+				 * This simply indicates there's no driver
+				 * loaded.  This is not an error.
+				 */
+				RTE_LOG(ERR, PMD,
+				      "Unable to get default VNIC for VF %d\n",
+					vf);
+			} else {
+				vnic.fw_vnic_id = dflt_vnic;
+				if (bnxt_hwrm_vnic_qcfg(bp,
+					&vnic, bp->pf.first_vf_id + vf) == 0) {
+					if (bnxt_hwrm_cfa_l2_set_rx_mask(bp,
+					   &vnic, bp->pf.vf_info[vf].vlan_count,
+					   bp->pf.vf_info[vf].vlan_table))
+						rc = -1;
+				}
+			}
+		}
+	} else {
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+	}
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->vlan_strip = *on;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d stripq on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+				rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+	if (rc)
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	int i, j;
+	int rc = 0;
+	struct bnxt_vlan_table_entry *ve;
+	uint16_t cnt;
+
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	for (i = 0; vf_mask; i++, vf_mask >>= 1) {
+		cnt = bp->pf.vf_info[i].vlan_count;
+		if (vf_mask & 1) {
+			if (bp->pf.vf_info[i].vlan_table == NULL) {
+				rc = -1;
+				continue;
+			}
+			if (vlan_on) {
+				/* First, search for a duplicate... */
+				for (j = 0; j < cnt; j++) {
+					if (rte_be_to_cpu_16(
+					 bp->pf.vf_info[i].vlan_table[j].vid) ==
+					    vlan)
+						break;
+				}
+				if (j == cnt) {
+					/* Now check that there's space */
+					if (cnt == getpagesize() /
+					 sizeof(struct bnxt_vlan_table_entry)) {
+						RTE_LOG(ERR, PMD,
+						  "VF %d VLAN table is full\n",
+						  i);
+						RTE_LOG(ERR, PMD,
+							"cannot add VLAN %u\n",
+							vlan);
+						rc = -1;
+						continue;
+					}
+
+					cnt = bp->pf.vf_info[i].vlan_count++;
+					/*
+					 * And finally, add to the
+					 * end of the table
+					 */
+					ve = &bp->pf.vf_info[i].vlan_table[cnt];
+					// TODO: Hardcoded TPID
+					ve->tpid = rte_cpu_to_be_16(0x8100);
+					ve->vid = rte_cpu_to_be_16(vlan);
+				}
+			} else {
+				for (j = 0; cnt; j++) {
+					if (rte_be_to_cpu_16(
+					bp->pf.vf_info[i].vlan_table[j].vid) !=
+					    vlan)
+						continue;
+					memmove(
+					 &bp->pf.vf_info[i].vlan_table[j],
+					 &bp->pf.vf_info[i].vlan_table[j + 1],
+					 getpagesize() -
+					 ((j + 1) *
+					 sizeof(struct bnxt_vlan_table_entry)));
+					j--;
+					cnt = bp->pf.vf_info[i].vlan_count--;
+				}
+			}
+			rte_pmd_bnxt_set_vf_vlan_anti_spoof(dev->data->port_id,
+					 i, bp->pf.vf_info[i].vlan_spoof_en);
+		}
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 292976d..b9176cd 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -37,6 +37,24 @@
 #include <rte_ethdev.h>
 
 /**
+ * Enable/Disable VF MAC anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF MAC anti spoof.
+ *    0 - Disable VF MAC anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
  * Set the VF MAC address.
  *
  * @param port
@@ -54,6 +72,48 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 		struct ether_addr *mac_addr);
 
 /**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
+ * received VLAN packets tagged with a given VLAN Tag Identifier.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vlan
+ *   The VLAN Tag Identifier whose filtering must be enabled or disabled.
+ * @param vf_mask
+ *    Bitmap listing which VFs participate in the VLAN filtering.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN filtering.
+ *    0 - Disable VFs VLAN filtering.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on);
+
+/**
  * Enable/Disable tx loopback
  *
  * @param port
@@ -84,4 +144,41 @@ int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * Set the VF rate limit.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param tx_rate
+ *   Tx rate for the VF
+ * @param q_msk
+ *   Mask of the Tx queue
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk);
+
+/**
+ * Enable/Disable VF VLAN anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF VLAN anti spoof.
+ *    0 - Disable VF VLAN anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index fa291cb..770b076 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -4,6 +4,11 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
 	rte_pmd_bnxt_set_vf_mac_addr;
+	rte_pmd_bnxt_set_vf_mac_anti_spoof;
+	rte_pmd_bnxt_set_vf_rate_limit;
+	rte_pmd_bnxt_set_vf_vlan_stripq;
+	rte_pmd_bnxt_set_vf_vlan_filter;
+	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 21/26] net/bnxt: add support to get and clear VF specific stats
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (19 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
                             ` (5 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to get and clear VF stats.
It also adds the necessary HWRM structures to send the command
to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - Move the PF related MAC/VLAN anti spoof counter to xstats.
---
 app/test-pmd/cmdline.c                    | 23 +++++++--
 drivers/net/bnxt/bnxt_hwrm.c              | 38 ++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  3 ++
 drivers/net/bnxt/bnxt_stats.c             | 60 +++++++++++++++++++++-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 83 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 52 +++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  3 ++
 7 files changed, 255 insertions(+), 7 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 90e4a27..f49d83b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -13079,9 +13079,16 @@ cmd_show_vf_stats_parsed(
 	memset(&stats, 0, sizeof(stats));
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_get_vf_stats(res->port_id,
-					res->vf_id,
-					&stats);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
 #endif
 
 	switch (ret) {
@@ -13177,8 +13184,14 @@ cmd_clear_vf_stats_parsed(
 		return;
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
-					  res->vf_id);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
+						  res->vf_id);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_reset_vf_stats(res->port_id,
+						  res->vf_id);
 #endif
 
 	switch (ret) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index f143541..6ea31ca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1237,6 +1237,27 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (dropped)
+		*dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats)
 {
@@ -1274,6 +1295,23 @@ int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 	return rc;
 }
 
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	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 f51ebcf..5aaf947 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -66,6 +66,9 @@ int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index ade8195..d7d0e35 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -165,6 +165,49 @@ static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
 				tx_bytes)},
 };
 
+static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
+	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_pkts)},
+	{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_pkts)},
+	{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_pkts)},
+	{"tx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_err_pkts)},
+	{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_drop_pkts)},
+	{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_bytes)},
+	{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_bytes)},
+	{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_bytes)},
+	{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_pkts)},
+	{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_pkts)},
+	{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_pkts)},
+	{"rx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_err_pkts)},
+	{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_drop_pkts)},
+	{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_bytes)},
+	{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_bytes)},
+	{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_bytes)},
+	{"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_pkts)},
+	{"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_bytes)},
+	{"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_events)},
+	{"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_aborts)},
+};
+
 /*
  * Statistics functions
  */
@@ -224,6 +267,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 
 	unsigned int count, i;
+	uint64_t tx_drop_pkts;
 
 	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
 		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
@@ -231,9 +275,10 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	}
 
 	bnxt_hwrm_port_qstats(bp);
+	bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
 
 	count = RTE_DIM(bnxt_rx_stats_strings) +
-		RTE_DIM(bnxt_tx_stats_strings);
+		RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
 
 	if (n < count)
 		return count;
@@ -255,6 +300,10 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+	/* The Tx drop pkts aka the Anti spoof coounter */
+	xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
+	count++;
+
 	return count;
 }
 
@@ -262,8 +311,9 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 	struct rte_eth_xstat_name *xstats_names,
 	__rte_unused unsigned int limit)
 {
+	/* Account for the Tx drop pkts aka the Anti spoof counter */
 	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
-				RTE_DIM(bnxt_tx_stats_strings);
+				RTE_DIM(bnxt_tx_stats_strings) + 1;
 	unsigned int i, count;
 
 	if (xstats_names != NULL) {
@@ -284,6 +334,12 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 				bnxt_tx_stats_strings[i].name);
 			count++;
 		}
+
+		snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_func_stats_strings[4].name);
+		count++;
 	}
 	return stat_cnt;
 }
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 4a714b1..d9e97ab 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -454,3 +454,86 @@ int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to get VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to reset VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d TX drops on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+					     count);
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index b9176cd..eef5212 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -165,6 +165,41 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
 
 /**
+ * Get VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param stats
+ *    A pointer to a structure of type *rte_eth_stats* to be filled with
+ *    the values of device counters supported statistics:
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id);
+
+/**
  * Enable/Disable VF VLAN anti spoof
  *
  * @param port
@@ -181,4 +216,21 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 770b076..f0eda7b 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -9,6 +9,9 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_stripq;
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+	rte_pmd_bnxt_get_vf_stats;
+	rte_pmd_bnxt_reset_vf_stats;
+	rte_pmd_bnxt_get_vf_tx_drop_count;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (20 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01 12:28             ` Ferruh Yigit
  2017-06-01  3:02           ` [PATCH v3 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
                             ` (4 subsequent siblings)
  26 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to determine the Rx status of a VF.
It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
the VNIC count of the function to get the Rx status.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
---
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 42 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 17 +++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 85 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6ea31ca..721e652 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2626,6 +2626,30 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 	return rc;
 }
 
+static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
+{
+	uint32_t *count = cbdata;
+
+	if (vnic->func_default)
+		*count = *count + 1;
+}
+
+static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
+				     struct bnxt_vnic_info *vnic __rte_unused)
+{
+	return 0;
+}
+
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf)
+{
+	uint32_t count = 0;
+
+	bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, bnxt_vnic_count,
+	    &count, bnxt_vnic_count_hwrm_stub);
+
+	return count;
+}
+
 static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
 					uint16_t *vnic_ids)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 5aaf947..01e72fa 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -141,6 +141,7 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index d9e97ab..a4bae26 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -510,6 +510,48 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
 	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
 }
 
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d RX stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_vf_default_vnic_count(bp, vf_id);
+}
+
+int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
+}
+
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index eef5212..e69910e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -217,6 +217,23 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+
+/**
+ * Returns the number of default RX queues on a VF
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @return
+ *   - Non-negative value - Number of default RX queues
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if on a function without VFs
+ *   - (-ENOMEM) on an allocation failure
+ *   - (-1) firmware interface error
+ */
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
+
 /**
  * Queries the TX drop counter for the function
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index f0eda7b..c68c125 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -3,6 +3,7 @@ DPDK_17.08 {
 
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_get_vf_rx_status;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 23/26] net/bnxt: add support to add a VF MAC address
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (21 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
                             ` (3 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support to allocate a filter and program
it in the hardware for every MAC address added to the specified
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
---
 drivers/net/bnxt/bnxt_filter.c            | 22 +++++++++
 drivers/net/bnxt/bnxt_filter.h            |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 76 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 18 ++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 118 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 0afde86..e9aac27 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -68,6 +68,22 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
 	return filter;
 }
 
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+	struct bnxt_filter_info *filter;
+
+	filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+	if (!filter) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for VF %hu filters\n",
+			vf);
+		return NULL;
+	}
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+	return filter;
+}
+
 void bnxt_init_filters(struct bnxt *bp)
 {
 	struct bnxt_filter_info *filter;
@@ -102,6 +118,12 @@ void bnxt_free_all_filters(struct bnxt *bp)
 			STAILQ_INIT(&vnic->filter);
 		}
 	}
+
+	for (i = 0; i < bp->pf.max_vfs; i++) {
+		STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+			bnxt_hwrm_clear_filter(bp, filter);
+		}
+	}
 }
 
 void bnxt_free_filter_mem(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 353b7f7..613b2ee 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -68,6 +68,7 @@ struct bnxt_filter_info {
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
 void bnxt_init_filters(struct bnxt *bp);
 void bnxt_free_all_filters(struct bnxt *bp);
 void bnxt_free_filter_mem(struct bnxt *bp);
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index a4bae26..a2c0a0e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -579,3 +579,79 @@ int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
 					     count);
 }
+
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
+				uint32_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	struct bnxt_filter_info *filter;
+	struct bnxt_vnic_info vnic;
+	struct ether_addr dflt_mac;
+	int rc;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to config VF %d MAC on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	/* If the VF currently uses a random MAC, update default to this one */
+	if (bp->pf.vf_info[vf_id].random_mac) {
+		if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+			rc = bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+	}
+
+	/* query the default VNIC id used by the function */
+	rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+	if (rc < 0)
+		goto exit;
+
+	memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+	vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+	rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+	if (rc < 0)
+		goto exit;
+
+	STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+		if (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) &&
+		    memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+			bnxt_hwrm_clear_filter(bp, filter);
+			break;
+		}
+	}
+
+	if (filter == NULL)
+		filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	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, addr, ETHER_ADDR_LEN);
+	memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+	/* Do not add a filter for the default MAC */
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+	    memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+		rc = bnxt_hwrm_set_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index e69910e..f1127a6 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -250,4 +250,22 @@ int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
  */
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param mac_addr
+ *    The MAC address to be programmed in the filter.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ *   - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
+				uint32_t vf_id);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index c68c125..e3cc7bc 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -13,6 +13,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_stats;
 	rte_pmd_bnxt_reset_vf_stats;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
+	rte_pmd_bnxt_mac_addr_add;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 24/26] net/bnxt: add code to configure a default VF VLAN
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (22 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
                             ` (2 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to insert a default VF VLAN.
Also track the current default VLAN per vnic for the VF.
When setting the default VLAN, avoid setting it to the current value.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    |  5 ++++
 drivers/net/bnxt/bnxt.h                   |  2 +-
 drivers/net/bnxt/bnxt_hwrm.c              | 39 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 50 +++++++++++++++++++++++++++++--
 drivers/net/bnxt/rte_pmd_bnxt.h           | 22 +++++++++++++-
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 7 files changed, 117 insertions(+), 4 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f49d83b..ff623c1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -11334,6 +11334,11 @@ cmd_set_vf_vlan_insert_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id,
 			res->vlan_id);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_insert(res->port_id, res->vf_id,
+			res->vlan_id);
+#endif
 
 	switch (ret) {
 	case 0:
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c1f9095..54428ba 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -103,8 +103,8 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
-	uint16_t		dflt_vlan;
 	uint16_t		max_tx_rate;
+	uint16_t		dflt_vlan;
 	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
 	uint8_t			vlan_spoof_en;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 721e652..bf0526d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2069,6 +2069,27 @@ static void reserve_resources_from_vf(struct bnxt *bp,
 	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
 }
 
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Check for zero MAC address */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg error %d\n", rc);
+		return -1;
+	}
+	return rte_le_to_cpu_16(resp->vlan);
+}
+
 static int update_pf_resource_max(struct bnxt *bp)
 {
 	struct hwrm_func_qcfg_input req = {0};
@@ -2423,6 +2444,24 @@ int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(bp->pf.vf_info[vf].dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 01e72fa..33d2885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -128,8 +128,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 			uint16_t max_bw, uint16_t enables);
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index a2c0a0e..4006141 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -377,18 +377,64 @@ rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
 	return rc;
 }
 
-int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d vlan insert on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	bp->pf.vf_info[vf].dflt_vlan = vlan_id;
+	if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
+	    bp->pf.vf_info[vf].dflt_vlan)
+		return 0;
+
+	rc = bnxt_hwrm_set_vf_vlan(bp, vf);
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
-	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
 	int i, j;
 	int rc = 0;
 	struct bnxt_vlan_table_entry *ve;
 	uint16_t cnt;
 
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
 	if (!is_bnxt_supported(dev))
 		return -ENOTSUP;
 
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
 	if (!bp->pf.vf_info)
 		return -EINVAL;
 
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index f1127a6..2144601 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -92,6 +92,26 @@ int
 rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
 
 /**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param vlan_id
+ *    0 - Disable VF's vlan insert.
+ *    n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id);
+
+/**
  * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
  * received VLAN packets tagged with a given VLAN Tag Identifier.
  *
@@ -110,7 +130,7 @@ rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
  *   - (-ENODEV) if *port_id* invalid.
  *   - (-EINVAL) if bad parameter.
  */
-int rte_pmd_bnxt_set_vf_vlan_filter(struct rte_eth_dev *dev, uint16_t vlan,
+int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on);
 
 /**
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index e3cc7bc..9433a1e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -14,6 +14,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_reset_vf_stats;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_mac_addr_add;
+	rte_pmd_bnxt_set_vf_vlan_insert;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 25/26] net/bnxt: add support to set VF rxmode
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (23 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01  3:02           ` [PATCH v3 26/26] doc: update release notes Ajit Khaparde
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to configure the VF L2 Rx settings.
The per VF setting is maintained in bnxt_child_vf_info.l2_rx_mask

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    | 15 +++++++--
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/bnxt_rxq.c               | 13 ++++++--
 drivers/net/bnxt/bnxt_vnic.h              |  5 +++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 54 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 19 +++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 8 files changed, 124 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ff623c1..28ff7cf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6802,7 +6802,7 @@ cmd_set_vf_rxmode_parsed(void *parsed_result,
 		       __attribute__((unused)) struct cmdline *cl,
 		       __attribute__((unused)) void *data)
 {
-	int ret;
+	int ret = -ENOTSUP;
 	uint16_t rx_mode = 0;
 	struct cmd_set_vf_rxmode *res = parsed_result;
 
@@ -6818,7 +6818,16 @@ cmd_set_vf_rxmode_parsed(void *parsed_result,
 			rx_mode |= ETH_VMDQ_ACCEPT_MULTICAST;
 	}
 
-	ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id, rx_mode, (uint8_t)is_on);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id,
+						  rx_mode, (uint8_t)is_on);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_rxmode(res->port_id, res->vf_id,
+						 rx_mode, (uint8_t)is_on);
+#endif
 	if (ret < 0)
 		printf("bad VF receive mode parameter, return code = %d \n",
 		ret);
@@ -13786,9 +13795,9 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_macsec_offload_off,
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sc,
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sa,
-	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
 #endif
+	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 	(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index bf0526d..6d98d5a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,23 +229,29 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
 	/* FIXME add multicast flag, when multicast adding options is supported
 	 * by ethtool.
 	 */
+	if (vnic->flags & BNXT_VNIC_INFO_BCAST)
+		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST;
+	if (vnic->flags & BNXT_VNIC_INFO_UNTAGGED)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN;
 	if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
-		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+		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;
+	if (vnic->flags & BNXT_VNIC_INFO_MCAST)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 	if (vnic->mc_addr_cnt) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
 		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
 	}
-	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
-				    mask);
 	if (vlan_count && vlan_table) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
 		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
 			 rte_mem_virt2phy(vlan_table));
 		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
 	}
+	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
+				    mask);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -2317,6 +2323,18 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
 	return rc;
 }
 
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp)
+{
+	uint32_t *flag = flagp;
+
+	vnic->flags = *flag;
+}
+
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 33d2885..a603dda 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -143,6 +143,8 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index d8b970e..0793820 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -76,6 +76,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto err_out;
 		}
+		vnic->flags |= BNXT_VNIC_INFO_BCAST;
 		STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
 		bp->nr_vnics++;
 
@@ -120,6 +121,9 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		}
 		/* For each pool, allocate MACVLAN CFA rule & VNIC */
 		if (!pools) {
+			pools = RTE_MIN(bp->max_vnics,
+			    RTE_MIN(bp->max_l2_ctx,
+			     RTE_MIN(bp->max_rsscos_ctx, ETH_64_POOLS)));
 			RTE_LOG(ERR, PMD,
 				"VMDq pool not set, defaulted to 64\n");
 			pools = ETH_64_POOLS;
@@ -137,6 +141,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 				rc = -ENOMEM;
 				goto err_out;
 			}
+			vnic->flags |= BNXT_VNIC_INFO_BCAST;
 			STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
 			bp->nr_vnics++;
 
@@ -177,6 +182,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		rc = -ENOMEM;
 		goto err_out;
 	}
+	vnic->flags |= BNXT_VNIC_INFO_BCAST;
 	/* 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];
@@ -295,7 +301,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
-		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+		RTE_LOG(ERR, PMD, "nb_desc %d is invalid\n", nb_desc);
 		rc = -EINVAL;
 		goto out;
 	}
@@ -308,7 +314,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	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!");
+		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -333,7 +339,8 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	/* Allocate RX ring hardware descriptors */
 	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
 			"rxr")) {
-		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
+		RTE_LOG(ERR, PMD,
+			"ring_dma_zone_reserve for rx_ring failed!\n");
 		bnxt_rx_queue_release_op(rxq);
 		rc = -ENOMEM;
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 0d50224..993f221 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -64,6 +64,11 @@ struct bnxt_vnic_info {
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
+#define BNXT_VNIC_INFO_BCAST			(1 << 2)
+#define BNXT_VNIC_INFO_UCAST			(1 << 3)
+#define BNXT_VNIC_INFO_MCAST			(1 << 4)
+#define BNXT_VNIC_INFO_TAGGED			(1 << 5)
+#define BNXT_VNIC_INFO_UNTAGGED			(1 << 6)
 
 	uint16_t	cos_rule;
 	uint16_t	lb_rule;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 4006141..0a947cf 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -415,6 +415,60 @@ rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
 	return rc;
 }
 
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t flag = 0;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	if (vf >= bp->pdev->max_vfs)
+		return -EINVAL;
+
+	if (rx_mask & (ETH_VMDQ_ACCEPT_UNTAG | ETH_VMDQ_ACCEPT_HASH_MC)) {
+		RTE_LOG(ERR, PMD, "Currently cannot toggle this setting\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC && !on) {
+		RTE_LOG(ERR, PMD, "Currently cannot disable UC Rx\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
+		flag |= BNXT_VNIC_INFO_BCAST;
+	if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
+		flag |= BNXT_VNIC_INFO_ALLMULTI;
+
+	if (on)
+		bp->pf.vf_info[vf].l2_rx_mask |= flag;
+	else
+		bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+					vf_vnic_set_rxmask_cb,
+					&bp->pf.vf_info[vf].l2_rx_mask,
+					bnxt_set_rx_mask_no_vlan);
+	if (rc)
+		RTE_LOG(ERR, PMD, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 2144601..db9ce77 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -237,6 +237,25 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+/**
+ * Set RX L2 Filtering mode of a VF of an Ethernet device.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param rx_mask
+ *    The RX mode mask
+ * @param on
+ *    1 - Enable a VF RX mode.
+ *    0 - Disable a VF RX mode.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on);
 
 /**
  * Returns the number of default RX queues on a VF
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 9433a1e..f61c736 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -15,6 +15,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_mac_addr_add;
 	rte_pmd_bnxt_set_vf_vlan_insert;
+	rte_pmd_bnxt_set_vf_rxmode;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v3 26/26] doc: update release notes
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (24 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
@ 2017-06-01  3:02           ` Ajit Khaparde
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01  3:02 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Update release doc briefly describing updates to bnxt PMD.

v1->v2:
  - Rebasing to next-net tree
  - Use doc in the patch subject line

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/rel_notes/release_17_08.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 7f12120..7bf6d25 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -56,6 +56,16 @@ New Features
   TX and RX path reworked to improve performance.  Also reduced latency
   for slow traffic.
 
+* **Updated bnxt PMD.**
+
+  Major enhancements include:
+  * Support MTU modification.
+  * Support LRO.
+  * Support VLAN filter and strip functionality.
+  * Other enhancements to add support for more dev_ops.
+  * Add PMD specific APIs mainly to control VF from PF.
+  * Update HWRM version to 1.7.7
+
 
 Resolved Issues
 ---------------
-- 
2.10.1 (Apple Git-78)

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

* Re: [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF
  2017-06-01  3:02           ` [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-06-01 12:28             ` Ferruh Yigit
  2017-06-01 16:36               ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-06-01 12:28 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Stephen Hurd

Hi Ajit,

On 6/1/2017 4:02 AM, Ajit Khaparde wrote:
> This patch adds code to determine the Rx status of a VF.
> It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
> the VNIC count of the function to get the Rx status.
> 
> Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

<...>

> +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
> +{
> +	struct rte_eth_dev *dev;
> +	struct rte_eth_dev_info dev_info;
> +	struct bnxt *bp;
> +
> +	dev = &rte_eth_devices[port];
> +	if (!is_bnxt_supported(dev))
> +		return -ENOTSUP;
> +
> +	rte_eth_dev_info_get(port, &dev_info);
> +	bp = (struct bnxt *)dev->data->dev_private;
> +
> +	return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> +}

I guess there is rebasing error here, this function left here and
causing a build error [1].
(or function tries to sneak in within another patch :)

[1]
.../drivers/net/bnxt/rte_pmd_bnxt.c:639:5: error: no previous prototype
for function 'rte_pmd_bnxt_get_tx_drop_count' [-Werror,-Wmissing-prototypes]
int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
    ^

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

* Re: [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF
  2017-06-01 12:28             ` Ferruh Yigit
@ 2017-06-01 16:36               ` Ajit Khaparde
  0 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 16:36 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Stephen Hurd

On Thu, Jun 1, 2017 at 7:28 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> Hi Ajit,
>
> On 6/1/2017 4:02 AM, Ajit Khaparde wrote:
> > This patch adds code to determine the Rx status of a VF.
> > It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
> > the VNIC count of the function to get the Rx status.
> >
> > Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
> > Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
>
> <...>
>
> > +int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
> > +{
> > +     struct rte_eth_dev *dev;
> > +     struct rte_eth_dev_info dev_info;
> > +     struct bnxt *bp;
> > +
> > +     dev = &rte_eth_devices[port];
> > +     if (!is_bnxt_supported(dev))
> > +             return -ENOTSUP;
> > +
> > +     rte_eth_dev_info_get(port, &dev_info);
> > +     bp = (struct bnxt *)dev->data->dev_private;
> > +
> > +     return bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, count);
> > +}
>
> I guess there is rebasing error here, this function left here and
> causing a build error [1].
> (or function tries to sneak in within another patch :)
>
​Yes. It seems to have. I was actually trying to avoid this and compile
testing
at a minimum during each rebase step to make sure.
But may be the warning message scrolled away.

I am sending a new series.

Thanks
​


>
> [1]
> .../drivers/net/bnxt/rte_pmd_bnxt.c:639:5: error: no previous prototype
> for function 'rte_pmd_bnxt_get_tx_drop_count'
> [-Werror,-Wmissing-prototypes]
> int rte_pmd_bnxt_get_tx_drop_count(uint8_t port, uint64_t *count)
>     ^
>

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

* [PATCH v4 00/26] bnxt patchset
  2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
                             ` (25 preceding siblings ...)
  2017-06-01  3:02           ` [PATCH v3 26/26] doc: update release notes Ajit Khaparde
@ 2017-06-01 17:06           ` Ajit Khaparde
  2017-06-01 17:06             ` [PATCH v4 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
                               ` (26 more replies)
  26 siblings, 27 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:06 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patchset amongst other changes adds support few more dev_ops,
updates HWRM to version 1.7.7, switches to polling stats from the
hardware, support for Jumbo MTU, LRO etc..

v1->v2:
  - Grouped in the end, it also has PMD specific APIs to control VF from PF.
  - I have updated the release notes and the features file wherever possible.

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - update testpmd to use the vendor specific APIs
  - Addressed other review comments as appropriate

v3->v4:
  - fix a rebase error

  --

  net/bnxt: update to new HWRM version
  net/bnxt: code reorg to properly allocate resources for PF/VF
  net/bnxt: handle VF/PF initialization appropriately
  net/bnxt: support lack of huge pages
  net/bnxt: add additonal HWRM debug info to error messages
  net/bnxt: add tunneling support
  net/bnxt: add support for xstats get/reset
  net/bnxt: add support for VLAN filter and strip
  net/bnxt: add support for set multicast addr list and MAC addr set
  doc: update bnxt.ini to document Allmulticast mode
  net/bnxt: add support to get fw version
  net/bnxt: add support to set MTU
  net/bnxt: add support for LRO
  net/bnxt: add rxq/txq info_get
  net/bnxt: add code to support VLAN pvid
  net/bnxt: reorg the query stats code
  doc: update default.ini to add LED support
  net/bnxt: add support for led on/off
  net/bnxt: add support for tx loopback, set vf mac and queues drop
  net/bnxt: add support for set VF QOS and MAC anti spoof
  net/bnxt: add support to get and clear VF specific stats
  net/bnxt: add code to determine the Rx status of VF
  net/bnxt: add support to add a VF MAC address
  net/bnxt: add code to configure a default VF VLAN
  net/bnxt: add support to set VF rxmode
  doc: update release notes

 app/test-pmd/Makefile                     |    4 +
 app/test-pmd/cmdline.c                    |   92 +-
 app/test-pmd/config.c                     |   20 +-
 doc/guides/nics/features/bnxt.ini         |   10 +
 doc/guides/nics/features/default.ini      |    1 +
 doc/guides/rel_notes/release_17_08.rst    |   10 +
 drivers/net/bnxt/Makefile                 |    4 +
 drivers/net/bnxt/bnxt.h                   |  144 +-
 drivers/net/bnxt/bnxt_cpr.c               |  132 +-
 drivers/net/bnxt/bnxt_cpr.h               |   17 +
 drivers/net/bnxt/bnxt_ethdev.c            |  852 ++-
 drivers/net/bnxt/bnxt_filter.c            |   54 +-
 drivers/net/bnxt/bnxt_filter.h            |    3 +
 drivers/net/bnxt/bnxt_hwrm.c              | 1605 ++++-
 drivers/net/bnxt/bnxt_hwrm.h              |   66 +-
 drivers/net/bnxt/bnxt_irq.c               |   21 +-
 drivers/net/bnxt/bnxt_ring.c              |  159 +-
 drivers/net/bnxt/bnxt_ring.h              |    4 +-
 drivers/net/bnxt/bnxt_rxq.c               |   54 +-
 drivers/net/bnxt/bnxt_rxq.h               |    3 +
 drivers/net/bnxt/bnxt_rxr.c               |  396 +-
 drivers/net/bnxt/bnxt_rxr.h               |   46 +
 drivers/net/bnxt/bnxt_stats.c             |  322 +-
 drivers/net/bnxt/bnxt_stats.h             |   10 +
 drivers/net/bnxt/bnxt_txr.c               |    3 +-
 drivers/net/bnxt/bnxt_vnic.c              |   68 +-
 drivers/net/bnxt/bnxt_vnic.h              |   20 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h    | 9678 +++++++++++++++++++++--------
 drivers/net/bnxt/rte_pmd_bnxt.c           |  738 +++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  310 +
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   19 +-
 31 files changed, 11899 insertions(+), 2966 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 01/26] net/bnxt: update to new HWRM version
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
@ 2017-06-01 17:06             ` Ajit Khaparde
  2017-06-01 17:06             ` [PATCH v4 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
                               ` (25 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:06 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch updates the Broadcom bnxt PMD to version 1.7.7
Most of the changes in the patch are in the hsi_struct_def_dpdk.h - an
autogenerated file. The changes in the *.c files are because of changes
in the macro names.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches per review comment

v2->v3:
 - rebasing to next-net tree
 - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c           |   10 +-
 drivers/net/bnxt/bnxt_ring.c           |    8 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 8710 +++++++++++++++++++++++---------
 3 files changed, 6241 insertions(+), 2487 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3849d1a..9100b7b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -511,7 +511,7 @@ static int bnxt_hwrm_port_phy_cfg(struct bnxt *bp, struct bnxt_link_info *conf)
 		req.enables = rte_cpu_to_le_32(enables);
 	} else {
 		req.flags =
-		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN);
+		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
 		RTE_LOG(INFO, PMD, "Force Link Down\n");
 	}
 
@@ -618,7 +618,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
 		/*
 		 * TODO: Some HWRM versions crash with
@@ -639,7 +639,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		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:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD,
 				"hwrm_ring_alloc cp failed. rc:%d\n", rc);
 			return rc;
@@ -680,7 +680,7 @@ int bnxt_hwrm_ring_free(struct bnxt *bp,
 			rc = rte_le_to_cpu_16(resp->error_code);
 
 		switch (ring_type) {
-		case HWRM_RING_FREE_INPUT_RING_TYPE_CMPL:
+		case HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL:
 			RTE_LOG(ERR, PMD, "hwrm_ring_free cp failed. rc:%d\n",
 				rc);
 			return rc;
@@ -1063,7 +1063,7 @@ static void bnxt_free_cp_ring(struct bnxt *bp,
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
 	bnxt_hwrm_ring_free(bp, cp_ring,
-			HWRM_RING_FREE_INPUT_RING_TYPE_CMPL);
+			HWRM_RING_FREE_INPUT_RING_TYPE_L2_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 *
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 0fafa13..52fbd89 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -219,8 +219,8 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *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);
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+					0, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = pci_dev->mem_resource[2].addr;
@@ -238,7 +238,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
@@ -276,7 +276,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL,
+					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
 					idx, HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index f024837..518f16d 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -1,7 +1,7 @@
 /*-
  *   BSD LICENSE
  *
- *   Copyright(c) Broadcom Limited.
+ *   Copyright(c) 2001-2017 Broadcom Limited.
  *   All rights reserved.
  *
  *   Redistribution and use in source and binary forms, with or without
@@ -31,74 +31,88 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-#ifndef _HSI_STRUCT_DEF_EXTERNAL_H_
-#define _HSI_STRUCT_DEF_EXTERNAL_H_
-
-/*
- * per-context HW statistics -- chip view
- */
-
-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_discard_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_discard_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;
-} __attribute__((packed));
-
-/* HW Resource Manager Specification 1.5.1 */
+#ifndef _HSI_STRUCT_DEF_DPDK_
+#define _HSI_STRUCT_DEF_DPDK_
+/* HSI and HWRM Specification 1.7.7 */
 #define HWRM_VERSION_MAJOR	1
-#define HWRM_VERSION_MINOR	5
-#define HWRM_VERSION_UPDATE	1
-
-#define HWRM_VERSION_STR	"1.5.1"
+#define HWRM_VERSION_MINOR	7
+#define HWRM_VERSION_UPDATE	7
 
+#define HWRM_VERSION_STR	"1.7.7"
 /*
  * 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.
+ * applicable	(All F's). Need to cast it the size of the field if needed.
  */
-#define HWRM_NA_SIGNATURE        ((uint32_t)(-1))
+#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_MAX_RESP_LEN	(248)  /* hwrm_selftest_qlist */
+#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 */
+#define HWRM_ROCE_SP_HSI_VERSION_MAJOR	1
+#define HWRM_ROCE_SP_HSI_VERSION_MINOR	7
+#define HWRM_ROCE_SP_HSI_VERSION_UPDATE	4
 
 /*
  * Request types
  */
 #define HWRM_VER_GET			(UINT32_C(0x0))
+#define HWRM_FUNC_BUF_UNRGTR		(UINT32_C(0xe))
+#define HWRM_FUNC_VF_CFG		(UINT32_C(0xf))
+    /* Reserved for future use */
+#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 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_PHY_QCFG		(UINT32_C(0x27))
+#define HWRM_PORT_MAC_QCFG		(UINT32_C(0x28))
+#define HWRM_PORT_PHY_QCAPS		(UINT32_C(0x2a))
+#define HWRM_PORT_LED_CFG		(UINT32_C(0x2d))
+#define HWRM_PORT_LED_QCFG		(UINT32_C(0x2e))
+#define HWRM_PORT_LED_QCAPS		(UINT32_C(0x2f))
 #define HWRM_QUEUE_QPORTCFG		(UINT32_C(0x30))
+#define HWRM_QUEUE_QCFG			(UINT32_C(0x31))
+#define HWRM_QUEUE_CFG			(UINT32_C(0x32))
+#define HWRM_FUNC_VLAN_CFG		(UINT32_C(0x33))
+#define HWRM_FUNC_VLAN_QCFG		(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_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_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_CFG_AGGINT_PARAM	(UINT32_C(0x53))
+#define HWRM_RING_RESET			(UINT32_C(0x5e))
+#define HWRM_RING_GRP_ALLOC		(UINT32_C(0x60))
 #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))
@@ -107,16 +121,69 @@ 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))
+    /* Reserved for future use */
+#define RESERVED4			(UINT32_C(0x94))
+#define HWRM_CFA_TUNNEL_FILTER_ALLOC	(UINT32_C(0x95))
+#define HWRM_CFA_TUNNEL_FILTER_FREE	(UINT32_C(0x96))
+#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_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_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_WOL_FILTER_ALLOC		(UINT32_C(0xf0))
+#define HWRM_WOL_FILTER_FREE		(UINT32_C(0xf1))
+#define HWRM_WOL_FILTER_QCFG		(UINT32_C(0xf2))
+#define HWRM_WOL_REASON_QCFG		(UINT32_C(0xf3))
+#define HWRM_DBG_DUMP			(UINT32_C(0xff14))
+#define HWRM_NVM_VALIDATE_OPTION	(UINT32_C(0xffef))
+#define HWRM_NVM_FLUSH			(UINT32_C(0xfff0))
+#define HWRM_NVM_GET_VARIABLE		(UINT32_C(0xfff1))
+#define HWRM_NVM_SET_VARIABLE		(UINT32_C(0xfff2))
+#define HWRM_NVM_INSTALL_UPDATE		(UINT32_C(0xfff3))
+#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_RAW_DUMP		(UINT32_C(0xfffc))
+#define HWRM_NVM_READ			(UINT32_C(0xfffd))
+#define HWRM_NVM_WRITE			(UINT32_C(0xfffe))
+#define HWRM_NVM_RAW_WRITE_BLK		(UINT32_C(0xffff))
 
-/* Return Codes */
-#define HWRM_ERR_CODE_INVALID_PARAMS                      (UINT32_C(0x2))
-#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED              (UINT32_C(0x3))
-
-/* Short TX BD (16 bytes) */
+/*
+ * Note: The Host Software Interface (HSI) and Hardware Resource Manager (HWRM)
+ * specification describes the data structures used in Ethernet packet or RDMA
+ * message data transfers as well as an abstract interface for managing Ethernet
+ * NIC hardware resources.
+ */
+/* Ethernet Data path Host Structures */
+/*
+ * Description: The following three sections document the host structures used
+ * between device and software drivers for communicating Ethernet packets.
+ */
+/* BD Ring Structures */
+/*
+ * Description: This structure is used to inform the NIC of a location for and
+ * an aggregation buffer that will be used for packet data that is received. An
+ * aggregation buffer creates a different kind of completion operation for a
+ * packet where a variable number of BDs may be used to place the packet in the
+ * host. RX Rings that have aggregation buffers are known as aggregation rings
+ * and must contain only aggregation buffers.
+ */
+/* Short TX BD	(16 bytes) */
 struct tx_bd_short {
 	uint16_t flags_type;
 	/*
@@ -149,10 +216,10 @@ struct tx_bd_short {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -173,7 +240,8 @@ struct tx_bd_short {
 	#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
+	#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
@@ -213,7 +281,7 @@ struct tx_bd_short {
 	 */
 } __attribute__((packed));
 
-/* Long TX BD (32 bytes split to 2 16-byte struct) */
+/* Long TX BD	(32 bytes split to 2 16-byte struct) */
 struct tx_bd_long {
 	uint16_t flags_type;
 	/*
@@ -246,10 +314,10 @@ struct tx_bd_long {
 	/*
 	 * 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
+	 * 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
+	 * 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)
@@ -270,7 +338,8 @@ struct tx_bd_long {
 	#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
+	#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
@@ -360,7 +429,7 @@ struct tx_bd_long_hi {
 	 * bit is set, outer UDP checksum will be calculated for the
 	 * following cases: 1. Packets with tcp_udp_chksum flag set to
 	 * offload checksum for inner packet AND the inner packet is
-	 * TCP/UDP. If the inner packet is ICMP for example (non-
+	 * TCP/UDP. If the inner packet is ICMP for example	(non-
 	 * TCP/UDP), even if the tcp_udp_chksum is set, the outer UDP
 	 * checksum will not be calculated. 2. Packets with lso flag set
 	 * which implies inner TCP checksum calculation as part of LSO
@@ -392,7 +461,7 @@ struct tx_bd_long_hi {
 	 * 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. The flag is ignored if the LSO packet is a normal
-	 * (non-tunneled) TCP packet.
+	 *	(non-tunneled) TCP packet.
 	 */
 	#define TX_BD_LONG_LFLAGS_T_IPID	UINT32_C(0x80)
 	/*
@@ -460,7 +529,7 @@ struct tx_bd_long_hi {
 	#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	\
+	#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)
@@ -474,15 +543,16 @@ struct tx_bd_long_hi {
 	/* No editing */
 	#define TX_BD_LONG_CFA_META_KEY_NONE	(UINT32_C(0x0) << 28)
 	/*
-	 * - meta[17:16] - TPID select value (0 =
+	 * - 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
+	#define TX_BD_LONG_CFA_META_KEY_LAST \
+		TX_BD_LONG_CFA_META_KEY_VLAN_TAG
 } __attribute__((packed));
 
-/* RX Producer Packet BD (16 bytes) */
+/* RX Producer Packet BD	(16 bytes) */
 struct rx_prod_pkt_bd {
 	uint16_t flags_type;
 	/* This value identifies the type of buffer descriptor. */
@@ -490,7 +560,7 @@ struct rx_prod_pkt_bd {
 	#define RX_PROD_PKT_BD_TYPE_SFT	0
 	/*
 	 * Indicates that this BD is 16B long and is an
-	 * RX Producer (ie. empty) buffer descriptor.
+	 * RX Producer	(ie. empty) buffer descriptor.
 	 */
 	#define RX_PROD_PKT_BD_TYPE_RX_PROD_PKT	UINT32_C(0x4)
 	/*
@@ -558,7 +628,7 @@ struct rx_prod_pkt_bd {
 
 /* Completion Ring Structures */
 /* Note: This structure is used by the HWRM to communicate HWRM Error. */
-/* Base Completion Record (16 bytes) */
+/* Base Completion Record	(16 bytes) */
 struct cmpl_base {
 	uint16_t type;
 	/* unused is 10 b */
@@ -637,7 +707,7 @@ struct cmpl_base {
 	/* info4 is 32 b */
 } __attribute__((packed));
 
-/* TX Completion Record (16 bytes) */
+/* TX Completion Record	(16 bytes) */
 struct tx_cmpl {
 	uint16_t flags_type;
 	/*
@@ -689,7 +759,7 @@ struct tx_cmpl {
 	#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	\
+	#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
@@ -726,7 +796,7 @@ struct tx_cmpl {
 	/* unused3 is 32 b */
 } __attribute__((packed));
 
-/* RX Packet Completion Record (32 bytes split to 2 16-byte struct) */
+/* RX Packet Completion Record	(32 bytes split to 2 16-byte struct) */
 struct rx_pkt_cmpl {
 	uint16_t flags_type;
 	/*
@@ -741,7 +811,9 @@ struct rx_pkt_cmpl {
 	 * RX L2 completion: Completion of and L2 RX
 	 * packet. Length = 32B
 	 */
-	#define RX_PKT_CMPL_TYPE_RX_L2	UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2			UINT32_C(0x11)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_START	UINT32_C(0x13)
+	#define RX_PKT_CMPL_TYPE_RX_L2_TPA_END		UINT32_C(0x15)
 	/*
 	 * When this bit is '1', it indicates a packet that has an error
 	 * of some type. Type of error is indicated in error_flags.
@@ -761,10 +833,12 @@ struct rx_pkt_cmpl {
 	 * 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
+	#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)
 	/* unused is 1 b */
+	#define RX_PKT_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
 	/*
 	 * This value indicates what the inner packet determined for the
 	 * packet was.
@@ -820,7 +894,8 @@ struct rx_pkt_cmpl {
 	 * 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_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 len;
@@ -938,7 +1013,7 @@ struct rx_pkt_cmpl_hi {
 	 * the vlan TPID value.
 	 */
 	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN	(UINT32_C(0x1) << 4)
-	#define RX_PKT_CMPL_FLAGS2_META_FORMAT_LAST	\
+	#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
@@ -988,15 +1063,18 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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	\
+	#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)
@@ -1037,39 +1115,45 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
+	#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)
+	#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
+	 * 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	\
+	#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
@@ -1089,15 +1173,17 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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
+	 * 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)
@@ -1106,18 +1192,21 @@ struct rx_pkt_cmpl_hi {
 	 * 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)
+	#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)
+	#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)
+	#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)
@@ -1126,9 +1215,9 @@ struct rx_pkt_cmpl_hi {
 	 * 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	\
+	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_L4_BAD_OPT_LEN \
 		(UINT32_C(0x8) << 12)
-	#define RX_PKT_CMPL_ERRORS_PKT_ERROR_LAST	\
+	#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
@@ -1149,7 +1238,474 @@ struct rx_pkt_cmpl_hi {
 	#define RX_PKT_CMPL_REORDER_SFT	0
 } __attribute__((packed));
 
-/* HWRM Forwarded Request (16 bytes) */
+/* RX L2 TPA Start Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_start_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_START_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_START_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA Start Completion: Completion at the
+	 * beginning of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_START_CMPL_TYPE_RX_TPA_START	UINT32_C(0x13)
+	/* This bit will always be '0' for TPA start completions. */
+	#define RX_TPA_START_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_JUMBO \
+		(UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS (UINT32_C(0x6) << 7)
+	#define RX_TPA_START_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_START_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* This bit is '1' if the RSS field in this completion is valid. */
+	#define RX_TPA_START_CMPL_FLAGS_RSS_VALID	UINT32_C(0x400)
+	/* unused is 1 b */
+	#define RX_TPA_START_CMPL_FLAGS_UNUSED	UINT32_C(0x800)
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_SFT	12
+	/* TCP Packet: Indicates that the packet was IP and TCP. */
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_TCP	(UINT32_C(0x2) << 12)
+	#define RX_TPA_START_CMPL_FLAGS_ITYPE_LAST \
+		RX_TPA_START_CMPL_FLAGS_ITYPE_TCP
+	#define RX_TPA_START_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_START_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value indicates the amount of packet data written to the
+	 * buffer the opaque field in this completion corresponds to.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t v1;
+	/* unused1 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 RX_TPA_START_CMPL_V1	UINT32_C(0x1)
+	/* unused1 is 7 b */
+	uint8_t rss_hash_type;
+	/*
+	 * 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]}
+	 * . The value of tuple_extrac_op provides the information about
+	 * what fields the hash was computed on. * 0: The RSS hash was
+	 * computed over source IP address, destination IP address,
+	 * source port, and destination port of inner IP and TCP or UDP
+	 * headers. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 1: The RSS hash was computed over
+	 * source IP address and destination IP address of inner IP
+	 * header. Note: For non-tunneled packets, the packet headers
+	 * are considered inner packet headers for the RSS hash
+	 * computation purpose. * 2: The RSS hash was computed over
+	 * source IP address, destination IP address, source port, and
+	 * destination port of IP and TCP or UDP headers of outer tunnel
+	 * headers. Note: For non-tunneled packets, this value is not
+	 * applicable. * 3: The RSS hash was computed over source IP
+	 * address and destination IP address of IP header of outer
+	 * tunnel headers. Note: For non-tunneled packets, this value is
+	 * not applicable. Note that 4-tuples values listed above are
+	 * applicable for layer 4 protocols supported and enabled for
+	 * RSS in the hardware, HWRM firmware, and drivers. For example,
+	 * if RSS hash is supported and enabled for TCP traffic only,
+	 * then the values of tuple_extract_op corresponding to 4-tuples
+	 * are only valid for TCP traffic.
+	 */
+	uint16_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 9 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_START_CMPL_AGG_ID_MASK	UINT32_C(0xfe00)
+	#define RX_TPA_START_CMPL_AGG_ID_SFT	9
+	uint32_t rss_hash;
+	/*
+	 * This value is the RSS hash value calculated for the packet
+	 * based on the mode bits and key value in the VNIC.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX L2 TPA Start Completion Record */
+struct rx_tpa_start_cmpl_hi {
+	uint32_t flags2;
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * inner packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_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 sum passed for
+	 * all segments included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC	UINT32_C(0x2)
+	/*
+	 * This indicates that the ip checksum was calculated for the
+	 * tunnel header and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_IP_CS_CALC	UINT32_C(0x4)
+	/*
+	 * This indicates that the UDP checksum was calculated for the
+	 * tunnel packet and that the sum passed for all segments
+	 * included in the aggregation.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_T_L4_CS_CALC	UINT32_C(0x8)
+	/* This value indicates what format the metadata field is. */
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_MASK UINT32_C(0xf0)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_SFT	4
+	/* No metadata informtaion. Value is zero. */
+	#define RX_TPA_START_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_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN (UINT32_C(0x1) << 4)
+	#define RX_TPA_START_CMPL_FLAGS2_META_FORMAT_LAST \
+		RX_TPA_START_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.
+	 */
+	#define RX_TPA_START_CMPL_FLAGS2_IP_TYPE	UINT32_C(0x100)
+	uint32_t metadata;
+	/*
+	 * 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_TPA_START_CMPL_METADATA_VID_MASK	UINT32_C(0xfff)
+	#define RX_TPA_START_CMPL_METADATA_VID_SFT	0
+	/* When meta_format=1, this value is the VLAN DE. */
+	#define RX_TPA_START_CMPL_METADATA_DE	UINT32_C(0x1000)
+	/* When meta_format=1, this value is the VLAN PRI. */
+	#define RX_TPA_START_CMPL_METADATA_PRI_MASK UINT32_C(0xe000)
+	#define RX_TPA_START_CMPL_METADATA_PRI_SFT	13
+	/* When meta_format=1, this value is the VLAN TPID. */
+	#define RX_TPA_START_CMPL_METADATA_TPID_MASK	UINT32_C(0xffff0000)
+	#define RX_TPA_START_CMPL_METADATA_TPID_SFT	16
+	uint16_t v2;
+	/* unused4 is 15 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 RX_TPA_START_CMPL_V2	UINT32_C(0x1)
+	/* unused4 is 15 b */
+	uint16_t cfa_code;
+	/*
+	 * This field identifies the CFA action rule that was used for
+	 * this packet.
+	 */
+	uint32_t inner_l4_size_inner_l3_offset_inner_l2_offset_outer_l3_offset;
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the outer L3 header. If there is no outer L3 header, then
+	 * this value is zero.
+	 */
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_MASK	UINT32_C(0x1ff)
+	#define RX_TPA_START_CMPL_OUTER_L3_OFFSET_SFT	0
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L2 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_MASK	UINT32_C(0x3fe00)
+	#define RX_TPA_START_CMPL_INNER_L2_OFFSET_SFT	9
+	/*
+	 * This is the offset from the beginning of the packet in bytes
+	 * for the inner most L3 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_MASK	UINT32_C(0x7fc0000)
+	#define RX_TPA_START_CMPL_INNER_L3_OFFSET_SFT	18
+	/*
+	 * This is the size in bytes of the inner most L4 header. This
+	 * can be subtracted from the payload_offset to determine the
+	 * start of the inner most L4 header.
+	 */
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_MASK	UINT32_C(0xf8000000)
+	#define RX_TPA_START_CMPL_INNER_L4_SIZE_SFT	27
+} __attribute__((packed));
+
+/* RX TPA End Completion Record (32 bytes split to 2 16-byte struct) */
+struct rx_tpa_end_cmpl {
+	uint16_t flags_type;
+	/*
+	 * 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_TPA_END_CMPL_TYPE_MASK	UINT32_C(0x3f)
+	#define RX_TPA_END_CMPL_TYPE_SFT	0
+	/*
+	 * RX L2 TPA End Completion: Completion at the
+	 * end of a TPA operation. Length = 32B
+	 */
+	#define RX_TPA_END_CMPL_TYPE_RX_TPA_END	UINT32_C(0x15)
+	/*
+	 * 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_TPA_END_CMPL_FLAGS_ERROR	UINT32_C(0x40)
+	/* This field indicates how the packet was placed in the buffer. */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_MASK	UINT32_C(0x380)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_SFT	7
+	/*
+	 * Jumbo: TPA Packet was placed using jumbo
+	 * algorithm. This means that the first buffer
+	 * will be filled with data before moving to
+	 * aggregation buffers. Each aggregation buffer
+	 * will be filled before moving to the next
+	 * aggregation buffer.
+	 */
+	#define RX_TPA_END_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_TPA_END_CMPL_FLAGS_PLACEMENT_HDS	(UINT32_C(0x2) << 7)
+	/*
+	 * GRO/Jumbo: Packet will be placed using
+	 * GRO/Jumbo where the first packet is filled
+	 * with data. Subsequent packets will be placed
+	 * such that any one packet does not span two
+	 * aggregation buffers unless it starts at the
+	 * beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_JUMBO (UINT32_C(0x5) << 7)
+	/*
+	 * GRO/Header-Data Separation: Packet will be
+	 * placed using GRO/HDS where the header is in
+	 * the first packet. Payload of each packet will
+	 * be placed such that any one packet does not
+	 * span two aggregation buffers unless it starts
+	 * at the beginning of an aggregation buffer.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS	(UINT32_C(0x6) << 7)
+	#define RX_TPA_END_CMPL_FLAGS_PLACEMENT_LAST \
+		RX_TPA_END_CMPL_FLAGS_PLACEMENT_GRO_HDS
+	/* unused is 2 b */
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_MASK	UINT32_C(0xc00)
+	#define RX_TPA_END_CMPL_FLAGS_UNUSED_SFT	10
+	/*
+	 * This value indicates what the inner packet determined for the
+	 * packet was. - 2 TCP Packet Indicates that the packet was IP
+	 * and TCP. This indicates that the ip_cs field is valid and
+	 * that the tcp_udp_cs field is valid and contains the TCP
+	 * checksum. This also indicates that the payload_offset field
+	 * is valid.
+	 */
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_MASK	UINT32_C(0xf000)
+	#define RX_TPA_END_CMPL_FLAGS_ITYPE_SFT	12
+	#define RX_TPA_END_CMPL_FLAGS_MASK	UINT32_C(0xffc0)
+	#define RX_TPA_END_CMPL_FLAGS_SFT	6
+	uint16_t len;
+	/*
+	 * This value is zero for TPA End completions. There is no data
+	 * in the buffer that corresponds to the opaque value in this
+	 * completion.
+	 */
+	uint32_t opaque;
+	/*
+	 * This is a copy of the opaque field from the RX BD this
+	 * completion corresponds to.
+	 */
+	uint8_t agg_bufs_v1;
+	/* unused1 is 1 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 RX_TPA_END_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
+	 * aggregation packet. If the value is zero, then the packet is
+	 * completely contained in the buffer space provided in the
+	 * aggregation start completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_BUFS_MASK	UINT32_C(0x7e)
+	#define RX_TPA_END_CMPL_AGG_BUFS_SFT	1
+	/* unused1 is 1 b */
+	uint8_t tpa_segs;
+	/* This value is the number of segments in the TPA operation. */
+	uint8_t payload_offset;
+	/*
+	 * This value indicates the offset in bytes from the beginning
+	 * of the packet where the inner payload starts. This value is
+	 * valid for TCP, UDP, FCoE, and RoCE packets. A value of zero
+	 * indicates an offset of 256 bytes.
+	 */
+	uint8_t agg_id;
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	/* unused2 is 1 b */
+	/*
+	 * This is the aggregation ID that the completion is associated
+	 * with. Use this number to correlate the TPA start completion
+	 * with the TPA end completion.
+	 */
+	#define RX_TPA_END_CMPL_AGG_ID_MASK	UINT32_C(0xfe)
+	#define RX_TPA_END_CMPL_AGG_ID_SFT	1
+	uint32_t tsdelta;
+	/*
+	 * For non-GRO packets, this value is the timestamp delta
+	 * between earliest and latest timestamp values for TPA packet.
+	 * If packets were not time stamped, then delta will be zero.
+	 * For GRO packets, this field is zero except for the following
+	 * sub-fields. - tsdelta[31] Timestamp present indication. When
+	 * '0', no Timestamp option is in the packet. When '1', then a
+	 * Timestamp option is present in the packet.
+	 */
+} __attribute__((packed));
+
+/* last 16 bytes of RX TPA End Completion Record */
+struct rx_tpa_end_cmpl_hi {
+	uint32_t tpa_dup_acks;
+	/* unused3 is 28 b */
+	/*
+	 * This value is the number of duplicate ACKs that have been
+	 * received as part of the TPA operation.
+	 */
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_MASK	UINT32_C(0xf)
+	#define RX_TPA_END_CMPL_TPA_DUP_ACKS_SFT	0
+	/* unused3 is 28 b */
+	uint16_t tpa_seg_len;
+	/*
+	 * This value is the valid when TPA completion is active. It
+	 * indicates the length of the longest segment of the TPA
+	 * operation for LRO mode and the length of the first segment in
+	 * GRO mode. This value may be used by GRO software to re-
+	 * construct the original packet stream from the TPA packet.
+	 * This is the length of all but the last segment for GRO. In
+	 * LRO mode this value may be used to indicate MSS size to the
+	 * stack.
+	 */
+	uint16_t unused_3;
+	/* unused4 is 16 b */
+	uint16_t errors_v2;
+	/*
+	 * 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_TPA_END_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_TPA_END_CMPL_ERRORS_BUFFER_ERROR_MASK	UINT32_C(0xe)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_SFT	1
+	/*
+	 * This error occurs when there is a fatal HW
+	 * problem in the chip only. It indicates that
+	 * there were not BDs on chip but that there was
+	 * adequate reservation. provided by the TPA
+	 * block.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_NOT_ON_CHIP \
+		(UINT32_C(0x2) << 1)
+	/*
+	 * This error occurs when TPA block was not
+	 * configured to reserve adequate BDs for TPA
+	 * operations on this RX ring. All data for the
+	 * TPA operation was not placed. This error can
+	 * also be generated when the number of segments
+	 * is not programmed correctly in TPA and the 33
+	 * total aggregation buffers allowed for the TPA
+	 * operation has been exceeded.
+	 */
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR \
+		(UINT32_C(0x4) << 1)
+	#define RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_LAST \
+		RX_TPA_END_CMPL_ERRORS_BUFFER_ERROR_RSV_ERROR
+	#define RX_TPA_END_CMPL_ERRORS_MASK	UINT32_C(0xfffe)
+	#define RX_TPA_END_CMPL_ERRORS_SFT	1
+	uint16_t unused_4;
+	/* unused5 is 16 b */
+	uint32_t start_opaque;
+	/*
+	 * This is the opaque value that was completed for the TPA start
+	 * completion that corresponds to this TPA end completion.
+	 */
+} __attribute__((packed));
+
+/* HWRM Forwarded Request	(16 bytes) */
 struct hwrm_fwd_req_cmpl {
 	uint16_t req_len_type;
 	/* Length of forwarded request in bytes. */
@@ -1188,7 +1744,7 @@ struct hwrm_fwd_req_cmpl {
 	#define HWRM_FWD_REQ_CMPL_REQ_BUF_ADDR_SFT	1
 } __attribute__((packed));
 
-/* HWRM Asynchronous Event Completion Record (16 bytes) */
+/* HWRM Asynchronous Event Completion Record	(16 bytes) */
 struct hwrm_async_event_cmpl {
 	uint16_t type;
 	/* unused1 is 10 b */
@@ -1210,19 +1766,20 @@ struct hwrm_async_event_cmpl {
 	/* Link MTU changed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_MTU_CHANGE	UINT32_C(0x1)
 	/* Link speed changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE  UINT32_C(0x2)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CHANGE UINT32_C(0x2)
 	/* DCB Configuration changed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE  UINT32_C(0x3)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_DCB_CONFIG_CHANGE UINT32_C(0x3)
 	/* Port connection not allowed */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_CONN_NOT_ALLOWED UINT32_C(0x4)
 	/* Link speed configuration was not allowed */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED UINT32_C(0x5)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_NOT_ALLOWED \
+		UINT32_C(0x5)
 	/* Link speed configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_LINK_SPEED_CFG_CHANGE UINT32_C(0x6)
 	/* Port PHY configuration change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PORT_PHY_CFG_CHANGE UINT32_C(0x7)
 	/* Function driver unloaded */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD   UINT32_C(0x10)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_UNLOAD UINT32_C(0x10)
 	/* Function driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_FUNC_DRVR_LOAD	UINT32_C(0x11)
 	/* Function FLR related processing has completed */
@@ -1231,12 +1788,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD	UINT32_C(0x20)
 	/* PF driver loaded */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_LOAD	UINT32_C(0x21)
-	/* VF Function Level Reset (FLR) */
+	/* VF Function Level Reset	(FLR) */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR	UINT32_C(0x30)
 	/* VF MAC Address Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_MAC_ADDR_CHANGE UINT32_C(0x31)
 	/* PF-VF communication channel status change. */
-	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE UINT32_C(0x32)
+	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_VF_COMM_STATUS_CHANGE \
+		UINT32_C(0x32)
 	/* VF Configuration Change */
 	#define HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE	UINT32_C(0x33)
 	/* HWRM Error */
@@ -1255,69 +1813,13 @@ struct hwrm_async_event_cmpl {
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_MASK	UINT32_C(0xfe)
 	#define HWRM_ASYNC_EVENT_CMPL_OPAQUE_SFT	1
 	uint8_t timestamp_lo;
-	/* 8-lsb timestamp from POR (100-msec resolution) */
+	/* 8-lsb timestamp from POR	(100-msec resolution) */
 	uint16_t timestamp_hi;
-	/* 16-lsb timestamp from POR (100-msec resolution) */
+	/* 16-lsb timestamp from POR	(100-msec resolution) */
 	uint32_t event_data1;
 	/* Event specific data */
 } __attribute__((packed));
 
-/*
- * 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 service is vital part of the chip.
- * The chip can not be used by a driver or HWRM client without the HWRM.
- */
-
-/* Input (16 bytes) */
-struct input {
-	uint16_t req_type;
-	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
-	 */
-	uint16_t cmpl_ring;
-	/*
-	 * 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 seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
-/* Output (8 bytes) */
-struct output {
-	uint16_t error_code;
-	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
-	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
-	/*
-	 * 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.
-	 */
-} __attribute__((packed));
-
 /* hwrm_ver_get */
 /*
  * Description: This function is called by a driver to determine the HWRM
@@ -1327,7 +1829,7 @@ struct output {
  * interface or firmware version with major = 0, minor = 0, and update = 0 shall
  * be considered an invalid version.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_ver_get_input {
 	uint16_t req_type;
 	/*
@@ -1384,7 +1886,7 @@ struct hwrm_ver_get_input {
 	uint8_t unused_0[5];
 } __attribute__((packed));
 
-/* Output (128 bytes) */
+/* Output	(128 bytes) */
 struct hwrm_ver_get_output {
 	uint16_t error_code;
 	/*
@@ -1454,7 +1956,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version of the HWRM
 	 * firmware.
 	 */
 	uint8_t mgmt_fw_maj;
@@ -1477,7 +1979,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint8_t netctrl_fw_maj;
 	/*
@@ -1500,7 +2002,7 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	uint32_t dev_caps_cfg;
 	/*
@@ -1512,13 +2014,27 @@ struct hwrm_ver_get_output {
 	 * supported. If set to 0, then secure firmware update behavior
 	 * is not supported.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  UINT32_C(0x1)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SECURE_FW_UPD_SUPPORTED  \
+		UINT32_C(0x1)
 	/*
 	 * If set to 1, then firmware based DCBX agent is supported. If
 	 * set to 0, then firmware based DCBX agent capability is not
 	 * supported on this device.
 	 */
-	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_FW_DCBX_AGENT_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, then HWRM short command format is supported. If
+	 * set to 0, then HWRM short command format is not supported.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_SUPPORTED	 \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, then HWRM short command format is required. If
+	 * set to 0, then HWRM short command format is not required.
+	 */
+	#define HWRM_VER_GET_OUTPUT_DEV_CAPS_CFG_SHORT_CMD_INPUTUIRED	\
+		UINT32_C(0x8)
 	uint8_t roce_fw_maj;
 	/*
 	 * This field represents the major version of RoCE firmware. A
@@ -1539,22 +2055,22 @@ struct hwrm_ver_get_output {
 	/*
 	 * 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
+	 * tied to a specific	(major,minor,update) version
 	 */
 	char hwrm_fw_name[16];
 	/*
-	 * This field represents the name of HWRM FW (ASCII chars with
+	 * This field represents the name of HWRM FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char mgmt_fw_name[16];
 	/*
-	 * This field represents the name of mgmt FW (ASCII chars with
+	 * This field represents the name of mgmt FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	char netctrl_fw_name[16];
 	/*
 	 * This field represents the name of network control firmware
-	 * (ASCII chars with NULL at the end).
+	 *	(ASCII chars with NULL at the end).
 	 */
 	uint32_t reserved2[4];
 	/*
@@ -1563,7 +2079,7 @@ struct hwrm_ver_get_output {
 	 */
 	char roce_fw_name[16];
 	/*
-	 * This field represents the name of RoCE FW (ASCII chars with
+	 * This field represents the name of RoCE FW	(ASCII chars with
 	 * NULL at the end).
 	 */
 	uint16_t chip_num;
@@ -1584,7 +2100,7 @@ struct hwrm_ver_get_output {
 	/* FPGA platform of the chip. */
 	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_FPGA	UINT32_C(0x1)
 	/* Palladium platform of the chip. */
-	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM	UINT32_C(0x2)
+	#define HWRM_VER_GET_OUTPUT_CHIP_PLATFORM_TYPE_PALLADIUM UINT32_C(0x2)
 	uint16_t max_req_win_len;
 	/*
 	 * This field returns the maximum value of request window that
@@ -1614,7 +2130,7 @@ struct hwrm_ver_get_output {
 
 /* hwrm_func_reset */
 /*
- * Description: This command resets a hardware function (PCIe function) and
+ * 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
@@ -1626,7 +2142,7 @@ struct hwrm_ver_get_output {
  * idled. The command returns all the resources owned by the function so a new
  * driver may allocate and configure resources normally.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_reset_input {
 	uint16_t req_type;
 	/*
@@ -1668,7 +2184,7 @@ struct hwrm_func_reset_input {
 	/* This value indicates the level of a function reset. */
 	/*
 	 * Reset the caller function and its children
-	 * VFs (if any). If no children functions exist,
+	 * 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)
@@ -1681,7 +2197,8 @@ struct hwrm_func_reset_input {
 	 * 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)
+	#define HWRM_FUNC_RESET_INPUT_FUNC_RESET_LEVEL_RESETCHILDREN \
+		UINT32_C(0x2)
 	/*
 	 * Reset a specific VF of the caller function
 	 * driver if the caller is the parent PF driver.
@@ -1694,7 +2211,7 @@ struct hwrm_func_reset_input {
 	uint8_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
+/* Output	(16 bytes) */
 struct hwrm_func_reset_output {
 	uint16_t error_code;
 	/*
@@ -1734,7 +2251,7 @@ struct hwrm_func_reset_output {
  * 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) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcaps_input {
 	uint16_t req_type;
 	/*
@@ -1765,12 +2282,12 @@ struct hwrm_func_qcaps_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (80 bytes) */
+/* Output	(80 bytes) */
 struct hwrm_func_qcaps_output {
 	uint16_t error_code;
 	/*
@@ -1795,54 +2312,56 @@ struct hwrm_func_qcaps_output {
 	uint16_t port_id;
 	/*
 	 * 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
+	 * 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.
 	 */
 	uint32_t flags;
 	/* If 1, then Push mode is supported on this function. */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PUSH_MODE_SUPPORTED	UINT32_C(0x1)
+	#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)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_GLOBAL_MSIX_AUTOMASKING	 \
+		UINT32_C(0x2)
 	/*
-	 * If 1, then the Precision Time Protocol (PTP) processing is
+	 * 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.
+	 * only a single Physical Function	(PF) per port.
 	 */
 	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_PTP_SUPPORTED	UINT32_C(0x4)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v1 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v1 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED	UINT32_C(0x8)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V1_SUPPORTED UINT32_C(0x8)
 	/*
-	 * If 1, then RDMA over Converged Ethernet (RoCE) v2 is
+	 * If 1, then RDMA over Converged Ethernet	(RoCE) v2 is
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED	UINT32_C(0x10)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_ROCE_V2_SUPPORTED UINT32_C(0x10)
 	/*
 	 * If 1, then control and configuration of WoL magic packet are
 	 * supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	UINT32_C(0x20)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_MAGICPKT_SUPPORTED	\
+		UINT32_C(0x20)
 	/*
 	 * If 1, then control and configuration of bitmap pattern packet
 	 * are supported on this function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED	UINT32_C(0x40)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_WOL_BMP_SUPPORTED UINT32_C(0x40)
 	/*
 	 * If set to 1, then the control and configuration of rate limit
 	 * of an allocated TX ring on the queried function is supported.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED	UINT32_C(0x80)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_RING_RL_SUPPORTED UINT32_C(0x80)
 	/*
 	 * If 1, then control and configuration of minimum and maximum
 	 * bandwidths are supported on the queried function.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED	UINT32_C(0x100)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_TX_BW_CFG_SUPPORTED UINT32_C(0x100)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1851,7 +2370,8 @@ struct hwrm_func_qcaps_output {
 	 * set to 0, then the PF does not have the capability to set the
 	 * rate limits on the TX rings of its children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	UINT32_C(0x200)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_TX_RING_RL_SUPPORTED	 \
+		UINT32_C(0x200)
 	/*
 	 * If the query is for a VF, then this flag shall be ignored. If
 	 * this query is for a PF and this flag is set to 1, then the PF
@@ -1861,7 +2381,17 @@ struct hwrm_func_qcaps_output {
 	 * capability to set the minimum or maximum bandwidths for its
 	 * children VFs.
 	 */
-	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED	UINT32_C(0x400)
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_VF_BW_CFG_SUPPORTED UINT32_C(0x400)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is supported on the
+	 * queried function. If set to 0, then standard TX ring mode is
+	 * not available on the queried function.
+	 */
+	#define HWRM_FUNC_QCAPS_OUTPUT_FLAGS_STD_TX_RING_MODE_SUPPORTED   \
+		UINT32_C(0x800)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -1901,7 +2431,7 @@ struct hwrm_func_qcaps_output {
 	uint16_t first_vf_id;
 	/*
 	 * 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
+	 * 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.
 	 */
@@ -1909,7 +2439,7 @@ struct hwrm_func_qcaps_output {
 	/*
 	 * 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-
+	 * 0xFF...	(All Fs) if this command is called on a PF with SR-
 	 * IOV disabled or on a VF.
 	 */
 	uint16_t max_stat_ctx;
@@ -1929,22 +2459,22 @@ struct hwrm_func_qcaps_output {
 	 */
 	uint32_t max_tx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_tx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the TX side.
 	 */
 	uint32_t max_rx_em_flows;
 	/*
-	 * The maximum number of Exact Match (EM) flows that can be
+	 * The maximum number of Exact Match	(EM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_rx_wm_flows;
 	/*
-	 * The maximum number of Wildcard Match (WM) flows that can be
+	 * The maximum number of Wildcard Match	(WM) flows that can be
 	 * offloaded by this function on the RX side.
 	 */
 	uint32_t max_mcast_filters;
@@ -1968,7 +2498,7 @@ struct hwrm_func_qcaps_output {
 	 * be allocated to the function. This number indicates the
 	 * maximum number of TX rings that can be assigned strict
 	 * priorities out of the maximum number of TX rings that can be
-	 * allocated (max_tx_rings) to the function.
+	 * allocated	(max_tx_rings) to the function.
 	 */
 	uint8_t unused_0;
 	uint8_t valid;
@@ -1989,9 +2519,13 @@ struct hwrm_func_qcaps_output {
  * 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.
+ * the PCI bus. This command should be called by every driver after
+ * 'hwrm_func_cfg' to get the actual number of resources allocated by the HWRM.
+ * The values returned by hwrm_func_qcfg are the values the driver shall use.
+ * These values may be different than what was originally requested in the
+ * 'hwrm_func_cfg' command.
  */
-/* Input (24 bytes) */
+/* Input	(24 bytes) */
 struct hwrm_func_qcfg_input {
 	uint16_t req_type;
 	/*
@@ -2022,12 +2556,12 @@ struct hwrm_func_qcfg_input {
 	uint16_t fid;
 	/*
 	 * Function ID of the function that is being queried. 0xFF...
-	 * (All Fs) if the query is for the requesting function.
+	 *	(All Fs) if the query is for the requesting function.
 	 */
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (72 bytes) */
+/* Output	(72 bytes) */
 struct hwrm_func_qcfg_output {
 	uint16_t error_code;
 	/*
@@ -2052,7 +2586,7 @@ struct hwrm_func_qcfg_output {
 	uint16_t port_id;
 	/*
 	 * Port ID of port that this function is associated with.
-	 * 0xFF... (All Fs) if this function is not associated with any
+	 * 0xFF...	(All Fs) if this function is not associated with any
 	 * port.
 	 */
 	uint16_t vlan;
@@ -2060,15 +2594,15 @@ struct hwrm_func_qcfg_output {
 	 * This value is the current VLAN setting for this function. The
 	 * value of 0 for this field indicates no priority tagging or
 	 * VLAN is used. This field's format is same as 802.1Q Tag's Tag
-	 * Control Information (TCI) format that includes both Priority
-	 * Code Point (PCP) and VLAN Identifier (VID).
+	 * Control Information	(TCI) format that includes both Priority
+	 * Code Point	(PCP) and VLAN Identifier	(VID).
 	 */
 	uint16_t flags;
 	/*
 	 * If 1, then magic packet based Out-Of-Box WoL is enabled on
 	 * the port associated with this function.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_OOB_WOL_MAGICPKT_ENABLED	 \
 		UINT32_C(0x1)
 	/*
 	 * If 1, then bitmap pattern based Out-Of-Box WoL packet is
@@ -2080,8 +2614,33 @@ struct hwrm_func_qcfg_output {
 	 * on the port associated with this function. If set to 0, then
 	 * DCBX agent is not running in the firmware.
 	 */
-	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED	\
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_DCBX_AGENT_ENABLED \
 		UINT32_C(0x4)
+	/*
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is enabled on the
+	 * queried function. If set to 0, then the standard TX ring mode
+	 * is disabled on the queried function. In this extended TX ring
+	 * resource mode, the minimum and maximum bandwidth settings are
+	 * not supported to allow the allocation of TX rings to span
+	 * multiple scheduler nodes.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_STD_TX_RING_MODE_ENABLED	 \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1 then FW based LLDP agent is enabled and running
+	 * on the port associated with this function. If set to 0 then
+	 * the LLDP agent is not running in the firmware.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_FW_LLDP_AGENT_ENABLED UINT32_C(0x10)
+	/*
+	 * If set to 1, then multi-host mode is active for this
+	 * function. If set to 0, then multi-host mode is inactive for
+	 * this function or not applicable for this device.
+	 */
+	#define HWRM_FUNC_QCFG_OUTPUT_FLAGS_MULTI_HOST		UINT32_C(0x20)
 	uint8_t mac_address[6];
 	/*
 	 * This value is current MAC address configured for this
@@ -2091,8 +2650,8 @@ struct hwrm_func_qcfg_output {
 	uint16_t pci_id;
 	/*
 	 * This value is current PCI ID of this function. If ARI is
-	 * enabled, then it is Bus Number (8b):Function Number(8b).
-	 * Otherwise, it is Bus Number (8b):Device Number (4b):Function
+	 * enabled, then it is Bus Number	(8b):Function Number(8b).
+	 * Otherwise, it is Bus Number	(8b):Device Number	(4b):Function
 	 * Number(4b).
 	 */
 	uint16_t alloc_rsscos_ctx;
@@ -2146,22 +2705,27 @@ struct hwrm_func_qcfg_output {
 	/* Multiple physical functions */
 	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_MPFS	UINT32_C(0x1)
 	/* Network Partitioning 1.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0	\
-		UINT32_C(0x2)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0 UINT32_C(0x2)
 	/* Network Partitioning 1.5 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5	\
-		UINT32_C(0x3)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5 UINT32_C(0x3)
 	/* Network Partitioning 2.0 */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0	\
-		UINT32_C(0x4)
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR2_0 UINT32_C(0x4)
 	/* Unknown */
-	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN	\
-		UINT32_C(0xff)
-	uint8_t unused_0;
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_UNKNOWN UINT32_C(0xff)
+	uint8_t port_pf_cnt;
+	/*
+	 * This field will indicate number of physical functions on this
+	 * port_partition. HWRM shall return unavail (i.e. value of 0)
+	 * for this field when this command is used to query VF's
+	 * configuration or from older firmware that doesn't support
+	 * this field.
+	 */
+	/* number of PFs is not available */
+	#define HWRM_FUNC_QCFG_OUTPUT_PORT_PF_CNT_UNAVAIL	UINT32_C(0x0)
 	uint16_t dflt_vnic_id;
 	/* The default VNIC ID assigned to a function that is being queried. */
+	uint8_t unused_0;
 	uint8_t unused_1;
-	uint8_t unused_2;
 	uint32_t min_bw;
 	/*
 	 * Minimum BW allocated for this function. The HWRM will
@@ -2169,26 +2733,41 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * the minimum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MIN_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MIN_BW_BW_VALUE_UNIT_INVALID
 	uint32_t max_bw;
 	/*
@@ -2197,43 +2776,58 @@ struct hwrm_func_qcfg_output {
 	 * for the scheduler inside the device. A value of 0 indicates
 	 * that the maximum bandwidth is not configured.
 	 */
-	/* Bandwidth value */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES \
+		(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_SCALE_LAST \
+		FUNC_QCFG_OUTPUT_MAX_BW_SCALE_BYTES
 	/* bw_value_unit is 3 b */
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
 		UINT32_C(0xe0000000)
 	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_MEGA \
 		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
 	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
 		(UINT32_C(0x1) << 29)
 	/* Invalid unit */
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
 		(UINT32_C(0x7) << 29)
-	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
+	#define HWRM_FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_LAST \
 		FUNC_QCFG_OUTPUT_MAX_BW_BW_VALUE_UNIT_INVALID
 	uint8_t evb_mode;
 	/*
 	 * This value indicates the Edge virtual bridge mode for the
 	 * domain that this function belongs to.
 	 */
-	/* No Edge Virtual Bridging (EVB) */
+	/* No Edge Virtual Bridging	(EVB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
-	/* Virtual Ethernet Bridge (VEB) */
+	/* Virtual Ethernet Bridge	(VEB) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEB	UINT32_C(0x1)
-	/* Virtual Ethernet Port Aggregator (VEPA) */
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
 	#define HWRM_FUNC_QCFG_OUTPUT_EVB_MODE_VEPA	UINT32_C(0x2)
-	uint8_t unused_3;
+	uint8_t unused_2;
 	uint16_t alloc_vfs;
 	/*
 	 * The number of VFs that are allocated to the function. This is
-	 * valid only on the PF with SR-IOV enabled. 0xFF... (All Fs) if
+	 * 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.
 	 */
@@ -2247,9 +2841,9 @@ struct hwrm_func_qcfg_output {
 	uint16_t alloc_sp_tx_rings;
 	/*
 	 * The number of strict priority transmit rings out of currently
-	 * allocated TX rings to the function (alloc_tx_rings).
+	 * allocated TX rings to the function	(alloc_tx_rings).
 	 */
-	uint8_t unused_4;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -2261,15 +2855,14 @@ struct hwrm_func_qcfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_func_drv_rgtr */
+/* hwrm_func_vlan_qcfg */
 /*
- * 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.
+ * Description: This command should be called by PF driver to get the current
+ * C-TAG, S-TAG and correcponsing PCP and TPID values configured for the
+ * function.
  */
-/* Input (80 bytes) */
-struct hwrm_func_drv_rgtr_input {
+/* Input (24 bytes) */
+struct hwrm_func_vlan_qcfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2296,96 +2889,17 @@ struct hwrm_func_drv_rgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 enables;
-	/* 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_INPUT_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)
-	uint16_t os_type;
-	/* This value indicates the type of OS. */
-	/* Unknown */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Other OS not listed below. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
-	/* MSDOS OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
-	/* Windows OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
-	/* Solaris OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
-	/* Linux OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
-	/* FreeBSD OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
-	/* VMware ESXi OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
-	/* Microsoft Windows 8 64-bit OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
-	/* Microsoft Windows Server 2012 R2 OS. */
-	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
-	uint8_t ver_maj;
-	/* This is the major version of the driver. */
-	uint8_t ver_min;
-	/* This is the minor version of the driver. */
-	uint8_t ver_upd;
-	/* This is the update version of the driver. */
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint32_t timestamp;
-	/*
-	 * This is a 32-bit timestamp provided by the driver for keep
-	 * alive. The timestamp is in multiples of 1ms.
-	 */
-	uint32_t unused_2;
-	uint32_t vf_req_fwd[8];
-	/*
-	 * 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 async_event_fwd[8];
+	uint16_t fid;
 	/*
-	 * 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.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-} __attribute__((packed));
+	uint16_t unused_0[3];
+};
 
-/* Output (16 bytes) */
-struct hwrm_func_drv_rgtr_output {
+/* Output (40 bytes) */
+struct hwrm_func_vlan_qcfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2414,16 +2928,40 @@ struct hwrm_func_drv_rgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_4;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_5;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t rsvd3;
+	/* Future use. */
+	uint32_t unused_6;
+};
 
-/* hwrm_func_drv_unrgtr */
+/* hwrm_func_vlan_cfg */
 /*
- * 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.
+ * Description: This command allows PF driver to configure C-TAG, S-TAG and
+ * corresponding PCP and TPID values for a function.
  */
-/* Input (24 bytes) */
-struct hwrm_func_drv_unrgtr_input {
+/* Input (48 bytes) */
+struct hwrm_func_vlan_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2450,17 +2988,56 @@ struct hwrm_func_drv_unrgtr_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint16_t fid;
 	/*
-	 * When this bit is '1', the function driver is notifying the
-	 * HWRM to prepare for the shutdown.
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF... (All Fs), then the configuration is for the
+	 * requesting function.
 	 */
-	#define HWRM_FUNC_DRV_UNRGTR_INPUT_FLAGS_PREPARE_FOR_SHUTDOWN	UINT32_C(0x1)
-	uint32_t unused_0;
-} __attribute__((packed));
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t enables;
+	/* This bit must be '1' for the stag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_VID	UINT32_C(0x1)
+	/* This bit must be '1' for the ctag_vid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_VID	UINT32_C(0x2)
+	/* This bit must be '1' for the stag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_PCP	UINT32_C(0x4)
+	/* This bit must be '1' for the ctag_pcp field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_PCP	UINT32_C(0x8)
+	/* This bit must be '1' for the stag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_STAG_TPID	UINT32_C(0x10)
+	/* This bit must be '1' for the ctag_tpid field to be configured. */
+	#define HWRM_FUNC_VLAN_CFG_INPUT_ENABLES_CTAG_TPID	UINT32_C(0x20)
+	uint16_t stag_vid;
+	/* S-TAG VLAN identifier configured for the function. */
+	uint8_t stag_pcp;
+	/* S-TAG PCP value configured for the function. */
+	uint8_t unused_2;
+	uint16_t stag_tpid;
+	/*
+	 * S-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint16_t ctag_vid;
+	/* C-TAG VLAN identifier configured for the function. */
+	uint8_t ctag_pcp;
+	/* C-TAG PCP value configured for the function. */
+	uint8_t unused_3;
+	uint16_t ctag_tpid;
+	/*
+	 * C-TAG TPID value configured for the function. This field is
+	 * specified in network byte order.
+	 */
+	uint32_t rsvd1;
+	/* Future use. */
+	uint32_t rsvd2;
+	/* Future use. */
+	uint32_t unused_4;
+};
 
 /* Output (16 bytes) */
-struct hwrm_func_drv_unrgtr_output {
+struct hwrm_func_vlan_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2489,19 +3066,45 @@ struct hwrm_func_drv_unrgtr_output {
 	 * internal processor, the order of writes has to be such that
 	 * this field is written last.
 	 */
-} __attribute__((packed));
+};
 
-/* hwrm_port_phy_cfg */
+/* hwrm_func_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.
+ * Description: This command allows configuration of a PF by the corresponding
+ * PF driver. This command also allows configuration of a child VF by its parent
+ * PF driver. The input FID value is used to indicate what function is being
+ * configured. This allows a PF driver to configure the PF owned by itself or a
+ * virtual function that is a child of the PF. This command allows to reserve
+ * resources for a VF by its parent PF. To reverse the process, the command
+ * should be called with all enables flags cleared for resources. This will free
+ * allocated resources for the VF and return them to the resource pool. If this
+ * command is requested by a VF driver to configure or reserve resources, then
+ * the HWRM shall fail this command. If default MAC address and/or VLAN are
+ * provided in this command, then the HWRM shall set up appropriate MAC/VLAN
+ * filters for the function that is being configured. If source properties
+ * checks are enabled and default MAC address and/or IP address are provided in
+ * this command, then the HWRM shall set appropriate source property checks
+ * based on provided MAC and/or IP addresses. The parent PF driver should not
+ * set MTU/MRU for a VF using this command. This is to allow MTU/MRU setting by
+ * the VF driver. If the MTU or MRU for a VF is set by the PF driver, then the
+ * HWRM should ignore it. A function's MTU/MRU should be set prior to allocating
+ * RX VNICs or TX rings. A PF driver calls hwrm_func_cfg to allocate resources
+ * for itself or its children VFs. All function drivers shall call hwrm_func_cfg
+ * to reserve resources. A request to hwrm_func_cfg may not be fully granted;
+ * that is, a request for resources may be larger than what can be supported by
+ * the device and the HWRM will allocate the best set of resources available,
+ * but that may be less than requested. If all the amounts requested could not
+ * be fulfilled, the HWRM shall allocate what it could and return a status code
+ * of success. A function driver should call hwrm_func_qcfg immediately after
+ * hwrm_func_cfg to determine what resources were assigned to the configured
+ * function. A call by a PF driver to hwrm_func_cfg to allocate resources for
+ * itself shall only allocate resources for the PF driver to use, not for its
+ * children VFs. Likewise, a call to hwrm_func_qcfg shall return the resources
+ * available for the PF driver to use, not what is available to its children
+ * VFs.
  */
-/* Input (56 bytes) */
-struct hwrm_port_phy_cfg_input {
+/* Input	(88 bytes) */
+struct hwrm_func_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2528,397 +3131,560 @@ struct hwrm_port_phy_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function that is being configured. If set
+	 * to 0xFF...	(All Fs), then the the configuration is for the
+	 * requesting function.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
 	uint32_t flags;
 	/*
-	 * 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.
+	 * When this bit is '1', the function is disabled with source
+	 * MAC address check. This is an anti-spoofing check. If this
+	 * flag is set, then the function shall be configured to
+	 * disallow transmission of frames with the source MAC address
+	 * that is configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY	UINT32_C(0x1)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE	 \
+		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.
+	 * When this bit is '1', the function is enabled with source MAC
+	 * address check. This is an anti-spoofing check. If this flag
+	 * is set, then the function shall be configured to allow
+	 * transmission of frames with the source MAC address that is
+	 * configured for this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DOWN	UINT32_C(0x2)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE	\
+		UINT32_C(0x2)
+	/* reserved */
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_MASK	UINT32_C(0x1fc)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_RSVD_SFT	2
 	/*
-	 * 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.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then standard TX ring mode is requested to be
+	 * enabled on the function being configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE	UINT32_C(0x4)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE	\
+		UINT32_C(0x200)
 	/*
-	 * When this bit is set to '1', the auto-negotiation process
-	 * shall be restarted on the link.
+	 * Standard TX Ring mode is used for the allocation of TX ring
+	 * and underlying scheduling resources that allow bandwidth
+	 * reservation and limit settings on the queried function. If
+	 * set to 1, then the standard TX ring mode is requested to be
+	 * disabled on the function being configured. In this extended
+	 * TX ring resource mode, the minimum and maximum bandwidth
+	 * settings are not supported to allow the allocation of TX
+	 * rings to span multiple scheduler nodes.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG	UINT32_C(0x8)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE	\
+		UINT32_C(0x400)
 	/*
-	 * 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.
+	 * If this bit is set, virtual mac address configured in this
+	 * command will be persistent over warm boot.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_ENABLE	UINT32_C(0x10)
+	#define HWRM_FUNC_CFG_INPUT_FLAGS_VIRT_MAC_PERSIST	UINT32_C(0x800)
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MTU	UINT32_C(0x1)
+	/* This bit must be '1' for the mru field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MRU	UINT32_C(0x2)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_rsscos_ctxs field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_DISABLE	UINT32_C(0x20)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS	UINT32_C(0x4)
 	/*
-	 * 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.
+	 * This bit must be '1' for the num_cmpl_rings field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_ENABLE	UINT32_C(0x40)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS	UINT32_C(0x8)
+	/* This bit must be '1' for the num_tx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS	UINT32_C(0x10)
+	/* This bit must be '1' for the num_rx_rings field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS	UINT32_C(0x20)
+	/* This bit must be '1' for the num_l2_ctxs field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS	UINT32_C(0x40)
+	/* This bit must be '1' for the num_vnics field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS	UINT32_C(0x80)
+	/*
+	 * This bit must be '1' for the num_stat_ctxs field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS	UINT32_C(0x100)
 	/*
-	 * When this bit is set to '1' and EEE is enabled on this link,
-	 * then TX LPI is requested to be disabled 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.
+	 * This bit must be '1' for the dflt_mac_addr field to be
+	 * configured.
+	 */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR	UINT32_C(0x200)
+	/* This bit must be '1' for the dflt_vlan field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN	UINT32_C(0x400)
+	/* This bit must be '1' for the dflt_ip_addr field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_IP_ADDR	UINT32_C(0x800)
+	/* This bit must be '1' for the min_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MIN_BW	UINT32_C(0x1000)
+	/* This bit must be '1' for the max_bw field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW	UINT32_C(0x2000)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_EEE_TX_LPI_DISABLE	UINT32_C(0x80)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR	UINT32_C(0x4000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC
-	 * autonegotitation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the vlan_antispoof_mode field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE	UINT32_C(0x100)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE	UINT32_C(0x8000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC
-	 * autonegotiation on this port if supported. When set to 0,
-	 * then this flag shall be ignored. If FEC autonegotiation is
-	 * not supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the allowed_vlan_pris field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	UINT32_C(0x200)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_ALLOWED_VLAN_PRIS UINT32_C(0x10000)
+	/* This bit must be '1' for the evb_mode field to be configured. */
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE	UINT32_C(0x20000)
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74 (Fire
-	 * Code) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_mcast_filters field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	UINT32_C(0x400)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_MCAST_FILTERS UINT32_C(0x40000)
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
-	 * (Fire Code) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 74 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * This bit must be '1' for the num_hw_ring_grps field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	UINT32_C(0x800)
+	#define HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS UINT32_C(0x80000)
+	uint16_t mtu;
 	/*
-	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91 (Reed
-	 * Solomon) on this port if supported. When set to 0, then this
-	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
-	 * then the HWRM shall ignore this flag.
+	 * The maximum transmission unit of the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed
+	 * the mtu of the physical port that this function is associated
+	 * with. In addition to configuring mtu per function, it is
+	 * possible to configure mtu per transmit ring. By default, the
+	 * mtu of each transmit ring associated with a function is equal
+	 * to the mtu of the function. The HWRM should make sure that
+	 * the mtu of each transmit ring that is assigned to a function
+	 * has a valid mtu.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	UINT32_C(0x1000)
+	uint16_t mru;
 	/*
-	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
-	 * (Reed Solomon) on this port if supported. When set to 0, then
-	 * this flag shall be ignored. If FEC CLAUSE 91 is not
-	 * supported, then the HWRM shall ignore this flag.
+	 * The maximum receive unit of the function. The HWRM should
+	 * make sure that the mru of the function does not exceed the
+	 * mru of the physical port that this function is associated
+	 * with. In addition to configuring mru per function, it is
+	 * possible to configure mru per vnic. By default, the mru of
+	 * each vnic associated with a function is equal to the mru of
+	 * the function. The HWRM should make sure that the mru of each
+	 * vnic that is assigned to a function has a valid mru.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	UINT32_C(0x2000)
-	uint32_t enables;
-	/* 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)
+	uint16_t num_rsscos_ctxs;
+	/* The number of RSS/COS contexts requested for the function. */
+	uint16_t num_cmpl_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed field to be
-	 * configured.
+	 * The number of completion rings requested for the function.
+	 * This does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEED	UINT32_C(0x8)
+	uint16_t num_tx_rings;
 	/*
-	 * This bit must be '1' for the auto_link_speed_mask field to be
-	 * configured.
+	 * The number of transmit rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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_WIOUTPUTEED	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)
+	uint16_t num_rx_rings;
 	/*
-	 * This bit must be '1' for the eee_link_speed_mask field to be
-	 * configured.
+	 * The number of receive rings requested for the function. This
+	 * does not include the rings allocated to any children
+	 * functions if any.
 	 */
-	#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)
-	uint16_t port_id;
-	/* Port ID of port that is to be configured. */
-	uint16_t force_link_speed;
+	uint16_t num_l2_ctxs;
+	/* The requested number of L2 contexts for the function. */
+	uint16_t num_vnics;
+	/* The requested number of vnics for the function. */
+	uint16_t num_stat_ctxs;
+	/* The requested number of statistic contexts for the function. */
+	uint16_t num_hw_ring_grps;
 	/*
-	 * This is the speed that will be used if the force bit is '1'.
-	 * If unsupported speed is selected, an error will be generated.
+	 * The number of HW ring groups that should be reserved for this
+	 * function.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
+	uint8_t dflt_mac_addr[6];
+	/* The default MAC address for the function being configured. */
+	uint16_t dflt_vlan;
 	/*
-	 * This value is used to identify what autoneg mode is used when
-	 * the link speed is not being forced.
+	 * The default VLAN for the function being configured. This
+	 * field's format is same as 802.1Q Tag's Tag Control
+	 * Information	(TCI) format that includes both Priority Code
+	 * Point	(PCP) and VLAN Identifier	(VID).
 	 */
+	uint32_t dflt_ip_addr[4];
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * The default IP address for the function being configured.
+	 * This address is only used in enabling source property check.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	uint32_t min_bw;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Minimum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MIN_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_MEGA \
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_KILO \
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MIN_BW_BW_VALUE_UNIT_INVALID
+	uint32_t max_bw;
+	/*
+	 * Maximum BW allocated for this function. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for the scheduler inside the device.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	/* The bandwidth value. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_MASK \
+		UINT32_C(0xfffffff)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES	(UINT32_C(0x1) << 28)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_SCALE_LAST \
+		FUNC_CFG_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	 \
+		UINT32_C(0xe0000000)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_BASE \
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA \
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		FUNC_CFG_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous
+	 * event completions. If this field is not valid, then the HWRM
+	 * shall use the default completion ring of the function that is
+	 * being configured as the target completion ring for providing
+	 * any asynchronous event completions for that function. If this
+	 * field is valid, then the HWRM shall use the completion ring
+	 * identified by this ID as the target completion ring for
+	 * providing any asynchronous event completions for the function
+	 * that is being configured.
+	 */
+	uint8_t vlan_antispoof_mode;
+	/* VLAN Anti-spoofing mode. */
+	/* No VLAN anti-spoofing checks are enabled */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK	UINT32_C(0x0)
+	/* Validate VLAN against the configured VLAN(s) */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN \
+		UINT32_C(0x1)
+	/* Insert VLAN if it does not exist, otherwise discard */
+	#define HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_IF_VLANDNE \
+		UINT32_C(0x2)
 	/*
-	 * 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.
+	 * Insert VLAN if it does not exist, override
+	 * VLAN if it exists
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ONE_OR_BELOW	UINT32_C(0x3)
+	#define \
+	HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_INSERT_OR_OVERRIDE_VLAN \
+		UINT32_C(0x3)
+	uint8_t allowed_vlan_pris;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * This bit field defines VLAN PRIs that are allowed on this
+	 * function. If nth bit is set, then VLAN PRI n is allowed on
+	 * this function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_duplex;
+	uint8_t evb_mode;
 	/*
-	 * This is the duplex setting that will be used if the
-	 * autoneg_mode is "one_speed" or "one_or_below".
+	 * The HWRM shall allow a PF driver to change EVB mode for the
+	 * partition it belongs to. The HWRM shall not allow a VF driver
+	 * to change the EVB mode. The HWRM shall take into account the
+	 * switching of EVB mode from one to another and reconfigure
+	 * hardware resources as appropriately. The switching from VEB
+	 * to VEPA mode requires the disabling of the loopback traffic.
+	 * Additionally, source knock outs are handled differently in
+	 * VEB and VEPA modes.
+	 */
+	/* No Edge Virtual Bridging	(EVB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_NO_EVB	UINT32_C(0x0)
+	/* Virtual Ethernet Bridge	(VEB) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEB	UINT32_C(0x1)
+	/* Virtual Ethernet Port Aggregator	(VEPA) */
+	#define HWRM_FUNC_CFG_INPUT_EVB_MODE_VEPA	UINT32_C(0x2)
+	uint8_t unused_2;
+	uint16_t num_mcast_filters;
+	/*
+	 * The number of multicast filters that should be reserved for
+	 * this function on the RX side.
 	 */
-	/* Half Duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
-	/* Both Half and Full dupex will be requested. */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
-	uint8_t auto_pause;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_cfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+} __attribute__((packed));
+
+/* hwrm_func_qstats */
+/*
+ * Description: This command returns statistics 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 HWRM shall return any unsupported counter with a value
+ * of 0xFFFFFFFF for 32-bit counters and 0xFFFFFFFFFFFFFFFF for 64-bit counters.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_qstats_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_PAUSE_AUTONEG_PAUSE	UINT32_C(0x4)
-	uint8_t unused_0;
-	uint16_t auto_link_speed;
+	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* This value controls the wirespeed feature. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* 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)
+	uint64_t resp_addr;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t fid;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Function ID of the function that is being queried. 0xFF...
+	 *	(All Fs) if the query is for the requesting function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(176 bytes) */
+struct hwrm_func_qstats_output {
+	uint16_t error_code;
 	/*
-	 * This value is used to configure the pause that will be used
-	 * for force mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
 	 */
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets on the function. */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets on the function. */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets on the function. */
+	uint64_t tx_err_pkts;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of transmitted packets that were discarded due to
+	 * internal NIC resource problems. For transmit, this can only
+	 * happen if TMP is configured to allow dropping in HOL blocking
+	 * conditions, which is not a normal configuration.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	uint64_t tx_drop_pkts;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * Number of dropped packets on transmit path on the function.
+	 * These are packets that have been marked for drop by the TE
+	 * CFA block or are packets that exceeded the transmit MTU limit
+	 * for the function.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t unused_1;
-	uint32_t preemphasis;
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic on the function. */
+	uint64_t tx_mcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for multicast traffic on the
+	 * function.
 	 */
-	uint16_t eee_link_speed_mask;
+	uint64_t tx_bcast_bytes;
 	/*
-	 * 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.
+	 * Number of transmitted bytes for broadcast traffic on the
+	 * function.
 	 */
-	/* 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)
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets on the function. */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets on the function. */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets on the function. */
+	uint64_t rx_err_pkts;
+	/*
+	 * Number of received packets that were discarded on the
+	 * function due to resource limitations. This can happen for 3
+	 * reasons. # The BD used for the packet has a bad format. #
+	 * There were no BDs available in the ring for the packet. #
+	 * There were no BDs available on-chip for the packet.
+	 */
+	uint64_t rx_drop_pkts;
+	/*
+	 * Number of dropped packets on received path on the function.
+	 * These are packets that have been marked for drop by the RE
+	 * CFA.
+	 */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic on the function. */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic on the function. */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic on the function. */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets on the function. */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes on the function. */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events on the function. */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations on the function. */
+	uint32_t unused_0;
+	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint32_t tx_lpi_timer;
-	uint32_t unused_4;
+	uint8_t valid;
 	/*
-	 * Reuested setting of TX LPI timer in microseconds. This field
-	 * is valid only when EEE is enabled and TX LPI is enabled.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_MASK	UINT32_C(0xffffff)
-	#define HWRM_PORT_PHY_CFG_INPUT_TX_LPI_TIMER_SFT	0
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_port_phy_cfg_output {
+/* hwrm_func_clr_stats */
+/*
+ * Description: This command clears statistics of a function. The input FID
+ * value is used to indicate what function's statistics is being cleared. This
+ * allows a physical function driver to clear statistics of virtual functions
+ * that are children of the physical function.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t fid;
+	/*
+	 * Function ID of the function. 0xFF...	(All Fs) if the query is
+	 * for the requesting function.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -2949,10 +3715,10 @@ struct hwrm_port_phy_cfg_output {
 	 */
 } __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 {
+/* hwrm_func_vf_vnic_ids_query */
+/* Description: This command is used to query vf vnic ids. */
+/* Input	(32 bytes) */
+struct hwrm_func_vf_vnic_ids_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -2979,13 +3745,21 @@ struct hwrm_port_phy_qcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint16_t port_id;
-	/* Port ID of port that is to be queried. */
-	uint16_t unused_0[3];
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_vnic_id_cnt;
+	/* Max number of vnic ids in vnic id table */
+	uint64_t vnic_id_tbl_addr;
+	/* This is the address for VF VNIC ID table */
 } __attribute__((packed));
 
-/* Output (96 bytes) */
-struct hwrm_port_phy_qcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_func_vf_vnic_ids_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3001,698 +3775,2769 @@ struct hwrm_port_phy_qcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t link;
-	/* 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)
-	/* There is no link, but a cable has been detected. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
-	/* There is a link. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t link_speed;
-	/* 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)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t duplex;
-	/* This value is indicates the duplex of the current connection. */
-	/* Half Duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
-	/* Full duplex connection. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
-	uint8_t pause;
+	uint32_t vnic_id_cnt;
 	/*
-	 * This value is used to indicate the current pause
-	 * configuration. When autoneg is enabled, this value represents
-	 * the autoneg results of pause configuration.
+	 * Actual number of vnic ids Each VNIC ID is written as a 32-bit
+	 * number.
 	 */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_TX	UINT32_C(0x1)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PAUSE_RX	UINT32_C(0x2)
-	uint16_t support_speeds;
+	uint16_t cmpl_ring;
 	/*
-	 * 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)
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 enables;
+	/* 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_INPUT_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)
+	uint16_t os_type;
+	/*
+	 * This value indicates the type of OS. The values are based on
+	 * CIM_OperatingSystem.mof file as published by the DMTF.
+	 */
+	/* Unknown */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Other OS not listed below. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_OTHER	UINT32_C(0x1)
+	/* MSDOS OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_MSDOS	UINT32_C(0xe)
+	/* Windows OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WINDOWS	UINT32_C(0x12)
+	/* Solaris OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_SOLARIS	UINT32_C(0x1d)
+	/* Linux OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_LINUX	UINT32_C(0x24)
+	/* FreeBSD OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_FREEBSD	UINT32_C(0x2a)
+	/* VMware ESXi OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_ESXI	UINT32_C(0x68)
+	/* Microsoft Windows 8 64-bit OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN864	UINT32_C(0x73)
+	/* Microsoft Windows Server 2012 R2 OS. */
+	#define HWRM_FUNC_DRV_RGTR_INPUT_OS_TYPE_WIN2012R2	UINT32_C(0x74)
+	uint8_t ver_maj;
+	/* This is the major version of the driver. */
+	uint8_t ver_min;
+	/* This is the minor version of the driver. */
+	uint8_t ver_upd;
+	/* This is the update version of the driver. */
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint32_t timestamp;
+	/*
+	 * This is a 32-bit timestamp provided by the driver for keep
+	 * alive. The timestamp is in multiples of 1ms.
+	 */
+	uint32_t unused_2;
+	uint32_t vf_req_fwd[8];
+	/*
+	 * 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 async_event_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.
+	 */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_drv_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_rgtr */
+/*
+ * Description: This command is used by the PF driver to register buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * register buffers for each PF-VF channel. A parent PF may issue this command
+ * per child VF. If VF ID is not valid, then this command is used to register
+ * buffers for all children VFs of the PF.
+ */
+/* Input	(128 bytes) */
+struct hwrm_func_buf_rgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the err_buf_addr field to be configured. */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_ENABLES_ERR_BUF_ADDR	UINT32_C(0x2)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t req_buf_num_pages;
+	/*
+	 * This field represents the number of pages used for request
+	 * buffer(s).
+	 */
+	uint16_t req_buf_page_size;
+	/* This field represents the page size used for request buffer(s). */
+	/* 16 bytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_16B UINT32_C(0x4)
+	/* 4 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4K	UINT32_C(0xc)
+	/* 8 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_8K	UINT32_C(0xd)
+	/* 64 Kbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_64K UINT32_C(0x10)
+	/* 2 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_2M	UINT32_C(0x15)
+	/* 4 Mbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_4M	UINT32_C(0x16)
+	/* 1 Gbytes */
+	#define HWRM_FUNC_BUF_RGTR_INPUT_INPUT_BUF_PAGE_SIZE_1G	UINT32_C(0x1e)
+	uint16_t req_buf_len;
+	/* The length of the request buffer per VF in bytes. */
+	uint16_t resp_buf_len;
+	/* The length of the response buffer in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint64_t req_buf_page_addr[10];
+	/* This field represents the page address of req buffer. */
+	uint64_t error_buf_addr;
+	/*
+	 * This field is used to receive the error reporting from the
+	 * chipset. Only applicable for PFs.
+	 */
+	uint64_t resp_buf_addr;
+	/* This field is used to receive the response forwarded by the HWRM. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_rgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_buf_unrgtr */
+/*
+ * Description: This command is used by the PF driver to unregister buffers used
+ * in the PF-VF communication with the HWRM. The PF driver uses this command to
+ * unregister buffers for PF-VF communication. A parent PF may issue this
+ * command to unregister buffers for communication between the PF and a specific
+ * VF. If the VF ID is not valid, then this command is used to unregister
+ * buffers used for communications with all children VFs of the PF.
+ */
+/* Input	(24 bytes) */
+struct hwrm_func_buf_unrgtr_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id field to be configured. */
+	#define HWRM_FUNC_BUF_UNRGTR_INPUT_ENABLES_VF_ID	UINT32_C(0x1)
+	uint16_t vf_id;
+	/*
+	 * This value is used to identify a Virtual Function	(VF). The
+	 * scope of VF ID is local within a PF.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_func_buf_unrgtr_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_func_vf_cfg */
+/*
+ * Description: This command allows configuration of a VF by its driver. If this
+ * function is called by a PF driver, then the HWRM shall fail this command. If
+ * guest VLAN and/or MAC address are provided in this command, then the HWRM
+ * shall set up appropriate MAC/VLAN filters for the VF that is being
+ * configured. A VF driver should set VF MTU/MRU using this command prior to
+ * allocating RX VNICs or TX rings for the corresponding VF.
+ */
+/* Input (32 bytes) */
+
+struct hwrm_func_vf_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the mtu field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_MTU                 UINT32_C(0x1)
+	/* This bit must be '1' for the guest_vlan field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_GUEST_VLAN          UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the async_event_cr field to be configured.
+	 */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR      UINT32_C(0x4)
+	/* This bit must be '1' for the dflt_mac_addr field to be configured. */
+	#define HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR       UINT32_C(0x8)
+	uint16_t mtu;
+	/*
+	 * The maximum transmission unit requested on the function. The HWRM
+	 * should make sure that the mtu of the function does not exceed the mtu
+	 * of the physical port that this function is associated with. In
+	 * addition to requesting mtu per function, it is possible to configure
+	 * mtu per transmit ring. By default, the mtu of each transmit ring
+	 * associated with a function is equal to the mtu of the function. The
+	 * HWRM should make sure that the mtu of each transmit ring that is
+	 * assigned to a function has a valid mtu.
+	 */
+	uint16_t guest_vlan;
+	/*
+	 * The guest VLAN for the function being configured. This field's format
+	 * is same as 802.1Q Tag's Tag Control Information (TCI) format that
+	 * includes both Priority Code Point (PCP) and VLAN Identifier (VID).
+	 */
+	uint16_t async_event_cr;
+	/*
+	 * ID of the target completion ring for receiving asynchronous event
+	 * completions. If this field is not valid, then the HWRM shall use the
+	 * default completion ring of the function that is being configured as
+	 * the target completion ring for providing any asynchronous event
+	 * completions for that function. If this field is valid, then the HWRM
+	 * shall use the completion ring identified by this ID as the target
+	 * completion ring for providing any asynchronous event completions for
+	 * the function that is being configured.
+	 */
+	uint8_t dflt_mac_addr[6];
+	/*
+	 * This value is the current MAC address requested by the VF driver to
+	 * be configured on this VF. A value of 00-00-00-00-00-00 indicates no
+	 * MAC address configuration is requested by the VF driver. The parent
+	 * PF driver may reject or overwrite this MAC address.
+	 */
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_func_vf_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* deprecated bit. Do not use!!! */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_DEPRECATED	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_ENABLE	UINT32_C(0x40)
+	/*
+	 * When this bit is set to '1' and EEE is enabled on this link,
+	 * then TX LPI is requested to be disabled 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_DISABLE UINT32_C(0x80)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC
+	 * autonegotitation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_ENABLE UINT32_C(0x100)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC
+	 * autonegotiation on this port if supported. When set to 0,
+	 * then this flag shall be ignored. If FEC autonegotiation is
+	 * not supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_AUTONEG_DISABLE	\
+		UINT32_C(0x200)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 74	(Fire
+	 * Code) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 74 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_ENABLE	\
+		UINT32_C(0x400)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 74
+	 *	(Fire Code) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 74 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE74_DISABLE	\
+		UINT32_C(0x800)
+	/*
+	 * When set to 1, then the HWRM shall enable FEC CLAUSE 91	(Reed
+	 * Solomon) on this port if supported. When set to 0, then this
+	 * flag shall be ignored. If FEC CLAUSE 91 is not supported,
+	 * then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_ENABLE	\
+		UINT32_C(0x1000)
+	/*
+	 * When set to 1, then the HWRM shall disable FEC CLAUSE 91
+	 *	(Reed Solomon) on this port if supported. When set to 0, then
+	 * this flag shall be ignored. If FEC CLAUSE 91 is not
+	 * supported, then the HWRM shall ignore this flag.
+	 */
+	#define HWRM_PORT_PHY_CFG_INPUT_FLAGS_FEC_CLAUSE91_DISABLE	\
+		UINT32_C(0x2000)
+	/*
+	 * 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_DWN UINT32_C(0x4000)
+	uint32_t enables;
+	/* 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_WIOUTPUTEED	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)
+	uint16_t port_id;
+	/* Port ID of port that is to be configured. */
+	uint16_t force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_duplex;
+	/*
+	 * 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)
+	/* Full duplex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_FULL	UINT32_C(0x1)
+	/* Both Half and Full dupex will be requested. */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH	UINT32_C(0x2)
+	uint8_t auto_pause;
+	/*
+	 * 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 unused_0;
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* This value controls the wirespeed feature. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_CFG_INPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 unused_1;
+	uint32_t preemphasis;
+	/*
+	 * 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.
+	 */
+	uint16_t eee_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t tx_lpi_timer;
+	uint32_t unused_4;
+	/*
+	 * 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
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_phy_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is to be queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(96 bytes) */
+struct hwrm_port_phy_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t link;
+	/* 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)
+	/* There is no link, but a cable has been detected. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SIGNAL	UINT32_C(0x1)
+	/* There is a link. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_LINK	UINT32_C(0x2)
+	uint8_t unused_0;
+	uint16_t link_speed;
+	/* 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB	UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10MB	UINT32_C(0xffff)
+	uint8_t duplex;
+	/* This value is indicates the duplex of the current connection. */
+	/* Half Duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_HALF	UINT32_C(0x0)
+	/* Full duplex connection. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_DUPLEX_FULL	UINT32_C(0x1)
+	uint8_t pause;
+	/*
+	 * 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)
+	uint16_t support_speeds;
+	/*
+	 * 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 force_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint8_t auto_mode;
+	/* 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t auto_pause;
+	/*
+	 * 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)
+	uint16_t auto_link_speed;
+	/*
+	 * 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)
+	/* 1Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
+	/* 2Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
+	/* 2.5Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
+	/* 10Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
+	/* 20Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
+	/* 25Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
+	/* 40Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
+	/* 50Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
+	/* 100Gb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB UINT32_C(0x3e8)
+	/* 10Mb link speed */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB UINT32_C(0xffff)
+	uint16_t auto_link_speed_mask;
+	/*
+	 * 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)
+	uint8_t wirespeed;
+	/* Current setting for wirespeed. */
+	/* Wirespeed feature is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
+	/* Wirespeed feature is enabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
+	uint8_t lpbk;
+	/* Current setting for loopback. */
+	/* No loopback is selected. Normal operation. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t force_pause;
+	/*
+	 * 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 module_status;
+	/*
+	 * 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)
+	/* Module is rejected and transmit side Laser is disabled. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX UINT32_C(0x1)
+	/* Module mismatch warning. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG UINT32_C(0x2)
+	/* Module is rejected and powered down. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
+	/* Module is not inserted. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED \
+		UINT32_C(0x4)
+	/* Module status is not applicable. */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE \
+		UINT32_C(0xff)
+	uint32_t preemphasis;
+	/* Current setting for preemphasis. */
+	uint8_t phy_maj;
+	/* This field represents the major version of the PHY. */
+	uint8_t phy_min;
+	/* This field represents the minor version of the PHY. */
+	uint8_t phy_bld;
+	/* This field represents the build version of the PHY. */
+	uint8_t phy_type;
+	/* This value represents a PHY type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* BASE-CR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
+	/* BASE-KR4	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
+	/* BASE-LR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
+	/* BASE-SR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
+	/* BASE-KR2	(Deprecated) */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
+	/* BASE-KX */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
+	/* BASE-KR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
+	/* BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
+	/* EEE capable BASE-T */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
+	/* SGMII connected external PHY */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
+	/* 25G_BASECR_CA_L */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_L UINT32_C(0xb)
+	/* 25G_BASECR_CA_S */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_S UINT32_C(0xc)
+	/* 25G_BASECR_CA_N */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASECR_CA_N UINT32_C(0xd)
+	/* 25G_BASESR */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_25G_BASESR	UINT32_C(0xe)
+	/* 100G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASECR4	UINT32_C(0xf)
+	/* 100G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR4	UINT32_C(0x10)
+	/* 100G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASELR4	UINT32_C(0x11)
+	/* 100G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASEER4	UINT32_C(0x12)
+	/* 100G_BASESR10 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_100G_BASESR10 UINT32_C(0x13)
+	/* 40G_BASECR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASECR4	UINT32_C(0x14)
+	/* 40G_BASESR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASESR4	UINT32_C(0x15)
+	/* 40G_BASELR4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASELR4	UINT32_C(0x16)
+	/* 40G_BASEER4 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_BASEER4	UINT32_C(0x17)
+	/* 40G_ACTIVE_CABLE */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_40G_ACTIVE_CABLE \
+		UINT32_C(0x18)
+	uint8_t media_type;
+	/* This value represents a media type. */
+	/* Unknown */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
+	/* Twisted Pair */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
+	/* Direct Attached Copper */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
+	/* Fiber */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
+	uint8_t xcvr_pkg_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)
+	/* PHY and MAC are in different packages */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL \
+		UINT32_C(0x2)
+	uint8_t eee_config_phy_addr;
+	/*
+	 * 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 parallel_detect;
+	/* 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
+	uint16_t link_partner_adv_speeds;
+	/*
+	 * 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_SUPPORT_SPEEDS_2GB	UINT32_C(0x10)
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_SPEEDS_2GB	\
+		UINT32_C(0x10)
 	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_2_5GB	UINT32_C(0x20)
+	#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)
+	uint8_t link_partner_adv_auto_mode;
+	/*
+	 * 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)
+	/* Select all possible speeds for autoneg mode. */
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	/*
+	 * 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)
+	uint8_t link_partner_adv_pause;
+	/* 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)
+	uint16_t adv_eee_link_speed_mask;
+	/*
+	 * 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 link_partner_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_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 force_link_speed;
+	#define \
+	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_EEE_LINK_SPEED_MASK_10GB \
+		UINT32_C(0x40)
+	uint32_t xcvr_identifier_type_tx_lpi_timer;
+	/* 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)
+	uint16_t fec_cfg;
+	/*
+	 * This value represents the current configuration of Forward
+	 * Error Correction	(FEC) on the port.
+	 */
+	/*
+	 * When set to 1, then FEC is not supported on this port. If
+	 * this flag is set to 1, then all other FEC configuration flags
+	 * shall be ignored. When set to 0, then FEC is supported as
+	 * indicated by other configuration flags. If no cable is
+	 * attached and the HWRM does not yet know the FEC capability,
+	 * then the HWRM shall set this flag to 1 when reporting FEC
+	 * capability.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	 \
+		UINT32_C(0x1)
+	/*
+	 * When set to 1, then FEC autonegotiation is supported on this
+	 * port. When set to 0, then FEC autonegotiation is not
+	 * supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
+		UINT32_C(0x2)
+	/*
+	 * When set to 1, then FEC autonegotiation is enabled on this
+	 * port. When set to 0, then FEC autonegotiation is disabled if
+	 * supported. This flag should be ignored if FEC autonegotiation
+	 * is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
+		UINT32_C(0x4)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is supported on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
+		UINT32_C(0x8)
+	/*
+	 * When set to 1, then FEC CLAUSE 74	(Fire Code) is enabled on
+	 * this port. When set to 0, then FEC CLAUSE 74	(Fire Code) is
+	 * disabled if supported. This flag should be ignored if FEC
+	 * CLAUSE 74 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
+		UINT32_C(0x10)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is supported
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
+		UINT32_C(0x20)
+	/*
+	 * When set to 1, then FEC CLAUSE 91	(Reed Solomon) is enabled
+	 * on this port. When set to 0, then FEC CLAUSE 91	(Reed
+	 * Solomon) is disabled if supported. This flag should be
+	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
+		UINT32_C(0x40)
+	uint8_t unused_1;
+	uint8_t unused_2;
+	char phy_vendor_name[16];
+	/*
+	 * 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_partnumber[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.
+	 */
+	uint32_t unused_3;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_qstats */
+/* Description: This function returns per port Ethernet statistics. */
+/* Input	(40 bytes) */
+struct hwrm_port_qstats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2[3];
+	uint8_t unused_3;
+	uint64_t tx_stat_host_addr;
+	/* This is the host address where Tx port statistics will be stored */
+	uint64_t rx_stat_host_addr;
+	/* This is the host address where Rx port statistics will be stored */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_qstats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 tx_stat_size;
+	/* The size of TX port statistics block in bytes. */
+	uint16_t rx_stat_size;
+	/* The size of RX port statistics block in bytes. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_clr_stats */
+/*
+ * Description: This function clears per port statistics. The HWRM shall not
+ * allow a VF driver to clear port statistics. The HWRM shall not allow a PF
+ * driver to clear port statistics in a partitioning mode. The HWRM may allow a
+ * PF driver to clear port statistics in the non-partitioning mode.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_clr_stats_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port that is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_clr_stats_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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)
+	/* rx path */
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST \
+		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
+	uint16_t port_id;
+	/*
+	 * Port ID of port for which the queue configuration is being
+	 * queried. This field is only required when sent by IPC.
+	 */
+	uint16_t unused_0;
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_queue_qportcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t max_configurable_queues;
+	/*
+	 * The maximum number of queues that can be configured on this
+	 * port. Valid values range from 1 through 8.
+	 */
+	uint8_t max_configurable_lossless_queues;
+	/*
+	 * The maximum number of lossless queues that can be configured
+	 * on this port. Valid values range from 0 through 8.
+	 */
+	uint8_t queue_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_cfg command. Each bit represents a specific queue
+	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
+	 * # A value of 0 indicates that the queue is not configurable
+	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
+	 * the queue is configurable. # A hwrm_queue_cfg command shall
+	 * return error when trying to configure a queue not
+	 * configurable.
+	 */
+	uint8_t queue_cfg_info;
+	/* Information about queue configuration. */
+	/*
+	 * If this flag is set to '1', then the queues are configured
+	 * asymmetrically on TX and RX sides. If this flag is set to
+	 * '0', then the queues are configured symmetrically on TX and
+	 * RX sides. For symmetric configuration, the queue
+	 * configuration including queue ids and service profiles on the
+	 * TX side is the same as the corresponding queue configuration
+	 * on the RX side.
+	 */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG UINT32_C(0x1)
+	uint8_t queue_pfcenable_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
+	 * specific priority where bit 0 represents priority 0 and bit 7
+	 * represents priority 7. # A value of 0 indicates that the
+	 * priority is not configurable by the hwrm_queue_pfcenable_cfg
+	 * command. # A value of 1 indicates that the priority is
+	 * configurable. # A hwrm_queue_pfcenable_cfg command shall
+	 * return error when trying to configure a priority that is not
+	 * configurable.
+	 */
+	uint8_t queue_pri2cos_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue that is not configurable.
+	 */
+	uint8_t queue_cos2bw_cfg_allowed;
+	/*
+	 * Bitmask indicating which queues can be configured by the
+	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
+	 * specific queue where bit 0 represents queue 0 and bit 7
+	 * represents queue 7. # A value of 0 indicates that the queue
+	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
+	 * A value of 1 indicates that the queue is configurable. # A
+	 * hwrm_queue_pri2cos_cfg command shall return error when trying
+	 * to configure a queue not configurable.
+	 */
+	uint8_t queue_id0;
+	/*
+	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id0_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id1;
+	/*
+	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id1_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id2;
+	/*
+	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id2_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id3;
+	/*
+	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id3_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id4;
+	/*
+	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id4_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
+	/*
+	 * 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)
+	uint8_t queue_id5;
+	/*
+	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	uint8_t queue_id5_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * Current setting of forced link speed. When the link speed is
-	 * not being forced, this value shall be set to 0.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100MB	\
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id6;
+	/*
+	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
+	 */
+	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)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
 		UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_2_5GB	\
-		UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_100GB	\
-		UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint8_t auto_mode;
-	/* Current setting of auto negotiation mode. */
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE	UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ALL_SPEEDS	UINT32_C(0x1)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t queue_id7;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
+	 * any subsequent call to an hwrm command that takes a queue id.
+	 * # IDs must always be queried by this command before any use
+	 * by the driver or software. # Any driver or software should
+	 * not make any assumptions about queue IDs. # A value of 0xff
+	 * indicates that the queue is not available. # Available queues
+	 * may not be in sequential order.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_SPEED	UINT32_C(0x2)
+	uint8_t queue_id7_service_profile;
+	/* This value is applicable to CoS queues only. */
+	/* Lossy	(best-effort) */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
+		UINT32_C(0x0)
+	/* Lossless */
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
+		UINT32_C(0x1)
 	/*
-	 * 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.
+	 * Set to 0xFF...	(All Fs) if there is no
+	 * service profile specified
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_ONE_OR_BELOW	\
-		UINT32_C(0x3)
+	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
+		UINT32_C(0xff)
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_SPEED_MASK	UINT32_C(0x4)
-	uint8_t auto_pause;
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Current setting of pause autonegotiation. Move autoneg_pause
-	 * flag here.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Generation of tx pause messages has
-	 * been requested. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_TX	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * When this bit is '1', Reception of rx pause messages has been
-	 * requested. Disabled otherwise.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_RX	UINT32_C(0x2)
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_PAUSE_AUTONEG_PAUSE	\
-		UINT32_C(0x4)
-	uint16_t auto_link_speed;
+	uint32_t flags;
 	/*
-	 * Current setting for auto_link_speed. This field is only valid
-	 * when auto_mode is set to "one_speed" or "one_or_below".
+	 * 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 unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __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 {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_free_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
 	 */
-	/* 100Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100MB	UINT32_C(0x1)
-	/* 1Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_1GB	UINT32_C(0xa)
-	/* 2Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2GB	UINT32_C(0x14)
-	/* 2.5Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_2_5GB	UINT32_C(0x19)
-	/* 10Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10GB	UINT32_C(0x64)
-	/* 20Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_20GB	UINT32_C(0xc8)
-	/* 25Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_25GB	UINT32_C(0xfa)
-	/* 40Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_40GB	UINT32_C(0x190)
-	/* 50Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_50GB	UINT32_C(0x1f4)
-	/* 100Gb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_100GB	UINT32_C(0x3e8)
-	/* 10Mb link speed */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_LINK_SPEED_10MB	UINT32_C(0xffff)
-	uint16_t auto_link_speed_mask;
+} __attribute__((packed));
+
+/* hwrm_vnic_cfg */
+/* Description: Configure the RX VNIC structure. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_cfg_input {
+	uint16_t req_type;
 	/*
-	 * 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.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	/* 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)
-	uint8_t wirespeed;
-	/* Current setting for wirespeed. */
-	/* Wirespeed feature is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_OFF	UINT32_C(0x0)
-	/* Wirespeed feature is enabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_WIOUTPUTEED_ON	UINT32_C(0x1)
-	uint8_t lpbk;
-	/* Current setting for loopback. */
-	/* No loopback is selected. Normal operation. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_NONE	UINT32_C(0x0)
+	uint16_t cmpl_ring;
 	/*
-	 * The HW will be configured with local loopback
-	 * such that host data is sent back to the host
-	 * without modification.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_LOCAL	UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * The HW will be configured with remote
-	 * loopback such that port logic will send
-	 * packets back out the transmitter that are
-	 * received.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LPBK_REMOTE	UINT32_C(0x2)
-	uint8_t force_pause;
+	uint64_t resp_addr;
 	/*
-	 * Current setting of forced pause. When the pause configuration
-	 * is not being forced, then this value shall be set to 0.
+	 * 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.
 	 */
+	uint32_t flags;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * When this bit is '1', the VNIC is requested to be the default
+	 * VNIC for the function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_TX	UINT32_C(0x1)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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_PORT_PHY_QCFG_OUTPUT_FORCE_PAUSE_RX	UINT32_C(0x2)
-	uint8_t module_status;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * This value indicates the current status of the optics module
-	 * on this port.
+	 * 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.
 	 */
-	/* Module is inserted and accepted */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NONE	UINT32_C(0x0)
-	/* Module is rejected and transmit side Laser is disabled. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_DISABLETX	\
-		UINT32_C(0x1)
-	/* Module mismatch warning. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_WARNINGMSG	\
-		UINT32_C(0x2)
-	/* Module is rejected and powered down. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_PWRDOWN	UINT32_C(0x3)
-	/* Module is not inserted. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTINSERTED	\
-		UINT32_C(0x4)
-	/* Module status is not applicable. */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MODULE_STATUS_NOTAPPLICABLE	\
-		UINT32_C(0xff)
-	uint32_t preemphasis;
-	/* Current setting for preemphasis. */
-	uint8_t phy_maj;
-	/* This field represents the major version of the PHY. */
-	uint8_t phy_min;
-	/* This field represents the minor version of the PHY. */
-	uint8_t phy_bld;
-	/* This field represents the build version of the PHY. */
-	uint8_t phy_type;
-	/* This value represents a PHY type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* BASE-CR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASECR	UINT32_C(0x1)
-	/* BASE-KR4 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR4	UINT32_C(0x2)
-	/* BASE-LR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASELR	UINT32_C(0x3)
-	/* BASE-SR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASESR	UINT32_C(0x4)
-	/* BASE-KR2 (Deprecated) */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR2	UINT32_C(0x5)
-	/* BASE-KX */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKX	UINT32_C(0x6)
-	/* BASE-KR */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASEKR	UINT32_C(0x7)
-	/* BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET	UINT32_C(0x8)
-	/* EEE capable BASE-T */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE	UINT32_C(0x9)
-	/* SGMII connected external PHY */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_SGMIIEXTPHY	UINT32_C(0xa)
-	uint8_t media_type;
-	/* This value represents a media type. */
-	/* Unknown */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_UNKNOWN	UINT32_C(0x0)
-	/* Twisted Pair */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP	UINT32_C(0x1)
-	/* Direct Attached Copper */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_DAC	UINT32_C(0x2)
-	/* Fiber */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_FIBRE	UINT32_C(0x3)
-	uint8_t xcvr_pkg_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)
-	/* PHY and MAC are in different packages */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_PKG_TYPE_XCVR_EXTERNAL	\
-		UINT32_C(0x2)
-	uint8_t eee_config_phy_addr;
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * 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).
+	 * 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.
 	 */
-	/* 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
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * 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_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ENABLED	\
-		UINT32_C(0x20)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. This flag is used to enable a mode where RSS is enabled
+	 * in the VNIC using a RSS context for computing RSS hash but
+	 * the RSS indirection table is not configured using
+	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
+	 * should not program RSS indirection table for the RSS context
+	 * that is used for computing RSS hash only.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_ACTIVE	UINT32_C(0x40)
+	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t enables;
 	/*
-	 * 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.
+	 * This bit must be '1' for the dflt_ring_grp field to be
+	 * configured.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_EEE_TX_LPI	UINT32_C(0x80)
+	#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)
+	uint16_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t dflt_ring_grp;
 	/*
-	 * 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).
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_MASK	UINT32_C(0xe0)
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_EEE_CONFIG_SFT	5
-	uint8_t parallel_detect;
-	/* Reserved field, set to 0 */
+	uint16_t rss_rule;
 	/*
-	 * 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.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#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
-	uint16_t link_partner_adv_speeds;
+	uint16_t cos_rule;
 	/*
-	 * The advertised speeds for the port by the link partner. Each
-	 * advertised speed will be set to '1'.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	/* 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)
-	uint8_t link_partner_adv_auto_mode;
+	uint16_t lb_rule;
 	/*
-	 * The advertised autoneg for the port by the link partner. This
-	 * field is deprecated and should be set to 0.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
+	uint16_t mru;
 	/*
-	 * Disable autoneg or autoneg disabled. No
-	 * speeds are selected.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_NONE \
-		UINT32_C(0x0)
-	/* Select all possible speeds for autoneg mode. */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ALL_SPEEDS \
-	UINT32_C(0x1)
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_cfg_output {
+	uint16_t error_code;
 	/*
-	 * Select only the auto_link_speed speed for
-	 * autoneg mode. This mode has been DEPRECATED.
-	 * An HWRM client should not use this mode.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_SPEED \
-		UINT32_C(0x2)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_ONE_OR_BELOW \
-	UINT32_C(0x3)
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * Select the speeds based on the corresponding
-	 * link speed mask value that is provided.
+	 * 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.
 	 */
-	#define \
-	HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_AUTO_MODE_SPEED_MASK \
-	UINT32_C(0x4)
-	uint8_t link_partner_adv_pause;
-	/* The advertised pause settings on the port by the link partner. */
+} __attribute__((packed));
+
+/* hwrm_vnic_qcfg */
+/*
+ * Description: Query the RX VNIC structure. This function can be used by a PF
+ * driver to query its own VNIC resource or VNIC resource of its child VF. This
+ * function can also be used by a VF driver to query its own VNIC resource.
+ */
+/* Input	(32 bytes) */
+struct hwrm_vnic_qcfg_input {
+	uint16_t req_type;
 	/*
-	 * When this bit is '1', Generation of tx pause messages is
-	 * supported. Disabled otherwise.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_TX	\
-		UINT32_C(0x1)
+	uint16_t cmpl_ring;
 	/*
-	 * When this bit is '1', Reception of rx pause messages is
-	 * supported. Disabled otherwise.
+	 * 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.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_LINK_PARTNER_ADV_PAUSE_RX	\
-		UINT32_C(0x2)
-	uint16_t adv_eee_link_speed_mask;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	/* 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 link_partner_adv_eee_link_speed_mask;
+	uint64_t resp_addr;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	/* 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)
-	uint32_t xcvr_identifier_type_tx_lpi_timer;
-	/* This value represents transceiver identifier type. */
+	uint32_t enables;
+	/* This bit must be '1' for the vf_id_valid field to be configured. */
+	#define HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID	UINT32_C(0x1)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t vf_id;
+	/* ID of Virtual Function whose VNIC resource is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(32 bytes) */
+struct hwrm_vnic_qcfg_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#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)
-	uint16_t fec_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This value represents the current configuration of Forward
-	 * Error Correction (FEC) on the port.
+	 * 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 dflt_ring_grp;
+	/* Default Completion ring for the VNIC. */
+	uint16_t rss_rule;
 	/*
-	 * When set to 1, then FEC is not supported on this port. If
-	 * this flag is set to 1, then all other FEC configuration flags
-	 * shall be ignored. When set to 0, then FEC is supported as
-	 * indicated by other configuration flags. If no cable is
-	 * attached and the HWRM does not yet know the FEC capability,
-	 * then the HWRM shall set this flag to 1 when reporting FEC
-	 * capability.
+	 * RSS ID for RSS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no RSS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_NONE_SUPPORTED	\
-		UINT32_C(0x1)
+	uint16_t cos_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is supported on this
-	 * port. When set to 0, then FEC autonegotiation is not
-	 * supported on this port.
+	 * RSS ID for COS rule/table structure. 0xFF...	(All Fs) if
+	 * there is no COS rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_SUPPORTED   \
-		UINT32_C(0x2)
+	uint16_t lb_rule;
 	/*
-	 * When set to 1, then FEC autonegotiation is enabled on this
-	 * port. When set to 0, then FEC autonegotiation is disabled if
-	 * supported. This flag should be ignored if FEC autonegotiation
-	 * is not supported on this port.
+	 * RSS ID for load balancing rule/table structure. 0xFF...	(All
+	 * Fs) if there is no LB rule.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_AUTONEG_ENABLED	\
-		UINT32_C(0x4)
+	uint16_t mru;
+	/* The maximum receive unit of the vnic. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t flags;
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is supported on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * not supported on this port.
+	 * When this bit is '1', the VNIC is the default VNIC for the
+	 * function.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_SUPPORTED  \
-		UINT32_C(0x8)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT	UINT32_C(0x1)
 	/*
-	 * When set to 1, then FEC CLAUSE 74 (Fire Code) is enabled on
-	 * this port. When set to 0, then FEC CLAUSE 74 (Fire Code) is
-	 * disabled if supported. This flag should be ignored if FEC
-	 * CLAUSE 74 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to strip VLAN in
+	 * the RX path. If set to '0', then VLAN stripping is disabled
+	 * on this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE74_ENABLED	\
-		UINT32_C(0x10)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is supported
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to buffer
+	 * receive packets in the hardware until the host posts new
+	 * receive buffers. If set to '0', then bd_stall is disabled on
+	 * this VNIC.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_SUPPORTED  \
-		UINT32_C(0x20)
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
 	/*
-	 * When set to 1, then FEC CLAUSE 91 (Reed Solomon) is enabled
-	 * on this port. When set to 0, then FEC CLAUSE 91 (Reed
-	 * Solomon) is disabled if supported. This flag should be
-	 * ignored if FEC CLAUSE 91 is not supported on this port.
+	 * When this bit is '1', the VNIC is configured to receive both
+	 * RoCE and non-RoCE traffic. If set to '0', then this VNIC is
+	 * not configured to operate in dual VNIC mode.
 	 */
-	#define HWRM_PORT_PHY_QCFG_OUTPUT_FEC_CFG_FEC_CLAUSE91_ENABLED	\
-		UINT32_C(0x40)
-	uint8_t unused_1;
-	uint8_t unused_2;
-	char phy_vendor_name[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
 	/*
-	 * 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.
+	 * When this flag is set to '1', the VNIC is configured to
+	 * receive only RoCE traffic. When this flag is set to '0', the
+	 * VNIC is not configured to receive only RoCE traffic. If
+	 * roce_dual_vnic_mode flag and this flag both are set to '1',
+	 * then it is an invalid configuration of the VNIC. The HWRM
+	 * should not allow that type of mis-configuration by HWRM
+	 * clients.
 	 */
-	char phy_vendor_partnumber[16];
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
 	/*
-	 * 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.
+	 * When a VNIC uses one destination ring group for certain
+	 * application	(e.g. Receive Flow Steering) where exact match is
+	 * used to direct packets to a VNIC with one destination ring
+	 * group only, there is no need to configure RSS indirection
+	 * table for that VNIC as only one destination ring group is
+	 * used. When this bit is set to '1', then the VNIC is enabled
+	 * in a mode where RSS is enabled in the VNIC using a RSS
+	 * context for computing RSS hash but the RSS indirection table
+	 * is not configured.
 	 */
-	uint32_t unused_3;
+	#define HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
+	uint32_t unused_2;
+	uint8_t unused_3;
 	uint8_t unused_4;
 	uint8_t unused_5;
-	uint8_t unused_6;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -3704,19 +6549,10 @@ struct hwrm_port_phy_qcfg_output {
 	 */
 } __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 {
+/* hwrm_vnic_rss_cfg */
+/* Description: This function is used to enable RSS configuration. */
+/* Input	(48 bytes) */
+struct hwrm_vnic_rss_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -3743,29 +6579,53 @@ struct hwrm_queue_qportcfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t hash_type;
 	/*
-	 * 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.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source and destination IPv4 addresses of IPv4 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_TX	UINT32_C(0x0)
-	/* rx path */
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX	UINT32_C(0x1)
-	#define HWRM_QUEUE_QPORTCFG_INPUT_FLAGS_PATH_LAST	\
-		QUEUE_QPORTCFG_INPUT_FLAGS_PATH_RX
-	uint16_t port_id;
+	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4	UINT32_C(0x1)
 	/*
-	 * Port ID of port for which the queue configuration is being
-	 * queried. This field is only required when sent by IPC.
+	 * When this bit is '1', the RSS hash shall be computed over
+	 * source/destination IPv4 addresses and source/destination
+	 * ports of TCP/IPv4 packets.
 	 */
-	uint16_t unused_0;
+	#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 unused_0;
+	uint64_t ring_grp_tbl_addr;
+	/* This is the address for rss ring group table */
+	uint64_t hash_key_tbl_addr;
+	/* This is the address for rss hash key table */
+	uint16_t rss_ctx_idx;
+	/* Index to the rss indirection table. */
+	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (32 bytes) */
-struct hwrm_queue_qportcfg_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -3781,265 +6641,363 @@ struct hwrm_queue_qportcfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint8_t max_configurable_queues;
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
 	/*
-	 * The maximum number of queues that can be configured on this
-	 * port. Valid values range from 1 through 8.
+	 * 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 max_configurable_lossless_queues;
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_cfg */
+/*
+ * Description: This function can be used to set placement mode configuration of
+ * the VNIC.
+ */
+/* Input (40 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_input {
+	uint16_t req_type;
 	/*
-	 * The maximum number of lossless queues that can be configured
-	 * on this port. Valid values range from 0 through 8.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
-	uint8_t queue_cfg_allowed;
+	uint16_t cmpl_ring;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_cfg command. Each bit represents a specific queue
-	 * where bit 0 represents queue 0 and bit 7 represents queue 7.
-	 * # A value of 0 indicates that the queue is not configurable
-	 * by the hwrm_queue_cfg command. # A value of 1 indicates that
-	 * the queue is configurable. # A hwrm_queue_cfg command shall
-	 * return error when trying to configure a queue not
-	 * configurable.
+	 * 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.
 	 */
-	uint8_t queue_cfg_info;
-	/* Information about queue configuration. */
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * If this flag is set to '1', then the queues are configured
-	 * asymmetrically on TX and RX sides. If this flag is set to
-	 * '0', then the queues are configured symmetrically on TX and
-	 * RX sides. For symmetric configuration, the queue
-	 * configuration including queue ids and service profiles on the
-	 * TX side is the same as the corresponding queue configuration
-	 * on the RX side.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to use regular
+	 * placement algorithm. By default, the regular placement algorithm
+	 * shall be enabled on the VNIC.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_CFG_INFO_ASYM_CFG	\
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
-	uint8_t queue_pfcenable_cfg_allowed;
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pfcenable_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pfcenable_cfg command.
-	 * # A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pfcenable_cfg command shall return error when
-	 * trying to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured use the jumbo
+	 * placement algorithm.
 	 */
-	uint8_t queue_pri2cos_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue that is not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv4 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv4, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv4, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv4 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv4 packet.
 	 */
-	uint8_t queue_cos2bw_cfg_allowed;
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4        UINT32_C(0x4)
 	/*
-	 * Bitmask indicating which queues can be configured by the
-	 * hwrm_queue_pri2cos_cfg command. Each bit represents a
-	 * specific queue where bit 0 represents queue 0 and bit 7
-	 * represents queue 7. # A value of 0 indicates that the queue
-	 * is not configurable by the hwrm_queue_pri2cos_cfg command. #
-	 * A value of 1 indicates that the queue is configurable. # A
-	 * hwrm_queue_pri2cos_cfg command shall return error when trying
-	 * to configure a queue not configurable.
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for IPv6 packets according to the following rules: # If
+	 * the packet is identified as TCP/IPv6, then the packet is split at the
+	 * beginning of the TCP payload. # If the packet is identified as
+	 * UDP/IPv6, then the packet is split at the beginning of UDP payload. #
+	 * If the packet is identified as non-TCP and non-UDP IPv6 packet, then
+	 * the packet is split at the beginning of the upper layer protocol
+	 * header carried in the IPv6 packet.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6        UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for FCoE packets at the beginning of FC payload.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_FCOE       UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to enable Header-
+	 * Data split for RoCE packets at the beginning of RoCE payload (after
+	 * BTH/GRH headers).
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_ROCE       UINT32_C(0x20)
+	uint32_t enables;
+	/*
+	 * This bit must be '1' for the jumbo_thresh_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID \
+		UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the hds_offset_valid field to be configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID \
+		UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the hds_threshold_valid field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID \
+		UINT32_C(0x4)
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint16_t jumbo_thresh;
+	/*
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
+	 */
+	uint16_t hds_offset;
+	/*
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
+	 */
+	uint16_t hds_threshold;
+	/*
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
+	 */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output (16 bytes) */
+
+struct hwrm_vnic_plcmodes_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_plcmodes_qcfg */
+/*
+ * Description: This function can be used to query placement mode configuration
+ * of the VNIC.
+ */
+/* Input (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* Logical vnic ID */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output (24 bytes) */
+
+struct hwrm_vnic_plcmodes_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
-	uint8_t queue_id0;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * ID of CoS Queue 0. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id0_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSLESS \
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC is configured to use regular placement
+	 * algorithm.
+	 */
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_REGULAR_PLACEMENT \
 		UINT32_C(0x1)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to use the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id1;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_JUMBO_PLACEMENT \
+		UINT32_C(0x2)
 	/*
-	 * ID of CoS Queue 1. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv4 packets.
 	 */
-	uint8_t queue_id1_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV4      UINT32_C(0x4)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for IPv6 packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID1_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id2;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_IPV6      UINT32_C(0x8)
 	/*
-	 * ID of CoS Queue 2. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for FCoE packets.
 	 */
-	uint8_t queue_id2_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_FCOE     UINT32_C(0x10)
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When this bit is '1', the VNIC is configured to enable Header-Data
+	 * split for RoCE packets.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID2_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id3;
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_HDS_ROCE     UINT32_C(0x20)
 	/*
-	 * ID of CoS Queue 3. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * When this bit is '1', the VNIC is configured to be the default VNIC
+	 * of the requesting function.
 	 */
-	uint8_t queue_id3_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	#define HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC    UINT32_C(0x40)
+	uint16_t jumbo_thresh;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When jumbo placement algorithm is enabled, this value is used to
+	 * determine the threshold for jumbo placement. Packets with length
+	 * larger than this value will be placed according to the jumbo
+	 * placement algorithm.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID3_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id4;
+	uint16_t hds_offset;
 	/*
-	 * ID of CoS Queue 4. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * This value is used to determine the offset into packet buffer where
+	 * the split data (payload) will be placed according to one of of HDS
+	 * placement algorithm. The lengths of packet buffers provided for split
+	 * data shall be larger than this value.
 	 */
-	uint8_t queue_id4_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t hds_threshold;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * When one of the HDS placement algorithm is enabled, this value is
+	 * used to determine the threshold for HDS placement. Packets with
+	 * length larger than this value will be placed according to the HDS
+	 * placement algorithm. This value shall be in multiple of 4 bytes.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID4_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id5;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
+	uint8_t valid;
 	/*
-	 * ID of CoS Queue 5. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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 queue_id5_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* hwrm_vnic_rss_cos_lb_ctx_alloc */
+/* Description: This function is used to allocate COS/Load Balance context. */
+/* Input	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+	uint16_t req_type;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID5_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id6;
+	uint16_t cmpl_ring;
 	/*
-	 * ID of CoS Queue 6. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	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)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID6_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
-	uint8_t queue_id7;
+	uint64_t resp_addr;
 	/*
-	 * ID of CoS Queue 7. FF - Invalid id # This ID can be used on
-	 * any subsequent call to an hwrm command that takes a queue id.
-	 * # IDs must always be queried by this command before any use
-	 * by the driver or software. # Any driver or software should
-	 * not make any assumptions about queue IDs. # A value of 0xff
-	 * indicates that the queue is not available. # Available queues
-	 * may not be in sequential order.
+	 * 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.
 	 */
-	uint8_t queue_id7_service_profile;
-	/* This value is applicable to CoS queues only. */
-	/* Lossy (best-effort) */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSY \
-		UINT32_C(0x0)
-	/* Lossless */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_LOSSLESS \
-		UINT32_C(0x1)
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+	uint16_t error_code;
 	/*
-	 * Set to 0xFF... (All Fs) if there is no
-	 * service profile specified
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID7_SERVICE_PROFILE_UNKNOWN \
-		UINT32_C(0xff)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4051,25 +7009,10 @@ struct hwrm_queue_qportcfg_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4096,17 +7039,13 @@ struct hwrm_vnic_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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 unused_0;
+	uint16_t rss_cos_lb_ctx_id;
+	/* rss_cos_lb_ctx_id is 16 b */
+	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_rss_cos_lb_ctx_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4122,11 +7061,10 @@ struct hwrm_vnic_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t vnic_id;
-	/* Logical vnic ID */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4134,18 +7072,14 @@ struct hwrm_vnic_alloc_output {
 	 * 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.
-	 */
-} __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 field is written last.
+	 */
+} __attribute__((packed));
+
+/* hwrm_vnic_tpa_cfg */
+/* Description: This function is used to enable/configure TPA on the VNIC. */
+/* Input	(40 bytes) */
+struct hwrm_vnic_tpa_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4172,13 +7106,122 @@ struct hwrm_vnic_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
+	uint32_t flags;
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of non-tunneled TCP
+	 * packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA	UINT32_C(0x1)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) of tunneled TCP packets.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA	UINT32_C(0x2)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Windows
+	 * Receive Segment Coalescing	(RSC) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE	UINT32_C(0x4)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) according to Linux
+	 * Generic Receive Offload	(GRO) rules.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO	UINT32_C(0x8)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for TCP packets with IP
+	 * ECN set to non-zero.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN	UINT32_C(0x10)
+	/*
+	 * When this bit is '1', the VNIC shall be configured to perform
+	 * transparent packet aggregation	(TPA) for GRE tunneled TCP
+	 * packets only if all packets have the same GRE sequence.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ	\
+		UINT32_C(0x20)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP/IPv4 packets with consecutively increasing
+	 * IPIDs. In other words, the last packet that is being
+	 * aggregated to an already existing aggregation context shall
+	 * have IPID 1 more than the IPID of the last packet that was
+	 * aggregated in that aggregation context.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_IPID_CHECK	UINT32_C(0x40)
+	/*
+	 * When this bit is '1' and the GRO mode is enabled, the VNIC
+	 * shall be configured to perform transparent packet aggregation
+	 *	(TPA) for TCP packets with the same TTL	(IPv4) or Hop limit
+	 *	(IPv6) value.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO_TTL_CHECK	UINT32_C(0x80)
+	uint32_t enables;
+	/* This bit must be '1' for the max_agg_segs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS	UINT32_C(0x1)
+	/* This bit must be '1' for the max_aggs field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS	UINT32_C(0x2)
+	/*
+	 * This bit must be '1' for the max_agg_timer field to be
+	 * configured.
+	 */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_TIMER	UINT32_C(0x4)
+	/* This bit must be '1' for the min_agg_len field to be configured. */
+	#define HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN	UINT32_C(0x8)
+	uint16_t vnic_id;
 	/* Logical vnic ID */
-	uint32_t unused_0;
+	uint16_t max_agg_segs;
+	/*
+	 * This is the maximum number of TCP segments that can be
+	 * aggregated	(unit is Log2). Max value is 31.
+	 */
+	/* 1 segment */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_1	UINT32_C(0x0)
+	/* 2 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_2	UINT32_C(0x1)
+	/* 4 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_4	UINT32_C(0x2)
+	/* 8 segments */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_8	UINT32_C(0x3)
+	/* Any segment size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGG_SEGS_MAX	UINT32_C(0x1f)
+	uint16_t max_aggs;
+	/*
+	 * This is the maximum number of aggregations this VNIC is
+	 * allowed	(unit is Log2). Max value is 7
+	 */
+	/* 1 aggregation */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_1	UINT32_C(0x0)
+	/* 2 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_2	UINT32_C(0x1)
+	/* 4 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_4	UINT32_C(0x2)
+	/* 8 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_8	UINT32_C(0x3)
+	/* 16 aggregations */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_16	UINT32_C(0x4)
+	/* Any aggregation size larger than this is not valid */
+	#define HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX	UINT32_C(0x7)
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint32_t max_agg_timer;
+	/*
+	 * This is the maximum amount of time allowed for an aggregation
+	 * context to complete after it was initiated.
+	 */
+	uint32_t min_agg_len;
+	/*
+	 * This is the minimum amount of payload length required to
+	 * start an aggregation context.
+	 */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_free_output {
+/* Output	(16 bytes) */
+struct hwrm_vnic_tpa_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4209,10 +7252,13 @@ struct hwrm_vnic_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_cfg */
-/* Description: Configure the RX VNIC structure. */
-/* Input (40 bytes) */
-struct hwrm_vnic_cfg_input {
+
+/* hwrm_ring_alloc */
+/*
+ * Description: This command allocates and does basic preparation for a ring.
+ */
+/* Input	(80 bytes) */
+struct hwrm_ring_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4239,103 +7285,295 @@ struct hwrm_vnic_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
+	uint32_t enables;
+	/* 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 ring_arb_cfg field to be configured. */
+	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
 	/*
-	 * When this bit is '1', the VNIC is requested to be the default
-	 * VNIC for the function.
+	 * This bit must be '1' for the stat_ctx_id_valid field to be
+	 * configured.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT	UINT32_C(0x1)
+	#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)
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t unused_1;
+	uint64_t page_tbl_addr;
+	/* This value is a pointer to the page table for the Ring. */
+	uint32_t fbo;
+	/* First Byte Offset of the first entry in the first page. */
+	uint8_t page_size;
 	/*
-	 * 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.
+	 * 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. - 21 = 2
+	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
+	 * GB Page size is 1 GB.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE	UINT32_C(0x2)
+	uint8_t page_tbl_depth;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE	UINT32_C(0x4)
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint32_t length;
 	/*
-	 * 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.
+	 * Number of 16B units in the ring. Minimum size for a ring is
+	 * 16 16B entries.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_DUAL_VNIC_MODE	UINT32_C(0x8)
+	uint16_t logical_id;
 	/*
-	 * 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'.
+	 * 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.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_ROCE_ONLY_VNIC_MODE	UINT32_C(0x10)
+	uint16_t cmpl_ring_id;
 	/*
-	 * When a VNIC uses one destination ring group for certain
-	 * application (e.g. Receive Flow Steering) where exact match is
-	 * used to direct packets to a VNIC with one destination ring
-	 * group only, there is no need to configure RSS indirection
-	 * table for that VNIC as only one destination ring group is
-	 * used. This flag is used to enable a mode where RSS is enabled
-	 * in the VNIC using a RSS context for computing RSS hash but
-	 * the RSS indirection table is not configured using
-	 * hwrm_vnic_rss_cfg. If this mode is enabled, then the driver
-	 * should not program RSS indirection table for the RSS context
-	 * that is used for computing RSS hash only.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what completion ring the TX ring is
+	 * associated with.
 	 */
-	#define HWRM_VNIC_CFG_INPUT_FLAGS_RSS_DFLT_CR_MODE	UINT32_C(0x20)
-	uint32_t enables;
+	uint16_t queue_id;
 	/*
-	 * This bit must be '1' for the dflt_ring_grp field to be
-	 * configured.
+	 * This field is used only when ring_type is a TX ring. This
+	 * value indicates what CoS queue the TX ring is associated
+	 * with.
 	 */
-	#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)
-	uint16_t vnic_id;
-	/* Logical vnic ID */
-	uint16_t dflt_ring_grp;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint32_t reserved1;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint16_t ring_arb_cfg;
+	/*
+	 * This field is used only when ring_type is a TX ring. This
+	 * field is used to configure arbitration related parameters for
+	 * a TX ring.
+	 */
+	/* Arbitration policy used for the ring. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK UINT32_C(0xf)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	/*
+	 * Use strict priority for the TX ring. Priority
+	 * value is specified in arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP \
+		(UINT32_C(0x1) << 0)
+	/*
+	 * Use weighted fair queue arbitration for the
+	 * TX ring. Weight is specified in
+	 * arb_policy_param
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ \
+		(UINT32_C(0x2) << 0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST \
+		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
+	/* Reserved field. */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	/*
+	 * Arbitration policy specific parameter. # For strict priority
+	 * arbitration policy, this field represents a priority value.
+	 * If set to 0, then the priority is not specified and the HWRM
+	 * is allowed to select any priority for this TX ring. # For
+	 * weighted fair queue arbitration policy, this field represents
+	 * a weight value. If set to 0, then the weight is not specified
+	 * and the HWRM is allowed to select any weight for this TX
+	 * ring.
+	 */
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
+		UINT32_C(0xff00)
+	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT	8
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint32_t reserved3;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t stat_ctx_id;
+	/*
+	 * 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 reserved4;
+	/* This field is reserved for the future use. It shall be set to 0. */
+	uint32_t max_bw;
+	/*
+	 * This field is used only when ring_type is a TX ring to
+	 * specify maximum BW allocated to the TX ring. The HWRM will
+	 * translate this value into byte counter and time interval used
+	 * for this ring inside the device.
+	 */
+	/* The bandwidth value. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK UINT32_C(0xfffffff)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
+	/* The granularity of the value	(bits or bytes). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE	UINT32_C(0x10000000)
+	/* Value is in bits. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BITS	(UINT32_C(0x0) << 28)
+	/* Value is in bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES (UINT32_C(0x1) << 28)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_SCALE_LAST \
+		RING_ALLOC_INPUT_MAX_BW_SCALE_BYTES
+	/* bw_value_unit is 3 b */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
+		UINT32_C(0xe0000000)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
+	/* Value is in Mb or MB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MEGA	\
+		(UINT32_C(0x0) << 29)
+	/* Value is in Kb or KB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_KILO	\
+		(UINT32_C(0x2) << 29)
+	/* Value is in bits or bytes. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_BASE	\
+		(UINT32_C(0x4) << 29)
+	/* Value is in Gb or GB	(base 10). */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_GIGA	\
+		(UINT32_C(0x6) << 29)
+	/* Value is in 1/100th of a percentage of total bandwidth. */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100 \
+		(UINT32_C(0x1) << 29)
+	/* Invalid unit */
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID \
+		(UINT32_C(0x7) << 29)
+	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST \
+		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
+	uint8_t int_mode;
+	/*
+	 * 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)
+	/* Reserved */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
+	/* MSI-X */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
+	/* No Interrupt - Polled mode */
+	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
+	uint8_t unused_8[3];
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_ring_alloc_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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 ring_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.
+	 * Physical number of ring allocated. This value shall be unique
+	 * for a ring type.
 	 */
-	uint16_t rss_rule;
+	uint16_t logical_ring_id;
+	/* Logical number of ring allocated. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * RSS ID for RSS rule/table structure. 0xFF... (All Fs) if
-	 * there is no RSS rule.
+	 * 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.
 	 */
-	uint16_t cos_rule;
+} __attribute__((packed));
+
+/* hwrm_ring_free */
+/*
+ * Description: This command is used to free a ring and associated resources.
+ * With QoS and DCBx agents, it is possible the traffic classes will be moved
+ * from one CoS queue to another. When this occurs, the driver shall call
+ * 'hwrm_ring_free' to free the allocated rings and then call 'hwrm_ring_alloc'
+ * to re-allocate each ring and assign it to a new CoS queue. hwrm_ring_free
+ * shall be called on a ring only after it has been idle for 500ms or more and
+ * no frames have been posted to the ring during this time. All frames queued
+ * for transmission shall be completed and at least 500ms time elapsed from the
+ * last completion before calling this command.
+ */
+/* Input	(24 bytes) */
+struct hwrm_ring_free_input {
+	uint16_t req_type;
 	/*
-	 * RSS ID for COS rule/table structure. 0xFF... (All Fs) if
-	 * there is no COS rule.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	uint16_t lb_rule;
+	uint16_t cmpl_ring;
 	/*
-	 * RSS ID for load balancing rule/table structure. 0xFF... (All
-	 * Fs) if there is no LB rule.
+	 * 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 mru;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t unused_0;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint8_t ring_type;
+	/* Ring Type. */
+	/* L2 Completion Ring	(CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_L2_CMPL	UINT32_C(0x0)
+	/* TX Ring	(TR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
+	/* RX Ring	(RR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
+	/* RoCE Notification Completion Ring	(ROCE_CR) */
+	#define HWRM_RING_FREE_INPUT_RING_TYPE_ROCE_CMPL	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t ring_id;
+	/* Physical number of ring allocated. */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4366,10 +7604,12 @@ struct hwrm_vnic_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cfg */
-/* Description: This function is used to enable RSS configuration. */
-/* Input (48 bytes) */
-struct hwrm_vnic_rss_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4396,53 +7636,25 @@ struct hwrm_vnic_rss_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t hash_type;
-	/*
-	 * 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)
+	uint16_t cr;
+	/* This value identifies the CR associated with the ring group. */
+	uint16_t rr;
+	/* This value identifies the main RR associated with the ring group. */
+	uint16_t ar;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of TCP/IPv6 packets.
+	 * 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.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6	UINT32_C(0x10)
+	uint16_t sc;
 	/*
-	 * When this bit is '1', the RSS hash shall be computed over
-	 * source/destination IPv6 addresses and source/destination
-	 * ports of UDP/IPv6 packets.
+	 * This value identifies the statistics context associated with
+	 * the ring group.
 	 */
-	#define HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6	UINT32_C(0x20)
-	uint32_t unused_0;
-	uint64_t ring_grp_tbl_addr;
-	/* This is the address for rss ring group table */
-	uint64_t hash_key_tbl_addr;
-	/* This is the address for rss hash key table */
-	uint16_t rss_ctx_idx;
-	/* Index to the rss indirection table. */
-	uint16_t unused_1[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4458,10 +7670,15 @@ struct hwrm_vnic_rss_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t ring_group_id;
+	/*
+	 * 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.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4473,10 +7690,17 @@ struct hwrm_vnic_rss_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_vnic_rss_cos_lb_ctx_alloc */
-/* Description: This function is used to allocate COS/Load Balance context. */
-/* Input (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4503,10 +7727,13 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
+	uint32_t ring_group_id;
+	/* This is the ring group ID value. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_ring_grp_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4522,13 +7749,10 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4540,10 +7764,64 @@ struct hwrm_vnic_rss_cos_lb_ctx_alloc_output {
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4556,269 +7834,355 @@ struct hwrm_vnic_rss_cos_lb_ctx_free_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t flags;
+	/*
+	 * 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 \
+		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 enables;
+	/* 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)
+	uint8_t l2_addr[6];
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the match value for the L2 MAC address.
+	 * Destination MAC address for RX path. Source MAC address for
+	 * TX path.
 	 */
-	uint64_t resp_addr;
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t l2_addr_mask[6];
 	/*
-	 * 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.
+	 * This value sets the mask value for the L2 address. A value of
+	 * 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t rss_cos_lb_ctx_id;
-	/* rss_cos_lb_ctx_id is 16 b */
-	uint16_t unused_0[3];
-} __attribute__((packed));
-
-/* Output (16 bytes) */
-struct hwrm_vnic_rss_cos_lb_ctx_free_output {
-	uint16_t error_code;
+	uint16_t l2_ovlan;
+	/* This value sets VLAN ID value for outer VLAN. */
+	uint16_t l2_ovlan_mask;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * This value sets the mask value for the ovlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint16_t req_type;
-	/* This field returns the type of original request. */
-	uint16_t seq_id;
-	/* This field provides original sequence number of the command. */
-	uint16_t resp_len;
+	uint16_t l2_ivlan;
+	/* This value sets VLAN ID value for inner VLAN. */
+	uint16_t l2_ivlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the ivlan id. A value of 0
+	 * will mask the corresponding bit from compare.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
 	uint8_t unused_2;
 	uint8_t unused_3;
-	uint8_t valid;
+	uint8_t t_l2_addr[6];
 	/*
-	 * 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.
+	 * This value sets the match value for the tunnel L2 MAC
+	 * address. Destination MAC address for RX path. Source MAC
+	 * address for TX path.
 	 */
-} __attribute__((packed));
-
-/* hwrm_ring_alloc */
-/*
- * Description: This command allocates and does basic preparation for a ring.
- */
-/* Input (80 bytes) */
-struct hwrm_ring_alloc_input {
-	uint16_t req_type;
+	uint8_t unused_4;
+	uint8_t unused_5;
+	uint8_t t_l2_addr_mask[6];
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value sets the mask value for the tunnel L2 address. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t cmpl_ring;
+	uint16_t t_l2_ovlan;
+	/* This value sets VLAN ID value for tunnel outer VLAN. */
+	uint16_t t_l2_ovlan_mask;
 	/*
-	 * 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.
+	 * This value sets the mask value for the tunnel ovlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
+	uint16_t t_l2_ivlan;
+	/* This value sets VLAN ID value for tunnel inner VLAN. */
+	uint16_t t_l2_ivlan_mask;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * This value sets the mask value for the tunnel ivlan id. A
+	 * value of 0 will mask the corresponding bit from compare.
 	 */
-	uint64_t resp_addr;
+	uint8_t src_type;
+	/* 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)
+	/* Physical function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
+	/* Virtual function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
+	/* Virtual NIC of a function */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
+	/* Embedded processor for CFA management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
+	/* Embedded processor for OOB management */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
+	/* Embedded processor for RoCE */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
+	/* Embedded processor for network proxy functions */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
+	uint8_t unused_6;
+	uint32_t src_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.
+	 * 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 enables;
-	/* 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 ring_arb_cfg field to be configured. */
-	#define HWRM_RING_ALLOC_INPUT_ENABLES_RING_ARB_CFG	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)
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Non-tunnel */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL \
+		UINT32_C(0x0)
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
 	/*
-	 * This bit must be '1' for the stat_ctx_id_valid field to be
-	 * configured.
+	 * Network Virtualization Generic Routing
+	 * Encapsulation	(NVGRE)
 	 */
-	#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)
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_ALLOC_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t unused_1;
-	uint64_t page_tbl_addr;
-	/* This value is a pointer to the page table for the Ring. */
-	uint32_t fbo;
-	/* First Byte Offset of the first entry in the first page. */
-	uint8_t page_size;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE \
+		UINT32_C(0x2)
 	/*
-	 * 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. - 21 = 2
-	 * MB Page size is 2 MB. - 22 = 4 MB Page size is 4 MB. - 30 = 1
-	 * GB Page size is 1 GB.
+	 * Generic Routing Encapsulation	(GRE) inside
+	 * Ethernet payload
 	 */
-	uint8_t page_tbl_depth;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE UINT32_C(0x3)
+	/* IP in IP */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	/* Multi-Protocol Lable Switching	(MPLS) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
+	/* Stateless Transport Tunnel	(STT) */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
 	/*
-	 * 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.
+	 * Generic Routing Encapsulation	(GRE) inside IP
+	 * datagram payload
 	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint32_t length;
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE UINT32_C(0x8)
+	/* Any tunneled traffic */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL \
+		UINT32_C(0xff)
+	uint8_t unused_7;
+	uint16_t dst_id;
 	/*
-	 * Number of 16B units in the ring. Minimum size for a ring is
-	 * 16 16B entries.
+	 * 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 logical_id;
+	uint16_t mirror_vnic_id;
+	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
+	uint8_t pri_hint;
 	/*
-	 * 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.
+	 * This hint is provided to help in placing the filter in the
+	 * filter table.
 	 */
-	uint16_t cmpl_ring_id;
+	/* No preference */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER \
+		UINT32_C(0x0)
+	/* Above the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER \
+		UINT32_C(0x1)
+	/* Below the given filter */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER \
+		UINT32_C(0x2)
+	/* As high as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
+	/* As low as possible */
+	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
+	uint8_t unused_8;
+	uint32_t unused_9;
+	uint64_t l2_filter_id_hint;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what completion ring the TX ring is
-	 * associated with.
+	 * 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
 	 */
-	uint16_t queue_id;
+} __attribute__((packed));
+
+/* Output	(24 bytes) */
+struct hwrm_cfa_l2_filter_alloc_output {
+	uint16_t error_code;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * value indicates what CoS queue the TX ring is associated
-	 * with.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint8_t unused_4;
-	uint8_t unused_5;
-	uint32_t reserved1;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint16_t ring_arb_cfg;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * field is used to configure arbitration related parameters for
-	 * a TX ring.
+	 * 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.
+	 */
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t flow_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.
 	 */
-	/* Arbitration policy used for the ring. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_MASK	\
-		UINT32_C(0xf)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SFT	0
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * Use strict priority for the TX ring. Priority
-	 * value is specified in arb_policy_param
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_SP	\
-		(UINT32_C(0x1) << 0)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * Use weighted fair queue arbitration for the
-	 * TX ring. Weight is specified in
-	 * arb_policy_param
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ	\
-		(UINT32_C(0x2) << 0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_LAST	\
-		RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_WFQ
-	/* Reserved field. */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_MASK	UINT32_C(0xf0)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_RSVD_SFT	4
+	uint16_t cmpl_ring;
 	/*
-	 * Arbitration policy specific parameter. # For strict priority
-	 * arbitration policy, this field represents a priority value.
-	 * If set to 0, then the priority is not specified and the HWRM
-	 * is allowed to select any priority for this TX ring. # For
-	 * weighted fair queue arbitration policy, this field represents
-	 * a weight value. If set to 0, then the weight is not specified
-	 * and the HWRM is allowed to select any weight for this TX
-	 * ring.
+	 * 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.
 	 */
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_MASK  \
-		UINT32_C(0xff00)
-	#define HWRM_RING_ALLOC_INPUT_RING_ARB_CFG_ARB_POLICY_PARAM_SFT   8
-	uint8_t unused_6;
-	uint8_t unused_7;
-	uint32_t reserved3;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t stat_ctx_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This field is used only when ring_type is a TX ring. This
-	 * input indicates what statistics context this ring should be
-	 * associated with.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t reserved4;
-	/* This field is reserved for the future use. It shall be set to 0. */
-	uint32_t max_bw;
+	uint64_t resp_addr;
 	/*
-	 * This field is used only when ring_type is a TX ring to
-	 * specify maximum BW allocated to the TX ring. The HWRM will
-	 * translate this value into byte counter and time interval used
-	 * for this ring inside the device.
+	 * 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.
 	 */
-	/* Bandwidth value */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_MASK	\
-		UINT32_C(0xfffffff)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_SFT	0
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_RSVD	UINT32_C(0x10000000)
-	/* bw_value_unit is 3 b */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MASK	\
-		UINT32_C(0xe0000000)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_SFT	29
-	/* Value is in Mbps */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_MBPS	\
-		(UINT32_C(0x0) << 29)
-	/* Value is in 1/100th of a percentage of total bandwidth. */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_PERCENT1_100  \
-		(UINT32_C(0x1) << 29)
-	/* Invalid unit */
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID	\
-		(UINT32_C(0x7) << 29)
-	#define HWRM_RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_LAST	\
-		RING_ALLOC_INPUT_MAX_BW_BW_VALUE_UNIT_INVALID
-	uint8_t int_mode;
+	uint64_t l2_filter_id;
 	/*
-	 * 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.
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
 	 */
-	/* Legacy INTA */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_LEGACY	UINT32_C(0x0)
-	/* Reserved */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_RSVD	UINT32_C(0x1)
-	/* MSI-X */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX	UINT32_C(0x2)
-	/* No Interrupt - Polled mode */
-	#define HWRM_RING_ALLOC_INPUT_INT_MODE_POLL	UINT32_C(0x3)
-	uint8_t unused_8[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4834,16 +8198,10 @@ struct hwrm_ring_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint16_t ring_id;
-	/*
-	 * Physical number of ring allocated. This value shall be unique
-	 * for a ring type.
-	 */
-	uint16_t logical_ring_id;
-	/* Logical number of ring allocated. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -4855,12 +8213,10 @@ struct hwrm_ring_alloc_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_filter_cfg */
+/* Description: Change the configuration of an existing L2 filter */
+/* Input	(40 bytes) */
+struct hwrm_cfa_l2_filter_cfg_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4887,22 +8243,52 @@ struct hwrm_ring_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint8_t ring_type;
-	/* Ring Type. */
-	/* Completion Ring (CR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_CMPL	UINT32_C(0x0)
-	/* TX Ring (TR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_TX	UINT32_C(0x1)
-	/* RX Ring (RR) */
-	#define HWRM_RING_FREE_INPUT_RING_TYPE_RX	UINT32_C(0x2)
-	uint8_t unused_0;
-	uint16_t ring_id;
-	/* Physical number of ring allocated. */
-	uint32_t unused_1;
+	uint32_t flags;
+	/*
+	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
+	/* tx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX \
+		(UINT32_C(0x0) << 0)
+	/* rx path */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX \
+		(UINT32_C(0x1) << 0)
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST \
+		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
+	/*
+	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
+	uint32_t enables;
+	/* This bit must be '1' for the dst_id field to be configured. */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	/*
+	 * This bit must be '1' for the new_mirror_vnic_id field to be
+	 * configured.
+	 */
+	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   \
+		UINT32_C(0x2)
+	uint64_t l2_filter_id;
+	/*
+	 * This value identifies a set of CFA data structures used for
+	 * an L2 context.
+	 */
+	uint32_t dst_id;
+	/*
+	 * 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.
+	 */
+	uint32_t new_mirror_vnic_id;
+	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_free_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_filter_cfg_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4933,12 +8319,10 @@ struct hwrm_ring_free_output {
 	 */
 } __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 {
+/* hwrm_cfa_l2_set_rx_mask */
+/* Description: This command will set rx mask of the function. */
+/* Input	(56 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -4959,31 +8343,116 @@ struct hwrm_ring_grp_alloc_input {
 	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
 	 * - HWRM
 	 */
-	uint64_t resp_addr;
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t vnic_id;
+	/* VNIC ID */
+	uint32_t mask;
+	/* 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)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for the VLAN-
+	 * tagged packets that match the TPID and VID fields of VLAN
+	 * tags in the VLAN tag table specified in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets that match the TPID
+	 * and VID fields of VLAN tags in the VLAN tag table specified
+	 * in this command.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+	/*
+	 * If this flag is set, the corresponding RX filters shall be
+	 * set up to cover multicast/broadcast filters for non-VLAN
+	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
+	 * If this flag is set, then the HWRM shall ignore VLAN tags
+	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
+	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
+	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
+	 * set at most one flag out of vlanonly, vlan_nonvlan, and
+	 * anyvlan_nonvlan.
+	 */
+	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	\
+		UINT32_C(0x100)
+	uint64_t mc_tbl_addr;
+	/* This is the address for mcast address tbl. */
+	uint32_t num_mc_entries;
 	/*
-	 * 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.
+	 * This value indicates how many entries in mc_tbl are valid.
+	 * Each entry is 6 bytes.
 	 */
-	uint16_t cr;
-	/* This value identifies the CR associated with the ring group. */
-	uint16_t rr;
-	/* This value identifies the main RR associated with the ring group. */
-	uint16_t ar;
+	uint32_t unused_0;
+	uint64_t vlan_tag_tbl_addr;
 	/*
-	 * 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.
+	 * This is the address for VLAN tag table. Each VLAN entry in
+	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
+	 * and VID fields in network byte order.
 	 */
-	uint16_t sc;
+	uint32_t num_vlan_tags;
 	/*
-	 * This value identifies the statistics context associated with
-	 * the ring group.
+	 * This value indicates how many entries in vlan_tag_tbl are
+	 * valid. Each entry is 4 bytes.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_cfa_l2_set_rx_mask_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -4999,15 +8468,10 @@ struct hwrm_ring_grp_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t ring_group_id;
-	/*
-	 * 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.
-	 */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5019,17 +8483,13 @@ struct hwrm_ring_grp_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_ring_grp_free */
+/* hwrm_tunnel_dst_port_query */
 /*
- * 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.
+ * Description: This function is called by a driver to query tunnel type
+ * specific destination port configuration.
  */
-/* Input (24 bytes) */
-struct hwrm_ring_grp_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_query_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5056,13 +8516,19 @@ struct hwrm_ring_grp_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t ring_group_id;
-	/* This is the ring group ID value. */
-	uint32_t unused_0;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_VXLAN \
+		UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_QUERY_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0[7];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_ring_grp_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_query_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5078,10 +8544,24 @@ struct hwrm_ring_grp_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint16_t tunnel_dst_port_id;
+	/*
+	 * This field represents the identifier of L4 destination port
+	 * used for the given tunnel type. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling.
+	 */
+	uint16_t tunnel_dst_port_val;
+	/*
+	 * This field represents the value of L4 destination port
+	 * identified by tunnel_dst_port_id. This field is valid for
+	 * specific tunnel types that use layer 4	(e.g. UDP) transports
+	 * for tunneling. This field is in network byte order. A value
+	 * of 0 means that the destination port is not configured.
+	 */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5093,15 +8573,24 @@ struct hwrm_ring_grp_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_alloc */
+/* hwrm_tunnel_dst_port_alloc */
 /*
- * A filter is used to identify traffic that contains a matching set of
- * parameters like unicast or broadcast MAC address or a VLAN tag amongst
- * other things which then allows the ASIC to direct the  incoming traffic
- * to an appropriate VNIC or Rx ring.
+ * Description: This function is called by a driver to allocate l4 destination
+ * port for a specific tunnel type. The destination port value is provided in
+ * the input. If the HWRM supports only one global destination port for a tunnel
+ * type, then the HWRM shall keep track of its usage as described below. # The
+ * first caller that allocates a destination port shall always succeed and the
+ * HWRM shall save the destination port configuration for that tunnel type and
+ * increment the usage count to 1. # Subsequent callers allocating the same
+ * destination port for that tunnel type shall succeed and the HWRM shall
+ * increment the usage count for that port for each subsequent caller that
+ * succeeds. # Any subsequent caller trying to allocate a different destination
+ * port for that tunnel type shall fail until the usage count for the original
+ * destination port goes to zero. # A caller that frees a port will cause the
+ * usage count for that port to decrement.
  */
-/* Input (96 bytes) */
-struct hwrm_cfa_l2_filter_alloc_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_alloc_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5114,253 +8603,41 @@ struct hwrm_cfa_l2_filter_alloc_input {
 	 * CR completion will be generated. Any other value must be a
 	 * valid CR ring_id value for this function.
 	 */
-	uint16_t seq_id;
-	/* This value indicates the command sequence number. */
-	uint16_t target_id;
-	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
-	 */
-	uint64_t resp_addr;
-	/*
-	 * 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.
-	 */
-	uint32_t flags;
-	/*
-	 * 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	\
-		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 enables;
-	/* 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)
-	uint8_t l2_addr[6];
-	/*
-	 * 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 unused_0;
-	uint8_t unused_1;
-	uint8_t l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the L2 address. A value of
-	 * 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ovlan;
-	/* This value sets VLAN ID value for outer VLAN. */
-	uint16_t l2_ovlan_mask;
-	/*
-	 * This value sets the mask value for the ovlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint16_t l2_ivlan;
-	/* This value sets VLAN ID value for inner VLAN. */
-	uint16_t l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the ivlan id. A value of 0
-	 * will mask the corresponding bit from compare.
-	 */
-	uint8_t unused_2;
-	uint8_t unused_3;
-	uint8_t t_l2_addr[6];
-	/*
-	 * 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 unused_4;
-	uint8_t unused_5;
-	uint8_t t_l2_addr_mask[6];
-	/*
-	 * This value sets the mask value for the tunnel L2 address. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint16_t t_l2_ovlan;
-	/* This value sets VLAN ID value for tunnel outer VLAN. */
-	uint16_t t_l2_ovlan_mask;
-	/*
-	 * 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_ivlan;
-	/* This value sets VLAN ID value for tunnel inner VLAN. */
-	uint16_t t_l2_ivlan_mask;
-	/*
-	 * This value sets the mask value for the tunnel ivlan id. A
-	 * value of 0 will mask the corresponding bit from compare.
-	 */
-	uint8_t src_type;
-	/* 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)
-	/* Physical function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_PF	UINT32_C(0x1)
-	/* Virtual function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VF	UINT32_C(0x2)
-	/* Virtual NIC of a function */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_VNIC	UINT32_C(0x3)
-	/* Embedded processor for CFA management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_KONG	UINT32_C(0x4)
-	/* Embedded processor for OOB management */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_APE	UINT32_C(0x5)
-	/* Embedded processor for RoCE */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_BONO	UINT32_C(0x6)
-	/* Embedded processor for network proxy functions */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_SRC_TYPE_TANG	UINT32_C(0x7)
-	uint8_t unused_6;
-	uint32_t src_id;
-	/*
-	 * 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
-	 */
-	uint8_t tunnel_type;
-	/* Tunnel Type. */
-	/* Non-tunnel */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NONTUNNEL	UINT32_C(0x0)
-	/* Virtual eXtensible Local Area Network (VXLAN) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_VXLAN	UINT32_C(0x1)
-	/*
-	 * Network Virtualization Generic Routing
-	 * Encapsulation (NVGRE)
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_NVGRE	UINT32_C(0x2)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside
-	 * Ethernet payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_L2GRE	UINT32_C(0x3)
-	/* IP in IP */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPIP	UINT32_C(0x4)
-	/* Generic Network Virtualization Encapsulation (Geneve) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_GENEVE	UINT32_C(0x5)
-	/* Multi-Protocol Lable Switching (MPLS) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_MPLS	UINT32_C(0x6)
-	/* Stateless Transport Tunnel (STT) */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_STT	UINT32_C(0x7)
-	/*
-	 * Generic Routing Encapsulation (GRE) inside IP
-	 * datagram payload
-	 */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_IPGRE	UINT32_C(0x8)
-	/* Any tunneled traffic */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_TUNNEL_TYPE_ANYTUNNEL	UINT32_C(0xff)
-	uint8_t unused_7;
-	uint16_t dst_id;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * 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.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint16_t mirror_vnic_id;
-	/* Logical VNIC ID of the VNIC where traffic is mirrored. */
-	uint8_t pri_hint;
+	uint64_t resp_addr;
 	/*
-	 * This hint is provided to help in placing the filter in the
-	 * filter table.
+	 * 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.
 	 */
-	/* No preference */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_NO_PREFER	UINT32_C(0x0)
-	/* Above the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_ABOVE_FILTER	UINT32_C(0x1)
-	/* Below the given filter */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_BELOW_FILTER	UINT32_C(0x2)
-	/* As high as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MAX	UINT32_C(0x3)
-	/* As low as possible */
-	#define HWRM_CFA_L2_FILTER_ALLOC_INPUT_PRI_HINT_MIN	UINT32_C(0x4)
-	uint8_t unused_8;
-	uint32_t unused_9;
-	uint64_t l2_filter_id_hint;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE \
+		UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_val;
 	/*
-	 * 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
+	 * This field represents the value of L4 destination port used
+	 * for the given tunnel type. This field is valid for specific
+	 * tunnel types that use layer 4	(e.g. UDP) transports for
+	 * tunneling. This field is in network byte order. A value of 0
+	 * shall fail the command.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (24 bytes) */
-struct hwrm_cfa_l2_filter_alloc_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5376,21 +8653,17 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint64_t l2_filter_id;
-	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
-	 */
-	uint32_t flow_id;
+	uint16_t tunnel_dst_port_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.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
 	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t unused_4;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5402,13 +8675,13 @@ struct hwrm_cfa_l2_filter_alloc_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_free */
+/* hwrm_tunnel_dst_port_free */
 /*
- * Description: Free a L2 filter. The HWRM shall free all associated filter
- * resources with the L2 filter.
+ * Description: This function is called by a driver to free l4 destination port
+ * for a specific tunnel type.
  */
-/* Input (24 bytes) */
-struct hwrm_cfa_l2_filter_free_input {
+/* Input	(24 bytes) */
+struct hwrm_tunnel_dst_port_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5435,15 +8708,24 @@ struct hwrm_cfa_l2_filter_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint64_t l2_filter_id;
+	uint8_t tunnel_type;
+	/* Tunnel Type. */
+	/* Virtual eXtensible Local Area Network	(VXLAN) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN UINT32_C(0x1)
+	/* Generic Network Virtualization Encapsulation	(Geneve) */
+	#define HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE UINT32_C(0x5)
+	uint8_t unused_0;
+	uint16_t tunnel_dst_port_id;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * Identifier of a tunnel L4 destination port value. Only
+	 * applies to tunnel types that has l4 destination port
+	 * parameters.
 	 */
+	uint32_t unused_1;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_free_output {
+/* Output	(16 bytes) */
+struct hwrm_tunnel_dst_port_free_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5474,10 +8756,13 @@ struct hwrm_cfa_l2_filter_free_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_filter_cfg */
-/* Description: Change the configuration of an existing L2 filter */
-/* Input (40 bytes) */
-struct hwrm_cfa_l2_filter_cfg_input {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5504,49 +8789,35 @@ struct hwrm_cfa_l2_filter_cfg_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t flags;
-	/*
-	 * 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_CFG_INPUT_FLAGS_PATH	UINT32_C(0x1)
-	/* tx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_TX	(UINT32_C(0x0) << 0)
-	/* rx path */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX	(UINT32_C(0x1) << 0)
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_LAST	\
-		CFA_L2_FILTER_CFG_INPUT_FLAGS_PATH_RX
-	/*
-	 * 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_CFG_INPUT_FLAGS_DROP	UINT32_C(0x2)
-	uint32_t enables;
-	/* This bit must be '1' for the dst_id field to be configured. */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_DST_ID	UINT32_C(0x1)
+	uint64_t stats_dma_addr;
+	/* This is the address for statistic block. */
+	uint32_t update_period_ms;
 	/*
-	 * This bit must be '1' for the new_mirror_vnic_id field to be
-	 * configured.
+	 * The statistic block update period in ms. e.g. 250ms, 500ms,
+	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
+	 * update shall be never done and the DMA address shall not be
+	 * used. In this case, the stat block can only be read by
+	 * hwrm_stat_ctx_query command.
 	 */
-	#define HWRM_CFA_L2_FILTER_CFG_INPUT_ENABLES_NEW_MIRROR_VNIC_ID   UINT32_C(0x2)
-	uint64_t l2_filter_id;
+	uint8_t stat_ctx_flags;
 	/*
-	 * This value identifies a set of CFA data structures used for
-	 * an L2 context.
+	 * This field is used to specify statistics context specific
+	 * configuration flags.
 	 */
-	uint32_t dst_id;
 	/*
-	 * 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.
+	 * When this bit is set to '1', the statistics context shall be
+	 * allocated for RoCE traffic only. In this case, traffic other
+	 * than offloaded RoCE traffic shall not be included in this
+	 * statistic context. When this bit is set to '0', the
+	 * statistics context shall be used for the network traffic
+	 * other than offloaded RoCE traffic.
 	 */
-	uint32_t new_mirror_vnic_id;
-	/* New Logical VNIC ID of the VNIC where traffic is mirrored. */
+	#define HWRM_STAT_CTX_ALLOC_INPUT_STAT_CTX_FLAGS_ROCE	UINT32_C(0x1)
+	uint8_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_filter_cfg_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_alloc_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5562,10 +8833,11 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
-	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5577,10 +8849,10 @@ struct hwrm_cfa_l2_filter_cfg_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_cfa_l2_set_rx_mask */
-/* Description: This command will set rx mask of the function. */
-/* Input (56 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_input {
+/* hwrm_stat_ctx_free */
+/* Description: This command is used to free a stat context. */
+/* Input	(24 bytes) */
+struct hwrm_stat_ctx_free_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5607,109 +8879,81 @@ struct hwrm_cfa_l2_set_rx_mask_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t vnic_id;
-	/* VNIC ID */
-	uint32_t mask;
-	/* 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)
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_free_output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_OUTERMOST	UINT32_C(0x20)
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for the VLAN-
-	 * tagged packets that match the TPID and VID fields of VLAN
-	 * tags in the VLAN tag table specified in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY	UINT32_C(0x40)
+	uint32_t stat_ctx_id;
+	/* This is the statistics context ID value. */
+	uint8_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t valid;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets that match the TPID
-	 * and VID fields of VLAN tags in the VLAN tag table specified
-	 * in this command.
+	 * 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.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN	UINT32_C(0x80)
+} __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 {
+	uint16_t req_type;
 	/*
-	 * If this flag is set, the corresponding RX filters shall be
-	 * set up to cover multicast/broadcast filters for non-VLAN
-	 * tagged packets and VLAN-tagged packets matching any VLAN tag.
-	 * If this flag is set, then the HWRM shall ignore VLAN tags
-	 * specified in vlan_tag_tbl. If none of vlanonly, vlan_nonvlan,
-	 * and anyvlan_nonvlan flags is set, then the HWRM shall ignore
-	 * VLAN tags specified in vlan_tag_tbl. The HWRM client shall
-	 * set at most one flag out of vlanonly, vlan_nonvlan, and
-	 * anyvlan_nonvlan.
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
 	 */
-	#define HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN	UINT32_C(0x100)
-	uint64_t mc_tbl_addr;
-	/* This is the address for mcast address tbl. */
-	uint32_t num_mc_entries;
+	uint16_t cmpl_ring;
 	/*
-	 * This value indicates how many entries in mc_tbl are valid.
-	 * Each entry is 6 bytes.
+	 * 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.
 	 */
-	uint32_t unused_0;
-	uint64_t vlan_tag_tbl_addr;
+	uint16_t seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
 	/*
-	 * This is the address for VLAN tag table. Each VLAN entry in
-	 * the table is 4 bytes of a VLAN tag including TPID, PCP, DEI,
-	 * and VID fields in network byte order.
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
 	 */
-	uint32_t num_vlan_tags;
-	/*
-	 * This value indicates how many entries in vlan_tag_tbl are
-	 * valid. Each entry is 4 bytes.
+	uint64_t resp_addr;
+	/*
+	 * 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.
 	 */
-	uint32_t unused_1;
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
+	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_cfa_l2_set_rx_mask_output {
+/* Output	(16 bytes) */
+struct hwrm_stat_ctx_clr_stats_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5740,58 +8984,48 @@ struct hwrm_cfa_l2_set_rx_mask_output {
 	 */
 } __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 {
+/* hwrm_stat_ctx_query */
+/* Description: This command returns statistics of a context. */
+/* Input (24 bytes) */
+
+struct hwrm_stat_ctx_query_input {
 	uint16_t req_type;
 	/*
-	 * This value indicates what type of request this is. The format
-	 * for the rest of the command is determined by this field.
+	 * This value indicates what type of request this is. The format for the
+	 * rest of the command is determined by this field.
 	 */
 	uint16_t cmpl_ring;
 	/*
-	 * 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.
+	 * 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 seq_id;
 	/* This value indicates the command sequence number. */
 	uint16_t target_id;
 	/*
-	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
-	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
-	 * - HWRM
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function ids
+	 * 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF - HWRM
 	 */
 	uint64_t resp_addr;
 	/*
-	 * 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 stats_dma_addr;
-	/* This is the address for statistic block. */
-	uint32_t update_period_ms;
-	/*
-	 * The statistic block update period in ms. e.g. 250ms, 500ms,
-	 * 750ms, 1000ms. If update_period_ms is 0, then the stats
-	 * update shall be never done and the DMA address shall not be
-	 * used. In this case, the stat block can only be read by
-	 * hwrm_stat_ctx_query command.
+	 * 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.
 	 */
+	uint32_t stat_ctx_id;
+	/* ID of the statistics context that is being queried. */
 	uint32_t unused_0;
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_alloc_output {
+/* Output (176 bytes) */
+
+struct hwrm_stat_ctx_query_output {
 	uint16_t error_code;
 	/*
-	 * Pass/Fail or error type Note: receiver to verify the in
-	 * parameters, and fail the call with an error when appropriate
+	 * Pass/Fail or error type Note: receiver to verify the in parameters,
+	 * and fail the call with an error when appropriate
 	 */
 	uint16_t req_type;
 	/* This field returns the type of original request. */
@@ -5799,30 +9033,76 @@ struct hwrm_stat_ctx_alloc_output {
 	/* This field provides original sequence number of the command. */
 	uint16_t resp_len;
 	/*
-	 * 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.
+	 * 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.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint64_t tx_ucast_pkts;
+	/* Number of transmitted unicast packets */
+	uint64_t tx_mcast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t tx_bcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t tx_err_pkts;
+	/* Number of transmitted packets with error */
+	uint64_t tx_drop_pkts;
+	/* Number of dropped packets on transmit path */
+	uint64_t tx_ucast_bytes;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t tx_mcast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t tx_bcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t rx_ucast_pkts;
+	/* Number of received unicast packets */
+	uint64_t rx_mcast_pkts;
+	/* Number of received multicast packets */
+	uint64_t rx_bcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t rx_err_pkts;
+	/* Number of received packets with error */
+	uint64_t rx_drop_pkts;
+	/* Number of dropped packets on received path */
+	uint64_t rx_ucast_bytes;
+	/* Number of received bytes for unicast traffic */
+	uint64_t rx_mcast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t rx_bcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t rx_agg_pkts;
+	/* Number of aggregated unicast packets */
+	uint64_t rx_agg_bytes;
+	/* Number of aggregated unicast bytes */
+	uint64_t rx_agg_events;
+	/* Number of aggregation events */
+	uint64_t rx_agg_aborts;
+	/* Number of aborted aggregations */
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
-	 * 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.
+	 * 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.
 	 */
 } __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 {
+/* 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 {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5849,13 +9129,24 @@ struct hwrm_stat_ctx_free_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * 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.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_free_output {
+/* Output	(16 bytes) */
+struct hwrm_exec_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5871,11 +9162,10 @@ struct hwrm_stat_ctx_free_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t stat_ctx_id;
-	/* This is the statistics context ID value. */
-	uint8_t unused_0;
+	uint32_t unused_0;
 	uint8_t unused_1;
 	uint8_t unused_2;
+	uint8_t unused_3;
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -5887,10 +9177,18 @@ struct hwrm_stat_ctx_free_output {
 	 */
 } __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 {
+/* hwrm_reject_fwd_resp */
+/*
+ * Description: This command is used to send an encapsulated request to the
+ * HWRM. This command instructs the HWRM to reject the request and forward the
+ * error 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_reject_fwd_resp_input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5917,13 +9215,25 @@ struct hwrm_stat_ctx_clr_stats_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t stat_ctx_id;
-	/* ID of the statistics context that is being queried. */
-	uint32_t unused_0;
+	uint32_t encap_request[26];
+	/*
+	 * This is an encapsulated request. This request should be
+	 * rejected by the HWRM and the error response should be
+	 * provided in the response buffer inside the encapsulated
+	 * request.
+	 */
+	uint16_t encap_resp_target_id;
+	/*
+	 * 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 unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_stat_ctx_clr_stats_output {
+/* Output	(16 bytes) */
+struct hwrm_reject_fwd_resp_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -5954,18 +9264,16 @@ struct hwrm_stat_ctx_clr_stats_output {
 	 */
 } __attribute__((packed));
 
-/* hwrm_exec_fwd_resp */
+/* Hardware Resource Manager Specification */
+/* Description: This structure is used to specify port description. */
 /*
- * 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.
+ * 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 service is vital part of the chip.
+ * The chip can not be used by a driver or HWRM client without the HWRM.
  */
-/* Input (128 bytes) */
-struct hwrm_exec_fwd_resp_input {
+/* Input	(16 bytes) */
+struct input {
 	uint16_t req_type;
 	/*
 	 * This value indicates what type of request this is. The format
@@ -5992,24 +9300,91 @@ struct hwrm_exec_fwd_resp_input {
 	 * when the request is complete. This area must be 16B aligned
 	 * and must be cleared to zero before the request is made.
 	 */
-	uint32_t encap_request[26];
+} __attribute__((packed));
+
+/* Output	(8 bytes) */
+struct output {
+	uint16_t error_code;
 	/*
-	 * 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.
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
 	 */
-	uint16_t encap_resp_target_id;
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
 	/*
-	 * 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
+	 * 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.
+	 */
+} __attribute__((packed));
+
+#define HWRM_GET_HWRM_ERROR_CODE(arg) \
+	{ \
+		typeof(arg) x = (arg); \
+	((x) == 0xf ? "HWRM_ERROR" : \
+	((x) == 0xffff ? "CMD_NOT_SUPPORTED" : \
+	((x) == 0xfffe ? "UNKNOWN_ERR" : \
+	((x) == 0x4 ? "RESOURCE_ALLOC_ERROR" : \
+	((x) == 0x5 ? "INVALID_FLAGS" : \
+	((x) == 0x6 ? "INVALID_ENABLES" : \
+	((x) == 0x0 ? "SUCCESS" : \
+	((x) == 0x1 ? "FAIL" : \
+	((x) == 0x2 ? "INVALID_PARAMS" : \
+	((x) == 0x3 ? "RESOURCE_ACCESS_DENIED" : \
+	"Unknown error_code")))))))))) \
+	}
+
+/* Return Codes	(8 bytes) */
+struct ret_codes {
+	uint16_t error_code;
+	/* These are numbers assigned to return/error codes. */
+	/* Request was successfully executed by the HWRM. */
+	#define HWRM_ERR_CODE_SUCCESS	(UINT32_C(0x0))
+	/* THe HWRM failed to execute the request. */
+	#define HWRM_ERR_CODE_FAIL	(UINT32_C(0x1))
+	/*
+	 * The request contains invalid argument(s) or
+	 * input parameters.
+	 */
+	#define HWRM_ERR_CODE_INVALID_PARAMS	(UINT32_C(0x2))
+	/*
+	 * The requester is not allowed to access the
+	 * requested resource. This error code shall be
+	 * provided in a response to a request to query
+	 * or modify an existing resource that is not
+	 * accessible by the requester.
+	 */
+	#define HWRM_ERR_CODE_RESOURCE_ACCESS_DENIED	(UINT32_C(0x3))
+	/*
+	 * The HWRM is unable to allocate the requested
+	 * resource. This code only applies to requests
+	 * for HWRM resource allocations.
 	 */
+	#define HWRM_ERR_CODE_RESOURCE_ALLOC_ERROR	(UINT32_C(0x4))
+	/* Invalid combination of flags is specified in the request. */
+	#define HWRM_ERR_CODE_INVALID_FLAGS	(UINT32_C(0x5))
+	/*
+	 * Invalid combination of enables fields is
+	 * specified in the request.
+	 */
+	#define HWRM_ERR_CODE_INVALID_ENABLES	(UINT32_C(0x6))
+	/*
+	 * Generic HWRM execution error that represents
+	 * an internal error.
+	 */
+	#define HWRM_ERR_CODE_HWRM_ERROR	(UINT32_C(0xf))
+	/* Unknown error */
+	#define HWRM_ERR_CODE_UNKNOWN_ERR	(UINT32_C(0xfffe))
+	/* Unsupported or invalid command */
+	#define HWRM_ERR_CODE_CMD_NOT_SUPPORTED	(UINT32_C(0xffff))
 	uint16_t unused_0[3];
 } __attribute__((packed));
 
-/* Output (16 bytes) */
-struct hwrm_exec_fwd_resp_output {
+/* Output	(16 bytes) */
+struct hwrm_err_output {
 	uint16_t error_code;
 	/*
 	 * Pass/Fail or error type Note: receiver to verify the in
@@ -6025,10 +9400,15 @@ struct hwrm_exec_fwd_resp_output {
 	 * byte of the response is a valid flag that will read as '1'
 	 * when the command has been completely written to memory.
 	 */
-	uint32_t unused_0;
-	uint8_t unused_1;
-	uint8_t unused_2;
-	uint8_t unused_3;
+	uint32_t opaque_0;
+	/* debug info for this error response. */
+	uint16_t opaque_1;
+	/* debug info for this error response. */
+	uint8_t cmd_err;
+	/*
+	 * In the case of an error response, command specific error code
+	 * is returned in this field.
+	 */
 	uint8_t valid;
 	/*
 	 * This field is used in Output records to indicate that the
@@ -6040,4 +9420,378 @@ struct hwrm_exec_fwd_resp_output {
 	 */
 } __attribute__((packed));
 
-#endif
+/* Port Tx Statistics Formats	(408 bytes) */
+struct tx_port_stats {
+	uint64_t tx_64b_frames;
+	/* Total Number of 64 Bytes frames transmitted */
+	uint64_t tx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames transmitted */
+	uint64_t tx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames transmitted */
+	uint64_t tx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames transmitted */
+	uint64_t tx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames transmitted */
+	uint64_t tx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames transmitted */
+	uint64_t tx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * transmitted which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t tx_1519b_2047_frames;
+	/* Total Number of 1519-2047 Bytes frames transmitted */
+	uint64_t tx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames transmitted */
+	uint64_t tx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames transmitted */
+	uint64_t tx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames transmitted */
+	uint64_t tx_good_frames;
+	/* Total Number of good frames transmitted */
+	uint64_t tx_total_frames;
+	/* Total Number of frames transmitted */
+	uint64_t tx_ucast_frames;
+	/* Total number of unicast frames transmitted */
+	uint64_t tx_mcast_frames;
+	/* Total number of multicast frames transmitted */
+	uint64_t tx_bcast_frames;
+	/* Total number of broadcast frames transmitted */
+	uint64_t tx_pause_frames;
+	/* Total number of PAUSE control frames transmitted */
+	uint64_t tx_pfc_frames;
+	/* Total number of PFC/per-priority PAUSE control frames transmitted */
+	uint64_t tx_jabber_frames;
+	/* Total number of jabber frames transmitted */
+	uint64_t tx_fcs_err_frames;
+	/* Total number of frames transmitted with FCS error */
+	uint64_t tx_control_frames;
+	/* Total number of control frames transmitted */
+	uint64_t tx_oversz_frames;
+	/* Total number of over-sized frames transmitted */
+	uint64_t tx_single_dfrl_frames;
+	/* Total number of frames with single deferral */
+	uint64_t tx_multi_dfrl_frames;
+	/* Total number of frames with multiple deferrals */
+	uint64_t tx_single_coll_frames;
+	/* Total number of frames with single collision */
+	uint64_t tx_multi_coll_frames;
+	/* Total number of frames with multiple collisions */
+	uint64_t tx_late_coll_frames;
+	/* Total number of frames with late collisions */
+	uint64_t tx_excessive_coll_frames;
+	/* Total number of frames with excessive collisions */
+	uint64_t tx_frag_frames;
+	/* Total number of fragmented frames transmitted */
+	uint64_t tx_err;
+	/* Total number of transmit errors */
+	uint64_t tx_tagged_frames;
+	/* Total number of single VLAN tagged frames transmitted */
+	uint64_t tx_dbl_tagged_frames;
+	/* Total number of double VLAN tagged frames transmitted */
+	uint64_t tx_runt_frames;
+	/* Total number of runt frames transmitted */
+	uint64_t tx_fifo_underruns;
+	/* Total number of TX FIFO under runs */
+	uint64_t tx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 0
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 1
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 2
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 3
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 4
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 5
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 6
+	 * transmitted
+	 */
+	uint64_t tx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of PFC frames with PFC enabled bit for Pri 7
+	 * transmitted
+	 */
+	uint64_t tx_eee_lpi_events;
+	/* Total number of EEE LPI Events on TX */
+	uint64_t tx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on TX */
+	uint64_t tx_llfc_logical_msgs;
+	/*
+	 * Total number of Link Level Flow Control	(LLFC) messages
+	 * transmitted
+	 */
+	uint64_t tx_hcfc_msgs;
+	/* Total number of HCFC messages transmitted */
+	uint64_t tx_total_collisions;
+	/* Total number of TX collisions */
+	uint64_t tx_bytes;
+	/* Total number of transmitted bytes */
+	uint64_t tx_xthol_frames;
+	/* Total number of end-to-end HOL frames */
+	uint64_t tx_stat_discard;
+	/* Total Tx Drops per Port reported by STATS block */
+	uint64_t tx_stat_error;
+	/* Total Tx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Port Rx Statistics Formats	(528 bytes) */
+struct rx_port_stats {
+	uint64_t rx_64b_frames;
+	/* Total Number of 64 Bytes frames received */
+	uint64_t rx_65b_127b_frames;
+	/* Total Number of 65-127 Bytes frames received */
+	uint64_t rx_128b_255b_frames;
+	/* Total Number of 128-255 Bytes frames received */
+	uint64_t rx_256b_511b_frames;
+	/* Total Number of 256-511 Bytes frames received */
+	uint64_t rx_512b_1023b_frames;
+	/* Total Number of 512-1023 Bytes frames received */
+	uint64_t rx_1024b_1518_frames;
+	/* Total Number of 1024-1518 Bytes frames received */
+	uint64_t rx_good_vlan_frames;
+	/*
+	 * Total Number of each good VLAN	(exludes FCS errors) frame
+	 * received which is 1519 to 1522 bytes in length inclusive
+	 *	(excluding framing bits but including FCS bytes).
+	 */
+	uint64_t rx_1519b_2047b_frames;
+	/* Total Number of 1519-2047 Bytes frames received */
+	uint64_t rx_2048b_4095b_frames;
+	/* Total Number of 2048-4095 Bytes frames received */
+	uint64_t rx_4096b_9216b_frames;
+	/* Total Number of 4096-9216 Bytes frames received */
+	uint64_t rx_9217b_16383b_frames;
+	/* Total Number of 9217-16383 Bytes frames received */
+	uint64_t rx_total_frames;
+	/* Total number of frames received */
+	uint64_t rx_ucast_frames;
+	/* Total number of unicast frames received */
+	uint64_t rx_mcast_frames;
+	/* Total number of multicast frames received */
+	uint64_t rx_bcast_frames;
+	/* Total number of broadcast frames received */
+	uint64_t rx_fcs_err_frames;
+	/* Total number of received frames with FCS error */
+	uint64_t rx_ctrl_frames;
+	/* Total number of control frames received */
+	uint64_t rx_pause_frames;
+	/* Total number of PAUSE frames received */
+	uint64_t rx_pfc_frames;
+	/* Total number of PFC frames received */
+	uint64_t rx_unsupported_opcode_frames;
+	/* Total number of frames received with an unsupported opcode */
+	uint64_t rx_unsupported_da_pausepfc_frames;
+	/*
+	 * Total number of frames received with an unsupported DA for
+	 * pause and PFC
+	 */
+	uint64_t rx_wrong_sa_frames;
+	/* Total number of frames received with an unsupported SA */
+	uint64_t rx_align_err_frames;
+	/* Total number of received packets with alignment error */
+	uint64_t rx_oor_len_frames;
+	/* Total number of received frames with out-of-range length */
+	uint64_t rx_code_err_frames;
+	/* Total number of received frames with error termination */
+	uint64_t rx_false_carrier_frames;
+	/*
+	 * Total number of received frames with a false carrier is
+	 * detected during idle, as defined by RX_ER samples active and
+	 * RXD is 0xE. The event is reported along with the statistics
+	 * generated on the next received frame. Only one false carrier
+	 * condition can be detected and logged between frames. Carrier
+	 * event, valid for 10M/100M speed modes only.
+	 */
+	uint64_t rx_ovrsz_frames;
+	/* Total number of over-sized frames received */
+	uint64_t rx_jbr_frames;
+	/* Total number of jabber packets received */
+	uint64_t rx_mtu_err_frames;
+	/* Total number of received frames with MTU error */
+	uint64_t rx_match_crc_frames;
+	/* Total number of received frames with CRC match */
+	uint64_t rx_promiscuous_frames;
+	/* Total number of frames received promiscuously */
+	uint64_t rx_tagged_frames;
+	/* Total number of received frames with one or two VLAN tags */
+	uint64_t rx_double_tagged_frames;
+	/* Total number of received frames with two VLAN tags */
+	uint64_t rx_trunc_frames;
+	/* Total number of truncated frames received */
+	uint64_t rx_good_frames;
+	/* Total number of good frames	(without errors) received */
+	uint64_t rx_pfc_xon2xoff_frames_pri0;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 0
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri1;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 1
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri2;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 2
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri3;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 3
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri4;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 4
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri5;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 5
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri6;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 6
+	 */
+	uint64_t rx_pfc_xon2xoff_frames_pri7;
+	/*
+	 * Total number of received PFC frames with transition from XON
+	 * to XOFF on Pri 7
+	 */
+	uint64_t rx_pfc_ena_frames_pri0;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 0
+	 */
+	uint64_t rx_pfc_ena_frames_pri1;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 1
+	 */
+	uint64_t rx_pfc_ena_frames_pri2;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 2
+	 */
+	uint64_t rx_pfc_ena_frames_pri3;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 3
+	 */
+	uint64_t rx_pfc_ena_frames_pri4;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 4
+	 */
+	uint64_t rx_pfc_ena_frames_pri5;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 5
+	 */
+	uint64_t rx_pfc_ena_frames_pri6;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 6
+	 */
+	uint64_t rx_pfc_ena_frames_pri7;
+	/*
+	 * Total number of received PFC frames with PFC enabled bit for
+	 * Pri 7
+	 */
+	uint64_t rx_sch_crc_err_frames;
+	/* Total Number of frames received with SCH CRC error */
+	uint64_t rx_undrsz_frames;
+	/* Total Number of under-sized frames received */
+	uint64_t rx_frag_frames;
+	/* Total Number of fragmented frames received */
+	uint64_t rx_eee_lpi_events;
+	/* Total number of RX EEE LPI Events */
+	uint64_t rx_eee_lpi_duration;
+	/* EEE LPI Duration Counter on RX */
+	uint64_t rx_llfc_physical_msgs;
+	/*
+	 * Total number of physical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_logical_msgs;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received
+	 */
+	uint64_t rx_llfc_msgs_with_crc_err;
+	/*
+	 * Total number of logical type Link Level Flow Control	(LLFC)
+	 * messages received with CRC error
+	 */
+	uint64_t rx_hcfc_msgs;
+	/* Total number of HCFC messages received */
+	uint64_t rx_hcfc_msgs_with_crc_err;
+	/* Total number of HCFC messages received with CRC error */
+	uint64_t rx_bytes;
+	/* Total number of received bytes */
+	uint64_t rx_runt_bytes;
+	/* Total number of bytes received in runt frames */
+	uint64_t rx_runt_frames;
+	/* Total number of runt frames received */
+	uint64_t rx_stat_discard;
+	/* Total Rx Discards per Port reported by STATS block */
+	uint64_t rx_stat_err;
+	/* Total Rx Error Drops per Port reported by STATS block */
+} __attribute__((packed));
+
+/* Periodic Statistics Context DMA to host	(160 bytes) */
+/*
+ * per-context HW statistics -- chip view
+ */
+
+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_discard_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_discard_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;
+} __attribute__((packed));
+
+#endif /* _HSI_STRUCT_DEF_DPDK_ */
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
  2017-06-01 17:06             ` [PATCH v4 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
@ 2017-06-01 17:06             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
                               ` (24 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:06 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) Move the function reset to bnxt_dev_init.
On the same lines, setup, enable and request interrupt to init path.
Memory allocation is also being done in the init path.
2) After a function reset, configure the VFs.  Distribute resources
evenly between all functions (PF and VF) for now. In the future, this
should be controllable.
3) The bnxt_vf_info and bnxt_pf_info had lot of duplication. Move the
common items to struct bnxt. And only unique items specific to PF remain
in the struct bnxt_pf_info.
4) Program the firmware to allow certain commands sent by a VF.
Disallowing these will prevent clean VF driver cleanup.
5) Since PF/VF need to allocate resources from a pool in the hardware,
use func_qcaps and func_qcfg to appropriately query the capabilities
and available resources.
6) If a PF is being initialized and no VFs are allocated, explicitly
call func_cfg to allocate the resources.
7) Once resources are requested from the firmware, update local copy
of resource count in struct bnxt only after sending the func_qcfg to
make sure the allocation request in the firmware went through.

The changes in this patch will be used by the subsequent patches
to allow proper initialization of PF/VF instance.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: Regroup related patches per review comment
  Also split bigger patch into smaller patches if possible.

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |  80 ++++--
 drivers/net/bnxt/bnxt_ethdev.c | 155 ++++++++---
 drivers/net/bnxt/bnxt_filter.c |  30 +-
 drivers/net/bnxt/bnxt_hwrm.c   | 614 +++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  17 +-
 drivers/net/bnxt/bnxt_vnic.c   |  45 +--
 drivers/net/bnxt/bnxt_vnic.h   |  11 +-
 7 files changed, 764 insertions(+), 188 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4418c7f..0c59c66 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -35,6 +35,7 @@
 #define _BNXT_H_
 
 #include <inttypes.h>
+#include <stdbool.h>
 #include <sys/queue.h>
 
 #include <rte_ethdev.h>
@@ -54,17 +55,19 @@ enum bnxt_hw_context {
 	HW_CONTEXT_IS_LB    = 3,
 };
 
-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;
-	uint16_t		vlan;
-	struct bnxt_pf_info	*pf;
+struct bnxt_vlan_table_entry {
+	uint16_t		tpid;
+	uint16_t		vid;
+} __attribute__((packed));
+
+struct bnxt_child_vf_info {
+	void			*req_buf;
+	struct bnxt_vlan_table_entry	*vlan_table;
+	STAILQ_HEAD(, bnxt_filter_info)	filter;
+	uint32_t		func_cfg_flags;
+	uint32_t		l2_rx_mask;
+	uint16_t		fid;
+	bool			random_mac;
 };
 
 struct bnxt_pf_info {
@@ -73,22 +76,20 @@ struct bnxt_pf_info {
 #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;
+	uint32_t		func_cfg_flags;
 	void			*vf_req_buf;
 	phys_addr_t		vf_req_buf_dma_addr;
 	uint32_t		vf_req_fwd[8];
-	struct bnxt_vf_info	*vf;
+	uint16_t		total_vnics;
+	struct bnxt_child_vf_info	*vf_info;
+#define BNXT_EVB_MODE_NONE	0
+#define BNXT_EVB_MODE_VEB	1
+#define BNXT_EVB_MODE_VEPA	2
+	uint8_t			evb_mode;
 };
 
 /* Max wait time is 10 * 100ms = 1s */
@@ -174,12 +175,49 @@ struct bnxt {
 	struct bnxt_link_info	link_info;
 	struct bnxt_cos_queue_info	cos_queue[BNXT_COS_QUEUE_COUNT];
 
+	uint16_t		fw_fid;
+	uint8_t			dflt_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		max_stat_ctx;
+	uint16_t		vlan;
 	struct bnxt_pf_info		pf;
-	struct bnxt_vf_info		vf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint32_t		fw_ver;
+};
+
+/*
+ * Response sent back to the caller after callback
+ */
+enum rte_pmd_bnxt_mb_event_rsp {
+	RTE_PMD_BNXT_MB_EVENT_NOOP_ACK,  /**< skip mbox request and ACK */
+	RTE_PMD_BNXT_MB_EVENT_NOOP_NACK, /**< skip mbox request and NACK */
+	RTE_PMD_BNXT_MB_EVENT_PROCEED,  /**< proceed with mbox request  */
+	RTE_PMD_BNXT_MB_EVENT_MAX       /**< max value of this enum */
+};
+
+/* mailbox message types */
+#define BNXT_VF_RESET			0x01 /* VF requests reset */
+#define BNXT_VF_SET_MAC_ADDR	0x02 /* VF requests PF to set MAC addr */
+#define BNXT_VF_SET_VLAN		0x03 /* VF requests PF to set VLAN */
+#define BNXT_VF_SET_MTU			0x04 /* VF requests PF to set MTU */
+#define BNXT_VF_SET_MRU			0x05 /* VF requests PF to set MRU */
+
+/*
+ * Data sent to the caller when the callback is executed.
+ */
+struct rte_pmd_bnxt_mb_event_param {
+	uint16_t vf_id;	/* Virtual Function number */
+	int	retval;	/* return value */
+	void	*msg;	/* pointer to message */
 };
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index c230394..6e7e4f6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -345,18 +345,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
-	}
+	if (BNXT_PF(bp))
+		dev_info->max_vfs = bp->pdev->max_vfs;
+	dev_info->max_rx_queues = bp->max_rx_rings;
+	dev_info->max_tx_queues = bp->max_tx_rings;
+	dev_info->reta_size = bp->max_rsscos_ctx;
+	max_vnics = bp->max_vnics;
 
 	/* Fast path specifics */
 	dev_info->min_rx_bufsize = 1;
@@ -488,41 +482,18 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	bp->dev_stopped = 0;
-	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);
-
 	bnxt_link_update_op(eth_dev, 0);
 	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;
 }
 
@@ -554,8 +525,6 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
-	bnxt_disable_int(bp);
-	bnxt_free_int(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1082,6 +1051,12 @@ static int bnxt_init_board(struct rte_eth_dev *eth_dev)
 
 static int bnxt_dev_uninit(struct rte_eth_dev *eth_dev);
 
+#define ALLOW_FUNC(x)	\
+	{ \
+		typeof(x) arg = (x); \
+		bp->pf.vf_req_fwd[((arg) >> 5)] &= \
+		~rte_cpu_to_le_32(1 << ((arg) & 0x1f)); \
+	}
 static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
@@ -1097,6 +1072,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
 		bp->flags |= BNXT_FLAG_VF;
@@ -1130,6 +1106,11 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		RTE_LOG(ERR, PMD, "hwrm query capability failure rc: %x\n", rc);
 		goto error_free;
 	}
+	if (bp->max_tx_rings == 0) {
+		RTE_LOG(ERR, PMD, "No TX rings available!\n");
+		rc = -EBUSY;
+		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) {
@@ -1140,10 +1121,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		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(bp->mac_addr, bp->dflt_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);
@@ -1155,8 +1133,29 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		goto error_free;
 	}
 
-	rc = bnxt_hwrm_func_driver_register(bp, 0,
-					    bp->pf.vf_req_fwd);
+	/* Forward all requests if firmware is new enough */
+	if (((bp->fw_ver >= ((20 << 24) | (6 << 16) | (100 << 8))) &&
+	    (bp->fw_ver < ((20 << 24) | (7 << 16)))) ||
+	    ((bp->fw_ver >= ((20 << 24) | (8 << 16))))) {
+		memset(bp->pf.vf_req_fwd, 0xff, sizeof(bp->pf.vf_req_fwd));
+	} else {
+		RTE_LOG(WARNING, PMD,
+			"Firmware too old for VF mailbox functionality\n");
+		memset(bp->pf.vf_req_fwd, 0, sizeof(bp->pf.vf_req_fwd));
+	}
+
+	/*
+	 * The following are used for driver cleanup.  If we disallow these,
+	 * VF drivers can't clean up cleanly.
+	 */
+	ALLOW_FUNC(HWRM_FUNC_DRV_UNRGTR);
+	ALLOW_FUNC(HWRM_VNIC_FREE);
+	ALLOW_FUNC(HWRM_RING_FREE);
+	ALLOW_FUNC(HWRM_RING_GRP_FREE);
+	ALLOW_FUNC(HWRM_VNIC_RSS_COS_LB_CTX_FREE);
+	ALLOW_FUNC(HWRM_CFA_L2_FILTER_FREE);
+	ALLOW_FUNC(HWRM_STAT_CTX_FREE);
+	rc = bnxt_hwrm_func_driver_register(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"Failed to register driver");
@@ -1169,10 +1168,55 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		pci_dev->mem_resource[0].phys_addr,
 		pci_dev->mem_resource[0].addr);
 
-	bp->dev_stopped = 0;
+	rc = bnxt_hwrm_func_reset(bp);
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm chip reset failure rc: %x\n", rc);
+		rc = -1;
+		goto error_free;
+	}
+
+	if (BNXT_PF(bp)) {
+		//if (bp->pf.active_vfs) {
+			// TODO: Deallocate VF resources?
+		//}
+		if (bp->pdev->max_vfs) {
+			rc = bnxt_hwrm_allocate_vfs(bp, bp->pdev->max_vfs);
+			if (rc) {
+				RTE_LOG(ERR, PMD, "Failed to allocate VFs\n");
+				goto error_free;
+			}
+		} else {
+			rc = bnxt_hwrm_allocate_pf_only(bp);
+			if (rc) {
+				RTE_LOG(ERR, PMD,
+					"Failed to allocate PF resources\n");
+				goto error_free;
+			}
+		}
+	}
+
+	rc = bnxt_setup_int(bp);
+	if (rc)
+		goto error_free;
+
+	rc = bnxt_alloc_mem(bp);
+	if (rc)
+		goto error_free_int;
+
+	rc = bnxt_request_int(bp);
+	if (rc)
+		goto error_free_int;
+
+	bnxt_enable_int(bp);
 
 	return 0;
 
+error_free_int:
+	bnxt_disable_int(bp);
+	bnxt_free_def_cp_ring(bp);
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 error_free:
 	bnxt_dev_uninit(eth_dev);
 error:
@@ -1184,6 +1228,9 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	struct bnxt *bp = eth_dev->data->dev_private;
 	int rc;
 
+	bnxt_disable_int(bp);
+	bnxt_free_int(bp);
+	bnxt_free_mem(bp);
 	if (eth_dev->data->mac_addrs != NULL) {
 		rte_free(eth_dev->data->mac_addrs);
 		eth_dev->data->mac_addrs = NULL;
@@ -1196,6 +1243,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	bnxt_free_hwrm_resources(bp);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
+	if (bp->pf.vf_info)
+		rte_free(bp->pf.vf_info);
 	eth_dev->dev_ops = NULL;
 	eth_dev->rx_pkt_burst = NULL;
 	eth_dev->tx_pkt_burst = NULL;
@@ -1203,6 +1252,24 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	return rc;
 }
 
+int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg)
+{
+	struct rte_pmd_bnxt_mb_event_param cb_param;
+
+	cb_param.retval = RTE_PMD_BNXT_MB_EVENT_PROCEED;
+	cb_param.vf_id = vf_id;
+	cb_param.msg = msg;
+
+	_rte_eth_dev_callback_process(bp->eth_dev, RTE_ETH_EVENT_VF_MBOX,
+			&cb_param);
+
+	/* Default to approve */
+	if (cb_param.retval == RTE_PMD_BNXT_MB_EVENT_PROCEED)
+		cb_param.retval = RTE_PMD_BNXT_MB_EVENT_NOOP_ACK;
+
+	return cb_param.retval == RTE_PMD_BNXT_MB_EVENT_NOOP_ACK ? true : false;
+}
+
 static int bnxt_pci_probe(struct rte_pci_driver *pci_drv __rte_unused,
 	struct rte_pci_device *pci_dev)
 {
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index df1042c..137c7b7 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -73,15 +73,7 @@ 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	STAILQ_INIT(&bp->free_filter_list);
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
@@ -122,15 +114,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 		return;
 
 	/* 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;
-	}
+	max_filters = bp->max_l2_ctx;
 	for (i = 0; i < max_filters; i++) {
 		filter = &bp->filter_info[i];
 		if (filter->fw_l2_filter_id != ((uint64_t)-1)) {
@@ -155,15 +139,7 @@ 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;
-	}
+	max_filters = bp->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),
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9100b7b..7aece5d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -31,6 +31,8 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -54,6 +56,38 @@
 
 #define HWRM_CMD_TIMEOUT		2000
 
+struct bnxt_plcmodes_cfg {
+	uint32_t	flags;
+	uint16_t	jumbo_thresh;
+	uint16_t	hds_offset;
+	uint16_t	hds_threshold;
+};
+
+static int page_getenum(size_t size)
+{
+	if (size <= 1 << 4)
+		return 4;
+	if (size <= 1 << 12)
+		return 12;
+	if (size <= 1 << 13)
+		return 13;
+	if (size <= 1 << 16)
+		return 16;
+	if (size <= 1 << 21)
+		return 21;
+	if (size <= 1 << 22)
+		return 22;
+	if (size <= 1 << 30)
+		return 30;
+	RTE_LOG(ERR, PMD, "Page size %zu out of range\n", size);
+	return sizeof(void *) * 8 - 1;
+}
+
+static int page_roundup(size_t size)
+{
+	return 1 << page_getenum(size);
+}
+
 /*
  * HWRM Functions (sent to HWRM)
  * These are named bnxt_hwrm_*() and return -1 if bnxt_hwrm_send_message()
@@ -275,6 +309,8 @@ 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;
+	uint16_t new_max_vfs;
+	int i;
 
 	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
 
@@ -286,31 +322,52 @@ int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 
 	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;
-
-		pf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		pf->port_id = resp->port_id;
-		memcpy(pf->mac_addr, resp->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);
+		bp->pf.port_id = resp->port_id;
+		bp->pf.first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+		new_max_vfs = bp->pdev->max_vfs;
+		if (new_max_vfs != bp->pf.max_vfs) {
+			if (bp->pf.vf_info)
+				rte_free(bp->pf.vf_info);
+			bp->pf.vf_info = rte_malloc("bnxt_vf_info",
+			    sizeof(bp->pf.vf_info[0]) * new_max_vfs, 0);
+			bp->pf.max_vfs = new_max_vfs;
+			for (i = 0; i < new_max_vfs; i++) {
+				bp->pf.vf_info[i].fid = bp->pf.first_vf_id + i;
+				bp->pf.vf_info[i].vlan_table =
+					rte_zmalloc("VF VLAN table",
+						    getpagesize(),
+						    getpagesize());
+				if (bp->pf.vf_info[i].vlan_table == NULL)
+					RTE_LOG(ERR, PMD,
+					"Fail to alloc VLAN table for VF %d\n",
+					i);
+				else
+					rte_mem_lock_page(
+						bp->pf.vf_info[i].vlan_table);
+				STAILQ_INIT(&bp->pf.vf_info[i].filter);
+			}
+		}
+	}
+
+	bp->fw_fid = rte_le_to_cpu_32(resp->fid);
+	memcpy(bp->dflt_mac_addr, &resp->mac_address, ETHER_ADDR_LEN);
+	bp->max_rsscos_ctx = rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	if (BNXT_PF(bp)) {
+		if (bp->pf.max_vfs)
+			bp->max_vnics = 1;
+		else
+			bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
 	} else {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		vf->fw_fid = rte_le_to_cpu_32(resp->fid);
-		memcpy(vf->mac_addr, &resp->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);
+		bp->max_vnics = 1;
 	}
+	bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
+	if (BNXT_PF(bp))
+		bp->pf.total_vnics = rte_le_to_cpu_16(resp->max_vnics);
 
 	return rc;
 }
@@ -332,8 +389,7 @@ int bnxt_hwrm_func_reset(struct bnxt *bp)
 	return rc;
 }
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd)
+int bnxt_hwrm_func_driver_register(struct bnxt *bp)
 {
 	int rc;
 	struct hwrm_func_drv_rgtr_input req = {.req_type = 0 };
@@ -343,16 +399,22 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
 		return 0;
 
 	HWRM_PREP(req, FUNC_DRV_RGTR, -1, resp);
-	req.flags = flags;
-	req.enables = HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
-			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD;
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VER |
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_ASYNC_EVENT_FWD);
 	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));
+	if (BNXT_PF(bp)) {
+		req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_DRV_RGTR_INPUT_ENABLES_VF_INPUT_FWD);
+		memcpy(req.vf_req_fwd, bp->pf.vf_req_fwd,
+		       RTE_MIN(sizeof(req.vf_req_fwd),
+			       sizeof(bp->pf.vf_req_fwd)));
+	}
 
 	req.async_event_fwd[0] |= rte_cpu_to_le_32(0x1);   /* TODO: Use MACRO */
+	memset(req.async_event_fwd, 0xff, sizeof(req.async_event_fwd));
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -391,6 +453,8 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 		resp->hwrm_intf_maj, resp->hwrm_intf_min,
 		resp->hwrm_intf_upd,
 		resp->hwrm_fw_maj, resp->hwrm_fw_min, resp->hwrm_fw_bld);
+	bp->fw_ver = (resp->hwrm_fw_maj << 24) | (resp->hwrm_fw_min << 16) |
+			(resp->hwrm_fw_bld << 8) | resp->hwrm_fw_rsvd;
 	RTE_LOG(INFO, PMD, "Driver HWRM version: %d.%d.%d\n",
 		HWRM_VERSION_MAJOR, HWRM_VERSION_MINOR, HWRM_VERSION_UPDATE);
 
@@ -825,10 +889,12 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		}
 		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;
-
+	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
+	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
+	vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				ETHER_CRC_LEN + VLAN_TAG_SIZE;
 	HWRM_PREP(req, VNIC_ALLOC, -1, resp);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -844,27 +910,45 @@ 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;
+	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
 
 	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);
+	if (vnic->lb_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_LB_RULE;
+	if (vnic->cos_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_COS_RULE;
+	if (vnic->rss_rule != 0xffff)
+		ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	req.enables |= rte_cpu_to_le_32(ctx_enable_flag);
 	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);
+	req.dflt_ring_grp = rte_cpu_to_le_16(vnic->dflt_ring_grp);
+	req.rss_rule = rte_cpu_to_le_16(vnic->rss_rule);
+	req.cos_rule = rte_cpu_to_le_16(vnic->cos_rule);
+	req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
+	req.mru = rte_cpu_to_le_16(vnic->mru);
 	if (vnic->func_default)
-		req.flags = 1;
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_DEFAULT);
 	if (vnic->vlan_strip)
 		req.flags |=
 		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_VLAN_STRIP_MODE);
+	if (vnic->bd_stall)
+		req.flags |=
+		    rte_cpu_to_le_32(HWRM_VNIC_CFG_INPUT_FLAGS_BD_STALL_MODE);
+	if (vnic->roce_dual)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE);
+	if (vnic->roce_only)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE);
+	if (vnic->rss_dflt_cr)
+		req.flags |= rte_cpu_to_le_32(
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -873,6 +957,45 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+		int16_t fw_vf_id)
+{
+	int rc = 0;
+	struct hwrm_vnic_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_QCFG, -1, resp);
+
+	req.enables =
+		rte_cpu_to_le_32(HWRM_VNIC_QCFG_INPUT_ENABLES_VF_ID_VALID);
+	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.vf_id = rte_cpu_to_le_16(fw_vf_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	vnic->dflt_ring_grp = rte_le_to_cpu_16(resp->dflt_ring_grp);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_rule);
+	vnic->cos_rule = rte_le_to_cpu_16(resp->cos_rule);
+	vnic->lb_rule = rte_le_to_cpu_16(resp->lb_rule);
+	vnic->mru = rte_le_to_cpu_16(resp->mru);
+	vnic->func_default = rte_le_to_cpu_32(
+			resp->flags) & HWRM_VNIC_QCFG_OUTPUT_FLAGS_DEFAULT;
+	vnic->vlan_strip = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_VLAN_STRIP_MODE;
+	vnic->bd_stall = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_BD_STALL_MODE;
+	vnic->roce_dual = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_DUAL_VNIC_MODE;
+	vnic->roce_only = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_ROCE_ONLY_VNIC_MODE;
+	vnic->rss_dflt_cr = rte_le_to_cpu_32(resp->flags) &
+			HWRM_VNIC_QCFG_OUTPUT_FLAGS_RSS_DFLT_CR_MODE;
+
+	return rc;
+}
+
 int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	int rc = 0;
@@ -886,7 +1009,7 @@ int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+	vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
 
 	return rc;
 }
@@ -900,13 +1023,13 @@ int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	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);
+	req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
 	HWRM_CHECK_RESULT;
 
-	vnic->fw_rss_cos_lb_ctx = INVALID_HW_RING_ID;
+	vnic->rss_rule = INVALID_HW_RING_ID;
 
 	return rc;
 }
@@ -947,7 +1070,7 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	    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);
+	req.rss_ctx_idx = rte_cpu_to_le_16(vnic->rss_rule);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -956,6 +1079,28 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+	memcpy(req.dflt_mac_addr, mac_addr, sizeof(req.dflt_mac_addr));
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	bp->pf.vf_info[vf].random_mac = false;
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -1217,7 +1362,8 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		return;
 
 	vnic = &bp->vnic_info[0];
-	bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
+	if (BNXT_PF(bp))
+		bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic);
 
 	/* VNIC resources */
 	for (i = 0; i < bp->nr_vnics; i++) {
@@ -1512,12 +1658,8 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	HWRM_CHECK_RESULT;
 
-	if (BNXT_VF(bp)) {
-		struct bnxt_vf_info *vf = &bp->vf;
-
-		/* Hard Coded.. 0xfff VLAN ID mask */
-		vf->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
-	}
+	/* Hard Coded.. 0xfff VLAN ID mask */
+	bp->vlan = rte_le_to_cpu_16(resp->vlan) & 0xfff;
 
 	switch (resp->port_partition_type) {
 	case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
@@ -1532,3 +1674,369 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
 
 	return rc;
 }
+
+static void copy_func_cfg_to_qcaps(struct hwrm_func_cfg_input *fcfg,
+				   struct hwrm_func_qcaps_output *qcaps)
+{
+	qcaps->max_rsscos_ctx = fcfg->num_rsscos_ctxs;
+	memcpy(qcaps->mac_address, fcfg->dflt_mac_addr,
+	       sizeof(qcaps->mac_address));
+	qcaps->max_l2_ctxs = fcfg->num_l2_ctxs;
+	qcaps->max_rx_rings = fcfg->num_rx_rings;
+	qcaps->max_tx_rings = fcfg->num_tx_rings;
+	qcaps->max_cmpl_rings = fcfg->num_cmpl_rings;
+	qcaps->max_stat_ctx = fcfg->num_stat_ctxs;
+	qcaps->max_vfs = 0;
+	qcaps->first_vf_id = 0;
+	qcaps->max_vnics = fcfg->num_vnics;
+	qcaps->max_decap_records = 0;
+	qcaps->max_encap_records = 0;
+	qcaps->max_tx_wm_flows = 0;
+	qcaps->max_tx_em_flows = 0;
+	qcaps->max_rx_wm_flows = 0;
+	qcaps->max_rx_em_flows = 0;
+	qcaps->max_flow_id = 0;
+	qcaps->max_mcast_filters = fcfg->num_mcast_filters;
+	qcaps->max_sp_tx_rings = 0;
+	qcaps->max_hw_ring_grps = fcfg->num_hw_ring_grps;
+}
+
+static int bnxt_hwrm_pf_func_cfg(struct bnxt *bp, int tx_rings)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				   ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req.num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx);
+	req.num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx);
+	req.num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings);
+	req.num_tx_rings = rte_cpu_to_le_16(tx_rings);
+	req.num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings);
+	req.num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx);
+	req.num_vnics = rte_cpu_to_le_16(bp->max_vnics);
+	req.num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps);
+	req.fid = rte_cpu_to_le_16(0xffff);
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+static void populate_vf_func_cfg_req(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *req,
+				     int num_vfs)
+{
+	req->enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_MTU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_MRU |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_STAT_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_CMPL_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_TX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_RX_RINGS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_L2_CTXS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_VNICS |
+			HWRM_FUNC_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS);
+
+	req->mtu = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->mru = rte_cpu_to_le_16(bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+				    ETHER_CRC_LEN + VLAN_TAG_SIZE);
+	req->num_rsscos_ctxs = rte_cpu_to_le_16(bp->max_rsscos_ctx /
+						(num_vfs + 1));
+	req->num_stat_ctxs = rte_cpu_to_le_16(bp->max_stat_ctx / (num_vfs + 1));
+	req->num_cmpl_rings = rte_cpu_to_le_16(bp->max_cp_rings /
+					       (num_vfs + 1));
+	req->num_tx_rings = rte_cpu_to_le_16(bp->max_tx_rings / (num_vfs + 1));
+	req->num_rx_rings = rte_cpu_to_le_16(bp->max_rx_rings / (num_vfs + 1));
+	req->num_l2_ctxs = rte_cpu_to_le_16(bp->max_l2_ctx / (num_vfs + 1));
+	/* TODO: For now, do not support VMDq/RFS on VFs. */
+	req->num_vnics = rte_cpu_to_le_16(1);
+	req->num_hw_ring_grps = rte_cpu_to_le_16(bp->max_ring_grps /
+						 (num_vfs + 1));
+}
+
+static void reserve_resources_from_vf(struct bnxt *bp,
+				      struct hwrm_func_cfg_input *cfg_req,
+				      int vf)
+{
+	struct hwrm_func_qcaps_input req = {0};
+	struct hwrm_func_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Get the actual allocated values now */
+	HWRM_PREP(req, FUNC_QCAPS, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps failed rc:%d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcaps error %d\n", rc);
+		copy_func_cfg_to_qcaps(cfg_req, resp);
+	}
+
+	bp->max_rsscos_ctx -= rte_le_to_cpu_16(resp->max_rsscos_ctx);
+	bp->max_stat_ctx -= rte_le_to_cpu_16(resp->max_stat_ctx);
+	bp->max_cp_rings -= rte_le_to_cpu_16(resp->max_cmpl_rings);
+	bp->max_tx_rings -= rte_le_to_cpu_16(resp->max_tx_rings);
+	bp->max_rx_rings -= rte_le_to_cpu_16(resp->max_rx_rings);
+	bp->max_l2_ctx -= rte_le_to_cpu_16(resp->max_l2_ctxs);
+	/*
+	 * TODO: While not supporting VMDq with VFs, max_vnics is always
+	 * forced to 1 in this case
+	 */
+	//bp->max_vnics -= rte_le_to_cpu_16(esp->max_vnics);
+	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
+}
+
+static int update_pf_resource_max(struct bnxt *bp)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* And copy the allocated numbers into the pf struct */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	/* Only TX ring value reflects actual allocation? TODO */
+	bp->max_tx_rings = rte_le_to_cpu_16(resp->alloc_tx_rings);
+	bp->pf.evb_mode = resp->evb_mode;
+
+	return rc;
+}
+
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
+{
+	int rc;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+	if (rc)
+		return rc;
+
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	return rc;
+}
+
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int i;
+	size_t sz;
+	int rc = 0;
+	size_t req_buf_sz;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD, "Attempt to allcoate VFs on a VF!\n");
+		return -1;
+	}
+
+	rc = bnxt_hwrm_func_qcaps(bp);
+
+	if (rc)
+		return rc;
+
+	bp->pf.active_vfs = num_vfs;
+
+	/*
+	 * First, configure the PF to only use one TX ring.  This ensures that
+	 * there are enough rings for all VFs.
+	 *
+	 * If we don't do this, when we call func_alloc() later, we will lock
+	 * extra rings to the PF that won't be available during func_cfg() of
+	 * the VFs.
+	 *
+	 * This has been fixed with firmware versions above 20.6.54
+	 */
+	bp->pf.func_cfg_flags &=
+		~(HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE |
+		  HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_DISABLE);
+	bp->pf.func_cfg_flags |=
+		HWRM_FUNC_CFG_INPUT_FLAGS_STD_TX_RING_MODE_ENABLE;
+	rc = bnxt_hwrm_pf_func_cfg(bp, 1);
+	if (rc)
+		return rc;
+
+	/*
+	 * Now, create and register a buffer to hold forwarded VF requests
+	 */
+	req_buf_sz = num_vfs * HWRM_MAX_REQ_LEN;
+	bp->pf.vf_req_buf = rte_malloc("bnxt_vf_fwd", req_buf_sz,
+		page_roundup(num_vfs * HWRM_MAX_REQ_LEN));
+	if (bp->pf.vf_req_buf == NULL) {
+		rc = -ENOMEM;
+		goto error_free;
+	}
+	for (sz = 0; sz < req_buf_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)bp->pf.vf_req_buf) + sz);
+	for (i = 0; i < num_vfs; i++)
+		bp->pf.vf_info[i].req_buf = ((char *)bp->pf.vf_req_buf) +
+					(i * HWRM_MAX_REQ_LEN);
+
+	rc = bnxt_hwrm_func_buf_rgtr(bp);
+	if (rc)
+		goto error_free;
+
+	populate_vf_func_cfg_req(bp, &req, num_vfs);
+
+	bp->pf.active_vfs = 0;
+	for (i = 0; i < num_vfs; i++) {
+		HWRM_PREP(req, FUNC_CFG, -1, resp);
+		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
+		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
+		rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+		/* Clear enable flag for next pass */
+		req.enables &= ~rte_cpu_to_le_32(
+				HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+
+		if (rc || resp->error_code) {
+			RTE_LOG(ERR, PMD,
+				"Failed to initizlie VF %d\n", i);
+			RTE_LOG(ERR, PMD,
+				"Not all VFs available. (%d, %d)\n",
+				rc, resp->error_code);
+			break;
+		}
+
+		reserve_resources_from_vf(bp, &req, i);
+		bp->pf.active_vfs++;
+	}
+
+	/*
+	 * Now configure the PF to use "the rest" of the resources
+	 * We're using STD_TX_RING_MODE here though which will limit the TX
+	 * rings.  This will allow QoS to function properly.  Not setting this
+	 * will cause PF rings to break bandwidth settings.
+	 */
+	rc = bnxt_hwrm_pf_func_cfg(bp, bp->max_tx_rings);
+	if (rc)
+		goto error_free;
+
+	rc = update_pf_resource_max(bp);
+	if (rc)
+		goto error_free;
+
+	return rc;
+
+error_free:
+	bnxt_hwrm_func_buf_unrgtr(bp);
+	return rc;
+}
+
+
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	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);
+
+	req.req_buf_num_pages = rte_cpu_to_le_16(1);
+	req.req_buf_page_size = rte_cpu_to_le_16(
+			 page_getenum(bp->pf.active_vfs * HWRM_MAX_REQ_LEN));
+	req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
+	req.req_buf_page_addr[0] =
+		rte_cpu_to_le_64(rte_mem_virt2phy(bp->pf.vf_req_buf));
+	if (req.req_buf_page_addr[0] == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map buffer address to physical memory\n");
+		return -ENOMEM;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
+{
+	int rc = 0;
+	struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
+	struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, FUNC_BUF_UNRGTR, -1, resp);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.flags = rte_cpu_to_le_32(bp->pf.func_cfg_flags);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_reject_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_reject_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, REJECT_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6519ef2..0046ba4 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,14 +51,17 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			      void *encaped, size_t ec_size);
 
-int bnxt_hwrm_func_driver_register(struct bnxt *bp, uint32_t flags,
-				   uint32_t *vf_req_fwd);
+int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp);
+int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp);
+int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
@@ -81,6 +84,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_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				int16_t fw_vf_id);
 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);
@@ -101,5 +106,11 @@ 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);
 int bnxt_hwrm_func_qcfg(struct bnxt *bp);
+int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
+int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
+int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
+			  const uint8_t *mac_addr);
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 33fdde2..4e378a9 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -69,21 +69,14 @@ void bnxt_init_vnics(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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;
+		vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
+		vnic->lb_rule = (uint16_t)HWRM_NA_SIGNATURE;
 
 		for (j = 0; j < MAX_QUEUES_PER_VNIC; j++)
 			vnic->fw_grp_ids[j] = (uint16_t)HWRM_NA_SIGNATURE;
@@ -181,15 +174,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	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;
-	}
+	max_vnics = bp->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);
@@ -232,15 +217,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp)
 	if (bp->vnic_info == NULL)
 		return;
 
-	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;
-	}
+	max_vnics = bp->max_vnics;
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
 		if (vnic->fw_vnic_id != (uint16_t)HWRM_NA_SIGNATURE) {
@@ -258,15 +235,7 @@ 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;
-	}
+	max_vnics = bp->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);
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 9671ba4..ca1c9cf 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -42,8 +42,7 @@ struct bnxt_vnic_info {
 	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;
+	uint16_t	rss_rule;
 #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 + \
@@ -51,6 +50,8 @@ struct bnxt_vnic_info {
 	uint16_t	start_grp_id;
 	uint16_t	end_grp_id;
 	uint16_t	fw_grp_ids[MAX_QUEUES_PER_VNIC];
+	uint16_t	dflt_ring_grp;
+	uint16_t	mru;
 	uint16_t	hash_type;
 	phys_addr_t	rss_table_dma_addr;
 	uint16_t	*rss_table;
@@ -60,8 +61,14 @@ struct bnxt_vnic_info {
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
 
+	uint16_t	cos_rule;
+	uint16_t	lb_rule;
 	bool		vlan_strip;
 	bool		func_default;
+	bool		bd_stall;
+	bool		roce_dual;
+	bool		roce_only;
+	bool		rss_dflt_cr;
 
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 03/26] net/bnxt: handle VF/PF initialization appropriately
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
  2017-06-01 17:06             ` [PATCH v4 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
  2017-06-01 17:06             ` [PATCH v4 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
                               ` (23 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

1) For a VF, query the firmware to determine if a MAC address is
already configured. If not configure a random default MAC address.
2) Do not initialize the default completion ring in
bnxt_alloc_hwrm_rings().
3) While registering for async events with the firmware,
use func_vf_cfg for a VF and use func_cfg for a PF.
4) Query the VNIC plcmode config using the bnxt_hwrm_vnic_plcmodes_qcfg
before a VNIC is updated. Reconfigure the VNIC with the plcmode
configuration queried earlier. Not doing this could overwrite
the plcmodes in some cases.
5) Reorg the bnxt_handle_fwd_req to properly handle the forwarded
requests. The previous code did not handle it completely.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other
  review comments.

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_cpr.c       | 131 ++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_cpr.h       |  17 ++++
 drivers/net/bnxt/bnxt_ethdev.c    |  30 +++++---
 drivers/net/bnxt/bnxt_filter.c    |   2 +-
 drivers/net/bnxt/bnxt_hwrm.c      | 158 +++++++++++++++++++++++++++++++++-----
 drivers/net/bnxt/bnxt_hwrm.h      |   4 +-
 drivers/net/bnxt/bnxt_irq.c       |  21 +++--
 drivers/net/bnxt/bnxt_ring.c      |  17 +---
 9 files changed, 294 insertions(+), 88 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 013a9cd..8fcabdb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -12,5 +12,7 @@ Multicast MAC filter = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
+SR-IOV               = Y
+Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 3aedcb8..d13e6cc 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -65,56 +65,115 @@ void bnxt_handle_async_event(struct bnxt *bp,
 
 void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl)
 {
+	struct hwrm_exec_fwd_resp_input *fwreq;
 	struct hwrm_fwd_req_cmpl *fwd_cmpl = (struct hwrm_fwd_req_cmpl *)cmpl;
 	struct input *fwd_cmd;
-	uint16_t logical_vf_id, error_code;
+	uint16_t fw_vf_id;
+	uint16_t vf_id;
+	uint16_t req_len;
+	int rc;
 
-	/* 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;
+	if (bp->pf.active_vfs <= 0) {
+		RTE_LOG(ERR, PMD, "Forwarded VF with no active VFs\n");
+		return;
 	}
 
+	/* Qualify the fwd request */
+	fw_vf_id = rte_le_to_cpu_16(fwd_cmpl->source_id);
+	vf_id = fw_vf_id - bp->pf.first_vf_id;
+
+	req_len = (rte_le_to_cpu_16(fwd_cmpl->req_len_type) &
+		   HWRM_FWD_REQ_CMPL_REQ_LEN_MASK) >>
+		HWRM_FWD_REQ_CMPL_REQ_LEN_SFT;
+	if (req_len > sizeof(fwreq->encap_request))
+		req_len = sizeof(fwreq->encap_request);
+
 	/* 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;
+	fwd_cmd = (struct input *)bp->pf.vf_info[vf_id].req_buf;
+
+	if (fw_vf_id < bp->pf.first_vf_id ||
+	    fw_vf_id >= (bp->pf.first_vf_id) + bp->pf.active_vfs) {
+		RTE_LOG(ERR, PMD,
+		"FWD req's source_id 0x%x out of range 0x%x - 0x%x (%d %d)\n",
+			fw_vf_id, bp->pf.first_vf_id,
+			(bp->pf.first_vf_id) + bp->pf.active_vfs - 1,
+			bp->pf.first_vf_id, bp->pf.active_vfs);
 		goto reject;
 	}
 
-	/* Forward */
-	fwd_cmd->target_id = fwd_cmpl->source_id;
-	bnxt_hwrm_exec_fwd_resp(bp, fwd_cmd);
-	return;
+	if (bnxt_rcv_msg_from_vf(bp, vf_id, fwd_cmd) == true) {
+		/*
+		 * In older firmware versions, the MAC had to be all zeros for
+		 * the VF to set it's MAC via hwrm_func_vf_cfg. Set to all
+		 * zeros if it's being configured and has been ok'd by caller.
+		 */
+		if (fwd_cmd->req_type == HWRM_FUNC_VF_CFG) {
+			struct hwrm_func_vf_cfg_input *vfc = (void *)fwd_cmd;
+
+			if (vfc->enables &
+			    HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR) {
+				bnxt_hwrm_func_vf_mac(bp, vf_id,
+				(const uint8_t *)"\x00\x00\x00\x00\x00");
+			}
+		}
+		if (fwd_cmd->req_type == HWRM_CFA_L2_SET_RX_MASK) {
+			struct hwrm_cfa_l2_set_rx_mask_input *srm =
+							(void *)fwd_cmd;
+
+			srm->vlan_tag_tbl_addr = rte_cpu_to_le_64(0);
+			srm->num_vlan_tags = rte_cpu_to_le_32(0);
+			srm->mask &= ~rte_cpu_to_le_32(
+				HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN |
+			    HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ANYVLAN_NONVLAN);
+		}
+		/* Forward */
+		rc = bnxt_hwrm_exec_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+		if (rc) {
+			RTE_LOG(ERR, PMD,
+				"Failed to send FWD req VF 0x%x, type 0x%x.\n",
+				fw_vf_id - bp->pf.first_vf_id,
+				rte_le_to_cpu_16(fwd_cmd->req_type));
+		}
+		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);
+	rc = bnxt_hwrm_reject_fwd_resp(bp, fw_vf_id, fwd_cmd, req_len);
+	if (rc) {
+		RTE_LOG(ERR, PMD,
+			"Failed to send REJECT req VF 0x%x, type 0x%x.\n",
+			fw_vf_id - bp->pf.first_vf_id,
+			rte_le_to_cpu_16(fwd_cmd->req_type));
+	}
+
+	return;
 }
 
 /* For the default completion ring only */
+int bnxt_alloc_def_cp_ring(struct bnxt *bp)
+{
+	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
+	int rc;
+
+	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
+				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
+				  0, HWRM_NA_SIGNATURE);
+	if (rc)
+		goto err_out;
+	cpr->cp_doorbell = bp->pdev->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;
+	if (BNXT_PF(bp))
+		rc = bnxt_hwrm_func_cfg_def_cp(bp);
+	else
+		rc = bnxt_hwrm_vf_func_cfg_def_cp(bp);
+
+err_out:
+	return rc;
+}
+
 void bnxt_free_def_cp_ring(struct bnxt *bp)
 {
 	struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 83e5376..a6e8785 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -33,6 +33,7 @@
 
 #ifndef _BNXT_CPR_H_
 #define _BNXT_CPR_H_
+#include <stdbool.h>
 
 #include <rte_io.h>
 
@@ -56,6 +57,19 @@
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
 		    ((cpr)->cp_doorbell))
 
+#define B_CP_DB_ARM(cpr)	rte_write32((DB_KEY_CP), ((cpr)->cp_doorbell))
+#define B_CP_DB_DISARM(cpr)	(*(uint32_t *)((cpr)->cp_doorbell) = \
+				 DB_KEY_CP | DB_IRQ_DIS)
+
+#define B_CP_DB_IDX_ARM(cpr, cons)					\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_REARM_FLAGS | \
+				(cons)))
+
+#define B_CP_DB_IDX_DISARM(cpr, cons)	do {				\
+		rte_smp_wmb();						\
+		(*(uint32_t *)((cpr)->cp_doorbell) = (DB_CP_FLAGS |	\
+				(cons));				\
+} while (0)
 #define B_CP_DIS_DB(cpr, raw_cons)					\
 	rte_write32((DB_CP_FLAGS |					\
 		    RING_CMP(((cpr)->cp_ring_struct), raw_cons)),	\
@@ -75,6 +89,8 @@ struct bnxt_cp_ring_info {
 	uint32_t		hw_stats_ctx_id;
 
 	struct bnxt_ring	*cp_ring_struct;
+	uint16_t		cp_cons;
+	bool			v;
 };
 
 #define RX_CMP_L2_ERRORS						\
@@ -82,6 +98,7 @@ struct bnxt_cp_ring_info {
 
 
 struct bnxt;
+int bnxt_alloc_def_cp_ring(struct bnxt *bp);
 void bnxt_free_def_cp_ring(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);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 6e7e4f6..7fe6969 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -228,28 +228,31 @@ static int bnxt_init_chip(struct bnxt *bp)
 
 		rc = bnxt_hwrm_vnic_alloc(bp, vnic);
 		if (rc) {
-			RTE_LOG(ERR, PMD, "HWRM vnic alloc failure rc: %x\n",
-				rc);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d alloc failure rc: %x\n",
+				i, 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);
+				"HWRM vnic %d ctx alloc failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD, "HWRM vnic %d cfg failure rc: %x\n",
+				i, 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);
+			RTE_LOG(ERR, PMD,
+				"HWRM vnic %d filter failure rc: %x\n",
+				i, rc);
 			goto err_out;
 		}
 		if (vnic->rss_table && vnic->hash_type) {
@@ -269,8 +272,8 @@ static int bnxt_init_chip(struct bnxt *bp)
 			rc = bnxt_hwrm_vnic_rss_cfg(bp, vnic);
 			if (rc) {
 				RTE_LOG(ERR, PMD,
-					"HWRM vnic set RSS failure rc: %x\n",
-					rc);
+					"HWRM vnic %d set RSS failure rc: %x\n",
+					i, rc);
 				goto err_out;
 			}
 		}
@@ -638,7 +641,7 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
 			new.link_speed = ETH_LINK_SPEED_100M;
 			new.link_duplex = ETH_LINK_FULL_DUPLEX;
 			RTE_LOG(ERR, PMD,
-				"Failed to retrieve link rc = 0x%x!", rc);
+				"Failed to retrieve link rc = 0x%x!\n", rc);
 			goto out;
 		}
 		rte_delay_ms(BNXT_LINK_WAIT_INTERVAL);
@@ -1010,7 +1013,8 @@ static bool bnxt_vf_pciid(uint16_t id)
 	if (id == BROADCOM_DEV_ID_57304_VF ||
 	    id == BROADCOM_DEV_ID_57406_VF ||
 	    id == BROADCOM_DEV_ID_5731X_VF ||
-	    id == BROADCOM_DEV_ID_5741X_VF)
+	    id == BROADCOM_DEV_ID_5741X_VF ||
+	    id == BROADCOM_DEV_ID_57414_VF)
 		return true;
 	return false;
 }
@@ -1066,7 +1070,7 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	int rc;
 
 	if (version_printed++ == 0)
-		RTE_LOG(INFO, PMD, "%s", bnxt_version);
+		RTE_LOG(INFO, PMD, "%s\n", bnxt_version);
 
 	rte_eth_copy_pci_info(eth_dev, pci_dev);
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
@@ -1207,6 +1211,10 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	if (rc)
 		goto error_free_int;
 
+	rc = bnxt_alloc_def_cp_ring(bp);
+	if (rc)
+		goto error_free_int;
+
 	bnxt_enable_int(bp);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 137c7b7..0afde86 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -126,7 +126,7 @@ void bnxt_free_filter_mem(struct bnxt *bp)
 				       "HWRM filter cannot be freed rc = %d\n",
 					rc);
 		}
-		filter->fw_l2_filter_id = -1;
+		filter->fw_l2_filter_id = UINT64_MAX;
 	}
 	STAILQ_INIT(&bp->free_filter_list);
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7aece5d..7c7c9ce 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -33,6 +33,8 @@
 
 #include <unistd.h>
 
+#include <unistd.h>
+
 #include <rte_byteorder.h>
 #include <rte_common.h>
 #include <rte_cycles.h>
@@ -286,24 +288,6 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	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_qcaps(struct bnxt *bp)
 {
 	int rc = 0;
@@ -905,12 +889,71 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+static int bnxt_hwrm_vnic_plcmodes_qcfg(struct bnxt *bp,
+					struct bnxt_vnic_info *vnic,
+					struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_qcfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_QCFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	pmode->flags = rte_le_to_cpu_32(resp->flags);
+	/* dflt_vnic bit doesn't exist in the _cfg command */
+	pmode->flags &= ~(HWRM_VNIC_PLCMODES_QCFG_OUTPUT_FLAGS_DFLT_VNIC);
+	pmode->jumbo_thresh = rte_le_to_cpu_16(resp->jumbo_thresh);
+	pmode->hds_offset = rte_le_to_cpu_16(resp->hds_offset);
+	pmode->hds_threshold = rte_le_to_cpu_16(resp->hds_threshold);
+
+	return rc;
+}
+
+static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
+				       struct bnxt_vnic_info *vnic,
+				       struct bnxt_plcmodes_cfg *pmode)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+	req.flags = rte_cpu_to_le_32(pmode->flags);
+	req.jumbo_thresh = rte_cpu_to_le_16(pmode->jumbo_thresh);
+	req.hds_offset = rte_cpu_to_le_16(pmode->hds_offset);
+	req.hds_threshold = rte_cpu_to_le_16(pmode->hds_threshold);
+	req.enables = rte_cpu_to_le_32(
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_OFFSET_VALID |
+	    HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID
+	);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	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;
 	uint32_t ctx_enable_flag = HWRM_VNIC_CFG_INPUT_ENABLES_RSS_RULE;
+	struct bnxt_plcmodes_cfg pmodes;
+
+	rc = bnxt_hwrm_vnic_plcmodes_qcfg(bp, vnic, &pmodes);
+	if (rc)
+		return rc;
 
 	HWRM_PREP(req, VNIC_CFG, -1, resp);
 
@@ -954,6 +997,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_CHECK_RESULT;
 
+	rc = bnxt_hwrm_vnic_plcmodes_cfg(bp, vnic, &pmodes);
+
 	return rc;
 }
 
@@ -1773,6 +1818,25 @@ static void populate_vf_func_cfg_req(struct bnxt *bp,
 						 (num_vfs + 1));
 }
 
+static void add_random_mac_if_needed(struct bnxt *bp,
+				     struct hwrm_func_cfg_input *cfg_req,
+				     int vf)
+{
+	struct ether_addr mac;
+
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf, &mac))
+		return;
+
+	if (memcmp(mac.addr_bytes, "\x00\x00\x00\x00\x00", 6) == 0) {
+		cfg_req->enables |=
+		rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+		eth_random_addr(cfg_req->dflt_mac_addr);
+		bp->pf.vf_info[vf].random_mac = true;
+	} else {
+		memcpy(cfg_req->dflt_mac_addr, mac.addr_bytes, ETHER_ADDR_LEN);
+	}
+}
+
 static void reserve_resources_from_vf(struct bnxt *bp,
 				      struct hwrm_func_cfg_input *cfg_req,
 				      int vf)
@@ -1914,6 +1978,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 
 	bp->pf.active_vfs = 0;
 	for (i = 0; i < num_vfs; i++) {
+		add_random_mac_if_needed(bp, &req, i);
+
 		HWRM_PREP(req, FUNC_CFG, -1, resp);
 		req.flags = rte_cpu_to_le_32(bp->pf.vf_info[i].func_cfg_flags);
 		req.fid = rte_cpu_to_le_16(bp->pf.vf_info[i].fid);
@@ -2019,6 +2085,23 @@ int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
+{
+	struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_vf_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_VF_CFG, -1, resp);
+	req.enables = rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
+	req.async_event_cr = rte_cpu_to_le_16(
+			bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
@@ -2040,3 +2123,42 @@ int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
+				       struct ether_addr *mac)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	memcpy(mac->addr_bytes, resp->mac_address, ETHER_ADDR_LEN);
+	return rc;
+}
+
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size)
+{
+	int rc = 0;
+	struct hwrm_exec_fwd_resp_input req = {.req_type = 0};
+	struct hwrm_exec_fwd_resp_output *resp = bp->hwrm_cmd_resp_addr;
+
+	if (ec_size > sizeof(req.encap_request))
+		return -1;
+
+	HWRM_PREP(req, EXEC_FWD_RESP, -1, resp);
+
+	req.encap_resp_target_id = rte_cpu_to_le_16(target_id);
+	memcpy(req.encap_request, encaped, ec_size);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 0046ba4..1ea78b2 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -51,7 +51,8 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 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);
+int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
+			    void *encaped, size_t ec_size);
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size);
 
@@ -62,6 +63,7 @@ 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_func_cfg_def_cp(struct bnxt *bp);
+int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
 int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index 20e17ff..a3d235d 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c
@@ -66,16 +66,26 @@ static void bnxt_int_handler(void *param)
 			/* Handle any async event */
 			bnxt_handle_async_event(bp, cmp);
 			break;
-		case CMPL_BASE_TYPE_HWRM_FWD_RESP:
+		case CMPL_BASE_TYPE_HWRM_FWD_REQ:
 			/* Handle HWRM forwarded responses */
 			bnxt_handle_fwd_req(bp, cmp);
 			break;
 		default:
 			/* Ignore any other events */
+			if (cmp->type & rte_cpu_to_le_16(0x01)) {
+				if (!CMP_VALID(cmp, raw_cons,
+					       cpr->cp_ring_struct))
+					goto no_more;
+			}
+			RTE_LOG(INFO, PMD,
+				"Ignoring %02x completion\n", CMP_TYPE(cmp));
 			break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
-	}
+
+	};
+no_more:
+	cpr->cp_raw_cons = raw_cons;
 	B_CP_DB_REARM(cpr, cpr->cp_raw_cons);
 }
 
@@ -102,14 +112,15 @@ 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);
+	if (cpr != NULL && cpr->cp_doorbell != NULL)
+		B_CP_DB_DISARM(cpr);
 }
 
 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);
+	B_CP_DB_ARM(cpr);
 }
 
 int bnxt_setup_int(struct bnxt *bp)
@@ -136,7 +147,7 @@ int bnxt_setup_int(struct bnxt *bp)
 	return 0;
 
 setup_exit:
-	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed");
+	RTE_LOG(ERR, PMD, "bnxt_irq_tbl setup failed\n");
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 52fbd89..c1698ea 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -213,21 +213,6 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 	unsigned int i;
 	int rc = 0;
 
-	/* Default completion ring */
-	{
-		struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
-		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
-
-		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
-					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					0, HWRM_NA_SIGNATURE);
-		if (rc)
-			goto err_out;
-		cpr->cp_doorbell = 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;
@@ -259,7 +244,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		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!");
+			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 04/26] net/bnxt: support lack of huge pages
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (2 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
                               ` (22 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

rte_malloc_virt2phy() does not return a physical address if huge pages
aren't in use.  Further, rte_memzone->phys_addr is not a physical address.

Use rte_mem_virt2phy() and manually lock pages to support lack of
huge pages.

Also check the return value of rte_mem_virt2phy()

Verify the function returns an address. Otherwise return an error and
log a message.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c | 17 +++++++++++++++--
 drivers/net/bnxt/bnxt_ring.c | 31 +++++++++++++++++++++++++------
 drivers/net/bnxt/bnxt_vnic.c | 16 +++++++++++++++-
 3 files changed, 55 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 7c7c9ce..d2a8d8f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -489,8 +489,15 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto error;
 		}
+		rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 		bp->hwrm_cmd_resp_dma_addr =
-			rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+			rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+		if (bp->hwrm_cmd_resp_dma_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"Unable to map response buffer to physical memory.\n");
+			rc = -ENOMEM;
+			goto error;
+		}
 		bp->max_resp_len = max_resp_len;
 	}
 
@@ -1363,10 +1370,16 @@ 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);
+	rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
 	if (bp->hwrm_cmd_resp_addr == NULL)
 		return -ENOMEM;
 	bp->hwrm_cmd_resp_dma_addr =
-		rte_malloc_virt2phy(bp->hwrm_cmd_resp_addr);
+		rte_mem_virt2phy(bp->hwrm_cmd_resp_addr);
+	if (bp->hwrm_cmd_resp_dma_addr == 0) {
+		RTE_LOG(ERR, PMD,
+			"unable to map response address to physical memory\n");
+		return -ENOMEM;
+	}
 	rte_spinlock_init(&bp->hwrm_lock);
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index c1698ea..5e4236a 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -32,6 +32,7 @@
  */
 
 #include <rte_memzone.h>
+#include <unistd.h>
 
 #include "bnxt.h"
 #include "bnxt_cpr.h"
@@ -96,6 +97,8 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	struct rte_pci_device *pdev = bp->pdev;
 	const struct rte_memzone *mz = NULL;
 	char mz_name[RTE_MEMZONE_NAMESIZE];
+	phys_addr_t mz_phys_addr;
+	int sz;
 
 	int stats_len = (tx_ring_info || rx_ring_info) ?
 	    RTE_CACHE_LINE_ROUNDUP(sizeof(struct ctx_hw_stats64)) : 0;
@@ -136,21 +139,37 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
 	mz = rte_memzone_lookup(mz_name);
 	if (!mz) {
-		mz = rte_memzone_reserve(mz_name, total_alloc_len,
+		mz = rte_memzone_reserve_aligned(mz_name, total_alloc_len,
 					 SOCKET_ID_ANY,
 					 RTE_MEMZONE_2MB |
-					 RTE_MEMZONE_SIZE_HINT_ONLY);
+					 RTE_MEMZONE_SIZE_HINT_ONLY,
+					 getpagesize());
 		if (mz == NULL)
 			return -ENOMEM;
 	}
 	memset(mz->addr, 0, mz->len);
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		for (sz = 0; sz < total_alloc_len; sz += getpagesize())
+			rte_mem_lock_page(((char *)mz->addr) + sz);
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map ring address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	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->bd_dma = mz_phys_addr + tx_ring_start;
 		tx_ring_info->tx_desc_mapping = tx_ring->bd_dma;
 		tx_ring->mem_zone = (const void *)mz;
 
@@ -170,7 +189,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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->bd_dma = mz_phys_addr + rx_ring_start;
 		rx_ring_info->rx_desc_mapping = rx_ring->bd_dma;
 		rx_ring->mem_zone = (const void *)mz;
 
@@ -185,7 +204,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
-	cp_ring->bd_dma = mz->phys_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;
 	cp_ring->mem_zone = (const void *)mz;
@@ -196,7 +215,7 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		*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_map = mz_phys_addr;
 	}
 	cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 4e378a9..fe2244b 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -173,6 +173,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 				HW_HASH_KEY_SIZE);
 	uint16_t max_vnics;
 	int i;
+	phys_addr_t mz_phys_addr;
 
 	max_vnics = bp->max_vnics;
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
@@ -189,6 +190,19 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 		if (!mz)
 			return -ENOMEM;
 	}
+	mz_phys_addr = mz->phys_addr;
+	if ((unsigned long)mz->addr == mz_phys_addr) {
+		RTE_LOG(WARNING, PMD,
+			"Memzone physical address same as virtual.\n");
+		RTE_LOG(WARNING, PMD,
+			"Using rte_mem_virt2phy()\n");
+		mz_phys_addr = rte_mem_virt2phy(mz->addr);
+		if (mz_phys_addr == 0) {
+			RTE_LOG(ERR, PMD,
+			"unable to map vnic address to physical memory\n");
+			return -ENOMEM;
+		}
+	}
 
 	for (i = 0; i < max_vnics; i++) {
 		vnic = &bp->vnic_info[i];
@@ -198,7 +212,7 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 			(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_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));
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 05/26] net/bnxt: add additonal HWRM debug info to error messages
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (3 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 06/26] net/bnxt: add tunneling support Ajit Khaparde
                               ` (21 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

Add the cmd_err and opaque_0 and opaque_1 fields to HWRM error
messages.  These allow better debugging of some classes of HWRM
errors.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt_hwrm.c | 19 +++++++++++++++++--
 1 file changed, 17 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d2a8d8f..3c2f148 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -139,7 +139,7 @@ static int bnxt_hwrm_send_message_locked(struct bnxt *bp, void *msg,
 	}
 
 	if (i >= HWRM_CMD_TIMEOUT) {
-		RTE_LOG(ERR, PMD, "Error sending msg %x\n",
+		RTE_LOG(ERR, PMD, "Error sending msg 0x%04x\n",
 			req->req_type);
 		goto err_ret;
 	}
@@ -176,7 +176,22 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg, uint32_t msg_len)
 		} \
 		if (resp->error_code) { \
 			rc = rte_le_to_cpu_16(resp->error_code); \
-			RTE_LOG(ERR, PMD, "%s error %d\n", __func__, rc); \
+			if (resp->resp_len >= 16) { \
+				struct hwrm_err_output *tmp_hwrm_err_op = \
+							(void *)resp; \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d:%d:%08x:%04x\n", \
+					__func__, \
+					rc, tmp_hwrm_err_op->cmd_err, \
+					rte_le_to_cpu_32(\
+						tmp_hwrm_err_op->opaque_0), \
+					rte_le_to_cpu_16(\
+						tmp_hwrm_err_op->opaque_1)); \
+			} \
+			else { \
+				RTE_LOG(ERR, PMD, \
+					"%s error %d\n", __func__, rc); \
+			} \
 			return rc; \
 		} \
 	}
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 06/26] net/bnxt: add tunneling support
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (4 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
                               ` (20 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for udp_tunnel_port_add/del dev_ops to configure a UDP port
for VXLAN and Geneve Tunnel protocols.
The HWRM supports only one global destination port for a tunnel type,
use a referene counter to keep track of its usage.
Cache the configured VXLAN/Geneve ports and use that value to check
if the right UDP port is being freed up.
Skip calling bnxt_hwrm_tunnel_dst_port_alloc if the same UDP port is
being programmed.
Skip calling bnxt_hwrm_tunnel_dst_port_free if no UDP port has been
configured.
Also update tx offload capabilities

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |   6 +++
 drivers/net/bnxt/bnxt_ethdev.c | 119 ++++++++++++++++++++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.c   |  56 +++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   5 ++
 drivers/net/bnxt/bnxt_txr.c    |   3 +-
 5 files changed, 187 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 0c59c66..3bc3f99 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -188,6 +188,12 @@ struct bnxt {
 	struct bnxt_pf_info		pf;
 	uint8_t			port_partition_type;
 	uint8_t			dev_stopped;
+	uint8_t			vxlan_port_cnt;
+	uint8_t			geneve_port_cnt;
+	uint16_t		vxlan_port;
+	uint16_t		geneve_port;
+	uint16_t		vxlan_fw_dst_port_id;
+	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7fe6969..076c4ce 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -363,7 +363,12 @@ static void bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	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;
+					DEV_TX_OFFLOAD_TCP_TSO |
+					DEV_TX_OFFLOAD_OUTER_IPV4_CKSUM |
+					DEV_TX_OFFLOAD_VXLAN_TNL_TSO |
+					DEV_TX_OFFLOAD_GRE_TNL_TSO |
+					DEV_TX_OFFLOAD_IPIP_TNL_TSO |
+					DEV_TX_OFFLOAD_GENEVE_TNL_TSO;
 
 	/* *INDENT-OFF* */
 	dev_info->default_rxconf = (struct rte_eth_rxconf) {
@@ -975,6 +980,116 @@ static int bnxt_flow_ctrl_set_op(struct rte_eth_dev *dev,
 	return bnxt_set_hwrm_link_config(bp, true);
 }
 
+/* Add UDP tunneling port */
+static int
+bnxt_udp_tunnel_port_add_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->vxlan_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->vxlan_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN;
+		bp->vxlan_port_cnt++;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "Tunnel Port %d already programmed\n",
+				udp_tunnel->udp_port);
+			if (bp->geneve_port != udp_tunnel->udp_port) {
+				RTE_LOG(ERR, PMD, "Only one port allowed\n");
+				return -ENOSPC;
+			}
+			bp->geneve_port_cnt++;
+			return 0;
+		}
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE;
+		bp->geneve_port_cnt++;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+	rc = bnxt_hwrm_tunnel_dst_port_alloc(bp, udp_tunnel->udp_port,
+					     tunnel_type);
+	return rc;
+}
+
+static int
+bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
+			 struct rte_eth_udp_tunnel *udp_tunnel)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	uint16_t tunnel_type = 0;
+	uint16_t port = 0;
+	int rc = 0;
+
+	switch (udp_tunnel->prot_type) {
+	case RTE_TUNNEL_TYPE_VXLAN:
+		if (!bp->vxlan_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->vxlan_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->vxlan_port);
+			return -EINVAL;
+		}
+		if (--bp->vxlan_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN;
+		port = bp->vxlan_fw_dst_port_id;
+		break;
+	case RTE_TUNNEL_TYPE_GENEVE:
+		if (!bp->geneve_port_cnt) {
+			RTE_LOG(ERR, PMD, "No Tunnel port configured yet\n");
+			return -EINVAL;
+		}
+		if (bp->geneve_port != udp_tunnel->udp_port) {
+			RTE_LOG(ERR, PMD, "Req Port: %d. Configured port: %d\n",
+				udp_tunnel->udp_port, bp->geneve_port);
+			return -EINVAL;
+		}
+		if (--bp->geneve_port_cnt)
+			return 0;
+
+		tunnel_type =
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE;
+		port = bp->geneve_fw_dst_port_id;
+		break;
+	default:
+		RTE_LOG(ERR, PMD, "Tunnel type is not supported\n");
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_tunnel_dst_port_free(bp, port, tunnel_type);
+	if (!rc) {
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN)
+			bp->vxlan_port = 0;
+		if (tunnel_type ==
+		    HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE)
+			bp->geneve_port = 0;
+	}
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1006,6 +1121,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.mac_addr_remove = bnxt_mac_addr_remove_op,
 	.flow_ctrl_get = bnxt_flow_ctrl_get_op,
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
+	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
+	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_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 3c2f148..dab4171 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1426,6 +1426,18 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+void bnxt_free_tunnel_ports(struct bnxt *bp)
+{
+	if (bp->vxlan_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->vxlan_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_VXLAN);
+	bp->vxlan_port = 0;
+	if (bp->geneve_port_cnt)
+		bnxt_hwrm_tunnel_dst_port_free(bp, bp->geneve_fw_dst_port_id,
+			HWRM_TUNNEL_DST_PORT_FREE_INPUT_TUNNEL_TYPE_GENEVE);
+	bp->geneve_port = 0;
+}
+
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 {
 	struct bnxt_vnic_info *vnic;
@@ -1451,6 +1463,7 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 	bnxt_free_all_hwrm_rings(bp);
 	bnxt_free_all_hwrm_ring_grps(bp);
 	bnxt_free_all_hwrm_stat_ctxs(bp);
+	bnxt_free_tunnel_ports(bp);
 }
 
 static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed)
@@ -2051,6 +2064,49 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_alloc_input req = {0};
+	struct hwrm_tunnel_dst_port_alloc_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_ALLOC, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_val = port;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	switch (tunnel_type) {
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_VXLAN:
+		bp->vxlan_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->vxlan_port = port;
+		break;
+	case HWRM_TUNNEL_DST_PORT_ALLOC_INPUT_TUNNEL_TYPE_GENEVE:
+		bp->geneve_fw_dst_port_id = resp->tunnel_dst_port_id;
+		bp->geneve_port = port;
+		break;
+	default:
+		break;
+	}
+	return rc;
+}
+
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type)
+{
+	struct hwrm_tunnel_dst_port_free_input req = {0};
+	struct hwrm_tunnel_dst_port_free_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, TUNNEL_DST_PORT_FREE, -1, resp);
+	req.tunnel_type = tunnel_type;
+	req.tunnel_dst_port_id = rte_cpu_to_be_16(port);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
 
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1ea78b2..cee8fca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -114,5 +114,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
+				uint8_t tunnel_type);
+void bnxt_free_tunnel_ports(struct bnxt *bp);
 
 #endif
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 0d15bb1..6870b16 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -213,7 +213,8 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 			/* TSO */
 			txbd1->lflags = TX_BD_LONG_LFLAGS_LSO;
 			txbd1->hdr_size = tx_pkt->l2_len + tx_pkt->l3_len +
-					tx_pkt->l4_len;
+					tx_pkt->l4_len + tx_pkt->outer_l2_len +
+					tx_pkt->outer_l3_len;
 			txbd1->mss = tx_pkt->tso_segsz;
 
 		} else if (tx_pkt->ol_flags & (PKT_TX_TCP_CKSUM |
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 07/26] net/bnxt: add support for xstats get/reset
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (5 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 06/26] net/bnxt: add tunneling support Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
                               ` (19 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to get and reset xstats dev_ops

dev_ops added:
xstats_get, xstats_get_name, xstats_reset

HWRM commands added:
hwrm_port_qstats, hwrm_port_clr_stats

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |   7 ++
 drivers/net/bnxt/bnxt_ethdev.c |  84 +++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   |  36 +++++++
 drivers/net/bnxt/bnxt_hwrm.h   |   3 +-
 drivers/net/bnxt/bnxt_stats.c  | 207 +++++++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_stats.h  |  10 ++
 6 files changed, 346 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 3bc3f99..fde2202 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -130,6 +130,7 @@ struct bnxt {
 	uint32_t		flags;
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
+#define BNXT_FLAG_PORT_STATS	(1 << 2)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -138,10 +139,16 @@ struct bnxt {
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	struct bnxt_rx_queue **rx_queues;
+	const void		*rx_mem_zone;
+	struct rx_port_stats    *hw_rx_port_stats;
+	phys_addr_t		hw_rx_port_stats_map;
 
 	unsigned int		tx_nr_rings;
 	unsigned int		tx_cp_nr_rings;
 	struct bnxt_tx_queue **tx_queues;
+	const void		*tx_mem_zone;
+	struct tx_port_stats    *hw_tx_port_stats;
+	phys_addr_t		hw_tx_port_stats_map;
 
 	/* Default completion ring */
 	struct bnxt_cp_ring_info	*def_cp_ring;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 076c4ce..1e2a8de 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -533,6 +533,7 @@ static void bnxt_dev_stop_op(struct rte_eth_dev *eth_dev)
 		eth_dev->data->dev_link.link_status = 0;
 	}
 	bnxt_set_hwrm_link_config(bp, false);
+	bnxt_hwrm_port_clr_stats(bp);
 	bnxt_shutdown_nic(bp);
 	bp->dev_stopped = 1;
 }
@@ -1123,6 +1124,9 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.xstats_get = bnxt_dev_xstats_get_op,
+	.xstats_get_names = bnxt_dev_xstats_get_names_op,
+	.xstats_reset = bnxt_dev_xstats_reset_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1182,7 +1186,11 @@ static int
 bnxt_dev_init(struct rte_eth_dev *eth_dev)
 {
 	struct rte_pci_device *pci_dev = RTE_ETH_DEV_TO_PCI(eth_dev);
+	char mz_name[RTE_MEMZONE_NAMESIZE];
+	const struct rte_memzone *mz = NULL;
 	static int version_printed;
+	uint32_t total_alloc_len;
+	phys_addr_t mz_phys_addr;
 	struct bnxt *bp;
 	int rc;
 
@@ -1208,6 +1216,80 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->rx_pkt_burst = &bnxt_recv_pkts;
 	eth_dev->tx_pkt_burst = &bnxt_xmit_pkts;
 
+	if (BNXT_PF(bp) && pci_dev->id.device_id != BROADCOM_DEV_ID_NS2) {
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "rx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct rx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->rx_mem_zone = (const void *)mz;
+		bp->hw_rx_port_stats = mz->addr;
+		bp->hw_rx_port_stats_map = mz_phys_addr;
+
+		snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
+			 "bnxt_%04x:%02x:%02x:%02x-%s", pci_dev->addr.domain,
+			 pci_dev->addr.bus, pci_dev->addr.devid,
+			 pci_dev->addr.function, "tx_port_stats");
+		mz_name[RTE_MEMZONE_NAMESIZE - 1] = 0;
+		mz = rte_memzone_lookup(mz_name);
+		total_alloc_len = RTE_CACHE_LINE_ROUNDUP(
+				sizeof(struct tx_port_stats) + 512);
+		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);
+		mz_phys_addr = mz->phys_addr;
+		if ((unsigned long)mz->addr == mz_phys_addr) {
+			RTE_LOG(WARNING, PMD,
+				"Memzone physical address same as virtual.\n");
+			RTE_LOG(WARNING, PMD,
+				"Using rte_mem_virt2phy()\n");
+			mz_phys_addr = rte_mem_virt2phy(mz->addr);
+			if (mz_phys_addr == 0) {
+				RTE_LOG(ERR, PMD,
+				"unable to map address to physical memory\n");
+				return -ENOMEM;
+			}
+		}
+
+		bp->tx_mem_zone = (const void *)mz;
+		bp->hw_tx_port_stats = mz->addr;
+		bp->hw_tx_port_stats_map = mz_phys_addr;
+
+		bp->flags |= BNXT_FLAG_PORT_STATS;
+	}
+
 	rc = bnxt_alloc_hwrm_resources(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
@@ -1366,6 +1448,8 @@ bnxt_dev_uninit(struct rte_eth_dev *eth_dev) {
 	}
 	rc = bnxt_hwrm_func_driver_unregister(bp, 0);
 	bnxt_free_hwrm_resources(bp);
+	rte_memzone_free((const struct rte_memzone *)bp->tx_mem_zone);
+	rte_memzone_free((const struct rte_memzone *)bp->rx_mem_zone);
 	if (bp->dev_stopped == 0)
 		bnxt_dev_close_op(eth_dev);
 	if (bp->pf.vf_info)
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dab4171..d942648 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2246,3 +2246,39 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 
 	return rc;
 }
+
+int bnxt_hwrm_port_qstats(struct bnxt *bp)
+{
+	struct hwrm_port_qstats_input req = {0};
+	struct hwrm_port_qstats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_QSTATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	req.tx_stat_host_addr = rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+	req.rx_stat_host_addr = rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
+
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
+{
+	struct hwrm_port_clr_stats_input req = {0};
+	struct hwrm_port_clr_stats_output *resp = bp->hwrm_cmd_resp_addr;
+	struct bnxt_pf_info *pf = &bp->pf;
+	int rc;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		return 0;
+
+	HWRM_PREP(req, PORT_CLR_STATS, -1, resp);
+	req.port_id = rte_cpu_to_le_16(pf->port_id);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index cee8fca..8f7d103 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -119,5 +119,6 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
-
+int bnxt_hwrm_port_qstats(struct bnxt *bp);
+int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 40c9cac..154dc0c 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -43,6 +43,128 @@
 #include "bnxt_txq.h"
 #include "hsi_struct_def_dpdk.h"
 
+static const struct bnxt_xstats_name_off bnxt_rx_stats_strings[] = {
+	{"rx_64b_frames", offsetof(struct rx_port_stats,
+				rx_64b_frames)},
+	{"rx_65b_127b_frames", offsetof(struct rx_port_stats,
+				rx_65b_127b_frames)},
+	{"rx_128b_255b_frames", offsetof(struct rx_port_stats,
+				rx_128b_255b_frames)},
+	{"rx_256b_511b_frames", offsetof(struct rx_port_stats,
+				rx_256b_511b_frames)},
+	{"rx_512b_1023b_frames", offsetof(struct rx_port_stats,
+				rx_512b_1023b_frames)},
+	{"rx_1024b_1518_frames", offsetof(struct rx_port_stats,
+				rx_1024b_1518_frames)},
+	{"rx_good_vlan_frames", offsetof(struct rx_port_stats,
+				rx_good_vlan_frames)},
+	{"rx_1519b_2047b_frames", offsetof(struct rx_port_stats,
+				rx_1519b_2047b_frames)},
+	{"rx_2048b_4095b_frames", offsetof(struct rx_port_stats,
+				rx_2048b_4095b_frames)},
+	{"rx_4096b_9216b_frames", offsetof(struct rx_port_stats,
+				rx_4096b_9216b_frames)},
+	{"rx_9217b_16383b_frames", offsetof(struct rx_port_stats,
+				rx_9217b_16383b_frames)},
+	{"rx_total_frames", offsetof(struct rx_port_stats,
+				rx_total_frames)},
+	{"rx_ucast_frames", offsetof(struct rx_port_stats,
+				rx_ucast_frames)},
+	{"rx_mcast_frames", offsetof(struct rx_port_stats,
+				rx_mcast_frames)},
+	{"rx_bcast_frames", offsetof(struct rx_port_stats,
+				rx_bcast_frames)},
+	{"rx_fcs_err_frames", offsetof(struct rx_port_stats,
+				rx_fcs_err_frames)},
+	{"rx_ctrl_frames", offsetof(struct rx_port_stats,
+				rx_ctrl_frames)},
+	{"rx_pause_frames", offsetof(struct rx_port_stats,
+				rx_pause_frames)},
+	{"rx_pfc_frames", offsetof(struct rx_port_stats,
+				rx_pfc_frames)},
+	{"rx_align_err_frames", offsetof(struct rx_port_stats,
+				rx_align_err_frames)},
+	{"rx_ovrsz_frames", offsetof(struct rx_port_stats,
+				rx_ovrsz_frames)},
+	{"rx_jbr_frames", offsetof(struct rx_port_stats,
+				rx_jbr_frames)},
+	{"rx_mtu_err_frames", offsetof(struct rx_port_stats,
+				rx_mtu_err_frames)},
+	{"rx_tagged_frames", offsetof(struct rx_port_stats,
+				rx_tagged_frames)},
+	{"rx_double_tagged_frames", offsetof(struct rx_port_stats,
+				rx_double_tagged_frames)},
+	{"rx_good_frames", offsetof(struct rx_port_stats,
+				rx_good_frames)},
+	{"rx_undrsz_frames", offsetof(struct rx_port_stats,
+				rx_undrsz_frames)},
+	{"rx_eee_lpi_events", offsetof(struct rx_port_stats,
+				rx_eee_lpi_events)},
+	{"rx_eee_lpi_duration", offsetof(struct rx_port_stats,
+				rx_eee_lpi_duration)},
+	{"rx_bytes", offsetof(struct rx_port_stats,
+				rx_bytes)},
+	{"rx_runt_bytes", offsetof(struct rx_port_stats,
+				rx_runt_bytes)},
+	{"rx_runt_frames", offsetof(struct rx_port_stats,
+				rx_runt_frames)},
+};
+
+static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
+	{"tx_64b_frames", offsetof(struct tx_port_stats,
+				tx_64b_frames)},
+	{"tx_65b_127b_frames", offsetof(struct tx_port_stats,
+				tx_65b_127b_frames)},
+	{"tx_128b_255b_frames", offsetof(struct tx_port_stats,
+				tx_128b_255b_frames)},
+	{"tx_256b_511b_frames", offsetof(struct tx_port_stats,
+				tx_256b_511b_frames)},
+	{"tx_512b_1023b_frames", offsetof(struct tx_port_stats,
+				tx_512b_1023b_frames)},
+	{"tx_1024b_1518_frames", offsetof(struct tx_port_stats,
+				tx_1024b_1518_frames)},
+	{"tx_good_vlan_frames", offsetof(struct tx_port_stats,
+				tx_good_vlan_frames)},
+	{"tx_1519b_2047_frames", offsetof(struct tx_port_stats,
+				tx_1519b_2047_frames)},
+	{"tx_2048b_4095b_frames", offsetof(struct tx_port_stats,
+				tx_2048b_4095b_frames)},
+	{"tx_4096b_9216b_frames", offsetof(struct tx_port_stats,
+				tx_4096b_9216b_frames)},
+	{"tx_9217b_16383b_frames", offsetof(struct tx_port_stats,
+				tx_9217b_16383b_frames)},
+	{"tx_good_frames", offsetof(struct tx_port_stats,
+				tx_good_frames)},
+	{"tx_total_frames", offsetof(struct tx_port_stats,
+				tx_total_frames)},
+	{"tx_ucast_frames", offsetof(struct tx_port_stats,
+				tx_ucast_frames)},
+	{"tx_mcast_frames", offsetof(struct tx_port_stats,
+				tx_mcast_frames)},
+	{"tx_bcast_frames", offsetof(struct tx_port_stats,
+				tx_bcast_frames)},
+	{"tx_pause_frames", offsetof(struct tx_port_stats,
+				tx_pause_frames)},
+	{"tx_pfc_frames", offsetof(struct tx_port_stats,
+				tx_pfc_frames)},
+	{"tx_jabber_frames", offsetof(struct tx_port_stats,
+				tx_jabber_frames)},
+	{"tx_fcs_err_frames", offsetof(struct tx_port_stats,
+				tx_fcs_err_frames)},
+	{"tx_err", offsetof(struct tx_port_stats,
+				tx_err)},
+	{"tx_fifo_underruns", offsetof(struct tx_port_stats,
+				tx_fifo_underruns)},
+	{"tx_eee_lpi_events", offsetof(struct tx_port_stats,
+				tx_eee_lpi_events)},
+	{"tx_eee_lpi_duration", offsetof(struct tx_port_stats,
+				tx_eee_lpi_duration)},
+	{"tx_total_collisions", offsetof(struct tx_port_stats,
+				tx_total_collisions)},
+	{"tx_bytes", offsetof(struct tx_port_stats,
+				tx_bytes)},
+};
+
 /*
  * Statistics functions
  */
@@ -140,3 +262,88 @@ void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
 
 	bnxt_clear_all_hwrm_stat_ctxs(bp);
 }
+
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	unsigned int count, i;
+
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
+		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
+		return 0;
+	}
+
+	bnxt_hwrm_port_qstats(bp);
+
+	count = RTE_DIM(bnxt_rx_stats_strings) +
+		RTE_DIM(bnxt_tx_stats_strings);
+
+	if (n < count)
+		return count;
+
+	count = 0;
+	for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+		uint64_t *rx_stats = (uint64_t *)bp->hw_rx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				*(uint64_t *)((char *)rx_stats +
+				bnxt_rx_stats_strings[i].offset));
+		count++;
+	}
+
+	for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+		uint64_t *tx_stats = (uint64_t *)bp->hw_tx_port_stats;
+		xstats[count].value = rte_le_to_cpu_64(
+				 *(uint64_t *)((char *)tx_stats +
+				bnxt_tx_stats_strings[i].offset));
+		count++;
+	}
+
+	return count;
+}
+
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit)
+{
+	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+				RTE_DIM(bnxt_tx_stats_strings);
+	unsigned int i, count;
+
+	if (xstats_names != NULL) {
+		count = 0;
+
+		for (i = 0; i < RTE_DIM(bnxt_rx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_rx_stats_strings[i].name);
+			count++;
+		}
+
+		for (i = 0; i < RTE_DIM(bnxt_tx_stats_strings); i++) {
+			snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_tx_stats_strings[i].name);
+			count++;
+		}
+	}
+	return stat_cnt;
+}
+
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (bp->flags & BNXT_FLAG_PORT_STATS && !BNXT_NPAR_PF(bp))
+		bnxt_hwrm_port_clr_stats(bp);
+
+	if (BNXT_VF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a VF device\n");
+	if (BNXT_NPAR_PF(bp))
+		RTE_LOG(ERR, PMD, "Operation not supported on a MF device\n");
+	if (!(bp->flags & BNXT_FLAG_PORT_STATS))
+		RTE_LOG(ERR, PMD, "Operation not supported\n");
+}
diff --git a/drivers/net/bnxt/bnxt_stats.h b/drivers/net/bnxt/bnxt_stats.h
index 65408a4..b6d133e 100644
--- a/drivers/net/bnxt/bnxt_stats.h
+++ b/drivers/net/bnxt/bnxt_stats.h
@@ -40,5 +40,15 @@ 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);
+int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
+	struct rte_eth_xstat_name *xstats_names,
+	__rte_unused unsigned int limit);
+int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
+			   struct rte_eth_xstat *xstats, unsigned int n);
+void bnxt_dev_xstats_reset_op(struct rte_eth_dev *eth_dev);
 
+struct bnxt_xstats_name_off {
+	char name[RTE_ETH_XSTATS_NAME_SIZE];
+	uint64_t offset;
+};
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 08/26] net/bnxt: add support for VLAN filter and strip
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (6 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
                               ` (18 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds VLAN strip and offload callbacks.
To add a VLAN filter:
    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

To remove a VLAN filter:
    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

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Fix a "pointer from integer" warning seen during compilation
---
 doc/guides/nics/features/bnxt.ini |   2 +
 drivers/net/bnxt/bnxt_ethdev.c    | 201 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 203 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 8fcabdb..78a738f 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -9,6 +9,8 @@ Queue start/stop     = Y
 Promiscuous mode     = Y
 Unicast MAC filter   = Y
 Multicast MAC filter = Y
+VLAN filter          = Y
+VLAN offload         = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 1e2a8de..5073cd8 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -141,6 +141,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_TCP |	\
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
+static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
 /***********************/
 
 /*
@@ -487,6 +488,7 @@ static int bnxt_dev_lsc_intr_setup(struct rte_eth_dev *eth_dev)
 static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	int vlan_mask = 0;
 	int rc;
 
 	bp->dev_stopped = 0;
@@ -496,6 +498,13 @@ static int bnxt_dev_start_op(struct rte_eth_dev *eth_dev)
 		goto error;
 
 	bnxt_link_update_op(eth_dev, 0);
+
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_filter)
+		vlan_mask |= ETH_VLAN_FILTER_MASK;
+	if (eth_dev->data->dev_conf.rxmode.hw_vlan_strip)
+		vlan_mask |= ETH_VLAN_STRIP_MASK;
+	bnxt_vlan_offload_set_op(eth_dev, vlan_mask);
+
 	return 0;
 
 error:
@@ -1091,6 +1100,196 @@ bnxt_udp_tunnel_port_del_op(struct rte_eth_dev *eth_dev,
 	return rc;
 }
 
+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 int i;
+	int rc = 0;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk &&
+				    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 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;
+					RTE_LOG(INFO, PMD,
+						"Del Vlan filter for %d\n",
+						vlan_id);
+				}
+				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 int i;
+	int rc = 0;
+	uint32_t en = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN |
+		HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK;
+	uint32_t chk = HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN;
+
+	/* Cycle through all VNICs */
+	for (i = 0; i < bp->nr_vnics; 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 & chk) {
+					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 |= en;
+				rc = bnxt_hwrm_set_filter(bp, vnic,
+							  new_filter);
+				if (rc)
+					goto exit;
+				RTE_LOG(INFO, PMD,
+					"Added Vlan filter for %d\n", vlan_id);
+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_offload_set_op(struct rte_eth_dev *dev, int mask)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	unsigned int i;
+
+	if (mask & ETH_VLAN_FILTER_MASK) {
+		if (!dev->data->dev_conf.rxmode.hw_vlan_filter) {
+			/* Remove any VLAN filters programmed */
+			for (i = 0; i < 4095; i++)
+				bnxt_del_vlan_filter(bp, i);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Filtering: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_filter);
+	}
+
+	if (mask & ETH_VLAN_STRIP_MASK) {
+		/* Enable or disable VLAN stripping */
+		for (i = 0; i < bp->nr_vnics; i++) {
+			struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+			if (dev->data->dev_conf.rxmode.hw_vlan_strip)
+				vnic->vlan_strip = true;
+			else
+				vnic->vlan_strip = false;
+			bnxt_hwrm_vnic_cfg(bp, vnic);
+		}
+		RTE_LOG(INFO, PMD, "VLAN Strip Offload: %d\n",
+			dev->data->dev_conf.rxmode.hw_vlan_strip);
+	}
+
+	if (mask & ETH_VLAN_EXTEND_MASK)
+		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
+}
+
 /*
  * Initialization
  */
@@ -1124,6 +1323,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.flow_ctrl_set = bnxt_flow_ctrl_set_op,
 	.udp_tunnel_port_add  = bnxt_udp_tunnel_port_add_op,
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
+	.vlan_filter_set = bnxt_vlan_filter_set_op,
+	.vlan_offload_set = bnxt_vlan_offload_set_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 09/26] net/bnxt: add support for set multicast addr list and MAC addr set
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (7 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
                               ` (17 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for set_mc_addr_list and
mac_addr_set dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Split the patch to document "Allmulticast mode" in bnxt.ini
---
 drivers/net/bnxt/bnxt_ethdev.c | 74 ++++++++++++++++++++++++++++++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.c   | 13 +++++---
 drivers/net/bnxt/bnxt_hwrm.h   |  2 +-
 drivers/net/bnxt/bnxt_vnic.c   |  7 +++-
 drivers/net/bnxt/bnxt_vnic.h   |  4 +++
 5 files changed, 91 insertions(+), 9 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5073cd8..ef14fb9 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -638,7 +638,7 @@ static int bnxt_mac_addr_add_op(struct rte_eth_dev *eth_dev,
 	STAILQ_INSERT_TAIL(&vnic->filter, filter, next);
 	filter->mac_index = index;
 	memcpy(filter->l2_addr, mac_addr, ETHER_ADDR_LEN);
-	return bnxt_hwrm_set_filter(bp, vnic, filter);
+	return bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 }
 
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete)
@@ -1155,7 +1155,7 @@ static int bnxt_del_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
 					       filter->l2_addr, ETHER_ADDR_LEN);
 					/* MAC only filter */
 					rc = bnxt_hwrm_set_filter(bp,
-							vnic,
+							vnic->fw_vnic_id,
 							new_filter);
 					if (rc)
 						goto exit;
@@ -1229,7 +1229,7 @@ static int bnxt_add_vlan_filter(struct bnxt *bp, uint16_t vlan_id)
 				new_filter->l2_ovlan = vlan_id;
 				new_filter->l2_ovlan_mask = 0xF000;
 				new_filter->enables |= en;
-				rc = bnxt_hwrm_set_filter(bp, vnic,
+				rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id,
 							  new_filter);
 				if (rc)
 					goto exit;
@@ -1290,6 +1290,72 @@ bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask)
 		RTE_LOG(ERR, PMD, "Extend VLAN Not supported\n");
 }
 
+static void
+bnxt_set_default_mac_addr_op(struct rte_eth_dev *dev, struct ether_addr *addr)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	/* Default Filter is tied to VNIC 0 */
+	struct bnxt_vnic_info *vnic = &bp->vnic_info[0];
+	struct bnxt_filter_info *filter;
+	int rc;
+
+	if (BNXT_VF(bp))
+		return;
+
+	memcpy(bp->mac_addr, addr, sizeof(bp->mac_addr));
+	memcpy(&dev->data->mac_addrs[0], bp->mac_addr, ETHER_ADDR_LEN);
+
+	STAILQ_FOREACH(filter, &vnic->filter, next) {
+		/* Default Filter is at Index 0 */
+		if (filter->mac_index != 0)
+			continue;
+		rc = bnxt_hwrm_clear_filter(bp, filter);
+		if (rc)
+			break;
+		memcpy(filter->l2_addr, bp->mac_addr, ETHER_ADDR_LEN);
+		memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+		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;
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
+		if (rc)
+			break;
+		filter->mac_index = 0;
+		RTE_LOG(DEBUG, PMD, "Set MAC addr\n");
+	}
+}
+
+static int
+bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
+			  struct ether_addr *mc_addr_set,
+			  uint32_t nb_mc_addr)
+{
+	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
+	char *mc_addr_list = (char *)mc_addr_set;
+	struct bnxt_vnic_info *vnic;
+	uint32_t off = 0, i = 0;
+
+	vnic = &bp->vnic_info[0];
+
+	if (nb_mc_addr > BNXT_MAX_MC_ADDRS) {
+		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+		goto allmulti;
+	}
+
+	/* TODO Check for Duplicate mcast addresses */
+	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
+	for (i = 0; i < nb_mc_addr; i++) {
+		memcpy(vnic->mc_list + off, &mc_addr_list[i], ETHER_ADDR_LEN);
+		off += ETHER_ADDR_LEN;
+	}
+
+	vnic->mc_addr_cnt = i;
+
+allmulti:
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+}
+
 /*
  * Initialization
  */
@@ -1325,9 +1391,11 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_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 d942648..22e18d6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,7 +229,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_ALL_MCAST;
+	if (vnic->mc_addr_cnt) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
+		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
+		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
+	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
 
@@ -261,7 +266,7 @@ int bnxt_hwrm_clear_filter(struct bnxt *bp,
 }
 
 int bnxt_hwrm_set_filter(struct bnxt *bp,
-			 struct bnxt_vnic_info *vnic,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter)
 {
 	int rc = 0;
@@ -275,7 +280,7 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 
 	enables = filter->enables |
 	      HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_DST_ID;
-	req.dst_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
+	req.dst_id = rte_cpu_to_le_16(dst_id);
 
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_ADDR)
@@ -1419,7 +1424,7 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	int rc = 0;
 
 	STAILQ_FOREACH(filter, &vnic->filter, next) {
-		rc = bnxt_hwrm_set_filter(bp, vnic, filter);
+		rc = bnxt_hwrm_set_filter(bp, vnic->fw_vnic_id, filter);
 		if (rc)
 			break;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 8f7d103..c15404f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -49,7 +49,7 @@ 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,
+			 uint16_t dst_id,
 			 struct bnxt_filter_info *filter);
 int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			    void *encaped, size_t ec_size);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index fe2244b..db9fb07 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -170,7 +170,8 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 	char mz_name[RTE_MEMZONE_NAMESIZE];
 	uint32_t entry_length = RTE_CACHE_LINE_ROUNDUP(
 				HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table) +
-				HW_HASH_KEY_SIZE);
+				HW_HASH_KEY_SIZE +
+				BNXT_MAX_MC_ADDRS * ETHER_ADDR_LEN);
 	uint16_t max_vnics;
 	int i;
 	phys_addr_t mz_phys_addr;
@@ -218,6 +219,10 @@ int bnxt_alloc_vnic_attributes(struct bnxt *bp)
 
 		vnic->rss_hash_key_dma_addr = vnic->rss_table_dma_addr +
 			     HW_HASH_INDEX_SIZE * sizeof(*vnic->rss_table);
+		vnic->mc_list = (void *)((char *)vnic->rss_hash_key +
+				HW_HASH_KEY_SIZE);
+		vnic->mc_list_dma_addr = vnic->rss_hash_key_dma_addr +
+				HW_HASH_KEY_SIZE;
 	}
 
 	return 0;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index ca1c9cf..0d50224 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -57,6 +57,10 @@ struct bnxt_vnic_info {
 	uint16_t	*rss_table;
 	phys_addr_t	rss_hash_key_dma_addr;
 	void		*rss_hash_key;
+	phys_addr_t	mc_list_dma_addr;
+	char		*mc_list;
+	uint32_t	mc_addr_cnt;
+#define BNXT_MAX_MC_ADDRS		16
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 10/26] doc: update bnxt.ini to document Allmulticast mode
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (8 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 11/26] net/bnxt: add support to get fw version Ajit Khaparde
                               ` (16 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch update bnxt.int to document Allmulticast mode
which is already supported by the PMD.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/nics/features/bnxt.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 78a738f..9b3cd94 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -11,6 +11,7 @@ Unicast MAC filter   = Y
 Multicast MAC filter = Y
 VLAN filter          = Y
 VLAN offload         = Y
+Allmulticast mode    = Y
 RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 11/26] net/bnxt: add support to get fw version
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (9 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 12/26] net/bnxt: add support to set MTU Ajit Khaparde
                               ` (15 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for fw_version_get dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 doc/guides/nics/features/bnxt.ini |  1 +
 drivers/net/bnxt/bnxt_ethdev.c    | 20 ++++++++++++++++++++
 2 files changed, 21 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 9b3cd94..b1be3fd 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -16,6 +16,7 @@ RSS reta update      = Y
 Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
+FW version           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index ef14fb9..e987732 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1356,6 +1356,25 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
 }
 
+static int
+bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint8_t fw_major = (bp->fw_ver >> 24) & 0xff;
+	uint8_t fw_minor = (bp->fw_ver >> 16) & 0xff;
+	uint8_t fw_updt = (bp->fw_ver >> 8) & 0xff;
+	int ret;
+
+	ret = snprintf(fw_version, fw_size, "%d.%d.%d",
+			fw_major, fw_minor, fw_updt);
+
+	ret += 1; /* add the size of '\0' */
+	if (fw_size < (uint32_t)ret)
+		return ret;
+	else
+		return 0;
+}
+
 /*
  * Initialization
  */
@@ -1395,6 +1414,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
 	.xstats_reset = bnxt_dev_xstats_reset_op,
+	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 };
 
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 12/26] net/bnxt: add support to set MTU
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (10 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 11/26] net/bnxt: add support to get fw version Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-06 12:47               ` Ferruh Yigit
  2017-06-01 17:07             ` [PATCH v4 13/26] net/bnxt: add support for LRO Ajit Khaparde
                               ` (14 subsequent siblings)
  26 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to modify MTU using the set_mtu dev_op.
To support frames > 2k, the PMD creates an aggregator ring.
When a frame greater than 2k is received, it is fragmented
and the resulting fragments are DMA'ed to the aggregator ring.
Now the driver can support jumbo frames upto 9500 bytes.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini      |   2 +
 drivers/net/bnxt/bnxt.h                |   4 +-
 drivers/net/bnxt/bnxt_cpr.c            |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c         |  59 ++++++++++
 drivers/net/bnxt/bnxt_hwrm.c           | 121 ++++++++++++--------
 drivers/net/bnxt/bnxt_hwrm.h           |   4 +-
 drivers/net/bnxt/bnxt_ring.c           |  81 ++++++++++++--
 drivers/net/bnxt/bnxt_ring.h           |   2 +
 drivers/net/bnxt/bnxt_rxq.c            |  29 +++--
 drivers/net/bnxt/bnxt_rxq.h            |   1 +
 drivers/net/bnxt/bnxt_rxr.c            | 195 +++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_rxr.h            |   6 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h |   1 -
 13 files changed, 422 insertions(+), 86 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index b1be3fd..066cb01 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -17,6 +17,8 @@ Basic stats          = Y
 Extended stats       = Y
 SR-IOV               = Y
 FW version           = Y
+Jumbo frame          = Y
+MTU update           = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index fde2202..8e6689f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -45,7 +45,7 @@
 
 #include "bnxt_cpr.h"
 
-#define BNXT_MAX_MTU		9000
+#define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
 
 enum bnxt_hw_context {
@@ -131,6 +131,7 @@ struct bnxt {
 #define BNXT_FLAG_REGISTERED	(1 << 0)
 #define BNXT_FLAG_VF		(1 << 1)
 #define BNXT_FLAG_PORT_STATS	(1 << 2)
+#define BNXT_FLAG_JUMBO		(1 << 3)
 #define BNXT_PF(bp)		(!((bp)->flags & BNXT_FLAG_VF))
 #define BNXT_VF(bp)		((bp)->flags & BNXT_FLAG_VF)
 #define BNXT_NPAR_ENABLED(bp)	((bp)->port_partition_type)
@@ -233,4 +234,5 @@ struct rte_pmd_bnxt_mb_event_param {
 int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
+#define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
 #endif
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index d13e6cc..f369cf6 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -159,7 +159,8 @@ int bnxt_alloc_def_cp_ring(struct bnxt *bp)
 
 	rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 				  HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-				  0, HWRM_NA_SIGNATURE);
+				  0, HWRM_NA_SIGNATURE,
+				  HWRM_NA_SIGNATURE);
 	if (rc)
 		goto err_out;
 	cpr->cp_doorbell = bp->pdev->mem_resource[2].addr;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index e987732..6197be1 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -199,6 +199,14 @@ static int bnxt_init_chip(struct bnxt *bp)
 	struct rte_eth_link new;
 	int rc;
 
+	if (bp->eth_dev->data->mtu > ETHER_MTU) {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+		bp->flags |= BNXT_FLAG_JUMBO;
+	} else {
+		bp->eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
 	rc = bnxt_alloc_all_hwrm_stat_ctxs(bp);
 	if (rc) {
 		RTE_LOG(ERR, PMD, "HWRM stat ctx alloc failure rc: %x\n", rc);
@@ -1375,6 +1383,56 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
+{
+	struct bnxt *bp = eth_dev->data->dev_private;
+	struct rte_eth_dev_info dev_info;
+	uint32_t max_dev_mtu;
+	uint32_t rc = 0;
+	uint32_t i;
+
+	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 * 2;
+
+	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) {
+		bp->flags |= BNXT_FLAG_JUMBO;
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 1;
+	} else {
+		eth_dev->data->dev_conf.rxmode.jumbo_frame = 0;
+		bp->flags &= ~BNXT_FLAG_JUMBO;
+	}
+
+	eth_dev->data->dev_conf.rxmode.max_rx_pkt_len =
+		new_mtu + ETHER_HDR_LEN + ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+
+	eth_dev->data->mtu = new_mtu;
+	RTE_LOG(INFO, PMD, "New MTU is %d\n", eth_dev->data->mtu);
+
+	for (i = 0; i < bp->nr_vnics; i++) {
+		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+		vnic->mru = bp->eth_dev->data->mtu + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + VLAN_TAG_SIZE * 2;
+		rc = bnxt_hwrm_vnic_cfg(bp, vnic);
+		if (rc)
+			break;
+
+		rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+		if (rc)
+			return rc;
+	}
+
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1410,6 +1468,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
 	.xstats_get_names = bnxt_dev_xstats_get_names_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 22e18d6..eb4f540 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -665,20 +665,20 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp)
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id)
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id)
 {
 	int rc = 0;
+	uint32_t enables = 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);
+	req.length = rte_cpu_to_le_32(ring->ring_size);
 
 	switch (ring_type) {
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_TX:
@@ -686,12 +686,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		/* FALLTHROUGH */
 	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.cmpl_ring_id = rte_cpu_to_le_16(cmpl_ring_id);
 		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);
+		if (stats_ctx_id != INVALID_STATS_CTX_ID)
+			enables |=
+			HWRM_RING_ALLOC_INPUT_ENABLES_STAT_CTX_ID_VALID;
 		break;
 	case HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL:
 		req.ring_type = ring_type;
@@ -700,13 +699,13 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 		 * 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:
 		RTE_LOG(ERR, PMD, "hwrm alloc invalid ring type %d\n",
 			ring_type);
 		return -1;
 	}
+	req.enables = rte_cpu_to_le_32(enables);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -837,8 +836,8 @@ 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 int idx)
+int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_alloc_input req = {.req_type = 0 };
@@ -857,13 +856,12 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 	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_ctx_free(struct bnxt *bp,
-			    struct bnxt_cp_ring_info *cpr, unsigned int idx)
+int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	int rc;
 	struct hwrm_stat_ctx_free_input req = {.req_type = 0 };
@@ -878,9 +876,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 
 	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;
 }
 
@@ -891,15 +886,10 @@ int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	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;
-		}
+	RTE_LOG(DEBUG, PMD, "Alloc VNIC. Start %x, End %x\n",
+		vnic->start_grp_id, vnic->end_grp_id);
+	for (i = vnic->start_grp_id, j = 0; i <= vnic->end_grp_id; i++, j++)
 		vnic->fw_grp_ids[j] = bp->grp_info[i].fw_grp_id;
-	}
 	vnic->dflt_ring_grp = bp->grp_info[vnic->start_grp_id].fw_grp_id;
 	vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
 	vnic->cos_rule = (uint16_t)HWRM_NA_SIGNATURE;
@@ -1151,6 +1141,39 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic)
+{
+	int rc = 0;
+	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t size;
+
+	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
+
+	req.flags = rte_cpu_to_le_32(
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
+			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
+//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+	req.enables = rte_cpu_to_le_32(
+		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
+//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
+
+	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
+	size -= RTE_PKTMBUF_HEADROOM;
+
+	req.jumbo_thresh = rte_cpu_to_le_16(size);
+//	req.hds_threshold = rte_cpu_to_le_16(size);
+	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1209,14 +1232,20 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
 	struct bnxt_cp_ring_info *cpr;
 
 	for (i = 0; i < bp->rx_cp_nr_rings + bp->tx_cp_nr_rings; i++) {
-		unsigned int 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);
+			rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
+			cpr->hw_stats_ctx_id = HWRM_NA_SIGNATURE;
+			/*
+			 * TODO. Need a better way to reset grp_info.stats_ctx
+			 * for Rx rings only. stats_ctx is not saved for Tx
+			 * in grp_info.
+			 */
+			bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 			if (rc)
 				return rc;
 		}
@@ -1233,7 +1262,6 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 		struct bnxt_tx_queue *txq;
 		struct bnxt_rx_queue *rxq;
 		struct bnxt_cp_ring_info *cpr;
-		unsigned int idx = i + 1;
 
 		if (i >= bp->rx_cp_nr_rings) {
 			txq = bp->tx_queues[i - bp->rx_cp_nr_rings];
@@ -1243,7 +1271,7 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 			cpr = rxq->cp_ring;
 		}
 
-		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, idx);
+		rc = bnxt_hwrm_stat_ctx_alloc(bp, cpr, i);
 
 		if (rc)
 			return rc;
@@ -1253,11 +1281,10 @@ int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp)
 
 int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
 {
-	uint16_t i;
+	uint16_t idx;
 	uint32_t rc = 0;
 
-	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int idx = i + 1;
+	for (idx = 0; idx < bp->rx_cp_nr_rings; idx++) {
 
 		if (bp->grp_info[idx].fw_grp_id == INVALID_HW_RING_ID) {
 			RTE_LOG(ERR, PMD,
@@ -1274,8 +1301,8 @@ 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 int idx)
+static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
+				unsigned int idx __rte_unused)
 {
 	struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
@@ -1313,8 +1340,10 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 			txr->tx_prod = 0;
 			txr->tx_cons = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
@@ -1336,17 +1365,26 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp)
 					rxr->rx_ring_struct->ring_size *
 					sizeof(*rxr->rx_buf_ring));
 			rxr->rx_prod = 0;
+			memset(rxr->ag_buf_ring, 0,
+					rxr->ag_ring_struct->ring_size *
+					sizeof(*rxr->ag_buf_ring));
+			rxr->ag_prod = 0;
 		}
-		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, idx);
+			bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID;
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	/* 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)
+		if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
 			bnxt_free_cp_ring(bp, cpr, 0);
+			cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID;
+		}
 	}
 
 	return rc;
@@ -1358,14 +1396,7 @@ int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp)
 	uint32_t rc = 0;
 
 	for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-		unsigned int 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);
-
+		rc = bnxt_hwrm_ring_grp_alloc(bp, i);
 		if (rc)
 			return rc;
 	}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index c15404f..79b27ee 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -70,7 +70,7 @@ int bnxt_hwrm_queue_qportcfg(struct bnxt *bp);
 int bnxt_hwrm_ring_alloc(struct bnxt *bp,
 			 struct bnxt_ring *ring,
 			 uint32_t ring_type, uint32_t map_index,
-			 uint32_t stats_ctx_id);
+			 uint32_t stats_ctx_id, uint32_t cmpl_ring_id);
 int bnxt_hwrm_ring_free(struct bnxt *bp,
 			struct bnxt_ring *ring, uint32_t ring_type);
 int bnxt_hwrm_ring_grp_alloc(struct bnxt *bp, unsigned int idx);
@@ -93,6 +93,8 @@ 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_hwrm_vnic_plcmode_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);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 5e4236a..a12c0aa 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -115,8 +115,15 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 	int rx_vmem_len = rx_ring_info ?
 		RTE_CACHE_LINE_ROUNDUP(rx_ring_info->
 						rx_ring_struct->vmem_size) : 0;
+	int ag_vmem_start = 0;
+	int ag_vmem_len = 0;
+	int cp_ring_start =  0;
+
+	ag_vmem_start = rx_vmem_start + rx_vmem_len;
+	ag_vmem_len = rx_ring_info ? RTE_CACHE_LINE_ROUNDUP(
+				rx_ring_info->ag_ring_struct->vmem_size) : 0;
+	cp_ring_start = ag_vmem_start + ag_vmem_len;
 
-	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));
 
@@ -131,6 +138,10 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		sizeof(struct rx_prod_pkt_bd)) : 0;
 
 	int total_alloc_len = rx_ring_start + rx_ring_len;
+	int ag_ring_start = 0;
+
+	ag_ring_start = rx_ring_start + rx_ring_len;
+	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -201,6 +212,24 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->rx_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring = rx_ring_info->ag_ring_struct;
+
+		rx_ring->bd = ((char *)mz->addr + ag_ring_start);
+		rx_ring_info->ag_desc_ring =
+		    (struct rx_prod_pkt_bd *)rx_ring->bd;
+		rx_ring->bd_dma = mz->phys_addr + ag_ring_start;
+		rx_ring_info->ag_desc_mapping = rx_ring->bd_dma;
+		rx_ring->mem_zone = (const void *)mz;
+
+		if (!rx_ring->bd)
+			return -ENOMEM;
+		if (rx_ring->vmem_size) {
+			rx_ring->vmem =
+			    (void **)((char *)mz->addr + ag_vmem_start);
+			rx_ring_info->ag_buf_ring =
+			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
+		}
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
@@ -239,35 +268,64 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
 		struct bnxt_ring *ring = rxr->rx_ring_struct;
 		unsigned int idx = i + 1;
+		unsigned int map_idx = idx + bp->rx_cp_nr_rings;
+
+		bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id;
 
 		/* Rx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 		cpr->cp_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id;
+		bp->grp_info[i].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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 		rxr->rx_prod = 0;
 		rxr->rx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
-		bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id;
+		bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id;
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+
+		ring = rxr->ag_ring_struct;
+		/* Agg ring */
+		if (ring == NULL)
+			RTE_LOG(ERR, PMD, "Alloc AGG Ring is NULL!\n");
+
+		rc = bnxt_hwrm_ring_alloc(bp, ring,
+				HWRM_RING_ALLOC_INPUT_RING_TYPE_RX,
+				map_idx, HWRM_NA_SIGNATURE,
+				cp_ring->fw_ring_id);
+		if (rc)
+			goto err_out;
+		RTE_LOG(DEBUG, PMD, "Alloc AGG Done!\n");
+		rxr->ag_prod = 0;
+		rxr->ag_doorbell =
+		    (char *)pci_dev->mem_resource[2].addr +
+		    map_idx * 0x80;
+		bp->grp_info[i].ag_fw_ring_id = ring->fw_ring_id;
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+
+		rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN +
+					ETHER_CRC_LEN + (2 * VLAN_TAG_SIZE);
 		if (bnxt_init_one_rx_ring(rxq)) {
 			RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!\n");
 			bnxt_rx_queue_release_op(rxq);
 			return -ENOMEM;
 		}
 		B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+		B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
+		rxq->index = idx;
 	}
 
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
@@ -276,29 +334,34 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp)
 		struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 		struct bnxt_tx_ring_info *txr = txq->tx_ring;
 		struct bnxt_ring *ring = txr->tx_ring_struct;
-		unsigned int idx = 1 + bp->rx_cp_nr_rings + i;
+		unsigned int idx = i + 1 + bp->rx_cp_nr_rings;
+
+		/* Account for AGG Rings. AGG ring cnt = Rx Cmpl ring cnt */
+		idx += bp->rx_cp_nr_rings;
 
 		/* Tx cmpl */
 		rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
 					HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL,
-					idx, HWRM_NA_SIGNATURE);
+					idx, HWRM_NA_SIGNATURE,
+					HWRM_NA_SIGNATURE);
 		if (rc)
 			goto err_out;
 
 		cpr->cp_doorbell = (char *)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);
+					idx, cpr->hw_stats_ctx_id,
+					cp_ring->fw_ring_id);
 		if (rc)
 			goto err_out;
 
 		txr->tx_doorbell = (char *)pci_dev->mem_resource[2].addr +
 		    idx * 0x80;
+		txq->index = idx;
 	}
 
 err_out:
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index 8656549..b5bd287 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -58,6 +58,7 @@
 #define DEFAULT_TX_RING_SIZE	256
 
 #define MAX_TPA		128
+#define AGG_RING_SIZE_FACTOR 2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
@@ -65,6 +66,7 @@
 #define MAX_CP_DESC_CNT (16 * 1024)
 
 #define INVALID_HW_RING_ID      ((uint16_t)-1)
+#define INVALID_STATS_CTX_ID		((uint16_t)-1)
 
 struct bnxt_ring {
 	void			*bd;
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 7625fb1..0d7d708 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -84,9 +84,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 		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;
+		vnic->start_grp_id = 0;
+		vnic->end_grp_id = vnic->start_grp_id;
 		filter = bnxt_alloc_filter(bp);
 		if (!filter) {
 			RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -126,8 +125,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			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;
+		start_grp_id = 0;
+		end_grp_id = nb_q_per_grp;
 
 		ring_idx = 0;
 		for (i = 0; i < pools; i++) {
@@ -188,9 +187,8 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 
 	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;
+	vnic->start_grp_id = 0;
+	vnic->end_grp_id = bp->rx_cp_nr_rings;
 	filter = bnxt_alloc_filter(bp);
 	if (!filter) {
 		RTE_LOG(ERR, PMD, "L2 filter alloc failed\n");
@@ -228,6 +226,16 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 				}
 			}
 		}
+		/* Free up mbufs in Agg ring */
+		sw_ring = rxq->rx_ring->ag_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;
+				}
+			}
+		}
 	}
 }
 
@@ -251,6 +259,8 @@ void bnxt_rx_queue_release_op(void *rx_queue)
 
 		/* Free RX ring hardware descriptors */
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
+		/* Free RX Agg ring hardware descriptors */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
 
 		/* Free RX completion ring hardware descriptors */
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -295,6 +305,9 @@ 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;
 
+	RTE_LOG(DEBUG, PMD, "RX Buf size is %d\n", rxq->rx_buf_use_size);
+	RTE_LOG(DEBUG, PMD, "RX Buf MTU %d\n", eth_dev->data->mtu);
+
 	rc = bnxt_init_rx_ring_struct(rxq, socket_id);
 	if (rc)
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 9554329..0695214 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -52,6 +52,7 @@ struct bnxt_rx_queue {
 	uint8_t			crc_len; /* 0 if CRC stripped, 4 otherwise */
 
 	struct bnxt		*bp;
+	int			index;
 	struct bnxt_vnic_info	*vnic;
 
 	uint32_t			rx_buf_size;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 5d93de2..04ac673 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -77,6 +77,32 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
+static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
+				     struct bnxt_rx_ring_info *rxr,
+				     uint16_t prod)
+{
+	struct rx_prod_pkt_bd *rxbd = &rxr->ag_desc_ring[prod];
+	struct bnxt_sw_rx_bd *rx_buf = &rxr->ag_buf_ring[prod];
+	struct rte_mbuf *data;
+
+	data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	if (!data)
+		return -ENOMEM;
+
+	if (rxbd == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
+	if (rx_buf == NULL)
+		RTE_LOG(ERR, PMD, "Jumbo Frame. rx_buf is NULL\n");
+
+
+	rx_buf->mbuf = data;
+
+	rxbd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(rx_buf->mbuf));
+
+	return 0;
+}
+
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -94,6 +120,24 @@ static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 	prod_bd->addr = cons_bd->addr;
 }
 
+static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+			       struct rte_mbuf *mbuf)
+{
+	uint16_t prod = rxr->ag_prod;
+	struct bnxt_sw_rx_bd *prod_rx_buf;
+	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+
+	prod_rx_buf = &rxr->ag_buf_ring[prod];
+
+	prod_rx_buf->mbuf = mbuf;
+
+	prod_bd = &rxr->ag_desc_ring[prod];
+	cons_bd = &rxr->ag_desc_ring[cons];
+
+	prod_bd->addr = cons_bd->addr;
+}
+#endif
+
 static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 			    struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -104,9 +148,12 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+	uint16_t ag_cons, ag_prod = rxr->ag_prod;
 	struct bnxt_sw_rx_bd *rx_buf;
 	struct rte_mbuf *mbuf;
 	int rc = 0;
+	uint8_t i;
+	uint8_t agg_buf = 0;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -126,6 +173,9 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	mbuf = rx_buf->mbuf;
 	rte_prefetch0(mbuf);
 
+	if (mbuf == NULL)
+		return -ENOMEM;
+
 	mbuf->nb_segs = 1;
 	mbuf->next = NULL;
 	mbuf->pkt_len = rxcmp->len;
@@ -139,6 +189,63 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->hash.fdir.id = rxcmp1->cfa_code;
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf) {
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
+			       cpr->cp_ring_struct))
+			return -EBUSY;
+		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
+			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
+	}
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+		ag_cons = rxcmp->opaque;
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		ag_mbuf->nb_segs = 1;
+		ag_mbuf->data_len = rxcmp->len;
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+		if (mbuf->next == NULL) {
+			mbuf->next = ag_mbuf;
+		} else {
+			struct rte_mbuf *temp_mbuf = mbuf;
+
+			while (temp_mbuf->next != NULL)
+				temp_mbuf = temp_mbuf->next;
+			temp_mbuf->next = ag_mbuf;
+		}
+		ag_buf->mbuf = NULL;
+
+		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
+		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n",
+				ag_prod);
+			rc = -ENOMEM;
+		}
+		rxr->ag_prod = ag_prod;
+
+#ifdef BNXT_DEBUG
+		if (!CMP_VALID((struct cmpl_base *)
+			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
+			cpr->cp_ring_struct))
+			return -EBUSY;
+#endif
+	}
+
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
 			(RX_PKT_CMPL_METADATA_VID_MASK |
@@ -148,13 +255,17 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	}
 
 	rx_buf->mbuf = NULL;
+#ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
 		bnxt_reuse_rx_mbuf(rxr, cons, mbuf);
+		if (agg_buf)
+			bnxt_reuse_ag_mbuf(rxr, ag_cons, mbuf);
 
 		rc = -EIO;
 		goto next_rx;
 	}
+#endif
 	/*
 	 * TODO: Redesign this....
 	 * If the allocation fails, the packet does not get received.
@@ -170,24 +281,23 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 * calls in favour of a tight loop with the same function being called
 	 * in it.
 	 */
+	prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	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;
+		//goto next_rx;
 	}
-
+	rxr->rx_prod = prod;
 	/*
 	 * 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;
+#ifdef BNXT_DEBUG
 next_rx:
-	rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
+#endif
+	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -203,8 +313,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	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;
+	uint16_t prod = rxr->rx_prod;
+	uint16_t ag_prod = rxr->ag_prod;
 
 	/* Handle RX burst request */
 	while (1) {
@@ -224,13 +335,13 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 				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) {
+
+	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
 		 * the doorbell if there are no new completions
@@ -240,8 +351,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **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);
+	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
+	/* Ring the AGG ring DB */
+	B_RX_DB(rxr->ag_doorbell, rxr->ag_prod);
 	return nb_rx_pkts;
 }
 
@@ -257,6 +369,12 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 		bnxt_free_ring(rxq->rx_ring->rx_ring_struct);
 		rte_free(rxq->rx_ring->rx_ring_struct);
+
+		/* Free the Aggregator ring */
+		bnxt_free_ring(rxq->rx_ring->ag_ring_struct);
+		rte_free(rxq->rx_ring->ag_ring_struct);
+		rxq->rx_ring->ag_ring_struct = NULL;
+
 		rte_free(rxq->rx_ring);
 
 		bnxt_free_ring(rxq->cp_ring->cp_ring_struct);
@@ -270,13 +388,11 @@ void bnxt_free_rx_rings(struct bnxt *bp)
 
 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;
 	struct bnxt_rx_ring_info *rxr;
 	struct bnxt_ring *ring;
 
-	rxq->rx_buf_use_size = bp->eth_dev->data->mtu +
-			       ETHER_HDR_LEN + ETHER_CRC_LEN +
+	rxq->rx_buf_use_size = BNXT_MAX_MTU + ETHER_HDR_LEN + ETHER_CRC_LEN +
 			       (2 * VLAN_TAG_SIZE);
 	rxq->rx_buf_size = rxq->rx_buf_use_size + sizeof(struct rte_mbuf);
 
@@ -313,13 +429,29 @@ int bnxt_init_rx_ring_struct(struct bnxt_rx_queue *rxq, unsigned int socket_id)
 	if (ring == NULL)
 		return -ENOMEM;
 	cpr->cp_ring_struct = ring;
-	ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	ring->ring_size = rte_align32pow2(rxr->rx_ring_struct->ring_size *
+					  (2 + AGG_RING_SIZE_FACTOR));
 	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;
 
+	/* Allocate Aggregator rings */
+	ring = rte_zmalloc_socket("bnxt_rx_ring_struct",
+				   sizeof(struct bnxt_ring),
+				   RTE_CACHE_LINE_SIZE, socket_id);
+	if (ring == NULL)
+		return -ENOMEM;
+	rxr->ag_ring_struct = ring;
+	ring->ring_size = rte_align32pow2(rxq->nb_rx_desc *
+					  AGG_RING_SIZE_FACTOR);
+	ring->ring_mask = ring->ring_size - 1;
+	ring->bd = (void *)rxr->ag_desc_ring;
+	ring->bd_dma = rxr->ag_desc_mapping;
+	ring->vmem_size = ring->ring_size * sizeof(struct bnxt_sw_rx_bd);
+	ring->vmem = (void **)&rxr->ag_buf_ring;
+
 	return 0;
 }
 
@@ -332,8 +464,8 @@ static void bnxt_init_rxbds(struct bnxt_ring *ring, uint32_t type,
 	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].flags_type = rte_cpu_to_le_16(type);
+		rx_bd_ring[j].len = rte_cpu_to_le_16(len);
 		rx_bd_ring[j].opaque = j;
 	}
 }
@@ -344,12 +476,17 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	struct bnxt_ring *ring;
 	uint32_t prod, type;
 	unsigned int i;
+	uint16_t size;
+
+	size = rte_pktmbuf_data_room_size(rxq->mb_pool) - RTE_PKTMBUF_HEADROOM;
+	if (rxq->rx_buf_use_size <= size)
+		size = rxq->rx_buf_use_size;
 
-	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT | RX_PROD_PKT_BD_FLAGS_EOP_PAD;
+	type = RX_PROD_PKT_BD_TYPE_RX_PROD_PKT;
 
 	rxr = rxq->rx_ring;
 	ring = rxr->rx_ring_struct;
-	bnxt_init_rxbds(ring, type, rxq->rx_buf_use_size);
+	bnxt_init_rxbds(ring, type, size);
 
 	prod = rxr->rx_prod;
 	for (i = 0; i < ring->ring_size; i++) {
@@ -362,6 +499,24 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		rxr->rx_prod = prod;
 		prod = RING_NEXT(rxr->rx_ring_struct, prod);
 	}
+	RTE_LOG(DEBUG, PMD, "%s\n", __func__);
+
+	ring = rxr->ag_ring_struct;
+	type = RX_PROD_AGG_BD_TYPE_RX_PROD_AGG;
+	bnxt_init_rxbds(ring, type, size);
+	prod = rxr->ag_prod;
+
+	for (i = 0; i < ring->ring_size; i++) {
+		if (bnxt_alloc_ag_data(rxq, rxr, prod) != 0) {
+			RTE_LOG(WARNING, PMD,
+			"init'ed AG ring %d with %d/%d mbufs only\n",
+			rxq->queue_id, i, ring->ring_size);
+			break;
+		}
+		rxr->ag_prod = prod;
+		prod = RING_NEXT(rxr->ag_ring_struct, prod);
+	}
+	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index f766b26..e104fbd 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -43,14 +43,20 @@ struct bnxt_sw_rx_bd {
 
 struct bnxt_rx_ring_info {
 	uint16_t		rx_prod;
+	uint16_t		ag_prod;
 	void			*rx_doorbell;
+	void			*ag_doorbell;
 
 	struct rx_prod_pkt_bd	*rx_desc_ring;
+	struct rx_prod_pkt_bd	*ag_desc_ring;
 	struct bnxt_sw_rx_bd	*rx_buf_ring; /* sw ring */
+	struct bnxt_sw_rx_bd	*ag_buf_ring; /* sw ring */
 
 	phys_addr_t		rx_desc_mapping;
+	phys_addr_t		ag_desc_mapping;
 
 	struct bnxt_ring	*rx_ring_struct;
+	struct bnxt_ring	*ag_ring_struct;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 518f16d..2fcfce6 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -7252,7 +7252,6 @@ struct hwrm_vnic_tpa_cfg_output {
 	 */
 } __attribute__((packed));
 
-
 /* hwrm_ring_alloc */
 /*
  * Description: This command allocates and does basic preparation for a ring.
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 13/26] net/bnxt: add support for LRO
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (11 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 12/26] net/bnxt: add support to set MTU Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
                               ` (13 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

This patch adds support to enable and disable LRO
To support this feature, the driver creates an aggregrator ring.
When the hardware starts doing LRO, it sends a tpa_start completion.
When the driver receives a tpa_end completion, it indicates that the
LRO chaining is complete.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 doc/guides/nics/features/bnxt.ini |   1 +
 drivers/net/bnxt/bnxt_ethdev.c    |   7 +
 drivers/net/bnxt/bnxt_hwrm.c      |  44 +++++-
 drivers/net/bnxt/bnxt_hwrm.h      |   2 +
 drivers/net/bnxt/bnxt_ring.c      |  32 +++-
 drivers/net/bnxt/bnxt_ring.h      |   4 +-
 drivers/net/bnxt/bnxt_rxq.c       |  12 ++
 drivers/net/bnxt/bnxt_rxq.h       |   2 +
 drivers/net/bnxt/bnxt_rxr.c       | 315 +++++++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_rxr.h       |  40 +++++
 10 files changed, 374 insertions(+), 85 deletions(-)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 066cb01..4fd8abb 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -19,6 +19,7 @@ SR-IOV               = Y
 FW version           = Y
 Jumbo frame          = Y
 MTU update           = Y
+LRO                  = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 6197be1..8f8024c 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -286,6 +286,13 @@ static int bnxt_init_chip(struct bnxt *bp)
 				goto err_out;
 			}
 		}
+
+		bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
+
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 1);
+		else
+			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
 	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
 	if (rc) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index eb4f540..dc4bb1b 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1152,19 +1152,15 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
 
 	req.flags = rte_cpu_to_le_32(
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
 			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
-//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
+
 	req.enables = rte_cpu_to_le_32(
 		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
-//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
 
 	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
 	size -= RTE_PKTMBUF_HEADROOM;
 
 	req.jumbo_thresh = rte_cpu_to_le_16(size);
-//	req.hds_threshold = rte_cpu_to_le_16(size);
 	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
@@ -1174,6 +1170,41 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	return rc;
 }
 
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			struct bnxt_vnic_info *vnic, bool enable)
+{
+	int rc = 0;
+	struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
+	struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_TPA_CFG, -1, resp);
+
+	if (enable) {
+		req.enables = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGG_SEGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MAX_AGGS |
+				HWRM_VNIC_TPA_CFG_INPUT_ENABLES_MIN_AGG_LEN);
+		req.flags = rte_cpu_to_le_32(
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_ENCAP_TPA |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_RSC_WND_UPDATE |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
+				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
+			HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
+		req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
+		req.max_agg_segs = rte_cpu_to_le_16(5);
+		req.max_aggs =
+			rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+		req.min_agg_len = rte_cpu_to_le_32(512);
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 {
 	struct hwrm_func_cfg_input req = {0};
@@ -1493,6 +1524,9 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 		bnxt_clear_hwrm_vnic_filters(bp, vnic);
 
 		bnxt_hwrm_vnic_ctx_free(bp, vnic);
+
+		bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
+
 		bnxt_hwrm_vnic_free(bp, vnic);
 	}
 	/* Ring resources */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 79b27ee..6ce0bc3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -95,6 +95,8 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 			   struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 				struct bnxt_vnic_info *vnic);
+int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
+			   struct bnxt_vnic_info *vnic, bool enable);
 
 int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp);
 int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index a12c0aa..9d0ae27 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -31,6 +31,7 @@
  *   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#include <rte_bitmap.h>
 #include <rte_memzone.h>
 #include <unistd.h>
 
@@ -137,11 +138,23 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 		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;
-	int ag_ring_start = 0;
+	int ag_ring_start = rx_ring_start + rx_ring_len;
+	int ag_ring_len = rx_ring_len * AGG_RING_SIZE_FACTOR;
 
-	ag_ring_start = rx_ring_start + rx_ring_len;
-	total_alloc_len = ag_ring_start + rx_ring_len * AGG_RING_SIZE_FACTOR;
+	int ag_bitmap_start = ag_ring_start + ag_ring_len;
+	int ag_bitmap_len =  rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(rte_bitmap_get_memory_footprint(
+			rx_ring_info->rx_ring_struct->ring_size *
+			AGG_RING_SIZE_FACTOR)) : 0;
+
+	int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
+	int tpa_info_len = rx_ring_info ?
+		RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
+				       sizeof(struct bnxt_tpa_info)) : 0;
+
+	int total_alloc_len = tpa_info_start;
+	if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+		total_alloc_len += tpa_info_len;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
@@ -230,6 +243,17 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			rx_ring_info->ag_buf_ring =
 			    (struct bnxt_sw_rx_bd *)rx_ring->vmem;
 		}
+
+		rx_ring_info->ag_bitmap =
+		    rte_bitmap_init(rx_ring_info->rx_ring_struct->ring_size *
+				    AGG_RING_SIZE_FACTOR, (uint8_t *)mz->addr +
+				    ag_bitmap_start, ag_bitmap_len);
+
+		/* TPA info */
+		if (bp->eth_dev->data->dev_conf.rxmode.enable_lro)
+			rx_ring_info->tpa_info =
+				((struct bnxt_tpa_info *)((char *)mz->addr +
+							  tpa_info_start));
 	}
 
 	cp_ring->bd = ((char *)mz->addr + cp_ring_start);
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index b5bd287..6d1eb58 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -57,8 +57,8 @@
 #define DEFAULT_RX_RING_SIZE	256
 #define DEFAULT_TX_RING_SIZE	256
 
-#define MAX_TPA		128
-#define AGG_RING_SIZE_FACTOR 2
+#define BNXT_TPA_MAX		64
+#define AGG_RING_SIZE_FACTOR	2
 
 /* These assume 4k pages */
 #define MAX_RX_DESC_CNT (8 * 1024)
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 0d7d708..d8b970e 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -214,6 +214,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 {
 	struct bnxt_sw_rx_bd *sw_ring;
+	struct bnxt_tpa_info *tpa_info;
 	uint16_t i;
 
 	if (rxq) {
@@ -236,6 +237,17 @@ static void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 				}
 			}
 		}
+
+		/* Free up mbufs in TPA */
+		tpa_info = rxq->rx_ring->tpa_info;
+		if (tpa_info) {
+			for (i = 0; i < BNXT_TPA_MAX; i++) {
+				if (tpa_info[i].mbuf) {
+					rte_pktmbuf_free_seg(tpa_info[i].mbuf);
+					tpa_info[i].mbuf = NULL;
+				}
+			}
+		}
 	}
 }
 
diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index 0695214..01aaa00 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -59,6 +59,8 @@ struct bnxt_rx_queue {
 	uint32_t			rx_buf_use_size;  /* useable size */
 	struct bnxt_rx_ring_info	*rx_ring;
 	struct bnxt_cp_ring_info	*cp_ring;
+
+	struct bnxt_tpa_info		*rx_tpa;
 };
 
 void bnxt_free_rxq_stats(struct bnxt_rx_queue *rxq);
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 04ac673..1f0afcb 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -34,6 +34,7 @@
 #include <inttypes.h>
 #include <stdbool.h>
 
+#include <rte_bitmap.h>
 #include <rte_byteorder.h>
 #include <rte_malloc.h>
 #include <rte_memory.h>
@@ -102,24 +103,28 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	return 0;
 }
 
-#ifdef BNXT_DEBUG
-static void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
+static inline void bnxt_reuse_rx_mbuf(struct bnxt_rx_ring_info *rxr,
 			       struct rte_mbuf *mbuf)
 {
-	uint16_t prod = rxr->rx_prod;
+	uint16_t prod = RING_NEXT(rxr->rx_ring_struct, rxr->rx_prod);
 	struct bnxt_sw_rx_bd *prod_rx_buf;
-	struct rx_prod_pkt_bd *prod_bd, *cons_bd;
+	struct rx_prod_pkt_bd *prod_bd;
 
 	prod_rx_buf = &rxr->rx_buf_ring[prod];
 
+	RTE_ASSERT(prod_rx_buf->mbuf == NULL);
+	RTE_ASSERT(mbuf != NULL);
+
 	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;
+	prod_bd->addr = rte_cpu_to_le_64(RTE_MBUF_DATA_DMA_ADDR(mbuf));
+
+	rxr->rx_prod = prod;
 }
 
+#ifdef BNXT_DEBUG
 static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 			       struct rte_mbuf *mbuf)
 {
@@ -138,7 +143,192 @@ static void bnxt_reuse_ag_mbuf(struct bnxt_rx_ring_info *rxr, uint16_t cons,
 }
 #endif
 
-static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
+static inline
+struct rte_mbuf *bnxt_consume_rx_buf(struct bnxt_rx_ring_info *rxr,
+				     uint16_t cons)
+{
+	struct bnxt_sw_rx_bd *cons_rx_buf;
+	struct rte_mbuf *mbuf;
+
+	cons_rx_buf = &rxr->rx_buf_ring[cons];
+	RTE_ASSERT(cons_rx_buf->mbuf != NULL);
+	mbuf = cons_rx_buf->mbuf;
+	cons_rx_buf->mbuf = NULL;
+	return mbuf;
+}
+
+static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
+			   struct rx_tpa_start_cmpl *tpa_start,
+			   struct rx_tpa_start_cmpl_hi *tpa_start1)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
+		RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+	uint16_t data_cons;
+	struct bnxt_tpa_info *tpa_info;
+	struct rte_mbuf *mbuf;
+
+	data_cons = tpa_start->opaque;
+	tpa_info = &rxr->tpa_info[agg_id];
+
+	mbuf = bnxt_consume_rx_buf(rxr, data_cons);
+
+	bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
+
+	tpa_info->mbuf = mbuf;
+	tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
+
+	mbuf->nb_segs = 1;
+	mbuf->next = NULL;
+	mbuf->pkt_len = rte_le_to_cpu_32(tpa_start->len);
+	mbuf->data_len = mbuf->pkt_len;
+	mbuf->port = rxq->port_id;
+	mbuf->ol_flags = PKT_RX_LRO;
+	if (likely(tpa_start->flags_type &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS_RSS_VALID))) {
+		mbuf->hash.rss = rte_le_to_cpu_32(tpa_start->rss_hash);
+		mbuf->ol_flags |= PKT_RX_RSS_HASH;
+	} else {
+		mbuf->hash.fdir.id = rte_le_to_cpu_16(tpa_start1->cfa_code);
+		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
+	}
+	if (tpa_start1->flags2 &
+	    rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_META_FORMAT_VLAN)) {
+		mbuf->vlan_tci = rte_le_to_cpu_32(tpa_start1->metadata);
+		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
+	}
+	if (likely(tpa_start1->flags2 &
+		   rte_cpu_to_le_32(RX_TPA_START_CMPL_FLAGS2_L4_CS_CALC)))
+		mbuf->ol_flags |= PKT_RX_L4_CKSUM_GOOD;
+
+	/* recycle next mbuf */
+	data_cons = RING_NEXT(rxr->rx_ring_struct, data_cons);
+	bnxt_reuse_rx_mbuf(rxr, bnxt_consume_rx_buf(rxr, data_cons));
+}
+
+static int bnxt_agg_bufs_valid(struct bnxt_cp_ring_info *cpr,
+		uint8_t agg_bufs, uint32_t raw_cp_cons)
+{
+	uint16_t last_cp_cons;
+	struct rx_pkt_cmpl *agg_cmpl;
+
+	raw_cp_cons = ADV_RAW_CMP(raw_cp_cons, agg_bufs);
+	last_cp_cons = RING_CMP(cpr->cp_ring_struct, raw_cp_cons);
+	agg_cmpl = (struct rx_pkt_cmpl *)&cpr->cp_desc_ring[last_cp_cons];
+	return CMP_VALID(agg_cmpl, raw_cp_cons, cpr->cp_ring_struct);
+}
+
+/* TPA consume agg buffer out of order, allocate connected data only */
+static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t next = RING_NEXT(rxr->ag_ring_struct, rxr->ag_prod);
+
+	/* TODO batch allocation for better performance */
+	while (rte_bitmap_get(rxr->ag_bitmap, next)) {
+		if (unlikely(bnxt_alloc_ag_data(rxq, rxr, next))) {
+			RTE_LOG(ERR, PMD,
+				"agg mbuf alloc failed: prod=0x%x\n", next);
+			break;
+		}
+		rte_bitmap_clear(rxr->ag_bitmap, next);
+		rxr->ag_prod = next;
+		next = RING_NEXT(rxr->ag_ring_struct, next);
+	}
+
+	return 0;
+}
+
+static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
+			 struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
+			 uint8_t agg_buf)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	int i;
+	uint16_t cp_cons, ag_cons;
+	struct rx_pkt_cmpl *rxcmp;
+	struct rte_mbuf *last = mbuf;
+
+	for (i = 0; i < agg_buf; i++) {
+		struct bnxt_sw_rx_bd *ag_buf;
+		struct rte_mbuf *ag_mbuf;
+		*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+		cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+		rxcmp = (struct rx_pkt_cmpl *)
+					&cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+		bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+		ag_cons = rxcmp->opaque;
+		RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = ag_buf->mbuf;
+		RTE_ASSERT(ag_mbuf != NULL);
+
+		ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
+
+		mbuf->nb_segs++;
+		mbuf->pkt_len += ag_mbuf->data_len;
+
+		last->next = ag_mbuf;
+		last = ag_mbuf;
+
+		ag_buf->mbuf = NULL;
+
+		/*
+		 * As aggregation buffer consumed out of order in TPA module,
+		 * use bitmap to track freed slots to be allocated and notified
+		 * to NIC
+		 */
+		rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+	}
+	bnxt_prod_ag_mbuf(rxq);
+	return 0;
+}
+
+static inline struct rte_mbuf *bnxt_tpa_end(
+		struct bnxt_rx_queue *rxq,
+		uint32_t *raw_cp_cons,
+		struct rx_tpa_end_cmpl *tpa_end,
+		struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
+			>> RX_TPA_END_CMPL_AGG_ID_SFT;
+	struct rte_mbuf *mbuf;
+	uint8_t agg_bufs;
+	//unsigned int len;
+	struct bnxt_tpa_info *tpa_info;
+
+	tpa_info = &rxr->tpa_info[agg_id];
+	mbuf = tpa_info->mbuf;
+	RTE_ASSERT(mbuf != NULL);
+
+	rte_prefetch0(mbuf);
+	//len = tpa_info->len;
+	agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
+		RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
+	if (agg_bufs) {
+		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+			return NULL;
+		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+	}
+	mbuf->l4_len = tpa_end->payload_offset;
+
+	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
+	RTE_ASSERT(new_data != NULL);
+	if (!new_data)
+		return NULL;
+	tpa_info->mbuf = new_data;
+
+	return mbuf;
+}
+
+static int 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;
@@ -148,12 +338,13 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	uint32_t tmp_raw_cons = *raw_cons;
 	uint16_t cons, prod, cp_cons =
 	    RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-	uint16_t ag_cons, ag_prod = rxr->ag_prod;
-	struct bnxt_sw_rx_bd *rx_buf;
+#ifdef BNXT_DEBUG
+	uint16_t ag_cons;
+#endif
 	struct rte_mbuf *mbuf;
 	int rc = 0;
-	uint8_t i;
 	uint8_t agg_buf = 0;
+	uint16_t cmp_type;
 
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
@@ -165,12 +356,34 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	if (!CMP_VALID(rxcmp1, tmp_raw_cons, cpr->cp_ring_struct))
 		return -EBUSY;
 
+	cmp_type = CMP_TYPE(rxcmp);
+	if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_START) {
+		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
+			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
+		rc = -EINVAL; /* Continue w/o new mbuf */
+		goto next_rx;
+	} else if (cmp_type == RX_PKT_CMPL_TYPE_RX_L2_TPA_END) {
+		mbuf = bnxt_tpa_end(rxq, &tmp_raw_cons,
+				   (struct rx_tpa_end_cmpl *)rxcmp,
+				   (struct rx_tpa_end_cmpl_hi *)rxcmp1);
+		if (unlikely(!mbuf))
+			return -EBUSY;
+		*rx_pkt = mbuf;
+		goto next_rx;
+	} else if (cmp_type != 0x11) {
+		rc = -EINVAL;
+		goto next_rx;
+	}
+
+	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
+			>> RX_PKT_CMPL_AGG_BUFS_SFT;
+	if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+		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;
+	mbuf = bnxt_consume_rx_buf(rxr, cons);
 	rte_prefetch0(mbuf);
 
 	if (mbuf == NULL)
@@ -190,61 +403,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_FDIR | PKT_RX_FDIR_ID;
 	}
 
-	agg_buf = (rxcmp->agg_bufs_v1 & RX_PKT_CMPL_AGG_BUFS_MASK)
-			>> RX_PKT_CMPL_AGG_BUFS_SFT;
-	if (agg_buf) {
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons + agg_buf);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		if (!CMP_VALID(rxcmp, tmp_raw_cons + agg_buf,
-			       cpr->cp_ring_struct))
-			return -EBUSY;
-		RTE_LOG(DEBUG, PMD, "JUMBO Frame %d. %x, agg_buf %x,\n",
-			mbuf->pkt_len, rxcmp->agg_bufs_v1,  agg_buf);
-	}
-
-	for (i = 0; i < agg_buf; i++) {
-		struct bnxt_sw_rx_bd *ag_buf;
-		struct rte_mbuf *ag_mbuf;
-		tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
-		cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
-		rxcmp = (struct rx_pkt_cmpl *)
-					&cpr->cp_desc_ring[cp_cons];
-		ag_cons = rxcmp->opaque;
-		ag_buf = &rxr->ag_buf_ring[ag_cons];
-		ag_mbuf = ag_buf->mbuf;
-		ag_mbuf->nb_segs = 1;
-		ag_mbuf->data_len = rxcmp->len;
-
-		mbuf->nb_segs++;
-		mbuf->pkt_len += ag_mbuf->data_len;
-		if (mbuf->next == NULL) {
-			mbuf->next = ag_mbuf;
-		} else {
-			struct rte_mbuf *temp_mbuf = mbuf;
-
-			while (temp_mbuf->next != NULL)
-				temp_mbuf = temp_mbuf->next;
-			temp_mbuf->next = ag_mbuf;
-		}
-		ag_buf->mbuf = NULL;
-
-		ag_prod = RING_NEXT(rxr->ag_ring_struct, ag_prod);
-		if (bnxt_alloc_ag_data(rxq, rxr, ag_prod)) {
-			RTE_LOG(ERR, PMD,
-				"agg mbuf alloc failed: prod=0x%x\n",
-				ag_prod);
-			rc = -ENOMEM;
-		}
-		rxr->ag_prod = ag_prod;
-
-#ifdef BNXT_DEBUG
-		if (!CMP_VALID((struct cmpl_base *)
-			&cpr->cp_desc_ring[cp_cons], tmp_raw_cons,
-			cpr->cp_ring_struct))
-			return -EBUSY;
-#endif
-	}
+	if (agg_buf)
+		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
 
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
@@ -254,7 +414,6 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_VLAN_PKT;
 	}
 
-	rx_buf->mbuf = NULL;
 #ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
 		/* Re-install the mbuf back to the rx ring */
@@ -294,10 +453,8 @@ static uint16_t bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	 */
 
 	*rx_pkt = mbuf;
-#ifdef BNXT_DEBUG
+
 next_rx:
-#endif
-	//rxr->rx_prod = RING_NEXT(rxr->rx_ring_struct, prod);
 
 	*raw_cons = tmp_raw_cons;
 
@@ -333,7 +490,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
 			if (likely(!rc))
 				nb_rx_pkts++;
-			else if (rc == -EBUSY)	/* partial completion */
+			if (rc == -EBUSY)	/* partial completion */
 				break;
 		}
 		raw_cons = NEXT_RAW_CMP(raw_cons);
@@ -341,6 +498,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			break;
 	}
 
+	cpr->cp_raw_cons = raw_cons;
 	if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) {
 		/*
 		 * For PMD, there is no need to keep on pushing to REARM
@@ -348,7 +506,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		 */
 		return nb_rx_pkts;
 	}
-	cpr->cp_raw_cons = raw_cons;
 
 	B_CP_DIS_DB(cpr, cpr->cp_raw_cons);
 	B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -518,5 +675,15 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	}
 	RTE_LOG(DEBUG, PMD, "%s AGG Done!\n", __func__);
 
+	if (rxr->tpa_info) {
+		for (i = 0; i < BNXT_TPA_MAX; i++) {
+			rxr->tpa_info[i].mbuf =
+				__bnxt_alloc_rx_data(rxq->mb_pool);
+			if (!rxr->tpa_info[i].mbuf)
+				return -ENOMEM;
+		}
+	}
+	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
+
 	return 0;
 }
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index e104fbd..f8d6dc8 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -37,6 +37,39 @@
 #define B_RX_DB(db, prod)						\
 		(*(uint32_t *)db = (DB_KEY_RX | prod))
 
+#define BNXT_TPA_L4_SIZE(x)	\
+	{ \
+		typeof(x) hdr_info = (x); \
+		(((hdr_info) & 0xf8000000) ? ((hdr_info) >> 27) : 32) \
+	}
+
+#define BNXT_TPA_INNER_L3_OFF(hdr_info)	\
+	(((hdr_info) >> 18) & 0x1ff)
+
+#define BNXT_TPA_INNER_L2_OFF(hdr_info)	\
+	(((hdr_info) >> 9) & 0x1ff)
+
+#define BNXT_TPA_OUTER_L3_OFF(hdr_info)	\
+	((hdr_info) & 0x1ff)
+
+enum pkt_hash_types {
+	PKT_HASH_TYPE_NONE,	/* Undefined type */
+	PKT_HASH_TYPE_L2,	/* Input: src_MAC, dest_MAC */
+	PKT_HASH_TYPE_L3,	/* Input: src_IP, dst_IP */
+	PKT_HASH_TYPE_L4,	/* Input: src_IP, dst_IP, src_port, dst_port */
+};
+
+struct bnxt_tpa_info {
+	struct rte_mbuf		*mbuf;
+	uint16_t			len;
+	unsigned short		gso_type;
+	uint32_t			flags2;
+	uint32_t			metadata;
+	enum pkt_hash_types	hash_type;
+	uint32_t			rss_hash;
+	uint32_t			hdr_info;
+};
+
 struct bnxt_sw_rx_bd {
 	struct rte_mbuf		*mbuf; /* data associated with RX descriptor */
 };
@@ -57,6 +90,13 @@ struct bnxt_rx_ring_info {
 
 	struct bnxt_ring	*rx_ring_struct;
 	struct bnxt_ring	*ag_ring_struct;
+
+	/*
+	 * To deal with out of order return from TPA, use free buffer indicator
+	 */
+	struct rte_bitmap	*ag_bitmap;
+
+	struct bnxt_tpa_info *tpa_info;
 };
 
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 14/26] net/bnxt: add rxq/txq info_get
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (12 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 13/26] net/bnxt: add support for LRO Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
                               ` (12 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Add support for txq_info_get and rxq_info_get dev_ops

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 drivers/net/bnxt/bnxt_ethdev.c | 39 +++++++++++++++++++++++++++++++++++++++
 1 file changed, 39 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 8f8024c..d884c7e 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1390,6 +1390,43 @@ bnxt_fw_version_get(struct rte_eth_dev *dev, char *fw_version, size_t fw_size)
 		return 0;
 }
 
+static void
+bnxt_rxq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_rxq_info *qinfo)
+{
+	struct bnxt_rx_queue *rxq;
+
+	rxq = dev->data->rx_queues[queue_id];
+
+	qinfo->mp = rxq->mb_pool;
+	qinfo->scattered_rx = dev->data->scattered_rx;
+	qinfo->nb_desc = rxq->nb_rx_desc;
+
+	qinfo->conf.rx_free_thresh = rxq->rx_free_thresh;
+	qinfo->conf.rx_drop_en = 0;
+	qinfo->conf.rx_deferred_start = 0;
+}
+
+static void
+bnxt_txq_info_get_op(struct rte_eth_dev *dev, uint16_t queue_id,
+	struct rte_eth_txq_info *qinfo)
+{
+	struct bnxt_tx_queue *txq;
+
+	txq = dev->data->tx_queues[queue_id];
+
+	qinfo->nb_desc = txq->nb_tx_desc;
+
+	qinfo->conf.tx_thresh.pthresh = txq->pthresh;
+	qinfo->conf.tx_thresh.hthresh = txq->hthresh;
+	qinfo->conf.tx_thresh.wthresh = txq->wthresh;
+
+	qinfo->conf.tx_free_thresh = txq->tx_free_thresh;
+	qinfo->conf.tx_rs_thresh = 0;
+	qinfo->conf.txq_flags = txq->txq_flags;
+	qinfo->conf.tx_deferred_start = txq->tx_deferred_start;
+}
+
 static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 {
 	struct bnxt *bp = eth_dev->data->dev_private;
@@ -1482,6 +1519,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.xstats_reset = bnxt_dev_xstats_reset_op,
 	.fw_version_get = bnxt_fw_version_get,
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
+	.rxq_info_get = bnxt_rxq_info_get_op,
+	.txq_info_get = bnxt_txq_info_get_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 15/26] net/bnxt: add code to support VLAN pvid
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (13 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
                               ` (11 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds code to support vlan_pvid_set dev_op

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Avoid using dev_ops in the patch subject line
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c | 21 +++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c   | 31 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |  1 +
 4 files changed, 54 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 8e6689f..adf0ab1 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -67,6 +67,7 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
+	uint16_t		dflt_vlan;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index d884c7e..178e581 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1477,6 +1477,26 @@ static int bnxt_mtu_set_op(struct rte_eth_dev *eth_dev, uint16_t new_mtu)
 	return rc;
 }
 
+static int
+bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+	uint16_t vlan = bp->vlan;
+	int rc;
+
+	if (BNXT_NPAR_PF(bp) || BNXT_VF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"PVID cannot be modified for this function\n");
+		return -ENOTSUP;
+	}
+	bp->vlan = on ? pvid : 0;
+
+	rc = bnxt_hwrm_set_default_vlan(bp, 0, 0);
+	if (rc)
+		bp->vlan = vlan;
+	return rc;
+}
+
 /*
  * Initialization
  */
@@ -1512,6 +1532,7 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.udp_tunnel_port_del  = bnxt_udp_tunnel_port_del_op,
 	.vlan_filter_set = bnxt_vlan_filter_set_op,
 	.vlan_offload_set = bnxt_vlan_offload_set_op,
+	.vlan_pvid_set = bnxt_vlan_pvid_set_op,
 	.mtu_set = bnxt_mtu_set_op,
 	.mac_addr_set = bnxt_set_default_mac_addr_op,
 	.xstats_get = bnxt_dev_xstats_get_op,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index dc4bb1b..3e595c3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2256,6 +2256,37 @@ int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	uint16_t dflt_vlan, fid;
+	uint32_t func_cfg_flags;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	if (is_vf) {
+		dflt_vlan = bp->pf.vf_info[vf].dflt_vlan;
+		fid = bp->pf.vf_info[vf].fid;
+		func_cfg_flags = bp->pf.vf_info[vf].func_cfg_flags;
+	} else {
+		fid = rte_cpu_to_le_16(0xffff);
+		func_cfg_flags = bp->pf.func_cfg_flags;
+		dflt_vlan = bp->vlan;
+	}
+
+	req.flags = rte_cpu_to_le_32(func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6ce0bc3..1759187 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -123,6 +123,7 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 void bnxt_free_tunnel_ports(struct bnxt *bp);
+int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 #endif
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 16/26] net/bnxt: reorg the query stats code
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (14 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 17/26] doc: update default.ini to add LED support Ajit Khaparde
                               ` (10 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

1) Use hwrm_stat_ctx_query command to query statistics
Using hwrm_stat_ctx_query command will allow polling
the statistics from hardware instead of using the current push
model from the hardware which does a DMA of the stats to the host
at fixed intervals.
2) Use the rx_mbuf_alloc_fail to track mbuf alloc failures.
3) We were wrongly incrementing hwrm_cmd_seq in bnxt_hwrm_stat_clear
and bnxt_hwrm_stat_ctx_alloc functions.  This patch fixes that.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
---
 drivers/net/bnxt/bnxt.h        |  1 +
 drivers/net/bnxt/bnxt_ethdev.c |  2 ++
 drivers/net/bnxt/bnxt_hwrm.c   | 82 ++++++++++++++++++++++++++++++++++++++----
 drivers/net/bnxt/bnxt_hwrm.h   |  4 +++
 drivers/net/bnxt/bnxt_rxr.c    | 16 ++++++---
 drivers/net/bnxt/bnxt_stats.c  | 59 ++++--------------------------
 6 files changed, 102 insertions(+), 62 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index adf0ab1..e411704 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -204,6 +204,7 @@ struct bnxt {
 	uint16_t		vxlan_fw_dst_port_id;
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
+	rte_atomic64_t		rx_mbuf_alloc_fail;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 178e581..4576156 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1616,6 +1616,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 	eth_dev->data->dev_flags |= RTE_ETH_DEV_DETACHABLE;
 
 	bp = eth_dev->data->dev_private;
+
+	rte_atomic64_init(&bp->rx_mbuf_alloc_fail);
 	bp->dev_stopped = 1;
 
 	if (bnxt_vf_pciid(pci_dev->id.device_id))
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3e595c3..a1aa80e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -821,13 +821,12 @@ int bnxt_hwrm_stat_clear(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 	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;
 
+	HWRM_PREP(req, STAT_CTX_CLR_STATS, -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));
 
@@ -845,9 +844,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 
 	HWRM_PREP(req, STAT_CTX_ALLOC, -1, resp);
 
-	req.update_period_ms = rte_cpu_to_le_32(1000);
+	req.update_period_ms = rte_cpu_to_le_32(0);
 
-	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);
 
@@ -870,7 +868,6 @@ int bnxt_hwrm_stat_ctx_free(struct bnxt *bp, struct bnxt_cp_ring_info *cpr,
 	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));
 
@@ -1227,6 +1224,43 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->ipackets = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->ipackets += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->ibytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->ibytes += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->opackets = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->opackets += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->obytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->obytes += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->ierrors = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->oerrors = rte_le_to_cpu_64(resp->tx_err_pkts);
+
+	stats->imissed = rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 /*
  * HWRM utility functions
  */
@@ -2348,6 +2382,42 @@ int bnxt_hwrm_exec_fwd_resp(struct bnxt *bp, uint16_t target_id,
 	return rc;
 }
 
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats)
+{
+	int rc = 0;
+	struct hwrm_stat_ctx_query_input req = {.req_type = 0};
+	struct hwrm_stat_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, STAT_CTX_QUERY, -1, resp);
+
+	req.stat_ctx_id = rte_cpu_to_le_32(cid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	stats->q_ipackets[idx] = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_mcast_pkts);
+	stats->q_ipackets[idx] += rte_le_to_cpu_64(resp->rx_bcast_pkts);
+	stats->q_ibytes[idx] = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_mcast_bytes);
+	stats->q_ibytes[idx] += rte_le_to_cpu_64(resp->rx_bcast_bytes);
+
+	stats->q_opackets[idx] = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_mcast_pkts);
+	stats->q_opackets[idx] += rte_le_to_cpu_64(resp->tx_bcast_pkts);
+	stats->q_obytes[idx] = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_mcast_bytes);
+	stats->q_obytes[idx] += rte_le_to_cpu_64(resp->tx_bcast_bytes);
+
+	stats->q_errors[idx] = rte_le_to_cpu_64(resp->rx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->tx_err_pkts);
+	stats->q_errors[idx] += rte_le_to_cpu_64(resp->rx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_port_qstats(struct bnxt *bp)
 {
 	struct hwrm_port_qstats_input req = {0};
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 1759187..ab42913 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -62,6 +62,8 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp);
 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_func_qstats(struct bnxt *bp, uint16_t fid,
+			  struct rte_eth_stats *stats);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
@@ -81,6 +83,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp,
 			     struct bnxt_cp_ring_info *cpr, unsigned int idx);
 int bnxt_hwrm_stat_ctx_free(struct bnxt *bp,
 			    struct bnxt_cp_ring_info *cpr, unsigned int idx);
+int bnxt_hwrm_ctx_qstats(struct bnxt *bp, uint32_t cid, int idx,
+			 struct rte_eth_stats *stats);
 
 int bnxt_hwrm_ver_get(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 1f0afcb..3001d81 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -68,8 +68,10 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	rx_buf->mbuf = data;
 
@@ -87,8 +89,10 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	struct rte_mbuf *data;
 
 	data = __bnxt_alloc_rx_data(rxq->mb_pool);
-	if (!data)
+	if (!data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return -ENOMEM;
+	}
 
 	if (rxbd == NULL)
 		RTE_LOG(ERR, PMD, "Jumbo Frame. rxbd is NULL\n");
@@ -321,8 +325,10 @@ static inline struct rte_mbuf *bnxt_tpa_end(
 
 	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
 	RTE_ASSERT(new_data != NULL);
-	if (!new_data)
+	if (!new_data) {
+		rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 		return NULL;
+	}
 	tpa_info->mbuf = new_data;
 
 	return mbuf;
@@ -679,8 +685,10 @@ int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 		for (i = 0; i < BNXT_TPA_MAX; i++) {
 			rxr->tpa_info[i].mbuf =
 				__bnxt_alloc_rx_data(rxq->mb_pool);
-			if (!rxr->tpa_info[i].mbuf)
+			if (!rxr->tpa_info[i].mbuf) {
+				rte_atomic64_inc(&rxq->bp->rx_mbuf_alloc_fail);
 				return -ENOMEM;
+			}
 		}
 	}
 	RTE_LOG(DEBUG, PMD, "%s TPA alloc Done!\n", __func__);
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 154dc0c..ade8195 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -196,64 +196,18 @@ void bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
 
 	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_discard_pkts);
+
+		bnxt_hwrm_ctx_qstats(bp, cpr->hw_stats_ctx_id, i, bnxt_stats);
 	}
+	bnxt_hwrm_func_qstats(bp, 0xffff, bnxt_stats);
+	bnxt_stats->rx_nombuf = rte_atomic64_read(&bp->rx_mbuf_alloc_fail);
 }
 
 void bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
@@ -261,6 +215,7 @@ 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);
+	rte_atomic64_clear(&bp->rx_mbuf_alloc_fail);
 }
 
 int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 17/26] doc: update default.ini to add LED support
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (15 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 18/26] net/bnxt: add support for led on/off Ajit Khaparde
                               ` (9 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Update default.ini to indicate LED on/off support
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/nics/features/default.ini | 1 +
 1 file changed, 1 insertion(+)

diff --git a/doc/guides/nics/features/default.ini b/doc/guides/nics/features/default.ini
index cafc6c7..5549acd 100644
--- a/doc/guides/nics/features/default.ini
+++ b/doc/guides/nics/features/default.ini
@@ -60,6 +60,7 @@ Stats per queue      =
 FW version           =
 EEPROM dump          =
 Registers dump       =
+LED                  =
 Multiprocess aware   =
 BSD nic_uio          =
 Linux UIO            =
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 18/26] net/bnxt: add support for led on/off
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (16 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 17/26] doc: update default.ini to add LED support Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
                               ` (8 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support for dev_led_on/off dev_ops

HWRM calls added:
bnxt_hwrm_port_led_qcaps()
bnxt_hwrm_port_led_cfg()

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1-v2:
  - rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Update bnxt.ini indicating support for LED on/off
---
 doc/guides/nics/features/bnxt.ini      |   1 +
 drivers/net/bnxt/bnxt.h                |  39 ++
 drivers/net/bnxt/bnxt_ethdev.c         |  20 +
 drivers/net/bnxt/bnxt_hwrm.c           |  70 +++
 drivers/net/bnxt/bnxt_hwrm.h           |   2 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h | 977 +++++++++++++++++++++++++++++++++
 6 files changed, 1109 insertions(+)

diff --git a/doc/guides/nics/features/bnxt.ini b/doc/guides/nics/features/bnxt.ini
index 4fd8abb..f582836 100644
--- a/doc/guides/nics/features/bnxt.ini
+++ b/doc/guides/nics/features/bnxt.ini
@@ -20,6 +20,7 @@ FW version           = Y
 Jumbo frame          = Y
 MTU update           = Y
 LRO                  = Y
+LED                  = Y
 Linux VFIO           = Y
 Linux UIO            = Y
 x86-64               = Y
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e411704..c23a836 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -47,6 +47,42 @@
 
 #define BNXT_MAX_MTU		9500
 #define VLAN_TAG_SIZE		4
+#define BNXT_MAX_LED		4
+
+struct bnxt_led_info {
+	uint8_t      led_id;
+	uint8_t      led_type;
+	uint8_t      led_group_id;
+	uint8_t      unused;
+	uint16_t  led_state_caps;
+#define BNXT_LED_ALT_BLINK_CAP(x)       ((x) &  \
+	rte_cpu_to_le_16(HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT))
+
+	uint16_t  led_color_caps;
+};
+
+struct bnxt_led_cfg {
+	uint8_t led_id;
+	uint8_t led_state;
+	uint8_t led_color;
+	uint8_t unused;
+	uint16_t led_blink_on;
+	uint16_t led_blink_off;
+	uint8_t led_group_id;
+	uint8_t rsvd;
+};
+
+#define BNXT_LED_DFLT_ENA                               \
+	(HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID |             \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE |          \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON |       \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF |      \
+	 HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID)
+
+#define BNXT_LED_DFLT_ENA_SHIFT		6
+
+#define BNXT_LED_DFLT_ENABLES(x)                        \
+	rte_cpu_to_le_32(BNXT_LED_DFLT_ENA << (BNXT_LED_DFLT_ENA_SHIFT * (x)))
 
 enum bnxt_hw_context {
 	HW_CONTEXT_NONE     = 0,
@@ -205,6 +241,9 @@ struct bnxt {
 	uint16_t		geneve_fw_dst_port_id;
 	uint32_t		fw_ver;
 	rte_atomic64_t		rx_mbuf_alloc_fail;
+
+	struct bnxt_led_info	leds[BNXT_MAX_LED];
+	uint8_t			num_leds;
 };
 
 /*
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 4576156..de901eb 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1497,6 +1497,22 @@ bnxt_vlan_pvid_set_op(struct rte_eth_dev *dev, uint16_t pvid, int on)
 	return rc;
 }
 
+static int
+bnxt_dev_led_on_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, true);
+}
+
+static int
+bnxt_dev_led_off_op(struct rte_eth_dev *dev)
+{
+	struct bnxt *bp = (struct bnxt *)dev->data->dev_private;
+
+	return bnxt_hwrm_port_led_cfg(bp, false);
+}
+
 /*
  * Initialization
  */
@@ -1542,6 +1558,8 @@ static const struct eth_dev_ops bnxt_dev_ops = {
 	.set_mc_addr_list = bnxt_dev_set_mc_addr_list_op,
 	.rxq_info_get = bnxt_rxq_info_get_op,
 	.txq_info_get = bnxt_txq_info_get_op,
+	.dev_led_on = bnxt_dev_led_on_op,
+	.dev_led_off = bnxt_dev_led_off_op,
 };
 
 static bool bnxt_vf_pciid(uint16_t id)
@@ -1815,6 +1833,8 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev)
 		}
 	}
 
+	bnxt_hwrm_port_led_qcaps(bp);
+
 	rc = bnxt_setup_int(bp);
 	if (rc)
 		goto error_free;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index a1aa80e..9a04885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2453,3 +2453,73 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp)
 	HWRM_CHECK_RESULT;
 	return rc;
 }
+
+int bnxt_hwrm_port_led_qcaps(struct bnxt *bp)
+{
+	struct hwrm_port_led_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_qcaps_input req = {0};
+	int rc;
+
+	if (BNXT_VF(bp))
+		return 0;
+
+	HWRM_PREP(req, PORT_LED_QCAPS, -1, resp);
+	req.port_id = bp->pf.port_id;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	if (resp->num_leds > 0 && resp->num_leds < BNXT_MAX_LED) {
+		unsigned int i;
+
+		bp->num_leds = resp->num_leds;
+		memcpy(bp->leds, &resp->led0_id,
+			sizeof(bp->leds[0]) * bp->num_leds);
+		for (i = 0; i < bp->num_leds; i++) {
+			struct bnxt_led_info *led = &bp->leds[i];
+
+			uint16_t caps = led->led_state_caps;
+
+			if (!led->led_group_id ||
+				!BNXT_LED_ALT_BLINK_CAP(caps)) {
+				bp->num_leds = 0;
+				break;
+			}
+		}
+	}
+	return rc;
+}
+
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
+{
+	struct hwrm_port_led_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_led_cfg_input req = {0};
+	struct bnxt_led_cfg *led_cfg;
+	uint8_t led_state = HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT;
+	uint16_t duration = 0;
+	int rc, i;
+
+	if (!bp->num_leds || BNXT_VF(bp))
+		return -EOPNOTSUPP;
+
+	HWRM_PREP(req, PORT_LED_CFG, -1, resp);
+	if (led_on) {
+		led_state = HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT;
+		duration = rte_cpu_to_le_16(500);
+	}
+	req.port_id = bp->pf.port_id;
+	req.num_leds = bp->num_leds;
+	led_cfg = (struct bnxt_led_cfg *)&req.led0_id;
+	for (i = 0; i < bp->num_leds; i++, led_cfg++) {
+		req.enables |= BNXT_LED_DFLT_ENABLES(i);
+		led_cfg->led_id = bp->leds[i].led_id;
+		led_cfg->led_state = led_state;
+		led_cfg->led_blink_on = duration;
+		led_cfg->led_blink_off = duration;
+		led_cfg->led_group_id = bp->leds[i].led_group_id;
+	}
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index ab42913..3591917 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -130,4 +130,6 @@ void bnxt_free_tunnel_ports(struct bnxt *bp);
 int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf);
 int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
+int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
+int bnxt_hwrm_port_led_qcaps(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 2fcfce6..17a912f 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -5743,6 +5743,983 @@ struct hwrm_port_clr_stats_output {
 	 */
 } __attribute__((packed));
 
+/* hwrm_port_led_cfg */
+/*
+ * Description: This function is used to configure LEDs on a given port. Each
+ * port has individual set of LEDs associated with it. These LEDs are used for
+ * speed/link configuration as well as activity indicator configuration. Up to
+ * three LEDs can be configured, one for activity and two for speeds.
+ */
+/* Input	(64 bytes) */
+struct hwrm_port_led_cfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint32_t enables;
+	/* This bit must be '1' for the led0_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_ID	UINT32_C(0x1)
+	/* This bit must be '1' for the led0_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_STATE	UINT32_C(0x2)
+	/* This bit must be '1' for the led0_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_COLOR	UINT32_C(0x4)
+	/*
+	 * This bit must be '1' for the led0_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_ON	UINT32_C(0x8)
+	/*
+	 * This bit must be '1' for the led0_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_BLINK_OFF UINT32_C(0x10)
+	/*
+	 * This bit must be '1' for the led0_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED0_GROUP_ID UINT32_C(0x20)
+	/* This bit must be '1' for the led1_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_ID	UINT32_C(0x40)
+	/* This bit must be '1' for the led1_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_STATE	UINT32_C(0x80)
+	/* This bit must be '1' for the led1_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_COLOR	UINT32_C(0x100)
+	/*
+	 * This bit must be '1' for the led1_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_ON UINT32_C(0x200)
+	/*
+	 * This bit must be '1' for the led1_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_BLINK_OFF UINT32_C(0x400)
+	/*
+	 * This bit must be '1' for the led1_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED1_GROUP_ID UINT32_C(0x800)
+	/* This bit must be '1' for the led2_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_ID	UINT32_C(0x1000)
+	/* This bit must be '1' for the led2_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_STATE	UINT32_C(0x2000)
+	/* This bit must be '1' for the led2_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_COLOR	UINT32_C(0x4000)
+	/*
+	 * This bit must be '1' for the led2_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_ON UINT32_C(0x8000)
+	/*
+	 * This bit must be '1' for the led2_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_BLINK_OFF UINT32_C(0x10000)
+	/*
+	 * This bit must be '1' for the led2_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED2_GROUP_ID UINT32_C(0x20000)
+	/* This bit must be '1' for the led3_id field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_ID	UINT32_C(0x40000)
+	/* This bit must be '1' for the led3_state field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_STATE  UINT32_C(0x80000)
+	/* This bit must be '1' for the led3_color field to be configured. */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_COLOR  UINT32_C(0x100000)
+	/*
+	 * This bit must be '1' for the led3_blink_on field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_ON UINT32_C(0x200000)
+	/*
+	 * This bit must be '1' for the led3_blink_off field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_BLINK_OFF	\
+		UINT32_C(0x400000)
+	/*
+	 * This bit must be '1' for the led3_group_id field to be
+	 * configured.
+	 */
+	#define HWRM_PORT_LED_CFG_INPUT_ENABLES_LED3_GROUP_ID UINT32_C(0x800000)
+	uint16_t port_id;
+	/* Port ID of port whose LEDs are configured. */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are being configured. Up to 4 LEDs
+	 * can be configured with this command.
+	 */
+	uint8_t rsvd;
+	/* Reserved field. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_state;
+	/* The requested state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The requested color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #0 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd0;
+	/* Reserved field. */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_state;
+	/* The requested state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The requested color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #1 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd1;
+	/* Reserved field. */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_state;
+	/* The requested state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The requested color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #2 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd2;
+	/* Reserved field. */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_state;
+	/* The requested state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The requested color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_CFG_INPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 shall not be grouped and shall
+	 * be treated as an individual resource. For all other non-zero
+	 * values of this field, LED #3 shall be grouped together with
+	 * the LEDs with the same group ID value.
+	 */
+	uint8_t rsvd3;
+	/* Reserved field. */
+} __attribute__((packed));
+
+/* Output	(16 bytes) */
+struct hwrm_port_led_cfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint32_t unused_0;
+	uint8_t unused_1;
+	uint8_t unused_2;
+	uint8_t unused_3;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcfg */
+/*
+ * Description: This function is used to query configuration of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration. Up to three LEDs can be configured, one for activity and two
+ * for speeds.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcfg_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(56 bytes) */
+struct hwrm_port_led_qcfg_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_state;
+	/* The current state of the LED #0. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led0_color;
+	/* The color of LED #0. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED0_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_0;
+	uint16_t led0_blink_on;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led0_blink_off;
+	/*
+	 * If the LED #0 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 is not grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_state;
+	/* The current state of the LED #1. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led1_color;
+	/* The color of LED #1. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED1_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_1;
+	uint16_t led1_blink_on;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led1_blink_off;
+	/*
+	 * If the LED #1 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #1 is not grouped. For all other
+	 * non-zero values of this field, LED #1 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_state;
+	/* The current state of the LED #2. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led2_color;
+	/* The color of LED #2. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED2_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_2;
+	uint16_t led2_blink_on;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led2_blink_off;
+	/*
+	 * If the LED #2 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #2 belongs to.
+	 * If set to 0, then the LED #2 is not grouped. For all other
+	 * non-zero values of this field, LED #2 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_state;
+	/* The current state of the LED #3. */
+	/* Default state of the LED */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_DEFAULT	UINT32_C(0x0)
+	/* Off */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_OFF	UINT32_C(0x1)
+	/* On */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_ON	UINT32_C(0x2)
+	/* Blink */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINK	UINT32_C(0x3)
+	/* Blink Alternately */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_STATE_BLINKALT	UINT32_C(0x4)
+	uint8_t led3_color;
+	/* The color of LED #3. */
+	/* Default */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_DEFAULT	UINT32_C(0x0)
+	/* Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_AMBER	UINT32_C(0x1)
+	/* Green */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREEN	UINT32_C(0x2)
+	/* Green or Amber */
+	#define HWRM_PORT_LED_QCFG_OUTPUT_LED3_COLOR_GREENAMBER	UINT32_C(0x3)
+	uint8_t unused_3;
+	uint16_t led3_blink_on;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED on
+	 * between cycles.
+	 */
+	uint16_t led3_blink_off;
+	/*
+	 * If the LED #3 state is "blink" or "blinkalt", then this field
+	 * represents the requested time in milliseconds to keep LED off
+	 * between cycles.
+	 */
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #3 is not grouped. For all other
+	 * non-zero values of this field, LED #3 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t unused_8;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
+/* hwrm_port_led_qcaps */
+/*
+ * Description: This function is used to query capabilities of LEDs on a given
+ * port. Each port has individual set of LEDs associated with it. These LEDs are
+ * used for speed/link configuration as well as activity indicator
+ * configuration.
+ */
+/* Input	(24 bytes) */
+struct hwrm_port_led_qcaps_input {
+	uint16_t req_type;
+	/*
+	 * This value indicates what type of request this is. The format
+	 * for the rest of the command is determined by this field.
+	 */
+	uint16_t cmpl_ring;
+	/*
+	 * 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 seq_id;
+	/* This value indicates the command sequence number. */
+	uint16_t target_id;
+	/*
+	 * Target ID of this command. 0x0 - 0xFFF8 - Used for function
+	 * ids 0xFFF8 - 0xFFFE - Reserved for internal processors 0xFFFF
+	 * - HWRM
+	 */
+	uint64_t resp_addr;
+	/*
+	 * 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.
+	 */
+	uint16_t port_id;
+	/* Port ID of port whose LED configuration is being queried. */
+	uint16_t unused_0[3];
+} __attribute__((packed));
+
+/* Output	(48 bytes) */
+struct hwrm_port_led_qcaps_output {
+	uint16_t error_code;
+	/*
+	 * Pass/Fail or error type Note: receiver to verify the in
+	 * parameters, and fail the call with an error when appropriate
+	 */
+	uint16_t req_type;
+	/* This field returns the type of original request. */
+	uint16_t seq_id;
+	/* This field provides original sequence number of the command. */
+	uint16_t resp_len;
+	/*
+	 * 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.
+	 */
+	uint8_t num_leds;
+	/*
+	 * The number of LEDs that are configured on this port. Up to 4
+	 * LEDs can be returned in the response.
+	 */
+	uint8_t unused_0[3];
+	/* Reserved for future use. */
+	uint8_t led0_id;
+	/* An identifier for the LED #0. */
+	uint8_t led0_type;
+	/* The type of LED #0. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led0_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_1;
+	uint16_t led0_state_caps;
+	/* The states supported by LED #0. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led0_color_caps;
+	/* The colors supported by LED #0. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED0_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led1_id;
+	/* An identifier for the LED #1. */
+	uint8_t led1_type;
+	/* The type of LED #1. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led1_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #1 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_2;
+	uint16_t led1_state_caps;
+	/* The states supported by LED #1. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led1_color_caps;
+	/* The colors supported by LED #1. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED1_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led2_id;
+	/* An identifier for the LED #2. */
+	uint8_t led2_type;
+	/* The type of LED #2. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led2_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #0 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_3;
+	uint16_t led2_state_caps;
+	/* The states supported by LED #2. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led2_color_caps;
+	/* The colors supported by LED #2. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED2_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t led3_id;
+	/* An identifier for the LED #3. */
+	uint8_t led3_type;
+	/* The type of LED #3. */
+	/* Speed LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_SPEED	UINT32_C(0x0)
+	/* Activity LED */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_ACTIVITY	UINT32_C(0x1)
+	/* Invalid */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_TYPE_INVALID	UINT32_C(0xff)
+	uint8_t led3_group_id;
+	/*
+	 * An identifier for the group of LEDs that LED #3 belongs to.
+	 * If set to 0, then the LED #0 cannot be grouped. For all other
+	 * non-zero values of this field, LED #0 is grouped together
+	 * with the LEDs with the same group ID value.
+	 */
+	uint8_t unused_4;
+	uint16_t led3_state_caps;
+	/* The states supported by LED #3. */
+	/*
+	 * If set to 1, this LED is enabled. If set to 0, this LED is
+	 * disabled.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ENABLED UINT32_C(0x1)
+	/*
+	 * If set to 1, off state is supported on this LED. If set to 0,
+	 * off state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_OFF_SUPPORTED  \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, on state is supported on this LED. If set to 0,
+	 * on state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_ON_SUPPORTED   \
+		UINT32_C(0x4)
+	/*
+	 * If set to 1, blink state is supported on this LED. If set to
+	 * 0, blink state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_SUPPORTED \
+		UINT32_C(0x8)
+	/*
+	 * If set to 1, blink_alt state is supported on this LED. If set
+	 * to 0, blink_alt state is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_STATE_CAPS_BLINK_ALT_SUPPORTED \
+		UINT32_C(0x10)
+	uint16_t led3_color_caps;
+	/* The colors supported by LED #3. */
+	/* reserved */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_RSVD	UINT32_C(0x1)
+	/*
+	 * If set to 1, Amber color is supported on this LED. If set to
+	 * 0, Amber color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_AMBER_SUPPORTED \
+		UINT32_C(0x2)
+	/*
+	 * If set to 1, Green color is supported on this LED. If set to
+	 * 0, Green color is not supported on this LED.
+	 */
+	#define HWRM_PORT_LED_QCAPS_OUTPUT_LED3_COLOR_CAPS_GREEN_SUPPORTED \
+		UINT32_C(0x4)
+	uint8_t unused_5;
+	uint8_t unused_6;
+	uint8_t unused_7;
+	uint8_t valid;
+	/*
+	 * 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.
+	 */
+} __attribute__((packed));
+
 /* hwrm_queue_qportcfg */
 /*
  * Description: This function is called by a driver to query queue configuration
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (17 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 18/26] net/bnxt: add support for led on/off Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-06 12:53               ` Ferruh Yigit
  2017-06-01 17:07             ` [PATCH v4 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
                               ` (7 subsequent siblings)
  26 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Steeven Li

Add functions rte_pmd_bnxt_set_tx_loopback,
rte_pmd_bnxt_set_all_queues_drop_en and
rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
queue_drop and VF MAC address setting in the hardware.
It also adds the necessary functions to send the HWRM commands
to the firmware.

Signed-off-by: Steeven Li <steeven.li@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add the copyright year.
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/Makefile                     |   4 +
 app/test-pmd/cmdline.c                    |  25 ++++-
 drivers/net/bnxt/Makefile                 |   4 +
 drivers/net/bnxt/bnxt.h                   |   2 +
 drivers/net/bnxt/bnxt_ethdev.c            |  15 +++
 drivers/net/bnxt/bnxt_hwrm.c              | 106 ++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |   4 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 172 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  87 +++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   7 +-
 10 files changed, 422 insertions(+), 4 deletions(-)
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.c
 create mode 100644 drivers/net/bnxt/rte_pmd_bnxt.h

diff --git a/app/test-pmd/Makefile b/app/test-pmd/Makefile
index 35ecee9..c36be19 100644
--- a/app/test-pmd/Makefile
+++ b/app/test-pmd/Makefile
@@ -73,6 +73,10 @@ ifeq ($(CONFIG_RTE_LIBRTE_I40E_PMD),y)
 LDLIBS += -lrte_pmd_i40e
 endif
 
+ifeq ($(CONFIG_RTE_LIBRTE_BNXT_PMD),y)
+LDLIBS += -lrte_pmd_bnxt
+endif
+
 ifeq ($(CONFIG_RTE_LIBRTE_PMD_XENVIRT),y)
 LDLIBS += -lrte_pmd_xenvirt
 endif
diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 0afac68..26b0da1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -94,6 +94,9 @@
 #ifdef RTE_LIBRTE_I40E_PMD
 #include <rte_pmd_i40e.h>
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
 #include "testpmd.h"
 
 static struct cmdline *testpmd_cl;
@@ -11402,6 +11405,10 @@ cmd_set_tx_loopback_parsed(
 	if (ret == -ENOTSUP)
 		ret = rte_pmd_i40e_set_tx_loopback(res->port_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_tx_loopback(res->port_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11434,7 +11441,6 @@ cmdline_parse_inst_t cmd_set_tx_loopback = {
 	},
 };
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 /* all queues drop enable configuration */
 
 /* Common result structure for all queues drop enable */
@@ -11480,13 +11486,20 @@ cmd_set_all_queues_drop_en_parsed(
 	__attribute__((unused)) void *data)
 {
 	struct cmd_all_queues_drop_en_result *res = parsed_result;
-	int ret = 0;
+	int ret = -ENOTSUP;
 	int is_on = (strcmp(res->on_off, "on") == 0) ? 1 : 0;
 
 	if (port_id_is_invalid(res->port_id, ENABLED_WARN))
 		return;
 
-	ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_ixgbe_set_all_queues_drop_en(res->port_id, is_on);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_all_queues_drop_en(res->port_id, is_on);
+#endif
 	switch (ret) {
 	case 0:
 		break;
@@ -11519,6 +11532,7 @@ cmdline_parse_inst_t cmd_set_all_queues_drop_en = {
 	},
 };
 
+#ifdef RTE_LIBRTE_IXGBE_PMD
 /* vf split drop enable configuration */
 
 /* Common result structure for vf split drop enable */
@@ -11673,6 +11687,11 @@ cmd_set_vf_mac_addr_parsed(
 		ret = rte_pmd_i40e_set_vf_mac_addr(res->port_id, res->vf_id,
 				&res->mac_addr);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_mac_addr(res->port_id, res->vf_id,
+				&res->mac_addr);
+#endif
 
 	switch (ret) {
 	case 0:
diff --git a/drivers/net/bnxt/Makefile b/drivers/net/bnxt/Makefile
index 0fffe35..b03f65d 100644
--- a/drivers/net/bnxt/Makefile
+++ b/drivers/net/bnxt/Makefile
@@ -38,6 +38,8 @@ include $(RTE_SDK)/mk/rte.vars.mk
 #
 LIB = librte_pmd_bnxt.a
 
+EXPORT_MAP := rte_pmd_bnxt_version.map
+
 LIBABIVER := 1
 
 CFLAGS += -O3
@@ -60,10 +62,12 @@ 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
 SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += bnxt_irq.c
+SRCS-$(CONFIG_RTE_LIBRTE_BNXT_PMD) += rte_pmd_bnxt.c
 
 #
 # Export include files
 #
 SYMLINK-y-include +=
+SYMLINK-$(CONFIG_RTE_LIBRTE_BNXT_PMD)-include := rte_pmd_bnxt.h
 
 include $(RTE_SDK)/mk/rte.lib.mk
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c23a836..e918517 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -276,4 +276,6 @@ int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete);
 int bnxt_rcv_msg_from_vf(struct bnxt *bp, uint16_t vf_id, void *msg);
 
 #define RX_PROD_AGG_BD_TYPE_RX_PROD_AGG		0x6
+
+bool is_bnxt_supported(struct rte_eth_dev *dev);
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index de901eb..57f9064 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -142,6 +142,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 	ETH_RSS_NONFRAG_IPV6_UDP)
 
 static void bnxt_vlan_offload_set_op(struct rte_eth_dev *dev, int mask);
+
 /***********************/
 
 /*
@@ -1936,6 +1937,20 @@ static struct rte_pci_driver bnxt_rte_pmd = {
 	.remove = bnxt_pci_remove,
 };
 
+static bool
+is_device_supported(struct rte_eth_dev *dev, struct rte_pci_driver *drv)
+{
+	if (strcmp(dev->data->drv_name, drv->driver.name))
+		return false;
+
+	return true;
+}
+
+bool is_bnxt_supported(struct rte_eth_dev *dev)
+{
+	return is_device_supported(dev, &bnxt_rte_pmd);
+}
+
 RTE_PMD_REGISTER_PCI(net_bnxt, bnxt_rte_pmd);
 RTE_PMD_REGISTER_PCI_TABLE(net_bnxt, bnxt_pci_id_map);
 RTE_PMD_REGISTER_KMOD_DEP(net_bnxt, "* igb_uio | uio_pci_generic | vfio");
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 9a04885..79c5ca8 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2168,6 +2168,24 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 	return rc;
 }
 
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+
+	req.fid = rte_cpu_to_le_16(0xffff);
+	req.enables = rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_EVB_MODE);
+	req.evb_mode = bp->pf.evb_mode;
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type)
 {
@@ -2523,3 +2541,91 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 
 	return rc;
 }
+
+static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
+					uint16_t *vnic_ids)
+{
+	struct hwrm_func_vf_vnic_ids_query_input req = {0};
+	struct hwrm_func_vf_vnic_ids_query_output *resp =
+						bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* First query all VNIC ids */
+	HWRM_PREP(req, FUNC_VF_VNIC_IDS_QUERY, -1, resp_vf_vnic_ids);
+
+	req.vf_id = rte_cpu_to_le_16(bp->pf.first_vf_id + vf);
+	req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
+	req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2phy(vnic_ids));
+
+	if (req.vnic_id_tbl_addr == 0) {
+		RTE_LOG(ERR, PMD,
+		"unable to map VNIC ID table address to physical memory\n");
+		return -ENOMEM;
+	}
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_vf_vnic_query error %d\n", rc);
+		return -1;
+	}
+
+	return rte_le_to_cpu_32(resp->vnic_id_cnt);
+}
+
+/*
+ * This function queries the VNIC IDs  for a specified VF. It then calls
+ * the vnic_cb to update the necessary field in vnic_info with cbdata.
+ * Then it calls the hwrm_cb function to program this new vnic configuration.
+ */
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic))
+{
+	struct bnxt_vnic_info vnic;
+	int rc = 0;
+	int i, num_vnic_ids;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	size_t sz;
+
+	/* First query all VNIC ids */
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	num_vnic_ids = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+
+	if (num_vnic_ids < 0)
+		return num_vnic_ids;
+
+	/* Retrieve VNIC, update bd_stall then update */
+
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf);
+		if (rc)
+			break;
+		if (vnic.mru == 4)	/* Indicates unallocated */
+			continue;
+
+		vnic_cb(&vnic, cbdata);
+
+		rc = hwrm_cb(bp, &vnic);
+		if (rc)
+			break;
+	}
+
+	rte_free(vnic_ids);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 3591917..b79df9d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -120,6 +120,7 @@ int bnxt_hwrm_allocate_pf_only(struct bnxt *bp);
 int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
+int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -132,4 +133,7 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
+	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
+	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
new file mode 100644
index 0000000..57a11a4
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -0,0 +1,172 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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>
+#include <rte_byteorder.h>
+
+#include "bnxt.h"
+#include "bnxt_filter.h"
+#include "bnxt_hwrm.h"
+#include "bnxt_vnic.h"
+#include "rte_pmd_bnxt.h"
+#include "hsi_struct_def_dpdk.h"
+
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set Tx loopback on non-PF port %d!\n",
+			port);
+		return -ENOTSUP;
+	}
+
+	if (on)
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEB;
+	else
+		bp->pf.evb_mode = BNXT_EVB_MODE_VEPA;
+
+	rc = bnxt_hwrm_pf_evb_mode(bp);
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_all_queues_drop_en_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->bd_stall = !(*on);
+}
+
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on)
+{
+	struct rte_eth_dev *eth_dev;
+	struct bnxt *bp;
+	uint32_t i;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set all queues drop on non-PF port!\n");
+		return -ENOTSUP;
+	}
+
+	if (bp->vnic_info == NULL)
+		return -ENODEV;
+
+	/* Stall PF */
+	for (i = 0; i < bp->nr_vnics; i++) {
+		bp->vnic_info[i].bd_stall = !on;
+		rc = bnxt_hwrm_vnic_cfg(bp, &bp->vnic_info[i]);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update PF VNIC %d.\n", i);
+			return rc;
+		}
+	}
+
+	/* Stall all active VFs */
+	for (i = 0; i < bp->pf.active_vfs; i++) {
+		rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, i,
+				rte_pmd_bnxt_set_all_queues_drop_en_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+		if (rc) {
+			RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", i);
+			break;
+		}
+	}
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+				struct ether_addr *mac_addr)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs || mac_addr == NULL)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d mac address on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_mac(bp, vf, (uint8_t *)mac_addr);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
new file mode 100644
index 0000000..292976d
--- /dev/null
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -0,0 +1,87 @@
+/*-
+ *   BSD LICENSE
+ *
+ *   Copyright(c) 2017 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 _PMD_BNXT_H_
+#define _PMD_BNXT_H_
+
+#include <rte_ethdev.h>
+
+/**
+ * Set the VF MAC address.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param mac_addr
+ *   VF MAC address.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
+		struct ether_addr *mac_addr);
+
+/**
+ * Enable/Disable tx loopback
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - Enable tx loopback.
+ *    0 - Disable tx loopback.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
+
+/**
+ * set all queues drop enable bit
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param on
+ *    1 - set the queue drop enable bit for all pools.
+ *    0 - reset the queue drop enable bit for all pools.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+#endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 349c6e1..fa291cb 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -1,4 +1,9 @@
-DPDK_16.04 {
+DPDK_17.08 {
+	global:
+
+	rte_pmd_bnxt_set_tx_loopback;
+	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_set_vf_mac_addr;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (18 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
                               ` (6 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to
1) enable VF MAC anti spoof.
2) QOS configuration for specified VF.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    |  24 ++-
 app/test-pmd/config.c                     |  20 ++-
 drivers/net/bnxt/bnxt.h                   |   4 +
 drivers/net/bnxt/bnxt_ethdev.c            |  12 +-
 drivers/net/bnxt/bnxt_filter.h            |   2 +
 drivers/net/bnxt/bnxt_hwrm.c              | 117 +++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h              |  10 +-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 289 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           |  97 ++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |   5 +
 10 files changed, 564 insertions(+), 16 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 26b0da1..90e4a27 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6964,6 +6964,11 @@ cmd_vf_rx_vlan_filter_parsed(void *parsed_result,
 		ret = rte_pmd_i40e_set_vf_vlan_filter(res->port_id,
 				res->vlan_id, res->vf_mask, is_add);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_filter(res->port_id,
+				res->vlan_id, res->vf_mask, is_add);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -7089,7 +7094,6 @@ cmdline_parse_inst_t cmd_queue_rate_limit = {
 	},
 };
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 /* *** SET RATE LIMIT FOR A VF OF A PORT *** */
 struct cmd_vf_rate_limit_result {
 	cmdline_fixed_string_t set;
@@ -7168,7 +7172,6 @@ cmdline_parse_inst_t cmd_vf_rate_limit = {
 		NULL,
 	},
 };
-#endif
 
 /* *** ADD TUNNEL FILTER OF A PORT *** */
 struct cmd_tunnel_filter_result {
@@ -11015,6 +11018,11 @@ cmd_set_vf_vlan_anti_spoof_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_anti_spoof(res->port_id,
 				res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_anti_spoof(res->port_id,
+				res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11116,6 +11124,11 @@ cmd_set_vf_mac_anti_spoof_parsed(
 		ret = rte_pmd_i40e_set_vf_mac_anti_spoof(res->port_id,
 			res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_mac_anti_spoof(res->port_id,
+			res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -11217,6 +11230,11 @@ cmd_set_vf_vlan_stripq_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_stripq(res->port_id,
 			res->vf_id, is_on);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_stripq(res->port_id,
+			res->vf_id, is_on);
+#endif
 
 	switch (ret) {
 	case 0:
@@ -13752,8 +13770,8 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sa,
 	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
-	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 #endif
+	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 	(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
 	(cmdline_parse_inst_t *)&cmd_set_vf_promisc,
diff --git a/app/test-pmd/config.c b/app/test-pmd/config.c
index 4d873cd..35eddc9 100644
--- a/app/test-pmd/config.c
+++ b/app/test-pmd/config.c
@@ -97,6 +97,9 @@
 #ifdef RTE_LIBRTE_IXGBE_PMD
 #include <rte_pmd_ixgbe.h>
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+#include <rte_pmd_bnxt.h>
+#endif
 
 #include "testpmd.h"
 
@@ -3053,20 +3056,27 @@ set_queue_rate_limit(portid_t port_id, uint16_t queue_idx, uint16_t rate)
 	return diag;
 }
 
-#ifdef RTE_LIBRTE_IXGBE_PMD
 int
 set_vf_rate_limit(portid_t port_id, uint16_t vf, uint16_t rate, uint64_t q_msk)
 {
-	int diag;
+	int diag = -ENOTSUP;
 
-	diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate, q_msk);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (diag == -ENOTSUP)
+		diag = rte_pmd_ixgbe_set_vf_rate_limit(port_id, vf, rate,
+						       q_msk);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (diag == -ENOTSUP)
+		diag = rte_pmd_bnxt_set_vf_rate_limit(port_id, vf, rate, q_msk);
+#endif
 	if (diag == 0)
 		return diag;
-	printf("rte_pmd_ixgbe_set_vf_rate_limit for port_id=%d failed diag=%d\n",
+
+	printf("set_vf_rate_limit for port_id=%d failed diag=%d\n",
 		port_id, diag);
 	return diag;
 }
-#endif
 
 /*
  * Functions to manage the set of filtered Multicast MAC addresses.
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e918517..c1f9095 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -104,6 +104,10 @@ struct bnxt_child_vf_info {
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
 	uint16_t		dflt_vlan;
+	uint16_t		max_tx_rate;
+	uint16_t		vlan_count;
+	uint8_t			mac_spoof_en;
+	uint8_t			vlan_spoof_en;
 	bool			random_mac;
 };
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 57f9064..a710c41 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -295,7 +295,7 @@ static int bnxt_init_chip(struct bnxt *bp)
 		else
 			bnxt_hwrm_vnic_tpa_cfg(bp, vnic, 0);
 	}
-	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0]);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, &bp->vnic_info[0], 0, NULL);
 	if (rc) {
 		RTE_LOG(ERR, PMD,
 			"HWRM cfa l2 rx mask failure rc: %x\n", rc);
@@ -703,7 +703,7 @@ static void bnxt_promiscuous_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
@@ -717,7 +717,7 @@ static void bnxt_promiscuous_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_PROMISC;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
@@ -731,7 +731,7 @@ static void bnxt_allmulticast_enable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
@@ -745,7 +745,7 @@ static void bnxt_allmulticast_disable_op(struct rte_eth_dev *eth_dev)
 	vnic = &bp->vnic_info[0];
 
 	vnic->flags &= ~BNXT_VNIC_INFO_ALLMULTI;
-	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int bnxt_reta_update_op(struct rte_eth_dev *eth_dev,
@@ -1369,7 +1369,7 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 	vnic->mc_addr_cnt = i;
 
 allmulti:
-	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic);
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
 }
 
 static int
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 06fe134..353b7f7 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -63,6 +63,8 @@ struct bnxt_filter_info {
 	uint32_t		vni;
 	uint8_t			pri_hint;
 	uint64_t		l2_filter_id_hint;
+	uint32_t		src_id;
+	uint8_t			src_type;
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 79c5ca8..f143541 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -213,7 +213,10 @@ int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
-int bnxt_hwrm_cfa_l2_set_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,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table)
 {
 	int rc = 0;
 	struct hwrm_cfa_l2_set_rx_mask_input req = {.req_type = 0 };
@@ -237,6 +240,12 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	}
 	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
 				    mask);
+	if (vlan_count && vlan_table) {
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
+		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
+			 rte_mem_virt2phy(vlan_table));
+		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
+	}
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -296,6 +305,10 @@ int bnxt_hwrm_set_filter(struct bnxt *bp,
 	if (enables &
 	    HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_L2_OVLAN_MASK)
 		req.l2_ovlan_mask = filter->l2_ovlan_mask;
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_ID)
+		req.src_id = rte_cpu_to_le_32(filter->src_id);
+	if (enables & HWRM_CFA_L2_FILTER_ALLOC_INPUT_ENABLES_SRC_TYPE)
+		req.src_type = filter->src_type;
 
 	req.enables = rte_cpu_to_le_32(enables);
 
@@ -2230,6 +2243,21 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 	return rc;
 }
 
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
@@ -2339,6 +2367,24 @@ int bnxt_hwrm_set_default_vlan(struct bnxt *bp, int vf, uint8_t is_vf)
 	return rc;
 }
 
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(enables);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.max_bw = rte_cpu_to_le_32(max_bw);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
@@ -2629,3 +2675,72 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 
 	return rc;
 }
+
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on)
+{
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_func_cfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(
+			HWRM_FUNC_CFG_INPUT_ENABLES_VLAN_ANTISPOOF_MODE);
+	req.vlan_antispoof_mode = on ?
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_VALIDATE_VLAN :
+		HWRM_FUNC_CFG_INPUT_VLAN_ANTISPOOF_MODE_NOCHECK;
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
+{
+	struct bnxt_vnic_info vnic;
+	uint16_t *vnic_ids;
+	size_t vnic_id_sz;
+	int num_vnic_ids, i;
+	size_t sz;
+	int rc;
+
+	vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
+	vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
+			RTE_CACHE_LINE_SIZE);
+	if (vnic_ids == NULL) {
+		rc = -ENOMEM;
+		return rc;
+	}
+
+	for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
+		rte_mem_lock_page(((char *)vnic_ids) + sz);
+
+	rc = bnxt_hwrm_func_vf_vnic_query(bp, vf, vnic_ids);
+	if (rc <= 0)
+		goto exit;
+	num_vnic_ids = rc;
+
+	/*
+	 * Loop through to find the default VNIC ID.
+	 * TODO: The easier way would be to obtain the resp->dflt_vnic_id
+	 * by sending the hwrm_func_qcfg command to the firmware.
+	 */
+	for (i = 0; i < num_vnic_ids; i++) {
+		memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+		vnic.fw_vnic_id = rte_le_to_cpu_16(vnic_ids[i]);
+		rc = bnxt_hwrm_vnic_qcfg(bp, &vnic,
+					bp->pf.first_vf_id + vf);
+		if (rc)
+			goto exit;
+		if (vnic.func_default) {
+			rte_free(vnic_ids);
+			return vnic.fw_vnic_id;
+		}
+	}
+	/* Could not find a default VNIC. */
+	RTE_LOG(ERR, PMD, "No default VNIC\n");
+exit:
+	rte_free(vnic_ids);
+	return -1;
+}
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index b79df9d..f51ebcf 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -45,7 +45,9 @@ 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_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic,
+				 uint16_t vlan_count,
+				 struct bnxt_vlan_table_entry *vlan_table);
 int bnxt_hwrm_clear_filter(struct bnxt *bp,
 			   struct bnxt_filter_info *filter);
 int bnxt_hwrm_set_filter(struct bnxt *bp,
@@ -121,6 +123,8 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs);
 int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 			  const uint8_t *mac_addr);
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
+int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
+			uint16_t max_bw, uint16_t enables);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
@@ -133,7 +137,11 @@ int bnxt_hwrm_port_qstats(struct bnxt *bp);
 int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
+int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
+int bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(struct bnxt *bp, uint16_t vf,
+					      bool on);
+int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf);
 #endif
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 57a11a4..644a890 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -33,6 +33,7 @@
 
 #include <inttypes.h>
 #include <stdbool.h>
+#include <unistd.h>
 
 #include <rte_dev.h>
 #include <rte_ethdev.h>
@@ -170,3 +171,291 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk)
+{
+	struct rte_eth_dev *eth_dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	uint16_t tot_rate = 0;
+	uint64_t idx;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	eth_dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(eth_dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)eth_dev->data->dev_private;
+
+	if (!bp->pf.active_vfs)
+		return -EINVAL;
+
+	if (vf >= bp->pf.max_vfs)
+		return -EINVAL;
+
+	/* Add up the per queue BW and configure MAX BW of the VF */
+	for (idx = 0; idx < 64; idx++) {
+		if ((1ULL << idx) & q_msk)
+			tot_rate += tx_rate;
+	}
+
+	/* Requested BW can't be greater than link speed */
+	if (tot_rate > eth_dev->data->dev_link.link_speed) {
+		RTE_LOG(ERR, PMD, "Rate > Link speed. Set to %d\n", tot_rate);
+		return -EINVAL;
+	}
+
+	/* Requested BW already configured */
+	if (tot_rate == bp->pf.vf_info[vf].max_tx_rate)
+		return 0;
+
+	rc = bnxt_hwrm_func_bw_cfg(bp, vf, tot_rate,
+				HWRM_FUNC_CFG_INPUT_ENABLES_MAX_BW);
+
+	if (!rc)
+		bp->pf.vf_info[vf].max_tx_rate = tot_rate;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	uint32_t func_flags;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	/* Prev setting same as new setting. */
+	if (on == bp->pf.vf_info[vf].mac_spoof_en)
+		return 0;
+
+	func_flags = bp->pf.vf_info[vf].func_cfg_flags;
+
+	if (on)
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_ENABLE;
+	else
+		func_flags |=
+			HWRM_FUNC_CFG_INPUT_FLAGS_SRC_MAC_ADDR_CHECK_DISABLE;
+
+	bp->pf.vf_info[vf].func_cfg_flags = func_flags;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_flags(bp, vf);
+	if (!rc)
+		bp->pf.vf_info[vf].mac_spoof_en = on;
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev_info dev_info;
+	struct rte_eth_dev *dev;
+	struct bnxt *bp;
+	int rc;
+	int dflt_vnic;
+	struct bnxt_vnic_info vnic;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	if (on > 1)
+		return -EINVAL;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set mac spoof on non-PF port %d!\n", port);
+		return -EINVAL;
+	}
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	rc = bnxt_hwrm_func_cfg_vf_set_vlan_anti_spoof(bp, vf, on);
+	if (!rc) {
+		bp->pf.vf_info[vf].vlan_spoof_en = on;
+		if (on) {
+			dflt_vnic = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf);
+			if (dflt_vnic < 0) {
+				/*
+				 * This simply indicates there's no driver
+				 * loaded.  This is not an error.
+				 */
+				RTE_LOG(ERR, PMD,
+				      "Unable to get default VNIC for VF %d\n",
+					vf);
+			} else {
+				vnic.fw_vnic_id = dflt_vnic;
+				if (bnxt_hwrm_vnic_qcfg(bp,
+					&vnic, bp->pf.first_vf_id + vf) == 0) {
+					if (bnxt_hwrm_cfa_l2_set_rx_mask(bp,
+					   &vnic, bp->pf.vf_info[vf].vlan_count,
+					   bp->pf.vf_info[vf].vlan_table))
+						rc = -1;
+				}
+			}
+		}
+	} else {
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+	}
+
+	return rc;
+}
+
+static void
+rte_pmd_bnxt_set_vf_vlan_stripq_cb(struct bnxt_vnic_info *vnic, void *onptr)
+{
+	uint8_t *on = onptr;
+	vnic->vlan_strip = *on;
+}
+
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d stripq on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+				rte_pmd_bnxt_set_vf_vlan_stripq_cb, &on,
+				bnxt_hwrm_vnic_cfg);
+	if (rc)
+		RTE_LOG(ERR, PMD, "Failed to update VF VNIC %d.\n", vf);
+
+	return rc;
+}
+
+int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on)
+{
+	struct bnxt_vlan_table_entry *ve;
+	struct rte_eth_dev *dev;
+	struct bnxt *bp;
+	uint16_t cnt;
+	int rc = 0;
+	int i, j;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	bp = (struct bnxt *)dev->data->dev_private;
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	for (i = 0; vf_mask; i++, vf_mask >>= 1) {
+		cnt = bp->pf.vf_info[i].vlan_count;
+		if (vf_mask & 1) {
+			if (bp->pf.vf_info[i].vlan_table == NULL) {
+				rc = -1;
+				continue;
+			}
+			if (vlan_on) {
+				/* First, search for a duplicate... */
+				for (j = 0; j < cnt; j++) {
+					if (rte_be_to_cpu_16(
+					 bp->pf.vf_info[i].vlan_table[j].vid) ==
+					    vlan)
+						break;
+				}
+				if (j == cnt) {
+					/* Now check that there's space */
+					if (cnt == getpagesize() /
+					 sizeof(struct bnxt_vlan_table_entry)) {
+						RTE_LOG(ERR, PMD,
+						  "VF %d VLAN table is full\n",
+						  i);
+						RTE_LOG(ERR, PMD,
+							"cannot add VLAN %u\n",
+							vlan);
+						rc = -1;
+						continue;
+					}
+
+					cnt = bp->pf.vf_info[i].vlan_count++;
+					/*
+					 * And finally, add to the
+					 * end of the table
+					 */
+					ve = &bp->pf.vf_info[i].vlan_table[cnt];
+					// TODO: Hardcoded TPID
+					ve->tpid = rte_cpu_to_be_16(0x8100);
+					ve->vid = rte_cpu_to_be_16(vlan);
+				}
+			} else {
+				for (j = 0; cnt; j++) {
+					if (rte_be_to_cpu_16(
+					bp->pf.vf_info[i].vlan_table[j].vid) !=
+					    vlan)
+						continue;
+					memmove(
+					 &bp->pf.vf_info[i].vlan_table[j],
+					 &bp->pf.vf_info[i].vlan_table[j + 1],
+					 getpagesize() -
+					 ((j + 1) *
+					 sizeof(struct bnxt_vlan_table_entry)));
+					j--;
+					cnt = bp->pf.vf_info[i].vlan_count--;
+				}
+			}
+			rte_pmd_bnxt_set_vf_vlan_anti_spoof(dev->data->port_id,
+					 i, bp->pf.vf_info[i].vlan_spoof_en);
+		}
+	}
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 292976d..024620f 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -37,6 +37,24 @@
 #include <rte_ethdev.h>
 
 /**
+ * Enable/Disable VF MAC anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF MAC anti spoof.
+ *    0 - Disable VF MAC anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_mac_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
  * Set the VF MAC address.
  *
  * @param port
@@ -54,6 +72,48 @@ int rte_pmd_bnxt_set_vf_mac_addr(uint8_t port, uint16_t vf,
 		struct ether_addr *mac_addr);
 
 /**
+ * Enable/Disable vf vlan strip for all queues in a pool
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param on
+ *    1 - Enable VF's vlan strip on RX queues.
+ *    0 - Disable VF's vlan strip on RX queues.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support this feature.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
+ * received VLAN packets tagged with a given VLAN Tag Identifier.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vlan
+ *   The VLAN Tag Identifier whose filtering must be enabled or disabled.
+ * @param vf_mask
+ *    Bitmap listing which VFs participate in the VLAN filtering.
+ * @param vlan_on
+ *    1 - Enable VFs VLAN filtering.
+ *    0 - Disable VFs VLAN filtering.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENOTSUP) if hardware doesn't support.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
+				    uint64_t vf_mask, uint8_t vlan_on);
+
+/**
  * Enable/Disable tx loopback
  *
  * @param port
@@ -84,4 +144,41 @@ int rte_pmd_bnxt_set_tx_loopback(uint8_t port, uint8_t on);
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_all_queues_drop_en(uint8_t port, uint8_t on);
+
+/**
+ * Set the VF rate limit.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param tx_rate
+ *   Tx rate for the VF
+ * @param q_msk
+ *   Mask of the Tx queue
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if *vf* or *mac_addr* is invalid.
+ */
+int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
+				uint16_t tx_rate, uint64_t q_msk);
+
+/**
+ * Enable/Disable VF VLAN anti spoof
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param on
+ *    1 - Enable VF VLAN anti spoof.
+ *    0 - Disable VF VLAN anti spoof.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index fa291cb..770b076 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -4,6 +4,11 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
 	rte_pmd_bnxt_set_vf_mac_addr;
+	rte_pmd_bnxt_set_vf_mac_anti_spoof;
+	rte_pmd_bnxt_set_vf_rate_limit;
+	rte_pmd_bnxt_set_vf_vlan_stripq;
+	rte_pmd_bnxt_set_vf_vlan_filter;
+	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 21/26] net/bnxt: add support to get and clear VF specific stats
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (19 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
                               ` (5 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to get and clear VF stats.
It also adds the necessary HWRM structures to send the command
to the firmware.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - Move the PF related MAC/VLAN anti spoof counter to xstats.
---
 app/test-pmd/cmdline.c                    | 23 +++++++--
 drivers/net/bnxt/bnxt_hwrm.c              | 38 ++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  3 ++
 drivers/net/bnxt/bnxt_stats.c             | 60 +++++++++++++++++++++-
 drivers/net/bnxt/rte_pmd_bnxt.c           | 83 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 52 +++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  3 ++
 7 files changed, 255 insertions(+), 7 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index 90e4a27..f49d83b 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -13079,9 +13079,16 @@ cmd_show_vf_stats_parsed(
 	memset(&stats, 0, sizeof(stats));
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_get_vf_stats(res->port_id,
-					res->vf_id,
-					&stats);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_get_vf_stats(res->port_id,
+						res->vf_id,
+						&stats);
 #endif
 
 	switch (ret) {
@@ -13177,8 +13184,14 @@ cmd_clear_vf_stats_parsed(
 		return;
 
 #ifdef RTE_LIBRTE_I40E_PMD
-	ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
-					  res->vf_id);
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_i40e_reset_vf_stats(res->port_id,
+						  res->vf_id);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_reset_vf_stats(res->port_id,
+						  res->vf_id);
 #endif
 
 	switch (ret) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index f143541..6ea31ca 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1237,6 +1237,27 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, const uint8_t *mac_addr)
 	return rc;
 }
 
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+
+	HWRM_CHECK_RESULT;
+
+	if (dropped)
+		*dropped = rte_le_to_cpu_64(resp->tx_drop_pkts);
+
+	return rc;
+}
+
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats)
 {
@@ -1274,6 +1295,23 @@ int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 	return rc;
 }
 
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid)
+{
+	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 = rte_cpu_to_le_16(fid);
+
+	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 f51ebcf..5aaf947 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -66,6 +66,9 @@ int bnxt_hwrm_func_reset(struct bnxt *bp);
 int bnxt_hwrm_func_driver_unregister(struct bnxt *bp, uint32_t flags);
 int bnxt_hwrm_func_qstats(struct bnxt *bp, uint16_t fid,
 			  struct rte_eth_stats *stats);
+int bnxt_hwrm_func_qstats_tx_drop(struct bnxt *bp, uint16_t fid,
+				  uint64_t *dropped);
+int bnxt_hwrm_func_clr_stats(struct bnxt *bp, uint16_t fid);
 int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp);
 int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp);
 
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index ade8195..d7d0e35 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -165,6 +165,49 @@ static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
 				tx_bytes)},
 };
 
+static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
+	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_pkts)},
+	{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_pkts)},
+	{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_pkts)},
+	{"tx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_err_pkts)},
+	{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				tx_drop_pkts)},
+	{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_ucast_bytes)},
+	{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_mcast_bytes)},
+	{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				tx_bcast_bytes)},
+	{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_pkts)},
+	{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_pkts)},
+	{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_pkts)},
+	{"rx_err_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_err_pkts)},
+	{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_drop_pkts)},
+	{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_ucast_bytes)},
+	{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_mcast_bytes)},
+	{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_bcast_bytes)},
+	{"rx_agg_pkts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_pkts)},
+	{"rx_agg_bytes", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_bytes)},
+	{"rx_agg_events", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_events)},
+	{"rx_agg_aborts", offsetof(struct hwrm_func_qstats_output,
+				rx_agg_aborts)},
+};
+
 /*
  * Statistics functions
  */
@@ -224,6 +267,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
 
 	unsigned int count, i;
+	uint64_t tx_drop_pkts;
 
 	if (!(bp->flags & BNXT_FLAG_PORT_STATS)) {
 		RTE_LOG(ERR, PMD, "xstats not supported for VF\n");
@@ -231,9 +275,10 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	}
 
 	bnxt_hwrm_port_qstats(bp);
+	bnxt_hwrm_func_qstats_tx_drop(bp, 0xffff, &tx_drop_pkts);
 
 	count = RTE_DIM(bnxt_rx_stats_strings) +
-		RTE_DIM(bnxt_tx_stats_strings);
+		RTE_DIM(bnxt_tx_stats_strings) + 1; /* For tx_drop_pkts */
 
 	if (n < count)
 		return count;
@@ -255,6 +300,10 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+	/* The Tx drop pkts aka the Anti spoof coounter */
+	xstats[count].value = rte_le_to_cpu_64(tx_drop_pkts);
+	count++;
+
 	return count;
 }
 
@@ -262,8 +311,9 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 	struct rte_eth_xstat_name *xstats_names,
 	__rte_unused unsigned int limit)
 {
+	/* Account for the Tx drop pkts aka the Anti spoof counter */
 	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
-				RTE_DIM(bnxt_tx_stats_strings);
+				RTE_DIM(bnxt_tx_stats_strings) + 1;
 	unsigned int i, count;
 
 	if (xstats_names != NULL) {
@@ -284,6 +334,12 @@ int bnxt_dev_xstats_get_names_op(__rte_unused struct rte_eth_dev *eth_dev,
 				bnxt_tx_stats_strings[i].name);
 			count++;
 		}
+
+		snprintf(xstats_names[count].name,
+				sizeof(xstats_names[count].name),
+				"%s",
+				bnxt_func_stats_strings[4].name);
+		count++;
 	}
 	return stat_cnt;
 }
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 644a890..ebe95b6 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -459,3 +459,86 @@ int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 
 	return rc;
 }
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to get VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats(bp, bp->pf.first_vf_id + vf_id, stats);
+}
+
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to reset VF %d stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
+}
+
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d TX drops on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
+					     count);
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 024620f..7bfd376 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -165,6 +165,41 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
 				uint16_t tx_rate, uint64_t q_msk);
 
 /**
+ * Get VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param stats
+ *    A pointer to a structure of type *rte_eth_stats* to be filled with
+ *    the values of device counters supported statistics:
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+
+int rte_pmd_bnxt_get_vf_stats(uint8_t port,
+			      uint16_t vf_id,
+			      struct rte_eth_stats *stats);
+
+/**
+ * Clear VF's statistics
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
+				uint16_t vf_id);
+
+/**
  * Enable/Disable VF VLAN anti spoof
  *
  * @param port
@@ -181,4 +216,21 @@ int rte_pmd_bnxt_set_vf_rate_limit(uint8_t port, uint16_t vf,
  *   - (-EINVAL) if bad parameter.
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
+
+/**
+ * Queries the TX drop counter for the function
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf_id
+ *    VF on which to get.
+ * @param count
+ *    Pointer to a uint64_t that will be populated with the counter value.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ */
+int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
+				      uint64_t *count);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 770b076..f0eda7b 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -9,6 +9,9 @@ DPDK_17.08 {
 	rte_pmd_bnxt_set_vf_vlan_stripq;
 	rte_pmd_bnxt_set_vf_vlan_filter;
 	rte_pmd_bnxt_set_vf_vlan_anti_spoof;
+	rte_pmd_bnxt_get_vf_stats;
+	rte_pmd_bnxt_reset_vf_stats;
+	rte_pmd_bnxt_get_vf_tx_drop_count;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 22/26] net/bnxt: add code to determine the Rx status of VF
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (20 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
                               ` (4 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to determine the Rx status of a VF.
It adds the rte_pmd_bnxt_get_vf_rx_status call, which calculates
the VNIC count of the function to get the Rx status.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id

v3->v4: fix a rebase error
---
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 26 ++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 17 +++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 69 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 6ea31ca..721e652 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2626,6 +2626,30 @@ int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on)
 	return rc;
 }
 
+static void bnxt_vnic_count(struct bnxt_vnic_info *vnic, void *cbdata)
+{
+	uint32_t *count = cbdata;
+
+	if (vnic->func_default)
+		*count = *count + 1;
+}
+
+static int bnxt_vnic_count_hwrm_stub(struct bnxt *bp __rte_unused,
+				     struct bnxt_vnic_info *vnic __rte_unused)
+{
+	return 0;
+}
+
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf)
+{
+	uint32_t count = 0;
+
+	bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf, bnxt_vnic_count,
+	    &count, bnxt_vnic_count_hwrm_stub);
+
+	return count;
+}
+
 static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
 					uint16_t *vnic_ids)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 5aaf947..01e72fa 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -141,6 +141,7 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
 	int (*hwrm_cb)(struct bnxt *bp, struct bnxt_vnic_info *vnic));
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index ebe95b6..05dfbb5 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -515,6 +515,32 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
 	return bnxt_hwrm_func_clr_stats(bp, bp->pf.first_vf_id + vf_id);
 }
 
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to query VF %d RX stats on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	return bnxt_vf_default_vnic_count(bp, vf_id);
+}
+
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 7bfd376..0987c0f 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -217,6 +217,23 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+
+/**
+ * Returns the number of default RX queues on a VF
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @return
+ *   - Non-negative value - Number of default RX queues
+ *   - (-EINVAL) if bad parameter.
+ *   - (-ENOTSUP) if on a function without VFs
+ *   - (-ENOMEM) on an allocation failure
+ *   - (-1) firmware interface error
+ */
+int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
+
 /**
  * Queries the TX drop counter for the function
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index f0eda7b..c68c125 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -3,6 +3,7 @@ DPDK_17.08 {
 
 	rte_pmd_bnxt_set_tx_loopback;
 	rte_pmd_bnxt_set_all_queues_drop_en;
+	rte_pmd_bnxt_get_vf_rx_status;
 	rte_pmd_bnxt_set_vf_mac_addr;
 	rte_pmd_bnxt_set_vf_mac_anti_spoof;
 	rte_pmd_bnxt_set_vf_rate_limit;
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 23/26] net/bnxt: add support to add a VF MAC address
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (21 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
                               ` (3 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds support to allocate a filter and program
it in the hardware for every MAC address added to the specified
function.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
---
 drivers/net/bnxt/bnxt_filter.c            | 22 +++++++++
 drivers/net/bnxt/bnxt_filter.h            |  1 +
 drivers/net/bnxt/rte_pmd_bnxt.c           | 76 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 18 ++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 5 files changed, 118 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_filter.c b/drivers/net/bnxt/bnxt_filter.c
index 0afde86..e9aac27 100644
--- a/drivers/net/bnxt/bnxt_filter.c
+++ b/drivers/net/bnxt/bnxt_filter.c
@@ -68,6 +68,22 @@ struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp)
 	return filter;
 }
 
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf)
+{
+	struct bnxt_filter_info *filter;
+
+	filter = rte_zmalloc("bnxt_vf_filter_info", sizeof(*filter), 0);
+	if (!filter) {
+		RTE_LOG(ERR, PMD, "Failed to alloc memory for VF %hu filters\n",
+			vf);
+		return NULL;
+	}
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	STAILQ_INSERT_TAIL(&bp->pf.vf_info[vf].filter, filter, next);
+	return filter;
+}
+
 void bnxt_init_filters(struct bnxt *bp)
 {
 	struct bnxt_filter_info *filter;
@@ -102,6 +118,12 @@ void bnxt_free_all_filters(struct bnxt *bp)
 			STAILQ_INIT(&vnic->filter);
 		}
 	}
+
+	for (i = 0; i < bp->pf.max_vfs; i++) {
+		STAILQ_FOREACH(filter, &bp->pf.vf_info[i].filter, next) {
+			bnxt_hwrm_clear_filter(bp, filter);
+		}
+	}
 }
 
 void bnxt_free_filter_mem(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_filter.h b/drivers/net/bnxt/bnxt_filter.h
index 353b7f7..613b2ee 100644
--- a/drivers/net/bnxt/bnxt_filter.h
+++ b/drivers/net/bnxt/bnxt_filter.h
@@ -68,6 +68,7 @@ struct bnxt_filter_info {
 };
 
 struct bnxt_filter_info *bnxt_alloc_filter(struct bnxt *bp);
+struct bnxt_filter_info *bnxt_alloc_vf_filter(struct bnxt *bp, uint16_t vf);
 void bnxt_init_filters(struct bnxt *bp);
 void bnxt_free_all_filters(struct bnxt *bp);
 void bnxt_free_filter_mem(struct bnxt *bp);
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 05dfbb5..40a3c8c 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -568,3 +568,79 @@ int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 	return bnxt_hwrm_func_qstats_tx_drop(bp, bp->pf.first_vf_id + vf_id,
 					     count);
 }
+
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
+				uint32_t vf_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	struct bnxt_filter_info *filter;
+	struct bnxt_vnic_info vnic;
+	struct ether_addr dflt_mac;
+	int rc;
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf_id >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to config VF %d MAC on non-PF port %d!\n",
+			vf_id, port);
+		return -ENOTSUP;
+	}
+
+	/* If the VF currently uses a random MAC, update default to this one */
+	if (bp->pf.vf_info[vf_id].random_mac) {
+		if (rte_pmd_bnxt_get_vf_rx_status(port, vf_id) <= 0)
+			rc = bnxt_hwrm_func_vf_mac(bp, vf_id, (uint8_t *)addr);
+	}
+
+	/* query the default VNIC id used by the function */
+	rc = bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(bp, vf_id);
+	if (rc < 0)
+		goto exit;
+
+	memset(&vnic, 0, sizeof(struct bnxt_vnic_info));
+	vnic.fw_vnic_id = rte_le_to_cpu_16(rc);
+	rc = bnxt_hwrm_vnic_qcfg(bp, &vnic, bp->pf.first_vf_id + vf_id);
+	if (rc < 0)
+		goto exit;
+
+	STAILQ_FOREACH(filter, &bp->pf.vf_info[vf_id].filter, next) {
+		if (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) &&
+		    memcmp(addr, filter->l2_addr, ETHER_ADDR_LEN) == 0) {
+			bnxt_hwrm_clear_filter(bp, filter);
+			break;
+		}
+	}
+
+	if (filter == NULL)
+		filter = bnxt_alloc_vf_filter(bp, vf_id);
+
+	filter->fw_l2_filter_id = UINT64_MAX;
+	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, addr, ETHER_ADDR_LEN);
+	memset(filter->l2_addr_mask, 0xff, ETHER_ADDR_LEN);
+
+	/* Do not add a filter for the default MAC */
+	if (bnxt_hwrm_func_qcfg_vf_default_mac(bp, vf_id, &dflt_mac) ||
+	    memcmp(filter->l2_addr, dflt_mac.addr_bytes, ETHER_ADDR_LEN))
+		rc = bnxt_hwrm_set_filter(bp, vnic.fw_vnic_id, filter);
+
+exit:
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 0987c0f..a523a95 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -250,4 +250,22 @@ int rte_pmd_bnxt_get_vf_rx_status(uint8_t port, uint16_t vf_id);
  */
 int rte_pmd_bnxt_get_vf_tx_drop_count(uint8_t port, uint16_t vf_id,
 				      uint64_t *count);
+
+/**
+ * Programs the MAC address for the function specified
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param mac_addr
+ *    The MAC address to be programmed in the filter.
+ * @param vf_id
+ *    VF on which to get.
+ * @return
+ *   - Positive Non-zero value - Error code from HWRM
+ *   - (-EINVAL) invalid vf_id specified.
+ *   - (-ENOTSUP) Ethernet device is not a PF
+ *   - (-ENOMEM) on an allocation failure
+ */
+int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *mac_addr,
+				uint32_t vf_id);
 #endif /* _PMD_BNXT_H_ */
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index c68c125..e3cc7bc 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -13,6 +13,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_stats;
 	rte_pmd_bnxt_reset_vf_stats;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
+	rte_pmd_bnxt_mac_addr_add;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 24/26] net/bnxt: add code to configure a default VF VLAN
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (22 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
                               ` (2 subsequent siblings)
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit, Stephen Hurd

This patch adds code to insert a default VF VLAN.
Also track the current default VLAN per vnic for the VF.
When setting the default VLAN, avoid setting it to the current value.

Signed-off-by: Stephen Hurd <stephen.hurd@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    |  5 ++++
 drivers/net/bnxt/bnxt.h                   |  2 +-
 drivers/net/bnxt/bnxt_hwrm.c              | 39 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 38 ++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 20 ++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 7 files changed, 106 insertions(+), 1 deletion(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index f49d83b..ff623c1 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -11334,6 +11334,11 @@ cmd_set_vf_vlan_insert_parsed(
 		ret = rte_pmd_i40e_set_vf_vlan_insert(res->port_id, res->vf_id,
 			res->vlan_id);
 #endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_vlan_insert(res->port_id, res->vf_id,
+			res->vlan_id);
+#endif
 
 	switch (ret) {
 	case 0:
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c1f9095..54428ba 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -103,8 +103,8 @@ struct bnxt_child_vf_info {
 	uint32_t		func_cfg_flags;
 	uint32_t		l2_rx_mask;
 	uint16_t		fid;
-	uint16_t		dflt_vlan;
 	uint16_t		max_tx_rate;
+	uint16_t		dflt_vlan;
 	uint16_t		vlan_count;
 	uint8_t			mac_spoof_en;
 	uint8_t			vlan_spoof_en;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 721e652..bf0526d 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2069,6 +2069,27 @@ static void reserve_resources_from_vf(struct bnxt *bp,
 	bp->max_ring_grps -= rte_le_to_cpu_16(resp->max_hw_ring_grps);
 }
 
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_qcfg_input req = {0};
+	struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc;
+
+	/* Check for zero MAC address */
+	HWRM_PREP(req, FUNC_QCFG, -1, resp);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	if (rc) {
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg failed rc:%d\n", rc);
+		return -1;
+	} else if (resp->error_code) {
+		rc = rte_le_to_cpu_16(resp->error_code);
+		RTE_LOG(ERR, PMD, "hwrm_func_qcfg error %d\n", rc);
+		return -1;
+	}
+	return rte_le_to_cpu_16(resp->vlan);
+}
+
 static int update_pf_resource_max(struct bnxt *bp)
 {
 	struct hwrm_func_qcfg_input req = {0};
@@ -2423,6 +2444,24 @@ int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 	return rc;
 }
 
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf)
+{
+	struct hwrm_func_cfg_input req = {0};
+	struct hwrm_func_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	int rc = 0;
+
+	HWRM_PREP(req, FUNC_CFG, -1, resp);
+	req.flags = rte_cpu_to_le_32(bp->pf.vf_info[vf].func_cfg_flags);
+	req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
+	req.enables |= rte_cpu_to_le_32(HWRM_FUNC_CFG_INPUT_ENABLES_DFLT_VLAN);
+	req.dflt_vlan = rte_cpu_to_le_16(bp->pf.vf_info[vf].dflt_vlan);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
+	HWRM_CHECK_RESULT;
+
+	return rc;
+}
+
 int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id,
 			      void *encaped, size_t ec_size)
 {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 01e72fa..33d2885 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -128,8 +128,10 @@ int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf,
 int bnxt_hwrm_pf_evb_mode(struct bnxt *bp);
 int bnxt_hwrm_func_bw_cfg(struct bnxt *bp, uint16_t vf,
 			uint16_t max_bw, uint16_t enables);
+int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_func_qcfg_vf_default_mac(struct bnxt *bp, uint16_t vf,
 				       struct ether_addr *mac);
+int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf);
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type);
 int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 40a3c8c..2ecd445 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -644,3 +644,41 @@ int rte_pmd_bnxt_mac_addr_add(uint8_t port, struct ether_addr *addr,
 exit:
 	return rc;
 }
+
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (vf >= dev_info.max_vfs)
+		return -EINVAL;
+
+	if (!BNXT_PF(bp)) {
+		RTE_LOG(ERR, PMD,
+			"Attempt to set VF %d vlan insert on non-PF port %d!\n",
+			vf, port);
+		return -ENOTSUP;
+	}
+
+	bp->pf.vf_info[vf].dflt_vlan = vlan_id;
+	if (bnxt_hwrm_func_qcfg_current_vf_vlan(bp, vf) ==
+	    bp->pf.vf_info[vf].dflt_vlan)
+		return 0;
+
+	rc = bnxt_hwrm_set_vf_vlan(bp, vf);
+
+	return rc;
+}
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index a523a95..2144601 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -92,6 +92,26 @@ int
 rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on);
 
 /**
+ * Enable/Disable vf vlan insert
+ *
+ * @param port
+ *    The port identifier of the Ethernet device.
+ * @param vf
+ *    ID specifying VF.
+ * @param vlan_id
+ *    0 - Disable VF's vlan insert.
+ *    n - Enable; n is inserted as the vlan id.
+ *
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int
+rte_pmd_bnxt_set_vf_vlan_insert(uint8_t port, uint16_t vf,
+		uint16_t vlan_id);
+
+/**
  * Enable/Disable hardware VF VLAN filtering by an Ethernet device of
  * received VLAN packets tagged with a given VLAN Tag Identifier.
  *
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index e3cc7bc..9433a1e 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -14,6 +14,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_reset_vf_stats;
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_mac_addr_add;
+	rte_pmd_bnxt_set_vf_vlan_insert;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 25/26] net/bnxt: add support to set VF rxmode
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (23 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-01 17:07             ` [PATCH v4 26/26] doc: update release notes Ajit Khaparde
  2017-06-06 14:48             ` [PATCH v4 00/26] bnxt patchset Ferruh Yigit
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

This patch adds support to configure the VF L2 Rx settings.
The per VF setting is maintained in bnxt_child_vf_info.l2_rx_mask

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: regroup related patches and incorporate other review comments

v2->v3:
  - Rebasing to next-net tree
  - Use net/bnxt instead of just bnxt in patch subject
  - Add a protection against application calling the API for different
  vendor's port_id
  - update testpmd to use these vendor specific APIs
---
 app/test-pmd/cmdline.c                    | 15 +++++++--
 drivers/net/bnxt/bnxt_hwrm.c              | 24 ++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.h              |  2 ++
 drivers/net/bnxt/bnxt_rxq.c               | 13 ++++++--
 drivers/net/bnxt/bnxt_vnic.h              |  5 +++
 drivers/net/bnxt/rte_pmd_bnxt.c           | 54 +++++++++++++++++++++++++++++++
 drivers/net/bnxt/rte_pmd_bnxt.h           | 19 +++++++++++
 drivers/net/bnxt/rte_pmd_bnxt_version.map |  1 +
 8 files changed, 124 insertions(+), 9 deletions(-)

diff --git a/app/test-pmd/cmdline.c b/app/test-pmd/cmdline.c
index ff623c1..28ff7cf 100644
--- a/app/test-pmd/cmdline.c
+++ b/app/test-pmd/cmdline.c
@@ -6802,7 +6802,7 @@ cmd_set_vf_rxmode_parsed(void *parsed_result,
 		       __attribute__((unused)) struct cmdline *cl,
 		       __attribute__((unused)) void *data)
 {
-	int ret;
+	int ret = -ENOTSUP;
 	uint16_t rx_mode = 0;
 	struct cmd_set_vf_rxmode *res = parsed_result;
 
@@ -6818,7 +6818,16 @@ cmd_set_vf_rxmode_parsed(void *parsed_result,
 			rx_mode |= ETH_VMDQ_ACCEPT_MULTICAST;
 	}
 
-	ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id, rx_mode, (uint8_t)is_on);
+#ifdef RTE_LIBRTE_IXGBE_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_ixgbe_set_vf_rxmode(res->port_id, res->vf_id,
+						  rx_mode, (uint8_t)is_on);
+#endif
+#ifdef RTE_LIBRTE_BNXT_PMD
+	if (ret == -ENOTSUP)
+		ret = rte_pmd_bnxt_set_vf_rxmode(res->port_id, res->vf_id,
+						 rx_mode, (uint8_t)is_on);
+#endif
 	if (ret < 0)
 		printf("bad VF receive mode parameter, return code = %d \n",
 		ret);
@@ -13786,9 +13795,9 @@ cmdline_parse_ctx_t main_ctx[] = {
 	(cmdline_parse_inst_t *)&cmd_set_macsec_offload_off,
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sc,
 	(cmdline_parse_inst_t *)&cmd_set_macsec_sa,
-	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_set_vf_traffic,
 #endif
+	(cmdline_parse_inst_t *)&cmd_set_vf_rxmode,
 	(cmdline_parse_inst_t *)&cmd_vf_rate_limit,
 	(cmdline_parse_inst_t *)&cmd_vf_rxvlan_filter,
 	(cmdline_parse_inst_t *)&cmd_set_vf_mac_addr,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index bf0526d..6d98d5a 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -229,23 +229,29 @@ int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp,
 	/* FIXME add multicast flag, when multicast adding options is supported
 	 * by ethtool.
 	 */
+	if (vnic->flags & BNXT_VNIC_INFO_BCAST)
+		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST;
+	if (vnic->flags & BNXT_VNIC_INFO_UNTAGGED)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLAN_NONVLAN;
 	if (vnic->flags & BNXT_VNIC_INFO_PROMISC)
-		mask = HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_PROMISCUOUS;
+		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;
+	if (vnic->flags & BNXT_VNIC_INFO_MCAST)
+		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 	if (vnic->mc_addr_cnt) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_MCAST;
 		req.num_mc_entries = rte_cpu_to_le_32(vnic->mc_addr_cnt);
 		req.mc_tbl_addr = rte_cpu_to_le_64(vnic->mc_list_dma_addr);
 	}
-	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
-				    mask);
 	if (vlan_count && vlan_table) {
 		mask |= HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_VLANONLY;
 		req.vlan_tag_tbl_addr = rte_cpu_to_le_16(
 			 rte_mem_virt2phy(vlan_table));
 		req.num_vlan_tags = rte_cpu_to_le_32((uint32_t)vlan_count);
 	}
+	req.mask = rte_cpu_to_le_32(HWRM_CFA_L2_SET_RX_MASK_INPUT_MASK_BCAST |
+				    mask);
 
 	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
 
@@ -2317,6 +2323,18 @@ int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf)
 	return rc;
 }
 
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp)
+{
+	uint32_t *flag = flagp;
+
+	vnic->flags = *flag;
+}
+
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+}
+
 int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
 {
 	int rc = 0;
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 33d2885..a603dda 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -143,6 +143,8 @@ int bnxt_hwrm_port_clr_stats(struct bnxt *bp);
 int bnxt_hwrm_port_led_cfg(struct bnxt *bp, bool led_on);
 int bnxt_hwrm_port_led_qcaps(struct bnxt *bp);
 int bnxt_hwrm_func_cfg_vf_set_flags(struct bnxt *bp, uint16_t vf);
+void vf_vnic_set_rxmask_cb(struct bnxt_vnic_info *vnic, void *flagp);
+int bnxt_set_rx_mask_no_vlan(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_vf_default_vnic_count(struct bnxt *bp, uint16_t vf);
 int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
 	void (*vnic_cb)(struct bnxt_vnic_info *, void *), void *cbdata,
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index d8b970e..0793820 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -76,6 +76,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 			rc = -ENOMEM;
 			goto err_out;
 		}
+		vnic->flags |= BNXT_VNIC_INFO_BCAST;
 		STAILQ_INSERT_TAIL(&bp->ff_pool[0], vnic, next);
 		bp->nr_vnics++;
 
@@ -120,6 +121,9 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		}
 		/* For each pool, allocate MACVLAN CFA rule & VNIC */
 		if (!pools) {
+			pools = RTE_MIN(bp->max_vnics,
+			    RTE_MIN(bp->max_l2_ctx,
+			     RTE_MIN(bp->max_rsscos_ctx, ETH_64_POOLS)));
 			RTE_LOG(ERR, PMD,
 				"VMDq pool not set, defaulted to 64\n");
 			pools = ETH_64_POOLS;
@@ -137,6 +141,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 				rc = -ENOMEM;
 				goto err_out;
 			}
+			vnic->flags |= BNXT_VNIC_INFO_BCAST;
 			STAILQ_INSERT_TAIL(&bp->ff_pool[i], vnic, next);
 			bp->nr_vnics++;
 
@@ -177,6 +182,7 @@ int bnxt_mq_rx_configure(struct bnxt *bp)
 		rc = -ENOMEM;
 		goto err_out;
 	}
+	vnic->flags |= BNXT_VNIC_INFO_BCAST;
 	/* 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];
@@ -295,7 +301,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	int rc = 0;
 
 	if (!nb_desc || nb_desc > MAX_RX_DESC_CNT) {
-		RTE_LOG(ERR, PMD, "nb_desc %d is invalid", nb_desc);
+		RTE_LOG(ERR, PMD, "nb_desc %d is invalid\n", nb_desc);
 		rc = -EINVAL;
 		goto out;
 	}
@@ -308,7 +314,7 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	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!");
+		RTE_LOG(ERR, PMD, "bnxt_rx_queue allocation failed!\n");
 		rc = -ENOMEM;
 		goto out;
 	}
@@ -333,7 +339,8 @@ int bnxt_rx_queue_setup_op(struct rte_eth_dev *eth_dev,
 	/* Allocate RX ring hardware descriptors */
 	if (bnxt_alloc_rings(bp, queue_idx, NULL, rxq->rx_ring, rxq->cp_ring,
 			"rxr")) {
-		RTE_LOG(ERR, PMD, "ring_dma_zone_reserve for rx_ring failed!");
+		RTE_LOG(ERR, PMD,
+			"ring_dma_zone_reserve for rx_ring failed!\n");
 		bnxt_rx_queue_release_op(rxq);
 		rc = -ENOMEM;
 		goto out;
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 0d50224..993f221 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -64,6 +64,11 @@ struct bnxt_vnic_info {
 	uint32_t	flags;
 #define BNXT_VNIC_INFO_PROMISC			(1 << 0)
 #define BNXT_VNIC_INFO_ALLMULTI			(1 << 1)
+#define BNXT_VNIC_INFO_BCAST			(1 << 2)
+#define BNXT_VNIC_INFO_UCAST			(1 << 3)
+#define BNXT_VNIC_INFO_MCAST			(1 << 4)
+#define BNXT_VNIC_INFO_TAGGED			(1 << 5)
+#define BNXT_VNIC_INFO_UNTAGGED			(1 << 6)
 
 	uint16_t	cos_rule;
 	uint16_t	lb_rule;
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.c b/drivers/net/bnxt/rte_pmd_bnxt.c
index 2ecd445..3f75f32 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.c
+++ b/drivers/net/bnxt/rte_pmd_bnxt.c
@@ -377,6 +377,60 @@ rte_pmd_bnxt_set_vf_vlan_stripq(uint8_t port, uint16_t vf, uint8_t on)
 	return rc;
 }
 
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on)
+{
+	struct rte_eth_dev *dev;
+	struct rte_eth_dev_info dev_info;
+	uint16_t flag = 0;
+	struct bnxt *bp;
+	int rc;
+
+	RTE_ETH_VALID_PORTID_OR_ERR_RET(port, -ENODEV);
+
+	dev = &rte_eth_devices[port];
+	if (!is_bnxt_supported(dev))
+		return -ENOTSUP;
+
+	rte_eth_dev_info_get(port, &dev_info);
+	bp = (struct bnxt *)dev->data->dev_private;
+
+	if (!bp->pf.vf_info)
+		return -EINVAL;
+
+	if (vf >= bp->pdev->max_vfs)
+		return -EINVAL;
+
+	if (rx_mask & (ETH_VMDQ_ACCEPT_UNTAG | ETH_VMDQ_ACCEPT_HASH_MC)) {
+		RTE_LOG(ERR, PMD, "Currently cannot toggle this setting\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_HASH_UC && !on) {
+		RTE_LOG(ERR, PMD, "Currently cannot disable UC Rx\n");
+		return -ENOTSUP;
+	}
+
+	if (rx_mask & ETH_VMDQ_ACCEPT_BROADCAST)
+		flag |= BNXT_VNIC_INFO_BCAST;
+	if (rx_mask & ETH_VMDQ_ACCEPT_MULTICAST)
+		flag |= BNXT_VNIC_INFO_ALLMULTI;
+
+	if (on)
+		bp->pf.vf_info[vf].l2_rx_mask |= flag;
+	else
+		bp->pf.vf_info[vf].l2_rx_mask &= ~flag;
+
+	rc = bnxt_hwrm_func_vf_vnic_query_and_config(bp, vf,
+					vf_vnic_set_rxmask_cb,
+					&bp->pf.vf_info[vf].l2_rx_mask,
+					bnxt_set_rx_mask_no_vlan);
+	if (rc)
+		RTE_LOG(ERR, PMD, "bnxt_hwrm_func_vf_vnic_set_rxmask failed\n");
+
+	return rc;
+}
+
 int rte_pmd_bnxt_set_vf_vlan_filter(uint8_t port, uint16_t vlan,
 				    uint64_t vf_mask, uint8_t vlan_on)
 {
diff --git a/drivers/net/bnxt/rte_pmd_bnxt.h b/drivers/net/bnxt/rte_pmd_bnxt.h
index 2144601..db9ce77 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt.h
+++ b/drivers/net/bnxt/rte_pmd_bnxt.h
@@ -237,6 +237,25 @@ int rte_pmd_bnxt_reset_vf_stats(uint8_t port,
  */
 int rte_pmd_bnxt_set_vf_vlan_anti_spoof(uint8_t port, uint16_t vf, uint8_t on);
 
+/**
+ * Set RX L2 Filtering mode of a VF of an Ethernet device.
+ *
+ * @param port
+ *   The port identifier of the Ethernet device.
+ * @param vf
+ *   VF id.
+ * @param rx_mask
+ *    The RX mode mask
+ * @param on
+ *    1 - Enable a VF RX mode.
+ *    0 - Disable a VF RX mode.
+ * @return
+ *   - (0) if successful.
+ *   - (-ENODEV) if *port_id* invalid.
+ *   - (-EINVAL) if bad parameter.
+ */
+int rte_pmd_bnxt_set_vf_rxmode(uint8_t port, uint16_t vf,
+				uint16_t rx_mask, uint8_t on);
 
 /**
  * Returns the number of default RX queues on a VF
diff --git a/drivers/net/bnxt/rte_pmd_bnxt_version.map b/drivers/net/bnxt/rte_pmd_bnxt_version.map
index 9433a1e..f61c736 100644
--- a/drivers/net/bnxt/rte_pmd_bnxt_version.map
+++ b/drivers/net/bnxt/rte_pmd_bnxt_version.map
@@ -15,6 +15,7 @@ DPDK_17.08 {
 	rte_pmd_bnxt_get_vf_tx_drop_count;
 	rte_pmd_bnxt_mac_addr_add;
 	rte_pmd_bnxt_set_vf_vlan_insert;
+	rte_pmd_bnxt_set_vf_rxmode;
 
 	local: *;
 };
-- 
2.10.1 (Apple Git-78)

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

* [PATCH v4 26/26] doc: update release notes
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (24 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
@ 2017-06-01 17:07             ` Ajit Khaparde
  2017-06-06 14:48             ` [PATCH v4 00/26] bnxt patchset Ferruh Yigit
  26 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-01 17:07 UTC (permalink / raw)
  To: dev; +Cc: ferruh.yigit

Update release doc briefly describing updates to bnxt PMD.

v1->v2:
  - Rebasing to next-net tree
  - Use doc in the patch subject line

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 doc/guides/rel_notes/release_17_08.rst | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/doc/guides/rel_notes/release_17_08.rst b/doc/guides/rel_notes/release_17_08.rst
index 7f12120..7bf6d25 100644
--- a/doc/guides/rel_notes/release_17_08.rst
+++ b/doc/guides/rel_notes/release_17_08.rst
@@ -56,6 +56,16 @@ New Features
   TX and RX path reworked to improve performance.  Also reduced latency
   for slow traffic.
 
+* **Updated bnxt PMD.**
+
+  Major enhancements include:
+  * Support MTU modification.
+  * Support LRO.
+  * Support VLAN filter and strip functionality.
+  * Other enhancements to add support for more dev_ops.
+  * Add PMD specific APIs mainly to control VF from PF.
+  * Update HWRM version to 1.7.7
+
 
 Resolved Issues
 ---------------
-- 
2.10.1 (Apple Git-78)

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

* Re: [PATCH v4 12/26] net/bnxt: add support to set MTU
  2017-06-01 17:07             ` [PATCH v4 12/26] net/bnxt: add support to set MTU Ajit Khaparde
@ 2017-06-06 12:47               ` Ferruh Yigit
  2017-06-06 14:00                 ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-06-06 12:47 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Steeven Li

On 6/1/2017 6:07 PM, Ajit Khaparde wrote:
> This patch adds support to modify MTU using the set_mtu dev_op.
> To support frames > 2k, the PMD creates an aggregator ring.
> When a frame greater than 2k is received, it is fragmented
> and the resulting fragments are DMA'ed to the aggregator ring.
> Now the driver can support jumbo frames upto 9500 bytes.
> 
> Signed-off-by: Steeven Li <steeven.li@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> 
> --
> v1->v2: regroup related patches and incorporate other review comments
> 
> v2->v3:
>   - rebasing to next-net tree
>   - Use net/bnxt instead of just bnxt in patch subject

<...>

> +int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
> +			struct bnxt_vnic_info *vnic)
> +{
> +	int rc = 0;
> +	struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
> +	struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
> +	uint16_t size;
> +
> +	HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
> +
> +	req.flags = rte_cpu_to_le_32(
> +//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT |
> +			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_JUMBO_PLACEMENT);
> +//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 | //TODO
> +//			HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);

Hi Ajit,

Would you mind if I remove these commented code, in this patch and other
patches, while applying?

Of course it would be better if you send the new version of the patch to
fix them, but I believe I can do this faster. Just let me know please.

Thanks,
ferruh

> +	req.enables = rte_cpu_to_le_32(
> +		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
> +//		HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
> +
> +	size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
> +	size -= RTE_PKTMBUF_HEADROOM;
> +
> +	req.jumbo_thresh = rte_cpu_to_le_16(size);
> +//	req.hds_threshold = rte_cpu_to_le_16(size);
> +	req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
> +
> +	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
> +
> +	HWRM_CHECK_RESULT;
> +
> +	return rc;
> +}

<...>

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

* Re: [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop
  2017-06-01 17:07             ` [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
@ 2017-06-06 12:53               ` Ferruh Yigit
  2017-06-06 14:09                 ` Ajit Khaparde
  0 siblings, 1 reply; 130+ messages in thread
From: Ferruh Yigit @ 2017-06-06 12:53 UTC (permalink / raw)
  To: Ajit Khaparde, dev; +Cc: Steeven Li

On 6/1/2017 6:07 PM, Ajit Khaparde wrote:
> Add functions rte_pmd_bnxt_set_tx_loopback,
> rte_pmd_bnxt_set_all_queues_drop_en and
> rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
> queue_drop and VF MAC address setting in the hardware.
> It also adds the necessary functions to send the HWRM commands
> to the firmware.

>From the patch title it is clear that this patch add three different
functionality.

For this patchset, since it already went for a few releases I wouldn't
mind, but for future, please send separate patches for each individual
feature.

Thanks,
ferruh

> 
> Signed-off-by: Steeven Li <steeven.li@broadcom.com>
> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>

<...>

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

* Re: [PATCH v4 12/26] net/bnxt: add support to set MTU
  2017-06-06 12:47               ` Ferruh Yigit
@ 2017-06-06 14:00                 ` Ajit Khaparde
  2017-06-06 14:25                   ` Ferruh Yigit
  0 siblings, 1 reply; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-06 14:00 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev, Steeven Li

Ferruh, if it save times, can you please do that.

Thanks
Ajit

On Tue, Jun 6, 2017 at 7:47 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> On 6/1/2017 6:07 PM, Ajit Khaparde wrote:
> > This patch adds support to modify MTU using the set_mtu dev_op.
> > To support frames > 2k, the PMD creates an aggregator ring.
> > When a frame greater than 2k is received, it is fragmented
> > and the resulting fragments are DMA'ed to the aggregator ring.
> > Now the driver can support jumbo frames upto 9500 bytes.
> >
> > Signed-off-by: Steeven Li <steeven.li@broadcom.com>
> > Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
> >
> > --
> > v1->v2: regroup related patches and incorporate other review comments
> >
> > v2->v3:
> >   - rebasing to next-net tree
> >   - Use net/bnxt instead of just bnxt in patch subject
>
> <...>
>
> > +int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
> > +                     struct bnxt_vnic_info *vnic)
> > +{
> > +     int rc = 0;
> > +     struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
> > +     struct hwrm_vnic_plcmodes_cfg_output *resp =
> bp->hwrm_cmd_resp_addr;
> > +     uint16_t size;
> > +
> > +     HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
> > +
> > +     req.flags = rte_cpu_to_le_32(
> > +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT
> |
> > +                     HWRM_VNIC_PLCMODES_CFG_INPUT_
> FLAGS_JUMBO_PLACEMENT);
> > +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 |
> //TODO
> > +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
>
> Hi Ajit,
>
> Would you mind if I remove these commented code, in this patch and other
> patches, while applying?
>
> Of course it would be better if you send the new version of the patch to
> fix them, but I believe I can do this faster. Just let me know please.
>
> Thanks,
> ferruh
>
> > +     req.enables = rte_cpu_to_le_32(
> > +             HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
> > +//           HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
> > +
> > +     size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
> > +     size -= RTE_PKTMBUF_HEADROOM;
> > +
> > +     req.jumbo_thresh = rte_cpu_to_le_16(size);
> > +//   req.hds_threshold = rte_cpu_to_le_16(size);
> > +     req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
> > +
> > +     rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
> > +
> > +     HWRM_CHECK_RESULT;
> > +
> > +     return rc;
> > +}
>
> <...>
>
>

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

* Re: [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop
  2017-06-06 12:53               ` Ferruh Yigit
@ 2017-06-06 14:09                 ` Ajit Khaparde
  0 siblings, 0 replies; 130+ messages in thread
From: Ajit Khaparde @ 2017-06-06 14:09 UTC (permalink / raw)
  To: Ferruh Yigit; +Cc: dev

On Tue, Jun 6, 2017 at 7:53 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:

> On 6/1/2017 6:07 PM, Ajit Khaparde wrote:
> > Add functions rte_pmd_bnxt_set_tx_loopback,
> > rte_pmd_bnxt_set_all_queues_drop_en and
> > rte_pmd_bnxt_set_vf_mac_addr to configure tx_loopback,
> > queue_drop and VF MAC address setting in the hardware.
> > It also adds the necessary functions to send the HWRM commands
> > to the firmware.
>
> From the patch title it is clear that this patch add three different
> functionality.
>
> For this patchset, since it already went for a few releases I wouldn't
> mind, but for future, please send separate patches for each individual
> feature.



​Sure, Ferruh.

Thanks
Ajit​

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

* Re: [PATCH v4 12/26] net/bnxt: add support to set MTU
  2017-06-06 14:00                 ` Ajit Khaparde
@ 2017-06-06 14:25                   ` Ferruh Yigit
  0 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-06-06 14:25 UTC (permalink / raw)
  To: Ajit Khaparde; +Cc: dev, Steeven Li

On 6/6/2017 3:00 PM, Ajit Khaparde wrote:
> Ferruh, if it save times, can you please do that.

Done.

> 
> Thanks
> Ajit
> 
> On Tue, Jun 6, 2017 at 7:47 AM, Ferruh Yigit <ferruh.yigit@intel.com> wrote:
> 
>> On 6/1/2017 6:07 PM, Ajit Khaparde wrote:
>>> This patch adds support to modify MTU using the set_mtu dev_op.
>>> To support frames > 2k, the PMD creates an aggregator ring.
>>> When a frame greater than 2k is received, it is fragmented
>>> and the resulting fragments are DMA'ed to the aggregator ring.
>>> Now the driver can support jumbo frames upto 9500 bytes.
>>>
>>> Signed-off-by: Steeven Li <steeven.li@broadcom.com>
>>> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
>>>
>>> --
>>> v1->v2: regroup related patches and incorporate other review comments
>>>
>>> v2->v3:
>>>   - rebasing to next-net tree
>>>   - Use net/bnxt instead of just bnxt in patch subject
>>
>> <...>
>>
>>> +int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
>>> +                     struct bnxt_vnic_info *vnic)
>>> +{
>>> +     int rc = 0;
>>> +     struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
>>> +     struct hwrm_vnic_plcmodes_cfg_output *resp =
>> bp->hwrm_cmd_resp_addr;
>>> +     uint16_t size;
>>> +
>>> +     HWRM_PREP(req, VNIC_PLCMODES_CFG, -1, resp);
>>> +
>>> +     req.flags = rte_cpu_to_le_32(
>>> +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_REGULAR_PLACEMENT
>> |
>>> +                     HWRM_VNIC_PLCMODES_CFG_INPUT_
>> FLAGS_JUMBO_PLACEMENT);
>>> +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV4 |
>> //TODO
>>> +//                   HWRM_VNIC_PLCMODES_CFG_INPUT_FLAGS_HDS_IPV6);
>>
>> Hi Ajit,
>>
>> Would you mind if I remove these commented code, in this patch and other
>> patches, while applying?
>>
>> Of course it would be better if you send the new version of the patch to
>> fix them, but I believe I can do this faster. Just let me know please.
>>
>> Thanks,
>> ferruh
>>
>>> +     req.enables = rte_cpu_to_le_32(
>>> +             HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_JUMBO_THRESH_VALID);
>>> +//           HWRM_VNIC_PLCMODES_CFG_INPUT_ENABLES_HDS_THRESHOLD_VALID);
>>> +
>>> +     size = rte_pktmbuf_data_room_size(bp->rx_queues[0]->mb_pool);
>>> +     size -= RTE_PKTMBUF_HEADROOM;
>>> +
>>> +     req.jumbo_thresh = rte_cpu_to_le_16(size);
>>> +//   req.hds_threshold = rte_cpu_to_le_16(size);
>>> +     req.vnic_id = rte_cpu_to_le_32(vnic->fw_vnic_id);
>>> +
>>> +     rc = bnxt_hwrm_send_message(bp, &req, sizeof(req));
>>> +
>>> +     HWRM_CHECK_RESULT;
>>> +
>>> +     return rc;
>>> +}
>>
>> <...>
>>
>>

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

* Re: [PATCH v4 00/26] bnxt patchset
  2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
                               ` (25 preceding siblings ...)
  2017-06-01 17:07             ` [PATCH v4 26/26] doc: update release notes Ajit Khaparde
@ 2017-06-06 14:48             ` Ferruh Yigit
  26 siblings, 0 replies; 130+ messages in thread
From: Ferruh Yigit @ 2017-06-06 14:48 UTC (permalink / raw)
  To: Ajit Khaparde, dev

On 6/1/2017 6:06 PM, Ajit Khaparde wrote:
> This patchset amongst other changes adds support few more dev_ops,
> updates HWRM to version 1.7.7, switches to polling stats from the
> hardware, support for Jumbo MTU, LRO etc..
> 
> v1->v2:
>   - Grouped in the end, it also has PMD specific APIs to control VF from PF.
>   - I have updated the release notes and the features file wherever possible.
> 
> v2->v3:
>   - Rebasing to next-net tree
>   - Use net/bnxt instead of just bnxt in patch subject
>   - update testpmd to use the vendor specific APIs
>   - Addressed other review comments as appropriate
> 
> v3->v4:
>   - fix a rebase error
> 
>   --
> 
>   net/bnxt: update to new HWRM version
>   net/bnxt: code reorg to properly allocate resources for PF/VF
>   net/bnxt: handle VF/PF initialization appropriately
>   net/bnxt: support lack of huge pages
>   net/bnxt: add additonal HWRM debug info to error messages
>   net/bnxt: add tunneling support
>   net/bnxt: add support for xstats get/reset
>   net/bnxt: add support for VLAN filter and strip
>   net/bnxt: add support for set multicast addr list and MAC addr set
>   doc: update bnxt.ini to document Allmulticast mode
>   net/bnxt: add support to get fw version
>   net/bnxt: add support to set MTU
>   net/bnxt: add support for LRO
>   net/bnxt: add rxq/txq info_get
>   net/bnxt: add code to support VLAN pvid
>   net/bnxt: reorg the query stats code
>   doc: update default.ini to add LED support
>   net/bnxt: add support for led on/off
>   net/bnxt: add support for tx loopback, set vf mac and queues drop
>   net/bnxt: add support for set VF QOS and MAC anti spoof
>   net/bnxt: add support to get and clear VF specific stats
>   net/bnxt: add code to determine the Rx status of VF
>   net/bnxt: add support to add a VF MAC address
>   net/bnxt: add code to configure a default VF VLAN
>   net/bnxt: add support to set VF rxmode
>   doc: update release notes

Series applied to dpdk-next-net/master, thanks.

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

end of thread, other threads:[~2017-06-06 14:48 UTC | newest]

Thread overview: 130+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-18  1:57 [PATCH 00/23] bnxt patchset Ajit Khaparde
2017-05-18  1:57 ` [PATCH 01/23] bnxt: add various hwrm input/output structures Ajit Khaparde
2017-05-18  1:57 ` [PATCH 02/23] bnxt: code reorg to properly allocate resources in PF/VF modes Ajit Khaparde
2017-05-18  1:57 ` [PATCH 03/23] bnxt: add tunneling support Ajit Khaparde
2017-05-18  1:57 ` [PATCH 04/23] bnxt: support lack of huge pages Ajit Khaparde
2017-05-18  1:57 ` [PATCH 05/23] bnxt: add functions for tx_loopback, set_vf_mac and queues_drop_en Ajit Khaparde
2017-05-18  1:57 ` [PATCH 06/23] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
2017-05-18  1:57 ` [PATCH 07/23] bnxt: add support for VLAN stripq, VLAN anti spoof and VLAN filtering for VFs Ajit Khaparde
2017-05-18  1:57 ` [PATCH 08/23] bnxt: add support to get and clear VF specific stats Ajit Khaparde
2017-05-18  1:57 ` [PATCH 09/23] bnxt: add code to determine the Rx status of VF Ajit Khaparde
2017-05-18  1:58 ` [PATCH 10/23] bnxt: add support to add a VF MAC address Ajit Khaparde
2017-05-18  1:58 ` [PATCH 11/23] bnxt: add support for xstats get/reset Ajit Khaparde
2017-05-18  1:58 ` [PATCH 12/23] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
2017-05-18  1:58 ` [PATCH 13/23] bnxt: add code to configure a default VF VLAN Ajit Khaparde
2017-05-18  1:58 ` [PATCH 14/23] bnxt: add support for set_mc_addr_list and mac_addr_set Ajit Khaparde
2017-05-18  1:58 ` [PATCH 15/23] bnxt: add support for fw_version_get dev_op Ajit Khaparde
2017-05-18  1:58 ` [PATCH 16/23] bnxt: add support to set MTU Ajit Khaparde
2017-05-18  1:58 ` [PATCH 17/23] bnxt: add support for LRO Ajit Khaparde
2017-05-18  1:58 ` [PATCH 18/23] bnxt: add rxq_info_get and txq_info_get dev_ops Ajit Khaparde
2017-05-18  1:58 ` [PATCH 19/23] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
2017-05-18  1:58 ` [PATCH 20/23] bnxt: reorg the query stats code Ajit Khaparde
2017-05-18  1:58 ` [PATCH 21/23] bnxt: update to HWRM version 1.7.5 Ajit Khaparde
2017-05-18  1:58 ` [PATCH 22/23] bnxt: Add support to set VF rxmode Ajit Khaparde
2017-05-18  1:58 ` [PATCH 23/23] bnxt: add code to support vlan_pvid_set dev_op Ajit Khaparde
2017-05-22 10:55 ` [PATCH 00/23] bnxt patchset Ferruh Yigit
2017-05-22 23:02   ` Thomas Monjalon
2017-05-23 17:58   ` Ajit Khaparde
2017-05-26 18:39     ` [PATCH v2 00/25] " Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 01/25] bnxt: update to new HWRM version Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 02/25] bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 03/25] bnxt: handle VF/PF initialization appropriately Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 04/25] bnxt: support lack of huge pages Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 05/25] bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 06/25] bnxt: add tunneling support Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 07/25] bnxt: add support for xstats get/reset Ajit Khaparde
2017-05-29 17:42         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 08/25] bnxt: Add support for VLAN filter and strip dev_ops Ajit Khaparde
2017-05-29 17:43         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 09/25] bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
2017-05-29 17:42         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 10/25] bnxt: add support for fw_version_get dev_op Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 11/25] bnxt: add support to set MTU Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 12/25] bnxt: add support for LRO Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 13/25] bnxt: add rxq/txq info_get dev_ops Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 14/25] bnxt: add code to support VLAN pvid set dev_op Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 15/25] bnxt: reorg the query stats code Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 16/25] bnxt: add support for led on/off Ajit Khaparde
2017-05-29 17:43         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 17/25] bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
2017-05-29 17:43         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 18/25] bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 19/25] bnxt: add support for VLAN stripq, anti spoof and filtering for VFs Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 20/25] bnxt: add support to get and clear VF specific stats Ajit Khaparde
2017-05-29 17:43         ` Ferruh Yigit
2017-05-31  2:12           ` Ajit Khaparde
2017-05-31  9:57             ` Ferruh Yigit
2017-05-31 14:27               ` Ajit Khaparde
2017-05-31 14:46                 ` Ferruh Yigit
2017-05-31 16:15                   ` Thomas Monjalon
2017-05-31 18:41                     ` Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 21/25] bnxt: add code to determine the Rx status of VF Ajit Khaparde
2017-05-29 17:43         ` Ferruh Yigit
2017-05-26 18:39       ` [PATCH v2 22/25] bnxt: add support to add a VF MAC address Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 23/25] bnxt: add code to configure a default VF VLAN Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 24/25] bnxt: Add support to set VF rxmode Ajit Khaparde
2017-05-26 18:39       ` [PATCH v2 25/25] update release notes Ajit Khaparde
2017-05-29 17:44         ` Ferruh Yigit
2017-05-29 17:44       ` [PATCH v2 00/25] bnxt patchset Ferruh Yigit
2017-06-01  3:02         ` [PATCH v3 00/26] " Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 06/26] net/bnxt: add tunneling support Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 11/26] net/bnxt: add support to get fw version Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 12/26] net/bnxt: add support to set MTU Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 13/26] net/bnxt: add support for LRO Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 17/26] doc: update default.ini to add LED support Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 18/26] net/bnxt: add support for led on/off Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
2017-06-01 12:28             ` Ferruh Yigit
2017-06-01 16:36               ` Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
2017-06-01  3:02           ` [PATCH v3 26/26] doc: update release notes Ajit Khaparde
2017-06-01 17:06           ` [PATCH v4 00/26] bnxt patchset Ajit Khaparde
2017-06-01 17:06             ` [PATCH v4 01/26] net/bnxt: update to new HWRM version Ajit Khaparde
2017-06-01 17:06             ` [PATCH v4 02/26] net/bnxt: code reorg to properly allocate resources for PF/VF Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 03/26] net/bnxt: handle VF/PF initialization appropriately Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 04/26] net/bnxt: support lack of huge pages Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 05/26] net/bnxt: add additonal HWRM debug info to error messages Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 06/26] net/bnxt: add tunneling support Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 07/26] net/bnxt: add support for xstats get/reset Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 08/26] net/bnxt: add support for VLAN filter and strip Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 09/26] net/bnxt: add support for set multicast addr list and MAC addr set Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 10/26] doc: update bnxt.ini to document Allmulticast mode Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 11/26] net/bnxt: add support to get fw version Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 12/26] net/bnxt: add support to set MTU Ajit Khaparde
2017-06-06 12:47               ` Ferruh Yigit
2017-06-06 14:00                 ` Ajit Khaparde
2017-06-06 14:25                   ` Ferruh Yigit
2017-06-01 17:07             ` [PATCH v4 13/26] net/bnxt: add support for LRO Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 14/26] net/bnxt: add rxq/txq info_get Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 15/26] net/bnxt: add code to support VLAN pvid Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 16/26] net/bnxt: reorg the query stats code Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 17/26] doc: update default.ini to add LED support Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 18/26] net/bnxt: add support for led on/off Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 19/26] net/bnxt: add support for tx loopback, set vf mac and queues drop Ajit Khaparde
2017-06-06 12:53               ` Ferruh Yigit
2017-06-06 14:09                 ` Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 20/26] net/bnxt: add support for set VF QOS and MAC anti spoof Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 21/26] net/bnxt: add support to get and clear VF specific stats Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 22/26] net/bnxt: add code to determine the Rx status of VF Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 23/26] net/bnxt: add support to add a VF MAC address Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 24/26] net/bnxt: add code to configure a default VF VLAN Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 25/26] net/bnxt: add support to set VF rxmode Ajit Khaparde
2017-06-01 17:07             ` [PATCH v4 26/26] doc: update release notes Ajit Khaparde
2017-06-06 14:48             ` [PATCH v4 00/26] bnxt patchset Ferruh Yigit

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.