DPDK patches and discussions
 help / color / mirror / Atom feed
* [PATCH 00/18] bnxt patchset
@ 2023-12-21 18:05 Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 01/18] net/bnxt: add support for UDP GSO Ajit Khaparde
                   ` (17 more replies)
  0 siblings, 18 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev

[-- Attachment #1: Type: text/plain, Size: 2419 bytes --]

This patchset contains more code fixes and reafctoring, apart from
extending more support for the newer P7 device family.
The patchset adds vector mode support for compressed Rx CQE.
This patchset includes support for checksum and XOR RSS hash mode.
It also adds support for forced speeds and autoneg support upto 400G.


Ajit Khaparde (9):
  net/bnxt: add support for UDP GSO
  net/bnxt: add support for compressed Rx CQE
  net/bnxt: reattempt mbuf allocation for Rx and AGG rings
  net/bnxt: refactor Rx doorbell during Rx flush
  net/bnxt: extend RSS hash support for P7 devices
  net/bnxt: add ESP and AH header based RSS support
  net/bnxt: set allmulti mode if multicast filter fails
  net/bnxt: add AVX2 support for compressed CQE
  net/bnxt: enable SSE mode for compressed CQE

Damodharam Ammepalli (4):
  net/bnxt: add flow query callback
  net/bnxt: add tunnel TPA support
  net/bnxt: add 400G get support for P7 devices
  net/bnxt: query extended stats from firmware

Jay Ding (1):
  net/bnxt: add VF FLR async event handler

Kalesh AP (4):
  net/bnxt: fix a typo while parsing link speed
  net/bnxt: fix setting 50G and 100G forced speed
  net/bnxt: fix speed change from 200G to 25G on Thor
  net/bnxt: support backward compatibility

 drivers/net/bnxt/bnxt.h                | 115 +++-
 drivers/net/bnxt/bnxt_cpr.c            |  20 +
 drivers/net/bnxt/bnxt_cpr.h            |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c         | 253 ++++++--
 drivers/net/bnxt/bnxt_flow.c           |  98 ++-
 drivers/net/bnxt/bnxt_hwrm.c           | 850 +++++++++++++++++++++++--
 drivers/net/bnxt/bnxt_hwrm.h           |  16 +-
 drivers/net/bnxt/bnxt_reps.c           |   2 +-
 drivers/net/bnxt/bnxt_ring.c           |  19 +-
 drivers/net/bnxt/bnxt_rxq.c            |   8 +-
 drivers/net/bnxt/bnxt_rxq.h            |   1 +
 drivers/net/bnxt/bnxt_rxr.c            | 320 ++++++++--
 drivers/net/bnxt/bnxt_rxr.h            |  59 ++
 drivers/net/bnxt/bnxt_rxtx_vec_avx2.c  | 309 +++++++++
 drivers/net/bnxt/bnxt_rxtx_vec_sse.c   | 167 ++++-
 drivers/net/bnxt/bnxt_stats.c          | 279 +++++++-
 drivers/net/bnxt/bnxt_txq.c            |   2 +
 drivers/net/bnxt/bnxt_txr.c            |   7 +-
 drivers/net/bnxt/bnxt_vnic.c           | 195 +++++-
 drivers/net/bnxt/bnxt_vnic.h           |  20 +-
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  10 +-
 21 files changed, 2548 insertions(+), 205 deletions(-)

-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 01/18] net/bnxt: add support for UDP GSO
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 02/18] net/bnxt: add support for compressed Rx CQE Ajit Khaparde
                   ` (16 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 3238 bytes --]

UDP GSO aka UDP Fragmentation Offload allows an application or stack
to provide a data payload larger than the MTU. The application then
updates the mbuf ol_flags and sets the PKT_TX_UDP_SEG flag. Then based
on the tso_segs and tso_mss fields in the mbuf the PMD can indicate
the UDP GSO transmit request to the hardware.
This feature is supported on Thor2 and will be enabled when the firmware
sets the UDP GSO support via the HWRM_FUNC_QCAPS.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt.h      | 1 +
 drivers/net/bnxt/bnxt_hwrm.c | 2 ++
 drivers/net/bnxt/bnxt_txq.c  | 2 ++
 drivers/net/bnxt/bnxt_txr.c  | 7 ++++++-
 4 files changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 7aed4c3da3..4b5c2c4b8f 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -801,6 +801,7 @@ struct bnxt {
 	(BNXT_CHIP_P5_P7((bp)) && \
 	 (bp)->hwrm_spec_code >= HWRM_VERSION_1_9_2 && \
 	 !BNXT_VF((bp)))
+#define BNXT_FW_CAP_UDP_GSO		BIT(13)
 #define BNXT_TRUFLOW_EN(bp)	((bp)->fw_cap & BNXT_FW_CAP_TRUFLOW_EN &&\
 				 (bp)->app_id != 0xFF)
 
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index e56f7693af..37cf179938 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -950,6 +950,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	flags_ext2 = rte_le_to_cpu_32(resp->flags_ext2);
 	if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_RX_ALL_PKTS_TIMESTAMPS_SUPPORTED)
 		bp->fw_cap |= BNXT_FW_CAP_RX_ALL_PKT_TS;
+	if (flags_ext2 & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT2_UDP_GSO_SUPPORTED)
+		bp->fw_cap |= BNXT_FW_CAP_UDP_GSO;
 
 unlock:
 	HWRM_UNLOCK();
diff --git a/drivers/net/bnxt/bnxt_txq.c b/drivers/net/bnxt/bnxt_txq.c
index 4df4604975..f99ad211db 100644
--- a/drivers/net/bnxt/bnxt_txq.c
+++ b/drivers/net/bnxt/bnxt_txq.c
@@ -42,6 +42,8 @@ uint64_t bnxt_get_tx_port_offloads(struct bnxt *bp)
 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_GENEVE_TNL_TSO;
 	if (BNXT_TUNNELED_OFFLOADS_CAP_IPINIP_EN(bp))
 		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_IPIP_TNL_TSO;
+	if (bp->fw_cap & BNXT_FW_CAP_UDP_GSO)
+		tx_offload_capa |= RTE_ETH_TX_OFFLOAD_UDP_TSO;
 
 	return tx_offload_capa;
 }
diff --git a/drivers/net/bnxt/bnxt_txr.c b/drivers/net/bnxt/bnxt_txr.c
index 899986764f..38da2d2829 100644
--- a/drivers/net/bnxt/bnxt_txr.c
+++ b/drivers/net/bnxt/bnxt_txr.c
@@ -123,6 +123,10 @@ bnxt_xmit_need_long_bd(struct rte_mbuf *tx_pkt, struct bnxt_tx_queue *txq)
 	return false;
 }
 
+/* Used for verifying TSO segments during TCP Segmentation Offload or
+ * UDP Fragmentation Offload. tx_pkt->tso_segsz stores the number of
+ * segments or fragments in those cases.
+ */
 static bool
 bnxt_zero_data_len_tso_segsz(struct rte_mbuf *tx_pkt, uint8_t data_len_chk)
 {
@@ -308,7 +312,8 @@ static uint16_t bnxt_start_xmit(struct rte_mbuf *tx_pkt,
 		else
 			txbd1->cfa_action = txq->bp->tx_cfa_action;
 
-		if (tx_pkt->ol_flags & RTE_MBUF_F_TX_TCP_SEG) {
+		if (tx_pkt->ol_flags & RTE_MBUF_F_TX_TCP_SEG ||
+		    tx_pkt->ol_flags & RTE_MBUF_F_TX_UDP_SEG) {
 			uint16_t hdr_size;
 
 			/* TSO */
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 02/18] net/bnxt: add support for compressed Rx CQE
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 01/18] net/bnxt: add support for UDP GSO Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 03/18] net/bnxt: fix a typo while parsing link speed Ajit Khaparde
                   ` (15 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Somnath Kotur, Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 17269 bytes --]

Thor2 supports compressed Rx completions instead of the
full featured 32-byte Rx completions.
Add support for these compressed CQEs in scalar mode.
Unlike in the typical Rx completions, the hardware does
not provide the opaque field to index into the aggregator
descriptor ring. So maintain the consumer index for the
aggregation ring in the driver.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  17 +++
 drivers/net/bnxt/bnxt_ethdev.c |  51 +++++++++
 drivers/net/bnxt/bnxt_hwrm.c   |  16 +++
 drivers/net/bnxt/bnxt_ring.c   |  13 ++-
 drivers/net/bnxt/bnxt_rxr.c    | 201 +++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxr.h    |  55 +++++++++
 6 files changed, 352 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 4b5c2c4b8f..cfdbfd3f54 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -782,6 +782,7 @@ struct bnxt {
 #define	BNXT_MULTIROOT_EN(bp)			\
 	((bp)->flags2 & BNXT_FLAGS2_MULTIROOT_EN)
 
+#define	BNXT_FLAGS2_COMPRESSED_RX_CQE		BIT(5)
 	uint32_t		fw_cap;
 #define BNXT_FW_CAP_HOT_RESET		BIT(0)
 #define BNXT_FW_CAP_IF_CHANGE		BIT(1)
@@ -814,6 +815,7 @@ struct bnxt {
 #define BNXT_VNIC_CAP_VLAN_RX_STRIP	BIT(3)
 #define BNXT_RX_VLAN_STRIP_EN(bp)	((bp)->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP)
 #define BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF	BIT(4)
+#define BNXT_VNIC_CAP_L2_CQE_MODE		BIT(8)
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	unsigned int		rx_num_qs_per_vnic;
@@ -1013,6 +1015,21 @@ inline uint16_t bnxt_max_rings(struct bnxt *bp)
 	return max_rings;
 }
 
+static inline bool
+bnxt_compressed_rx_cqe_mode_enabled(struct bnxt *bp)
+{
+	uint64_t rx_offloads = bp->eth_dev->data->dev_conf.rxmode.offloads;
+
+	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_L2_CQE_MODE &&
+		bp->flags2 & BNXT_FLAGS2_COMPRESSED_RX_CQE &&
+		!(rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) &&
+		!(rx_offloads & RTE_ETH_RX_OFFLOAD_BUFFER_SPLIT) &&
+		!bp->num_reps && !bp->ieee_1588)
+		return true;
+
+	return false;
+}
+
 #define BNXT_FC_TIMER	1 /* Timer freq in Sec Flow Counters */
 
 /**
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 75e968394f..0f1c4326c4 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -103,6 +103,7 @@ static const struct rte_pci_id bnxt_pci_id_map[] = {
 #define BNXT_DEVARG_REP_FC_F2R  "rep-fc-f2r"
 #define BNXT_DEVARG_APP_ID	"app-id"
 #define BNXT_DEVARG_IEEE_1588	"ieee-1588"
+#define BNXT_DEVARG_CQE_MODE	"cqe-mode"
 
 static const char *const bnxt_dev_args[] = {
 	BNXT_DEVARG_REPRESENTOR,
@@ -116,9 +117,15 @@ static const char *const bnxt_dev_args[] = {
 	BNXT_DEVARG_REP_FC_F2R,
 	BNXT_DEVARG_APP_ID,
 	BNXT_DEVARG_IEEE_1588,
+	BNXT_DEVARG_CQE_MODE,
 	NULL
 };
 
+/*
+ * cqe-mode = an non-negative 8-bit number
+ */
+#define BNXT_DEVARG_CQE_MODE_INVALID(val)		((val) > 1)
+
 /*
  * app-id = an non-negative 8-bit number
  */
@@ -5706,6 +5713,43 @@ bnxt_parse_devarg_max_num_kflows(__rte_unused const char *key,
 	return 0;
 }
 
+static int
+bnxt_parse_devarg_cqe_mode(__rte_unused const char *key,
+			   const char *value, void *opaque_arg)
+{
+	struct bnxt *bp = opaque_arg;
+	unsigned long cqe_mode;
+	char *end = NULL;
+
+	if (!value || !opaque_arg) {
+		PMD_DRV_LOG(ERR,
+			    "Invalid parameter passed to cqe-mode "
+			    "devargs.\n");
+		return -EINVAL;
+	}
+
+	cqe_mode = strtoul(value, &end, 10);
+	if (end == NULL || *end != '\0' ||
+	    (cqe_mode == ULONG_MAX && errno == ERANGE)) {
+		PMD_DRV_LOG(ERR,
+			    "Invalid parameter passed to cqe-mode "
+			    "devargs.\n");
+		return -EINVAL;
+	}
+
+	if (BNXT_DEVARG_CQE_MODE_INVALID(cqe_mode)) {
+		PMD_DRV_LOG(ERR, "Invalid cqe-mode(%d) devargs.\n",
+			    (uint16_t)cqe_mode);
+		return -EINVAL;
+	}
+
+	if (cqe_mode == 1)
+		bp->flags2 |= BNXT_FLAGS2_COMPRESSED_RX_CQE;
+	PMD_DRV_LOG(INFO, "cqe-mode=%d feature enabled.\n", (uint8_t)cqe_mode);
+
+	return 0;
+}
+
 static int
 bnxt_parse_devarg_app_id(__rte_unused const char *key,
 				 const char *value, void *opaque_arg)
@@ -6047,6 +6091,13 @@ bnxt_parse_dev_args(struct bnxt *bp, struct rte_devargs *devargs)
 	rte_kvargs_process(kvlist, BNXT_DEVARG_IEEE_1588,
 			   bnxt_parse_devarg_ieee_1588, bp);
 
+	/*
+	 * Handler for "cqe-mode" devarg.
+	 * Invoked as for ex: "-a 000:00:0d.0,cqe-mode=1"
+	 */
+	rte_kvargs_process(kvlist, BNXT_DEVARG_CQE_MODE,
+			   bnxt_parse_devarg_cqe_mode, bp);
+
 	rte_kvargs_free(kvlist);
 	return ret;
 }
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 37cf179938..378be997d3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2228,6 +2228,12 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	req.lb_rule = rte_cpu_to_le_16(vnic->lb_rule);
 
 config_mru:
+	if (bnxt_compressed_rx_cqe_mode_enabled(bp)) {
+		req.l2_cqe_mode = HWRM_VNIC_CFG_INPUT_L2_CQE_MODE_COMPRESSED;
+		enables |= HWRM_VNIC_CFG_INPUT_ENABLES_L2_CQE_MODE;
+		PMD_DRV_LOG(DEBUG, "Enabling compressed Rx CQE\n");
+	}
+
 	req.enables = rte_cpu_to_le_32(enables);
 	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
 	req.mru = rte_cpu_to_le_16(vnic->mru);
@@ -2604,6 +2610,16 @@ int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
 	struct hwrm_vnic_tpa_cfg_input req = {.req_type = 0 };
 	struct hwrm_vnic_tpa_cfg_output *resp = bp->hwrm_cmd_resp_addr;
 
+	if (bnxt_compressed_rx_cqe_mode_enabled(bp)) {
+		/* Don't worry if disabling TPA */
+		if (!enable)
+			return 0;
+
+		/* Return an error if enabling TPA w/ compressed Rx CQE. */
+		PMD_DRV_LOG(ERR, "No HW support for LRO with compressed Rx\n");
+		return -ENOTSUP;
+	}
+
 	if ((BNXT_CHIP_P5(bp) || BNXT_CHIP_P7(bp)) && !bp->max_tpa_v2) {
 		if (enable)
 			PMD_DRV_LOG(ERR, "No HW support for LRO\n");
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 90cad6c9c6..4bf0b9c6ed 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -573,6 +573,7 @@ static int bnxt_alloc_rx_agg_ring(struct bnxt *bp, int queue_index)
 		return rc;
 
 	rxr->ag_raw_prod = 0;
+	rxr->ag_cons = 0;
 	if (BNXT_HAS_RING_GRPS(bp))
 		bp->grp_info[queue_index].ag_fw_ring_id = ring->fw_ring_id;
 	bnxt_set_db(bp, &rxr->ag_db, ring_type, map_idx, ring->fw_ring_id,
@@ -595,7 +596,17 @@ int bnxt_alloc_hwrm_rx_ring(struct bnxt *bp, int queue_index)
 	 * Storage for the cp ring is allocated based on worst-case
 	 * usage, the actual size to be used by hw is computed here.
 	 */
-	cp_ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	if (bnxt_compressed_rx_cqe_mode_enabled(bp)) {
+		if (bnxt_need_agg_ring(bp->eth_dev))
+			/* Worst case scenario, needed to accommodate Rx flush
+			 * completion during RING_FREE.
+			 */
+			cp_ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+		else
+			cp_ring->ring_size = rxr->rx_ring_struct->ring_size;
+	} else {
+		cp_ring->ring_size = rxr->rx_ring_struct->ring_size * 2;
+	}
 
 	if (bnxt_need_agg_ring(bp->eth_dev))
 		cp_ring->ring_size *= AGG_RING_SIZE_FACTOR;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 59ea0121de..b919922a64 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -907,6 +907,203 @@ void bnxt_set_mark_in_mbuf(struct bnxt *bp,
 	mbuf->ol_flags |= RTE_MBUF_F_RX_FDIR | RTE_MBUF_F_RX_FDIR_ID;
 }
 
+static void
+bnxt_set_ol_flags_crx(struct bnxt_rx_ring_info *rxr,
+		      struct rx_pkt_compress_cmpl *rxcmp,
+		      struct rte_mbuf *mbuf)
+{
+	uint16_t flags_type, errors, flags;
+	uint16_t cserr, tmp;
+	uint64_t ol_flags;
+
+	flags_type = rte_le_to_cpu_16(rxcmp->flags_type);
+
+	cserr = rte_le_to_cpu_16(rxcmp->metadata1_cs_error_calc_v1) &
+		(RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_MASK |
+		 BNXT_RXC_METADATA1_VLAN_VALID);
+
+	flags = cserr & BNXT_CRX_CQE_CSUM_CALC_MASK;
+	tmp = flags;
+
+	/* Set tunnel frame indicator.
+	 * This is to correctly index into the flags_err table.
+	 */
+	flags |= (flags & BNXT_CRX_TUN_CS_CALC) ? BNXT_PKT_CMPL_T_IP_CS_CALC << 3 : 0;
+
+	flags = flags >> BNXT_CRX_CQE_CSUM_CALC_SFT;
+
+	errors = cserr & BNXT_CRX_CQE_CSUM_ERROR_MASK;
+	errors = (errors >> RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_SFT) & flags;
+
+	ol_flags = rxr->ol_flags_table[flags & ~errors];
+
+	if (unlikely(errors)) {
+		/* Set tunnel frame indicator.
+		 * This is to correctly index into the flags_err table.
+		 */
+		errors |= (tmp & BNXT_CRX_TUN_CS_CALC) ? BNXT_PKT_CMPL_T_IP_CS_CALC << 2 : 0;
+		ol_flags |= rxr->ol_flags_err_table[errors];
+	}
+
+	if (flags_type & RX_PKT_COMPRESS_CMPL_FLAGS_RSS_VALID) {
+		mbuf->hash.rss = rte_le_to_cpu_32(rxcmp->rss_hash);
+		ol_flags |= RTE_MBUF_F_RX_RSS_HASH;
+	}
+
+#ifdef RTE_LIBRTE_IEEE1588
+	/* TODO: TIMESTAMP flags need to be parsed and set. */
+#endif
+
+	mbuf->ol_flags = ol_flags;
+}
+
+static uint32_t
+bnxt_parse_pkt_type_crx(struct rx_pkt_compress_cmpl *rxcmp)
+{
+	uint16_t flags_type, meta_cs;
+	uint8_t index;
+
+	flags_type = rte_le_to_cpu_16(rxcmp->flags_type);
+	meta_cs = rte_le_to_cpu_16(rxcmp->metadata1_cs_error_calc_v1);
+
+	/* Validate ptype table indexing at build time. */
+	/* TODO */
+	/* bnxt_check_ptype_constants(); */
+
+	/*
+	 * Index format:
+	 *     bit 0: Set if IP tunnel encapsulated packet.
+	 *     bit 1: Set if IPv6 packet, clear if IPv4.
+	 *     bit 2: Set if VLAN tag present.
+	 *     bits 3-6: Four-bit hardware packet type field.
+	 */
+	index = BNXT_CMPL_ITYPE_TO_IDX(flags_type) |
+		BNXT_CMPL_VLAN_TUN_TO_IDX_CRX(meta_cs) |
+		BNXT_CMPL_IP_VER_TO_IDX(flags_type);
+
+	return bnxt_ptype_table[index];
+}
+
+static int bnxt_rx_pages_crx(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_compress_cmpl *rxcmp;
+	struct rte_mbuf *last = mbuf;
+
+	for (i = 0; i < agg_buf; i++) {
+		struct rte_mbuf **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_compress_cmpl *)&cpr->cp_desc_ring[cp_cons];
+
+#ifdef BNXT_DEBUG
+		bnxt_dump_cmpl(cp_cons, rxcmp);
+#endif
+
+		/*
+		 * The consumer index aka the opaque field for the agg buffers
+		 * is not * available in errors_agg_bufs_opaque. So maintain it
+		 * in driver itself.
+		 */
+		ag_cons = rxr->ag_cons;
+		ag_buf = &rxr->ag_buf_ring[ag_cons];
+		ag_mbuf = *ag_buf;
+
+		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 = NULL;
+		/*
+		 * As aggregation buffer consumed out of order in TPA module,
+		 * use bitmap to track freed slots to be allocated and notified
+		 * to NIC. TODO: Is this needed. Most likely not.
+		 */
+		rte_bitmap_set(rxr->ag_bitmap, ag_cons);
+		rxr->ag_cons = RING_IDX(rxr->ag_ring_struct, RING_NEXT(ag_cons));
+	}
+	last->next = NULL;
+	bnxt_prod_ag_mbuf(rxq);
+	return 0;
+}
+
+static int bnxt_crx_pkt(struct rte_mbuf **rx_pkt,
+				struct bnxt_rx_queue *rxq,
+				struct rx_pkt_compress_cmpl *rxcmp,
+				uint32_t *raw_cons)
+{
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint32_t tmp_raw_cons = *raw_cons;
+	uint16_t cons, raw_prod;
+	struct rte_mbuf *mbuf;
+	int rc = 0;
+	uint8_t agg_buf = 0;
+
+	agg_buf = BNXT_CRX_CQE_AGG_BUFS(rxcmp);
+	/*
+	 * Since size of rx_pkt_cmpl is same as rx_pkt_compress_cmpl,
+	 * we should be able to use bnxt_agg_bufs_valid to check if AGG
+	 * bufs are valid when using compressed CQEs.
+	 * All we want to check here is if the CQE is valid and the
+	 * location of valid bit is same irrespective of the CQE type.
+	 */
+	if (agg_buf && !bnxt_agg_bufs_valid(cpr, agg_buf, tmp_raw_cons))
+		return -EBUSY;
+
+	raw_prod = rxr->rx_raw_prod;
+
+	cons = rxcmp->errors_agg_bufs_opaque & BNXT_CRX_CQE_OPAQUE_MASK;
+	mbuf = bnxt_consume_rx_buf(rxr, cons);
+	if (mbuf == NULL)
+		return -EBUSY;
+
+	mbuf->data_off = RTE_PKTMBUF_HEADROOM;
+	mbuf->nb_segs = 1;
+	mbuf->next = NULL;
+	mbuf->pkt_len = rxcmp->len;
+	mbuf->data_len = mbuf->pkt_len;
+	mbuf->port = rxq->port_id;
+
+#ifdef RTE_LIBRTE_IEEE1588
+	/* TODO: Add timestamp support. */
+#endif
+
+	bnxt_set_ol_flags_crx(rxr, rxcmp, mbuf);
+	mbuf->packet_type = bnxt_parse_pkt_type_crx(rxcmp);
+	bnxt_set_vlan_crx(rxcmp, mbuf);
+
+	if (bnxt_alloc_rx_data(rxq, rxr, raw_prod)) {
+		PMD_DRV_LOG(ERR, "mbuf alloc failed with prod=0x%x\n",
+			    raw_prod);
+		rc = -ENOMEM;
+		goto rx;
+	}
+	raw_prod = RING_NEXT(raw_prod);
+	rxr->rx_raw_prod = raw_prod;
+
+	if (agg_buf)
+		bnxt_rx_pages_crx(rxq, mbuf, &tmp_raw_cons, agg_buf);
+
+rx:
+	rxr->rx_next_cons = RING_IDX(rxr->rx_ring_struct, RING_NEXT(cons));
+	*rx_pkt = mbuf;
+
+	*raw_cons = tmp_raw_cons;
+
+	return rc;
+}
+
 static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		       struct bnxt_rx_queue *rxq, uint32_t *raw_cons)
 {
@@ -1148,6 +1345,10 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			break;
 		if (CMP_TYPE(rxcmp) == CMPL_BASE_TYPE_HWRM_DONE) {
 			PMD_DRV_LOG(ERR, "Rx flush done\n");
+		} else if (CMP_TYPE(rxcmp) == CMPL_BASE_TYPE_RX_L2_COMPRESS) {
+			rc = bnxt_crx_pkt(&rx_pkts[nb_rx_pkts], rxq,
+					  (struct rx_pkt_compress_cmpl *)rxcmp,
+					  &raw_cons);
 		} else if ((CMP_TYPE(rxcmp) >= CMPL_BASE_TYPE_RX_TPA_START_V2) &&
 			   (CMP_TYPE(rxcmp) <= CMPL_BASE_TYPE_RX_TPA_START_V3)) {
 			rc = bnxt_rx_pkt(&rx_pkts[nb_rx_pkts], rxq, &raw_cons);
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index 439d29a07f..c51bb2d62c 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -52,6 +52,52 @@ static inline uint16_t bnxt_tpa_start_agg_id(struct bnxt *bp,
 #define BNXT_OL_FLAGS_TBL_DIM	64
 #define BNXT_OL_FLAGS_ERR_TBL_DIM 32
 
+#define BNXT_CRX_CQE_OPAQUE_MASK		\
+	RX_PKT_COMPRESS_CMPL_ERRORS_AGG_BUFS_OPAQUE_OPAQUE_MASK
+#define BNXT_CRX_CQE_AGG_BUF_MASK		\
+	RX_PKT_COMPRESS_CMPL_ERRORS_AGG_BUFS_OPAQUE_AGG_BUFS_MASK
+#define BNXT_CRX_CQE_AGG_BUF_SFT		\
+	RX_PKT_COMPRESS_CMPL_ERRORS_AGG_BUFS_OPAQUE_AGG_BUFS_SFT
+#define BNXT_CRX_CQE_AGG_BUFS(cmp)		\
+	(((cmp)->errors_agg_bufs_opaque & BNXT_CRX_CQE_AGG_BUF_MASK) >> \
+	 BNXT_CRX_CQE_AGG_BUF_SFT)
+#define BNXT_CRX_CQE_CSUM_CALC_MASK		\
+	(RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_IP_CS_CALC | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_L4_CS_CALC | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_IP_CS_CALC | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_L4_CS_CALC)
+#define BNXT_CRX_CQE_CSUM_CALC_SFT	8
+#define BNXT_PKT_CMPL_T_IP_CS_CALC	0x4
+
+#define BNXT_CRX_TUN_CS_CALC                                  \
+	(!!(RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_IP_CS_CALC | \
+	    RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_L4_CS_CALC))
+
+# define BNXT_CRX_CQE_CSUM_ERROR_MASK		\
+	(RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_IP_CS_ERROR | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_L4_CS_ERROR | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_IP_CS_ERROR | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_L4_CS_ERROR)
+
+/* meta_format != 0 and bit3 is valid, the value in meta is VLAN.
+ * Use the bit as VLAN valid bit
+ */
+#define BNXT_RXC_METADATA1_VLAN_VALID		\
+	RX_PKT_COMPRESS_CMPL_METADATA1_VALID
+
+static inline void bnxt_set_vlan_crx(struct rx_pkt_compress_cmpl *rxcmp,
+				     struct rte_mbuf *mbuf)
+{
+	uint16_t metadata = rte_le_to_cpu_16(rxcmp->metadata1_cs_error_calc_v1);
+	uint16_t vlan_tci = rte_le_to_cpu_16(rxcmp->vlanc_tcid);
+
+	if (metadata & RX_PKT_COMPRESS_CMPL_METADATA1_VALID)
+		mbuf->vlan_tci =
+			vlan_tci & (RX_PKT_COMPRESS_CMPL_VLANC_TCID_VID_MASK |
+				    RX_PKT_COMPRESS_CMPL_VLANC_TCID_DE |
+				    RX_PKT_COMPRESS_CMPL_VLANC_TCID_PRI_MASK);
+}
+
 struct bnxt_tpa_info {
 	struct rte_mbuf			*mbuf;
 	uint16_t			len;
@@ -70,6 +116,7 @@ struct bnxt_tpa_info {
 struct bnxt_rx_ring_info {
 	uint16_t		rx_raw_prod;
 	uint16_t		ag_raw_prod;
+	uint16_t		ag_cons; /* Needed with compressed CQE */
 	uint16_t                rx_cons; /* Needed for representor */
 	uint16_t                rx_next_cons;
 	struct bnxt_db_info     rx_db;
@@ -160,6 +207,10 @@ bnxt_cfa_code_dynfield(struct rte_mbuf *mbuf)
 #define CMPL_FLAGS2_VLAN_TUN_MSK \
 	(RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN | RX_PKT_CMPL_FLAGS2_T_IP_CS_CALC)
 
+#define CMPL_FLAGS2_VLAN_TUN_MSK_CRX \
+	(RX_PKT_COMPRESS_CMPL_METADATA1_VALID | \
+	 RX_PKT_COMPRESS_CMPL_CS_ERROR_CALC_T_IP_CS_CALC)
+
 #define BNXT_CMPL_ITYPE_TO_IDX(ft) \
 	(((ft) & RX_PKT_CMPL_FLAGS_ITYPE_MASK) >> \
 	  (RX_PKT_CMPL_FLAGS_ITYPE_SFT - BNXT_PTYPE_TBL_TYPE_SFT))
@@ -168,6 +219,10 @@ bnxt_cfa_code_dynfield(struct rte_mbuf *mbuf)
 	(((f2) & CMPL_FLAGS2_VLAN_TUN_MSK) >> \
 	 (RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT - BNXT_PTYPE_TBL_VLAN_SFT))
 
+#define BNXT_CMPL_VLAN_TUN_TO_IDX_CRX(md) \
+	(((md) & CMPL_FLAGS2_VLAN_TUN_MSK_CRX) >> \
+	 (RX_PKT_COMPRESS_CMPL_METADATA1_SFT - BNXT_PTYPE_TBL_VLAN_SFT))
+
 #define BNXT_CMPL_IP_VER_TO_IDX(f2) \
 	(((f2) & RX_PKT_CMPL_FLAGS2_IP_TYPE) >> \
 	 (RX_PKT_CMPL_FLAGS2_IP_TYPE_SFT - BNXT_PTYPE_TBL_IP_VER_SFT))
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 03/18] net/bnxt: fix a typo while parsing link speed
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 01/18] net/bnxt: add support for UDP GSO Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 02/18] net/bnxt: add support for compressed Rx CQE Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 04/18] net/bnxt: fix setting 50G and 100G forced speed Ajit Khaparde
                   ` (14 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Kalesh AP

[-- Attachment #1: Type: text/plain, Size: 1881 bytes --]

From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>

While setting forced speed, the speed should have mapped to
macro "HWRM_PORT_PHY_CFG_INPUT_FORCE_xxx" instead of
"HWRM_PORT_PHY_CFG_INPUT_AUTO_xxx". We do not see any issue
as both these macros are defined to the same value.

Fixing it for better convey the intent.

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 10 +++++-----
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 378be997d3..8f99582819 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -3168,15 +3168,15 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 	case RTE_ETH_LINK_SPEED_100M_HD:
 		/* FALLTHROUGH */
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_100MB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100MB;
 		break;
 	case RTE_ETH_LINK_SPEED_1G:
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_1GB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_1GB;
 		break;
 	case RTE_ETH_LINK_SPEED_2_5G:
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_2_5GB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_2_5GB;
 		break;
 	case RTE_ETH_LINK_SPEED_10G:
 		eth_link_speed =
@@ -3184,11 +3184,11 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 		break;
 	case RTE_ETH_LINK_SPEED_20G:
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_20GB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_20GB;
 		break;
 	case RTE_ETH_LINK_SPEED_25G:
 		eth_link_speed =
-			HWRM_PORT_PHY_CFG_INPUT_AUTO_LINK_SPEED_25GB;
+			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB;
 		break;
 	case RTE_ETH_LINK_SPEED_40G:
 		eth_link_speed =
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 04/18] net/bnxt: fix setting 50G and 100G forced speed
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (2 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 03/18] net/bnxt: fix a typo while parsing link speed Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 05/18] net/bnxt: fix speed change from 200G to 25G on Thor Ajit Khaparde
                   ` (13 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Kalesh AP, stable, Somnath Kotur

[-- Attachment #1: Type: text/plain, Size: 2941 bytes --]

From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>

Thor based NICs can support PAM4 as well as NRZ link negotiation.
While PAM4 can negotiate speeds at 50G, 100G and 200G, the PMD will
use NRZ signaling for 50G and 100G speeds. PAM4 signaling will be
used only for 200G speed negotiations.

Driver has to check for NRZ speed support first while forcing speed.

Fixes: c23f9ded0391 ("net/bnxt: support 200G PAM4 link")
Cc: stable@dpdk.org

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 22 ++++++++++++----------
 1 file changed, 12 insertions(+), 10 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 8f99582819..c31a5d4226 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -3158,6 +3158,8 @@ static uint16_t bnxt_check_eth_link_autoneg(uint32_t conf_link)
 static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 					  struct bnxt_link_info *link_info)
 {
+	uint16_t support_pam4_speeds = link_info->support_pam4_speeds;
+	uint16_t support_speeds = link_info->support_speeds;
 	uint16_t eth_link_speed = 0;
 
 	if (conf_link_speed == RTE_ETH_LINK_SPEED_AUTONEG)
@@ -3195,23 +3197,23 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_40GB;
 		break;
 	case RTE_ETH_LINK_SPEED_50G:
-		if (link_info->support_pam4_speeds &
-		    HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G) {
-			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_50GB;
-			link_info->link_signal_mode = BNXT_SIG_MODE_PAM4;
-		} else {
+		if (support_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_50GB) {
 			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_50GB;
 			link_info->link_signal_mode = BNXT_SIG_MODE_NRZ;
+		} else if (support_pam4_speeds &
+			   HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_50G) {
+			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_50GB;
+			link_info->link_signal_mode = BNXT_SIG_MODE_PAM4;
 		}
 		break;
 	case RTE_ETH_LINK_SPEED_100G:
-		if (link_info->support_pam4_speeds &
-		    HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G) {
-			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_100GB;
-			link_info->link_signal_mode = BNXT_SIG_MODE_PAM4;
-		} else {
+		if (support_speeds & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS_100GB) {
 			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_100GB;
 			link_info->link_signal_mode = BNXT_SIG_MODE_NRZ;
+		} else if (support_pam4_speeds &
+			   HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_PAM4_SPEEDS_100G) {
+			eth_link_speed = HWRM_PORT_PHY_CFG_INPUT_FORCE_PAM4_LINK_SPEED_100GB;
+			link_info->link_signal_mode = BNXT_SIG_MODE_PAM4;
 		}
 		break;
 	case RTE_ETH_LINK_SPEED_200G:
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 05/18] net/bnxt: fix speed change from 200G to 25G on Thor
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (3 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 04/18] net/bnxt: fix setting 50G and 100G forced speed Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 06/18] net/bnxt: support backward compatibility Ajit Khaparde
                   ` (12 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Kalesh AP, stable, Somnath Kotur

[-- Attachment #1: Type: text/plain, Size: 1207 bytes --]

From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>

While forcing speed to 200G, driver sets the structure variable
"bp->link_info->link_signal_mode" value to BNXT_SIG_MODE_PAM4.
After that when the user forces the speed back to 25G, this
cached value is not set back to BNXT_SIG_MODE_NRZ which results
in issuing the HWRM_PORT_PHY_CFG command with wrong inputs.

Fixes: c23f9ded0391 ("net/bnxt: support 200G PAM4 link")
Cc: stable@dpdk.org

Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_hwrm.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index c31a5d4226..a1f3a8251f 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -3191,6 +3191,7 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 	case RTE_ETH_LINK_SPEED_25G:
 		eth_link_speed =
 			HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEED_25GB;
+		link_info->link_signal_mode = BNXT_SIG_MODE_NRZ;
 		break;
 	case RTE_ETH_LINK_SPEED_40G:
 		eth_link_speed =
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 06/18] net/bnxt: support backward compatibility
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (4 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 05/18] net/bnxt: fix speed change from 200G to 25G on Thor Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 07/18] net/bnxt: reattempt mbuf allocation for Rx and AGG rings Ajit Khaparde
                   ` (11 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Kalesh AP, stable

[-- Attachment #1: Type: text/plain, Size: 1634 bytes --]

From: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>

On older firmware versions, HWRM_FUNC_QCAPS response is not
returning the maximum number of multicast filters that can be
supported by the function. As a result, memory allocation with
size 0 fails.

Bugzilla ID: 1309
Cc: stable@dpdk.org

Signed-off-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h      | 1 +
 drivers/net/bnxt/bnxt_hwrm.c | 2 ++
 2 files changed, 3 insertions(+)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index cfdbfd3f54..cd85a944e8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -974,6 +974,7 @@ struct bnxt {
 	struct rte_ether_addr	*mcast_addr_list;
 	rte_iova_t		mc_list_dma_addr;
 	uint32_t		nb_mc_addr;
+#define BNXT_DFLT_MAX_MC_ADDR	16 /* for compatibility with older firmware */
 	uint32_t		max_mcast_addr; /* maximum number of mcast filters supported */
 
 	struct rte_eth_rss_conf	rss_conf; /* RSS configuration. */
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index a1f3a8251f..d649f217ec 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -901,6 +901,8 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
 		    bp->max_l2_ctx, bp->max_vnics);
 	bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
 	bp->max_mcast_addr = rte_le_to_cpu_32(resp->max_mcast_filters);
+	if (!bp->max_mcast_addr)
+		bp->max_mcast_addr = BNXT_DFLT_MAX_MC_ADDR;
 	memcpy(bp->dsn, resp->device_serial_number, sizeof(bp->dsn));
 
 	if (BNXT_PF(bp))
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 07/18] net/bnxt: reattempt mbuf allocation for Rx and AGG rings
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (5 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 06/18] net/bnxt: support backward compatibility Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 08/18] net/bnxt: refactor Rx doorbell during Rx flush Ajit Khaparde
                   ` (10 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Somnath Kotur

[-- Attachment #1: Type: text/plain, Size: 7128 bytes --]

Normally the PMD allocates a new mbuf for every mbuf consumed.
In case of mbuf alloc failure, that slot in the Rx or AGG ring remains
empty till a new mbuf is not allocated for that slot. If this happens
too frequently the Rx ring or the aggregation ring could be completely
drained of mbufs and can cause unexpected behavior.

To prevent this, in case of an mbuf allocation failure, set a bit and
try to reattempt mbuf allocation to fill the empty slots. Since this
should not happen under normal circumstances, it should not impact
regular Rx performance.

The need_realloc bit is set in the RxQ if mbuf allocation fails for
Rx ring or the AGG ring.

As long as the application calls the Rx burst function even in cases
where the Rx rings became completely empty, the logic should be able to
reattempt buffer allocation for the associated Rx and aggregation rings.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Somnath Kotur <somnath.kotur@broadcom.com>
---
 drivers/net/bnxt/bnxt_rxq.h |   1 +
 drivers/net/bnxt/bnxt_rxr.c | 101 ++++++++++++++++++++++--------------
 2 files changed, 64 insertions(+), 38 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_rxq.h b/drivers/net/bnxt/bnxt_rxq.h
index b9908be5f4..77bc382a1d 100644
--- a/drivers/net/bnxt/bnxt_rxq.h
+++ b/drivers/net/bnxt/bnxt_rxq.h
@@ -41,6 +41,7 @@ struct bnxt_rx_queue {
 	struct bnxt_cp_ring_info	*cp_ring;
 	struct rte_mbuf			fake_mbuf;
 	uint64_t			rx_mbuf_alloc_fail;
+	uint8_t				need_realloc;
 	const struct rte_memzone *mz;
 };
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index b919922a64..c5c9f9e6e6 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -50,6 +50,8 @@ static inline int bnxt_alloc_rx_data(struct bnxt_rx_queue *rxq,
 	mbuf = __bnxt_alloc_rx_data(rxq->mb_pool);
 	if (!mbuf) {
 		__atomic_fetch_add(&rxq->rx_mbuf_alloc_fail, 1, __ATOMIC_RELAXED);
+		/* If buff has failed already, setting this again won't hurt */
+		rxq->need_realloc = 1;
 		return -ENOMEM;
 	}
 
@@ -85,6 +87,8 @@ static inline int bnxt_alloc_ag_data(struct bnxt_rx_queue *rxq,
 	mbuf = __bnxt_alloc_rx_data(rxq->mb_pool);
 	if (!mbuf) {
 		__atomic_fetch_add(&rxq->rx_mbuf_alloc_fail, 1, __ATOMIC_RELAXED);
+		/* If buff has failed already, setting this again won't hurt */
+		rxq->need_realloc = 1;
 		return -ENOMEM;
 	}
 
@@ -139,7 +143,6 @@ static void bnxt_rx_ring_reset(void *arg)
 	int i, rc = 0;
 	struct bnxt_rx_queue *rxq;
 
-
 	for (i = 0; i < (int)bp->rx_nr_rings; i++) {
 		struct bnxt_rx_ring_info *rxr;
 
@@ -357,7 +360,8 @@ static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
 		RTE_ASSERT(ag_cons <= rxr->ag_ring_struct->ring_mask);
 		ag_buf = &rxr->ag_buf_ring[ag_cons];
 		ag_mbuf = *ag_buf;
-		RTE_ASSERT(ag_mbuf != NULL);
+		if (ag_mbuf == NULL)
+			return -EBUSY;
 
 		ag_mbuf->data_len = rte_le_to_cpu_16(rxcmp->len);
 
@@ -452,7 +456,7 @@ static inline struct rte_mbuf *bnxt_tpa_end(
 	RTE_ASSERT(mbuf != NULL);
 
 	if (agg_bufs) {
-		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs, tpa_info);
+		(void)bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs, tpa_info);
 	}
 	mbuf->l4_len = payload_offset;
 
@@ -1230,8 +1234,11 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		bnxt_set_mark_in_mbuf(rxq->bp, rxcmp1, mbuf);
 
 reuse_rx_mbuf:
-	if (agg_buf)
-		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf, NULL);
+	if (agg_buf) {
+		rc = bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf, NULL);
+		if (rc != 0)
+			return -EBUSY;
+	}
 
 #ifdef BNXT_DEBUG
 	if (rxcmp1->errors_v2 & RX_CMP_L2_ERRORS) {
@@ -1293,6 +1300,48 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	return rc;
 }
 
+static void bnxt_reattempt_buffer_alloc(struct bnxt_rx_queue *rxq)
+{
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	struct bnxt_ring *ring;
+	uint16_t raw_prod;
+	uint32_t cnt;
+
+	/* Assume alloc passes. On failure,
+	 * need_realloc will be set inside bnxt_alloc_XY_data.
+	 */
+	rxq->need_realloc = 0;
+	if (!bnxt_need_agg_ring(rxq->bp->eth_dev))
+		goto alloc_rx;
+
+	raw_prod = rxr->ag_raw_prod;
+	bnxt_prod_ag_mbuf(rxq);
+	if (raw_prod != rxr->ag_raw_prod)
+		bnxt_db_write(&rxr->ag_db, rxr->ag_raw_prod);
+
+alloc_rx:
+	raw_prod = rxr->rx_raw_prod;
+	ring = rxr->rx_ring_struct;
+	for (cnt = 0; cnt < ring->ring_size; cnt++) {
+		struct rte_mbuf **rx_buf;
+		uint16_t ndx;
+
+		ndx = RING_IDX(ring, raw_prod + cnt);
+		rx_buf = &rxr->rx_buf_ring[ndx];
+
+		/* Buffer already allocated for this index. */
+		if (*rx_buf != NULL && *rx_buf != &rxq->fake_mbuf)
+			continue;
+
+		/* This slot is empty. Alloc buffer for Rx */
+		if (bnxt_alloc_rx_data(rxq, rxr, raw_prod + cnt))
+			break;
+
+		rxr->rx_raw_prod = raw_prod + cnt;
+		bnxt_db_write(&rxr->rx_db, rxr->rx_raw_prod);
+	}
+}
+
 uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 			       uint16_t nb_pkts)
 {
@@ -1302,7 +1351,6 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	uint16_t rx_raw_prod = rxr->rx_raw_prod;
 	uint16_t ag_raw_prod = rxr->ag_raw_prod;
 	uint32_t raw_cons = cpr->cp_raw_cons;
-	bool alloc_failed = false;
 	uint32_t cons;
 	int nb_rx_pkts = 0;
 	int nb_rep_rx_pkts = 0;
@@ -1358,10 +1406,8 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 				break;
 			else if (rc == -ENODEV)	/* completion for representor */
 				nb_rep_rx_pkts++;
-			else if (rc == -ENOMEM) {
+			else if (rc == -ENOMEM)
 				nb_rx_pkts++;
-				alloc_failed = true;
-			}
 		} else if (!BNXT_NUM_ASYNC_CPR(rxq->bp)) {
 			evt =
 			bnxt_event_hwrm_resp_handler(rxq->bp,
@@ -1372,7 +1418,12 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 		}
 
 		raw_cons = NEXT_RAW_CMP(raw_cons);
-		if (nb_rx_pkts == nb_pkts || nb_rep_rx_pkts == nb_pkts || evt)
+		/*
+		 * The HW reposting may fall behind if mbuf allocation has
+		 * failed. Break and reattempt allocation to prevent that.
+		 */
+		if (nb_rx_pkts == nb_pkts || nb_rep_rx_pkts == nb_pkts || evt ||
+		    rxq->need_realloc != 0)
 			break;
 	}
 
@@ -1395,35 +1446,9 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts,
 	/* Ring the AGG ring DB */
 	if (ag_raw_prod != rxr->ag_raw_prod)
 		bnxt_db_write(&rxr->ag_db, rxr->ag_raw_prod);
-
-	/* Attempt to alloc Rx buf in case of a previous allocation failure. */
-	if (alloc_failed) {
-		int cnt;
-
-		rx_raw_prod = RING_NEXT(rx_raw_prod);
-		for (cnt = 0; cnt < nb_rx_pkts + nb_rep_rx_pkts; cnt++) {
-			struct rte_mbuf **rx_buf;
-			uint16_t ndx;
-
-			ndx = RING_IDX(rxr->rx_ring_struct, rx_raw_prod + cnt);
-			rx_buf = &rxr->rx_buf_ring[ndx];
-
-			/* Buffer already allocated for this index. */
-			if (*rx_buf != NULL && *rx_buf != &rxq->fake_mbuf)
-				continue;
-
-			/* This slot is empty. Alloc buffer for Rx */
-			if (!bnxt_alloc_rx_data(rxq, rxr, rx_raw_prod + cnt)) {
-				rxr->rx_raw_prod = rx_raw_prod + cnt;
-				bnxt_db_write(&rxr->rx_db, rxr->rx_raw_prod);
-			} else {
-				PMD_DRV_LOG(ERR, "Alloc  mbuf failed\n");
-				break;
-			}
-		}
-	}
-
 done:
+	if (unlikely(rxq->need_realloc))
+		bnxt_reattempt_buffer_alloc(rxq);
 	return nb_rx_pkts;
 }
 
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 08/18] net/bnxt: refactor Rx doorbell during Rx flush
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (6 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 07/18] net/bnxt: reattempt mbuf allocation for Rx and AGG rings Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 09/18] net/bnxt: extend RSS hash support for P7 devices Ajit Khaparde
                   ` (9 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 874 bytes --]

Ring the Rx doorbell during the Rx ring flush processing only if
there is a valid completion.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt_rxr.c | 9 +++++----
 1 file changed, 5 insertions(+), 4 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index c5c9f9e6e6..d0706874a6 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -1713,10 +1713,11 @@ int bnxt_flush_rx_cmp(struct bnxt_cp_ring_info *cpr)
 		nb_rx++;
 	} while (nb_rx < ring_mask);
 
-	cpr->cp_raw_cons = raw_cons;
-
-	/* Ring the completion queue doorbell. */
-	bnxt_db_cq(cpr);
+	if (nb_rx) {
+		cpr->cp_raw_cons = raw_cons;
+		/* Ring the completion queue doorbell. */
+		bnxt_db_cq(cpr);
+	}
 
 	return 0;
 }
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 09/18] net/bnxt: extend RSS hash support for P7 devices
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (7 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 08/18] net/bnxt: refactor Rx doorbell during Rx flush Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 10/18] net/bnxt: add flow query callback Ajit Khaparde
                   ` (8 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 20735 bytes --]

P7 adapters support XOR based and checksum based RSS hashing.
Add support for checksum and XOR based RSS hash for these adapters.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  15 +--
 drivers/net/bnxt/bnxt_ethdev.c |  72 ++++++---------
 drivers/net/bnxt/bnxt_flow.c   |  37 +++++++-
 drivers/net/bnxt/bnxt_hwrm.c   |   6 ++
 drivers/net/bnxt/bnxt_reps.c   |   2 +-
 drivers/net/bnxt/bnxt_vnic.c   | 161 +++++++++++++++++++++++++++++++--
 drivers/net/bnxt/bnxt_vnic.h   |  18 +++-
 7 files changed, 242 insertions(+), 69 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index cd85a944e8..e7b288c849 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -638,15 +638,6 @@ struct bnxt_rep_info {
 #define BNXT_FW_STATUS_HEALTHY		0x8000
 #define BNXT_FW_STATUS_SHUTDOWN		0x100000
 
-#define BNXT_ETH_RSS_SUPPORT (	\
-	RTE_ETH_RSS_IPV4 |		\
-	RTE_ETH_RSS_NONFRAG_IPV4_TCP |	\
-	RTE_ETH_RSS_NONFRAG_IPV4_UDP |	\
-	RTE_ETH_RSS_IPV6 |		\
-	RTE_ETH_RSS_NONFRAG_IPV6_TCP |	\
-	RTE_ETH_RSS_NONFRAG_IPV6_UDP |	\
-	RTE_ETH_RSS_LEVEL_MASK)
-
 #define BNXT_HWRM_SHORT_REQ_LEN		sizeof(struct hwrm_short_input)
 
 struct bnxt_flow_stat_info {
@@ -815,7 +806,10 @@ struct bnxt {
 #define BNXT_VNIC_CAP_VLAN_RX_STRIP	BIT(3)
 #define BNXT_RX_VLAN_STRIP_EN(bp)	((bp)->vnic_cap_flags & BNXT_VNIC_CAP_VLAN_RX_STRIP)
 #define BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF	BIT(4)
-#define BNXT_VNIC_CAP_L2_CQE_MODE		BIT(8)
+#define BNXT_VNIC_CAP_XOR_MODE		BIT(5)
+#define BNXT_VNIC_CAP_CHKSM_MODE	BIT(6)
+#define BNXT_VNIC_CAP_L2_CQE_MODE	BIT(8)
+
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
 	unsigned int		rx_num_qs_per_vnic;
@@ -1176,4 +1170,5 @@ void bnxt_handle_vf_cfg_change(void *arg);
 int bnxt_flow_meter_ops_get(struct rte_eth_dev *eth_dev, void *arg);
 struct bnxt_vnic_info *bnxt_get_default_vnic(struct bnxt *bp);
 struct tf *bnxt_get_tfp_session(struct bnxt *bp, enum bnxt_session_type type);
+uint64_t bnxt_eth_rss_support(struct bnxt *bp);
 #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 0f1c4326c4..ef5e65ff16 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -982,6 +982,25 @@ uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
 	return speed_capa;
 }
 
+uint64_t bnxt_eth_rss_support(struct bnxt *bp)
+{
+	uint64_t support;
+
+	support = RTE_ETH_RSS_IPV4 |
+		  RTE_ETH_RSS_NONFRAG_IPV4_TCP |
+		  RTE_ETH_RSS_NONFRAG_IPV4_UDP |
+		  RTE_ETH_RSS_IPV6 |
+		  RTE_ETH_RSS_NONFRAG_IPV6_TCP |
+		  RTE_ETH_RSS_NONFRAG_IPV6_UDP |
+		  RTE_ETH_RSS_LEVEL_MASK;
+
+	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
+		support |= (RTE_ETH_RSS_IPV4_CHKSUM |
+			    RTE_ETH_RSS_L4_CHKSUM);
+
+	return support;
+}
+
 static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 				struct rte_eth_dev_info *dev_info)
 {
@@ -1023,7 +1042,7 @@ static int bnxt_dev_info_get_op(struct rte_eth_dev *eth_dev,
 	dev_info->tx_queue_offload_capa = RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE;
 	dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(bp) |
 				    dev_info->tx_queue_offload_capa;
-	dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
+	dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(bp);
 
 	dev_info->speed_capa = bnxt_get_speed_capabilities(bp);
 	dev_info->dev_capa = RTE_ETH_DEV_CAPA_RUNTIME_RX_QUEUE_SETUP |
@@ -2175,7 +2194,7 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
 		if (!rss_conf->rss_hf)
 			PMD_DRV_LOG(ERR, "Hash type NONE\n");
 	} else {
-		if (rss_conf->rss_hf & BNXT_ETH_RSS_SUPPORT)
+		if (rss_conf->rss_hf & bnxt_eth_rss_support(bp))
 			return -EINVAL;
 	}
 
@@ -2185,6 +2204,12 @@ static int bnxt_rss_hash_update_op(struct rte_eth_dev *eth_dev,
 	vnic->hash_mode =
 		bnxt_rte_to_hwrm_hash_level(bp, rss_conf->rss_hf,
 					    RTE_ETH_RSS_LEVEL(rss_conf->rss_hf));
+	rc = bnxt_rte_eth_to_hwrm_ring_select_mode(bp, rss_conf->rss_hf, vnic);
+	if (rc != 0)
+		return rc;
+
+	/* Cache the hash function */
+	bp->rss_conf.rss_hf = rss_conf->rss_hf;
 
 	/* Cache the hash function */
 	bp->rss_conf.rss_hf = rss_conf->rss_hf;
@@ -2218,60 +2243,21 @@ static int bnxt_rss_hash_conf_get_op(struct rte_eth_dev *eth_dev,
 	struct bnxt *bp = eth_dev->data->dev_private;
 	struct bnxt_vnic_info *vnic = bnxt_get_default_vnic(bp);
 	int len, rc;
-	uint32_t hash_types;
 
 	rc = is_bnxt_in_error(bp);
 	if (rc)
 		return rc;
 
-	/* RSS configuration is the same for all VNICs */
+	/* Return the RSS configuration of the default VNIC. */
 	if (vnic && vnic->rss_hash_key) {
 		if (rss_conf->rss_key) {
 			len = rss_conf->rss_key_len <= HW_HASH_KEY_SIZE ?
 			      rss_conf->rss_key_len : HW_HASH_KEY_SIZE;
 			memcpy(rss_conf->rss_key, vnic->rss_hash_key, len);
 		}
-
-		hash_types = vnic->hash_type;
-		rss_conf->rss_hf = 0;
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_IPV4;
-			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
-		}
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
-			hash_types &=
-				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
-		}
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
-			hash_types &=
-				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4;
-		}
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_IPV6;
-			hash_types &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
-		}
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
-			hash_types &=
-				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
-		}
-		if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6) {
-			rss_conf->rss_hf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
-			hash_types &=
-				~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
-		}
-
+		bnxt_hwrm_rss_to_rte_hash_conf(vnic, &rss_conf->rss_hf);
 		rss_conf->rss_hf |=
 			bnxt_hwrm_to_rte_rss_level(bp, vnic->hash_mode);
-
-		if (hash_types) {
-			PMD_DRV_LOG(ERR,
-				"Unknown RSS config from firmware (%08x), RSS disabled",
-				vnic->hash_type);
-			return -ENOTSUP;
-		}
 	} else {
 		rss_conf->rss_hf = 0;
 	}
diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c
index 15f0e1b308..2d707b48d2 100644
--- a/drivers/net/bnxt/bnxt_flow.c
+++ b/drivers/net/bnxt/bnxt_flow.c
@@ -881,6 +881,7 @@ static void bnxt_vnic_cleanup(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	vnic->fw_grp_ids = NULL;
 
 	vnic->rx_queue_cnt = 0;
+	vnic->hash_type = 0;
 }
 
 static int bnxt_vnic_prep(struct bnxt *bp, struct bnxt_vnic_info *vnic,
@@ -1067,7 +1068,7 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
 {
 	const struct rte_flow_action_rss *rss;
 	unsigned int rss_idx, i, j, fw_idx;
-	uint16_t hash_type;
+	uint32_t hash_type;
 	uint64_t types;
 	int rc;
 
@@ -1115,9 +1116,9 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
 		}
 	}
 
-	/* Currently only Toeplitz hash is supported. */
-	if (rss->func != RTE_ETH_HASH_FUNCTION_DEFAULT &&
-	    rss->func != RTE_ETH_HASH_FUNCTION_TOEPLITZ) {
+	if (BNXT_IS_HASH_FUNC_DEFAULT(rss->func) &&
+	    BNXT_IS_HASH_FUNC_TOEPLITZ(rss->func) &&
+	    BNXT_IS_HASH_FUNC_SIMPLE_XOR(bp, rss->func)) {
 		rte_flow_error_set(error,
 				   ENOTSUP,
 				   RTE_FLOW_ERROR_TYPE_ACTION,
@@ -1175,6 +1176,34 @@ bnxt_vnic_rss_cfg_update(struct bnxt *bp,
 	vnic->hash_mode =
 		bnxt_rte_to_hwrm_hash_level(bp, rss->types, rss->level);
 
+	/* For P7 chips update the hash_type if hash_type not explicitly passed.
+	 * TODO: For P5 chips.
+	 */
+	if (BNXT_CHIP_P7(bp) &&
+	    vnic->hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type)
+		vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+			HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+
+	/* TODO:
+	 * hash will be performed on the L3 and L4 packet headers.
+	 * specific RSS hash types like IPv4-TCP etc... or L4-chksum or IPV4-chksum
+	 * will NOT have any bearing and will not be honored.
+	 * Check and reject flow create accordingly. TODO.
+	 */
+
+	rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss->func,
+						    rss->types,
+						    bp, vnic);
+	if (rc) {
+		rte_flow_error_set(error,
+				   ENOTSUP,
+				   RTE_FLOW_ERROR_TYPE_ACTION,
+				   act,
+				   "Unsupported RSS hash parameters");
+		rc = -rte_errno;
+		goto ret;
+	}
+
 	/* Update RSS key only if key_len != 0 */
 	if (rss->key_len != 0)
 		memcpy(vnic->rss_hash_key, rss->key, rss->key_len);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index d649f217ec..587433a878 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1025,6 +1025,12 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
 		PMD_DRV_LOG(DEBUG, "Rx VLAN strip capability enabled\n");
 	}
 
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_XOR_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_XOR_MODE;
+
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_TOEPLITZ_CHKSM_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_CHKSM_MODE;
+
 	bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
 
 	HWRM_UNLOCK();
diff --git a/drivers/net/bnxt/bnxt_reps.c b/drivers/net/bnxt/bnxt_reps.c
index 78337431af..d96d972904 100644
--- a/drivers/net/bnxt/bnxt_reps.c
+++ b/drivers/net/bnxt/bnxt_reps.c
@@ -569,7 +569,7 @@ int bnxt_rep_dev_info_get_op(struct rte_eth_dev *eth_dev,
 
 	dev_info->rx_offload_capa = bnxt_get_rx_port_offloads(parent_bp);
 	dev_info->tx_offload_capa = bnxt_get_tx_port_offloads(parent_bp);
-	dev_info->flow_type_rss_offloads = BNXT_ETH_RSS_SUPPORT;
+	dev_info->flow_type_rss_offloads = bnxt_eth_rss_support(parent_bp);
 
 	dev_info->switch_info.name = eth_dev->device->name;
 	dev_info->switch_info.domain_id = rep_bp->switch_domain_id;
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index bf93120d28..6a57f85ea7 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -256,10 +256,15 @@ int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return 0;
 }
 
-uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
+uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 {
-	uint16_t hwrm_type = 0;
+	uint32_t hwrm_type = 0;
 
+	if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
+		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+	if (rte_type & RTE_ETH_RSS_L4_CHKSUM)
+		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+			     HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
 	if ((rte_type & RTE_ETH_RSS_IPV4) ||
 	    (rte_type & RTE_ETH_RSS_ECPRI))
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
@@ -273,6 +278,9 @@ uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
 	if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
+	if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
+		hwrm_type |=
+			HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
 
 	return hwrm_type;
 }
@@ -287,6 +295,8 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)
 			     RTE_ETH_RSS_NONFRAG_IPV6_TCP));
 	bool l3_only = l3 && !l4;
 	bool l3_and_l4 = l3 && l4;
+	bool cksum = !!(hash_f &
+			(RTE_ETH_RSS_IPV4_CHKSUM | RTE_ETH_RSS_L4_CHKSUM));
 
 	/* If FW has not advertised capability to configure outer/inner
 	 * RSS hashing , just log a message. HW will work in default RSS mode.
@@ -302,12 +312,12 @@ int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl)
 	switch (lvl) {
 	case BNXT_RSS_LEVEL_INNERMOST:
 		/* Irrespective of what RTE says, FW always does 4 tuple */
-		if (l3_and_l4 || l4 || l3_only)
+		if (l3_and_l4 || l4 || l3_only || cksum)
 			mode = BNXT_HASH_MODE_INNERMOST;
 		break;
 	case BNXT_RSS_LEVEL_OUTERMOST:
 		/* Irrespective of what RTE says, FW always does 4 tuple */
-		if (l3_and_l4 || l4 || l3_only)
+		if (l3_and_l4 || l4 || l3_only || cksum)
 			mode = BNXT_HASH_MODE_OUTERMOST;
 		break;
 	default:
@@ -733,6 +743,16 @@ bnxt_vnic_rss_create(struct bnxt *bp,
 		goto fail_cleanup;
 	}
 
+	/* Remove unsupported types */
+	rss_info->rss_types &= bnxt_eth_rss_support(bp);
+
+	/* If only unsupported type(s) are specified then quit */
+	if (rss_info->rss_types == 0) {
+		PMD_DRV_LOG(ERR,
+			    "Unsupported RSS hash type(s)\n");
+		goto fail_cleanup;
+	}
+
 	/* hwrm_type conversion */
 	vnic->hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
 	vnic->hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
@@ -803,9 +823,11 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
 			       struct bnxt_vnic_rss_info *rss_info)
 {
 	uint8_t old_rss_hash_key[HW_HASH_KEY_SIZE] = { 0 };
-	uint16_t	hash_type;
-	uint8_t		hash_mode;
+	uint32_t hash_type;
+	uint8_t hash_mode;
+	uint8_t ring_mode;
 	uint32_t apply = 0;
+	int rc;
 
 	/* validate key length */
 	if (rss_info->key_len != 0 && rss_info->key_len != HW_HASH_KEY_SIZE) {
@@ -815,12 +837,40 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
 		return -EINVAL;
 	}
 
+	/* Remove unsupported types */
+	rss_info->rss_types &= bnxt_eth_rss_support(bp);
+
+	/* If only unsupported type(s) are specified then quit */
+	if (!rss_info->rss_types) {
+		PMD_DRV_LOG(ERR,
+			    "Unsupported RSS hash type\n");
+		return -EINVAL;
+	}
+
 	/* hwrm_type conversion */
 	hash_type = bnxt_rte_to_hwrm_hash_types(rss_info->rss_types);
 	hash_mode = bnxt_rte_to_hwrm_hash_level(bp, rss_info->rss_types,
 						rss_info->rss_level);
+	ring_mode = vnic->ring_select_mode;
+
+	/* For P7 chips update the hash_type if hash_type not explicitly passed.
+	 * TODO: For P5 chips.
+	 */
+	if (BNXT_CHIP_P7(bp) &&
+	    hash_mode == BNXT_HASH_MODE_DEFAULT && !hash_type)
+		vnic->hash_type = HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4 |
+			HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6;
+
+	rc = bnxt_rte_flow_to_hwrm_ring_select_mode(rss_info->rss_func,
+						    rss_info->rss_types,
+						    bp,
+						    vnic);
+	if (rc)
+		return -EINVAL;
+
 	if (vnic->hash_mode != hash_mode ||
-	    vnic->hash_type != hash_type) {
+	    vnic->hash_type != hash_type ||
+	    vnic->ring_select_mode != ring_mode) {
 		apply = 1;
 		vnic->hash_mode = hash_mode;
 		vnic->hash_type = hash_type;
@@ -839,10 +889,10 @@ bnxt_vnic_rss_hash_algo_update(struct bnxt *bp,
 	if (apply) {
 		if (bnxt_hwrm_vnic_rss_cfg(bp, vnic)) {
 			memcpy(vnic->rss_hash_key, old_rss_hash_key, HW_HASH_KEY_SIZE);
-			BNXT_TF_DBG(ERR, "Error configuring vnic RSS config\n");
+			PMD_DRV_LOG(ERR, "Error configuring vnic RSS config\n");
 			return -EINVAL;
 		}
-		BNXT_TF_DBG(INFO, "Rss config successfully applied\n");
+		PMD_DRV_LOG(INFO, "Rss config successfully applied\n");
 	}
 	return 0;
 }
@@ -1245,3 +1295,96 @@ bnxt_get_default_vnic(struct bnxt *bp)
 {
 	return &bp->vnic_info[bp->vnic_queue_db.dflt_vnic_id];
 }
+
+uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f)
+{
+	/* If RTE_ETH_HASH_FUNCTION_DEFAULT || RTE_ETH_HASH_FUNCTION_TOEPLITZ */
+	uint8_t mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
+
+	if (hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)
+		mode = HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_XOR;
+
+	return mode;
+}
+
+int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
+					   uint64_t types, struct bnxt *bp,
+					   struct bnxt_vnic_info *vnic)
+{
+	if (hash_f != RTE_ETH_HASH_FUNCTION_TOEPLITZ &&
+	    hash_f != RTE_ETH_HASH_FUNCTION_DEFAULT) {
+		if (hash_f == RTE_ETH_HASH_FUNCTION_SYMMETRIC_TOEPLITZ ||
+		    (!BNXT_CHIP_P7(bp) && hash_f == RTE_ETH_HASH_FUNCTION_SIMPLE_XOR)) {
+			PMD_DRV_LOG(ERR, "Unsupported hash function\n");
+			return -ENOTSUP;
+		}
+	}
+
+	if (types & RTE_ETH_RSS_IPV4_CHKSUM || types & RTE_ETH_RSS_L4_CHKSUM) {
+		if ((bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE) &&
+			(hash_f == RTE_ETH_HASH_FUNCTION_DEFAULT ||
+			 hash_f == RTE_ETH_HASH_FUNCTION_TOEPLITZ)) {
+			/* Checksum mode cannot with hash func makes no sense */
+			vnic->ring_select_mode =
+				HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+			/* shadow copy types as !hash_f is always true with default func */
+			return 0;
+		}
+		PMD_DRV_LOG(ERR, "Hash function not supported with checksun type\n");
+		return -ENOTSUP;
+	}
+
+	vnic->ring_select_mode = _bnxt_rte_to_hwrm_ring_select_mode(hash_f);
+	return 0;
+}
+
+int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
+					  struct bnxt_vnic_info *vnic)
+{
+	/* If the config update comes via ethdev, there is no way to
+	 * specify anything for hash function.
+	 * So its either TOEPLITZ or the Checksum mode.
+	 * Note that checksum mode is not supported on older devices.
+	 */
+	if (types == RTE_ETH_RSS_IPV4_CHKSUM) {
+		if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
+			vnic->ring_select_mode =
+			HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+		else
+			return -ENOTSUP;
+	}
+
+	/* Older devices can support TOEPLITZ only.
+	 * Thor2 supports other hash functions, but can't change using this path.
+	 */
+	vnic->ring_select_mode =
+		HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
+	return 0;
+}
+
+void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
+				    uint64_t *rss_conf)
+{
+	uint32_t hash_types;
+
+	hash_types = vnic->hash_type;
+	*rss_conf = 0;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4)
+		*rss_conf |= RTE_ETH_RSS_IPV4;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4)
+		*rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_TCP;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV4)
+		*rss_conf |= RTE_ETH_RSS_NONFRAG_IPV4_UDP;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV6)
+		*rss_conf |= RTE_ETH_RSS_IPV6;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6)
+		*rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_TCP;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6)
+		*rss_conf |= RTE_ETH_RSS_NONFRAG_IPV6_UDP;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6 ||
+	    hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4)
+		*rss_conf |= RTE_ETH_RSS_AH;
+	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6 ||
+	    hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4)
+		*rss_conf |= RTE_ETH_RSS_ESP;
+}
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index 7a6a0aa739..d01c9ebdb4 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -31,6 +31,11 @@
 	 (BNXT_VF(bp) && BNXT_VF_IS_TRUSTED(bp) &&				\
 	  !((bp)->vnic_cap_flags & BNXT_VNIC_CAP_OUTER_RSS_TRUSTED_VF)) ||	\
 	 (BNXT_VF(bp) && !BNXT_VF_IS_TRUSTED(bp)))
+#define BNXT_IS_HASH_FUNC_DEFAULT(f)	((f) != RTE_ETH_HASH_FUNCTION_DEFAULT)
+#define BNXT_IS_HASH_FUNC_TOEPLITZ(f)	((f) != RTE_ETH_HASH_FUNCTION_TOEPLITZ)
+#define BNXT_IS_HASH_FUNC_SIMPLE_XOR(b, f)	\
+	((b)->vnic_cap_flags & BNXT_VNIC_CAP_XOR_MODE && \
+	 ((f) != RTE_ETH_HASH_FUNCTION_SIMPLE_XOR))
 
 struct bnxt_vnic_info {
 	STAILQ_ENTRY(bnxt_vnic_info)	next;
@@ -73,6 +78,7 @@ struct bnxt_vnic_info {
 
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 	STAILQ_HEAD(, rte_flow)	flow_list;
+	uint8_t		ring_select_mode;
 };
 
 struct bnxt_vnic_queue_db {
@@ -83,6 +89,7 @@ struct bnxt_vnic_queue_db {
 
 /* RSS structure to pass values as an structure argument*/
 struct bnxt_vnic_rss_info {
+	uint32_t rss_func;
 	uint32_t rss_level;
 	uint64_t rss_types;
 	uint32_t key_len; /**< Hash key length in bytes. */
@@ -102,7 +109,7 @@ void bnxt_free_vnic_mem(struct bnxt *bp);
 int bnxt_alloc_vnic_mem(struct bnxt *bp);
 int bnxt_vnic_grp_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 void bnxt_prandom_bytes(void *dest_ptr, size_t len);
-uint16_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
+uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type);
 int bnxt_rte_to_hwrm_hash_level(struct bnxt *bp, uint64_t hash_f, uint32_t lvl);
 uint64_t bnxt_hwrm_to_rte_rss_level(struct bnxt *bp, uint32_t mode);
 
@@ -139,5 +146,12 @@ struct bnxt_vnic_info *
 bnxt_vnic_queue_id_get_next(struct bnxt *bp, uint16_t queue_id,
 			    uint16_t *vnic_idx);
 void bnxt_vnic_tpa_cfg(struct bnxt *bp, uint16_t queue_id, bool flag);
-
+uint8_t _bnxt_rte_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f);
+int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
+					   uint64_t types, struct bnxt *bp,
+					   struct bnxt_vnic_info *vnic);
+int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
+					  struct bnxt_vnic_info *vnic);
+void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
+				    uint64_t *rss_conf);
 #endif
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 10/18] net/bnxt: add flow query callback
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (8 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 09/18] net/bnxt: extend RSS hash support for P7 devices Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 11/18] net/bnxt: add ESP and AH header based RSS support Ajit Khaparde
                   ` (7 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 4240 bytes --]

From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>

This patch addsbnxt query callback to rte_flow_ops in non TruFlow mode.
At this point only the RSS hash function type is displayed.

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_flow.c | 61 ++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_vnic.c | 11 +++++++
 drivers/net/bnxt/bnxt_vnic.h |  2 ++
 3 files changed, 74 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_flow.c b/drivers/net/bnxt/bnxt_flow.c
index 2d707b48d2..f25bc6ff78 100644
--- a/drivers/net/bnxt/bnxt_flow.c
+++ b/drivers/net/bnxt/bnxt_flow.c
@@ -1917,6 +1917,66 @@ void bnxt_flow_cnt_alarm_cb(void *arg)
 			  (void *)bp);
 }
 
+/* Query an requested flow rule. */
+static int
+bnxt_flow_query_all(struct rte_flow *flow,
+		    const struct rte_flow_action *actions, void *data,
+		    struct rte_flow_error *error)
+{
+	struct rte_flow_action_rss *rss_conf;
+	struct bnxt_vnic_info *vnic;
+
+	vnic = flow->vnic;
+	if (vnic == NULL)
+		return rte_flow_error_set(error, EINVAL,
+					  RTE_FLOW_ERROR_TYPE_HANDLE, flow,
+					  "Invalid flow: failed to query flow.");
+
+	for (; actions->type != RTE_FLOW_ACTION_TYPE_END; actions++) {
+		switch (actions->type) {
+		case RTE_FLOW_ACTION_TYPE_VOID:
+			break;
+		case RTE_FLOW_ACTION_TYPE_COUNT:
+			break;
+		case RTE_FLOW_ACTION_TYPE_RSS:
+			/* Full details of rte_flow_action_rss not available yet TBD*/
+			rss_conf = (struct rte_flow_action_rss *)data;
+
+			/* toeplitz is default */
+			if (vnic->ring_select_mode ==
+					HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ)
+				rss_conf->func = vnic->hash_f_local;
+			else
+				rss_conf->func = RTE_ETH_HASH_FUNCTION_SIMPLE_XOR;
+
+			break;
+		default:
+			return rte_flow_error_set(error, ENOTSUP,
+						  RTE_FLOW_ERROR_TYPE_ACTION, actions,
+						  "action is not supported");
+		}
+	}
+
+	return 0;
+}
+
+static int
+bnxt_flow_query(struct rte_eth_dev *dev, struct rte_flow *flow,
+		const struct rte_flow_action *actions, void *data,
+		struct rte_flow_error *error)
+{
+	struct bnxt *bp = dev->data->dev_private;
+	int ret = 0;
+
+	if (bp == NULL)
+		return -ENODEV;
+
+	bnxt_acquire_flow_lock(bp);
+	ret = bnxt_flow_query_all(flow, actions, data, error);
+	bnxt_release_flow_lock(bp);
+
+	return ret;
+}
 
 static struct rte_flow *
 bnxt_flow_create(struct rte_eth_dev *dev,
@@ -2374,4 +2434,5 @@ const struct rte_flow_ops bnxt_flow_ops = {
 	.create = bnxt_flow_create,
 	.destroy = bnxt_flow_destroy,
 	.flush = bnxt_flow_flush,
+	.query = bnxt_flow_query,
 };
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 6a57f85ea7..bf1f0ea09f 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -1335,6 +1335,9 @@ int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
 	}
 
 	vnic->ring_select_mode = _bnxt_rte_to_hwrm_ring_select_mode(hash_f);
+	vnic->hash_f_local = hash_f;
+	/* shadow copy types as !hash_f is always true with default func */
+	vnic->rss_types_local = types;
 	return 0;
 }
 
@@ -1359,6 +1362,8 @@ int bnxt_rte_eth_to_hwrm_ring_select_mode(struct bnxt *bp, uint64_t types,
 	 */
 	vnic->ring_select_mode =
 		HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
+	vnic->hash_f_local =
+		HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ;
 	return 0;
 }
 
@@ -1367,6 +1372,12 @@ void bnxt_hwrm_rss_to_rte_hash_conf(struct bnxt_vnic_info *vnic,
 {
 	uint32_t hash_types;
 
+	/* check for local shadow rte types */
+	if (vnic->rss_types_local != 0) {
+		*rss_conf = vnic->rss_types_local;
+		return;
+	}
+
 	hash_types = vnic->hash_type;
 	*rss_conf = 0;
 	if (hash_types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4)
diff --git a/drivers/net/bnxt/bnxt_vnic.h b/drivers/net/bnxt/bnxt_vnic.h
index d01c9ebdb4..93155648e2 100644
--- a/drivers/net/bnxt/bnxt_vnic.h
+++ b/drivers/net/bnxt/bnxt_vnic.h
@@ -79,6 +79,8 @@ struct bnxt_vnic_info {
 	STAILQ_HEAD(, bnxt_filter_info)	filter;
 	STAILQ_HEAD(, rte_flow)	flow_list;
 	uint8_t		ring_select_mode;
+	enum rte_eth_hash_function hash_f_local;
+	uint64_t	rss_types_local;
 };
 
 struct bnxt_vnic_queue_db {
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 11/18] net/bnxt: add ESP and AH header based RSS support
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (9 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 10/18] net/bnxt: add flow query callback Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 12/18] net/bnxt: set allmulti mode if multicast filter fails Ajit Khaparde
                   ` (6 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 10621 bytes --]

Check if the firmware can support RSS based on these types and
program the hardware accodringly when requested when the
firmware indicates that the underlying hardware supports the
functionality.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |   6 ++
 drivers/net/bnxt/bnxt_ethdev.c |   8 ++-
 drivers/net/bnxt/bnxt_hwrm.c   | 104 +++++++++++++++++++++++++--------
 drivers/net/bnxt/bnxt_hwrm.h   |   1 +
 drivers/net/bnxt/bnxt_vnic.c   |  13 ++++-
 5 files changed, 102 insertions(+), 30 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index e7b288c849..576688bbff 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -809,6 +809,12 @@ struct bnxt {
 #define BNXT_VNIC_CAP_XOR_MODE		BIT(5)
 #define BNXT_VNIC_CAP_CHKSM_MODE	BIT(6)
 #define BNXT_VNIC_CAP_L2_CQE_MODE	BIT(8)
+#define BNXT_VNIC_CAP_AH_SPI4_CAP	BIT(9)
+#define BNXT_VNIC_CAP_AH_SPI6_CAP	BIT(10)
+#define BNXT_VNIC_CAP_ESP_SPI4_CAP	BIT(11)
+#define BNXT_VNIC_CAP_ESP_SPI6_CAP	BIT(12)
+#define BNXT_VNIC_CAP_AH_SPI_CAP	(BNXT_VNIC_CAP_AH_SPI4_CAP | BNXT_VNIC_CAP_AH_SPI6_CAP)
+#define BNXT_VNIC_CAP_ESP_SPI_CAP	(BNXT_VNIC_CAP_ESP_SPI4_CAP | BNXT_VNIC_CAP_ESP_SPI6_CAP)
 
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index ef5e65ff16..5b775e7716 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -995,8 +995,12 @@ uint64_t bnxt_eth_rss_support(struct bnxt *bp)
 		  RTE_ETH_RSS_LEVEL_MASK;
 
 	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_CHKSM_MODE)
-		support |= (RTE_ETH_RSS_IPV4_CHKSUM |
-			    RTE_ETH_RSS_L4_CHKSUM);
+		support |= RTE_ETH_RSS_IPV4_CHKSUM |
+			   RTE_ETH_RSS_L4_CHKSUM;
+	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_AH_SPI_CAP)
+		support |= RTE_ETH_RSS_AH;
+	if (bp->vnic_cap_flags & BNXT_VNIC_CAP_ESP_SPI_CAP)
+		support |= RTE_ETH_RSS_ESP;
 
 	return support;
 }
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 587433a878..1ac3f30074 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1031,6 +1031,21 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
 	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RING_SELECT_MODE_TOEPLITZ_CHKSM_CAP)
 		bp->vnic_cap_flags |= BNXT_VNIC_CAP_CHKSM_MODE;
 
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_L2_CQE_MODE_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_L2_CQE_MODE;
+
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_IPSEC_AH_SPI_IPV4_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_AH_SPI4_CAP;
+
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_IPSEC_AH_SPI_IPV6_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_AH_SPI6_CAP;
+
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_IPSEC_ESP_SPI_IPV4_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_ESP_SPI4_CAP;
+
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_IPSEC_ESP_SPI_IPV6_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_ESP_SPI6_CAP;
+
 	bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
 
 	HWRM_UNLOCK();
@@ -2412,6 +2427,52 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 	return rc;
 }
 
+static uint32_t bnxt_sanitize_rss_type(struct bnxt *bp, uint32_t types)
+{
+	uint32_t hwrm_type = types;
+
+	if (types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4 &&
+	    !(bp->vnic_cap_flags & BNXT_VNIC_CAP_ESP_SPI4_CAP))
+		hwrm_type &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4;
+	if (types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6 &&
+	    !(bp->vnic_cap_flags & BNXT_VNIC_CAP_ESP_SPI6_CAP))
+		hwrm_type &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6;
+
+	if (types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4 &&
+	    !(bp->vnic_cap_flags & BNXT_VNIC_CAP_AH_SPI4_CAP))
+		hwrm_type &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4;
+
+	if (types & HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6 &&
+	    !(bp->vnic_cap_flags & BNXT_VNIC_CAP_AH_SPI6_CAP))
+		hwrm_type &= ~HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6;
+
+	return hwrm_type;
+}
+
+#ifdef RTE_LIBRTE_BNXT_TRUFLOW_DEBUG
+static int
+bnxt_hwrm_vnic_rss_qcfg_p5(struct bnxt *bp)
+{
+	struct hwrm_vnic_rss_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_vnic_rss_qcfg_input req = {0};
+	int rc;
+
+	HWRM_PREP(&req, HWRM_VNIC_RSS_QCFG, BNXT_USE_CHIMP_MB);
+	/* vnic_id and rss_ctx_idx must be set to INVALID to read the
+	 * global hash mode.
+	 */
+	req.vnic_id = rte_cpu_to_le_16(BNXT_DFLT_VNIC_ID_INVALID);
+	req.rss_ctx_idx = rte_cpu_to_le_16(BNXT_RSS_CTX_IDX_INVALID);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req),
+				    BNXT_USE_CHIMP_MB);
+	HWRM_CHECK_RESULT();
+	HWRM_UNLOCK();
+	PMD_DRV_LOG(DEBUG, "RSS QCFG: Hash level %d\n", resp->hash_mode_flags);
+
+	return rc;
+}
+#endif
+
 static int
 bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
@@ -2425,7 +2486,10 @@ bnxt_hwrm_vnic_rss_cfg_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		HWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);
 
 		req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
-		req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
+		req.hash_type = rte_cpu_to_le_32(bnxt_sanitize_rss_type(bp, vnic->hash_type));
+		/* Update req with vnic ring_select_mode for P7 */
+		if (BNXT_CHIP_P7(bp))
+			req.ring_select_mode = vnic->ring_select_mode;
 		/* When the vnic_id in the request field is a valid
 		 * one, the hash_mode_flags in the request field must
 		 * be set to DEFAULT. And any request to change the
@@ -2524,7 +2588,7 @@ bnxt_hwrm_vnic_rss_cfg_non_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 
 	HWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);
 
-	req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
+	req.hash_type = rte_cpu_to_le_32(bnxt_sanitize_rss_type(bp, vnic->hash_type));
 	req.hash_mode_flags = vnic->hash_mode;
 
 	req.ring_grp_tbl_addr =
@@ -2550,29 +2614,18 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
 	if (!vnic->rss_table)
 		return 0;
 
-	if (BNXT_CHIP_P5(bp)) {
-		rc = bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic);
-		if (rc)
-			return rc;
-		/* Configuring the hash mode has to be done in a
-		 * different VNIC_RSS_CFG HWRM command by setting
-		 * vnic_id & rss_ctx_id to INVALID. The only
-		 * exception to this is if the USER doesn't want
-		 * to change the default behavior. So, ideally
-		 * bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 should be
-		 * called when user is explicitly changing the hash
-		 * mode. However, this logic will unconditionally
-		 * call bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 to
-		 * simplify the logic as there is no harm in calling
-		 * bnxt_hwrm_vnic_rss_cfg_hash_mode_p5 even when
-		 * user is not setting it explicitly. Because, this
-		 * routine will convert the default value to inner
-		 * which is our adapter's default behavior.
-		 */
+	/* Handle all the non-thor skus rss here */
+	if (!BNXT_CHIP_P5_P7(bp))
+		return bnxt_hwrm_vnic_rss_cfg_non_p5(bp, vnic);
+
+	/* Handle Thor2 and Thor skus rss here */
+	rc = bnxt_hwrm_vnic_rss_cfg_p5(bp, vnic);
+
+	/* configure hash mode for Thor/Thor2 */
+	if (!rc)
 		return bnxt_hwrm_vnic_rss_cfg_hash_mode_p5(bp, vnic);
-	}
 
-	return bnxt_hwrm_vnic_rss_cfg_non_p5(bp, vnic);
+	return rc;
 }
 
 int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
@@ -5343,7 +5396,7 @@ int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
 	return 0;
 }
 
-static int
+int
 bnxt_vnic_rss_configure_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
 	struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
@@ -5363,8 +5416,9 @@ bnxt_vnic_rss_configure_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 		HWRM_PREP(&req, HWRM_VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);
 
 		req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
-		req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
+		req.hash_type = rte_cpu_to_le_32(bnxt_sanitize_rss_type(bp, vnic->hash_type));
 		req.hash_mode_flags = vnic->hash_mode;
+		req.ring_select_mode = vnic->ring_select_mode;
 
 		req.ring_grp_tbl_addr =
 		    rte_cpu_to_le_64(vnic->rss_table_dma_addr +
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 3d5194257b..56b232d7de 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -357,6 +357,7 @@ void bnxt_free_hwrm_tx_ring(struct bnxt *bp, int queue_index);
 int bnxt_alloc_hwrm_tx_ring(struct bnxt *bp, int queue_index);
 int bnxt_hwrm_config_host_mtu(struct bnxt *bp);
 int bnxt_vnic_rss_clear_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
+int bnxt_vnic_rss_configure_p5(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_func_backing_store_qcaps_v2(struct bnxt *bp);
 int bnxt_hwrm_func_backing_store_cfg_v2(struct bnxt *bp,
 					struct bnxt_ctx_mem *ctxm);
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index bf1f0ea09f..5ea34f7cb6 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -268,6 +268,8 @@ uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 	if ((rte_type & RTE_ETH_RSS_IPV4) ||
 	    (rte_type & RTE_ETH_RSS_ECPRI))
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
+	if (rte_type & RTE_ETH_RSS_ECPRI)
+		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_IPV4;
 	if (rte_type & RTE_ETH_RSS_NONFRAG_IPV4_TCP)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV4;
 	if (rte_type & RTE_ETH_RSS_NONFRAG_IPV4_UDP)
@@ -278,9 +280,12 @@ uint32_t bnxt_rte_to_hwrm_hash_types(uint64_t rte_type)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_TCP_IPV6;
 	if (rte_type & RTE_ETH_RSS_NONFRAG_IPV6_UDP)
 		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_UDP_IPV6;
-	if (rte_type & RTE_ETH_RSS_IPV4_CHKSUM)
-		hwrm_type |=
-			HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+	if (rte_type & RTE_ETH_RSS_ESP)
+		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV4 |
+			     HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_ESP_SPI_IPV6;
+	if (rte_type & RTE_ETH_RSS_AH)
+		hwrm_type |= HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV4 |
+			     HWRM_VNIC_RSS_CFG_INPUT_HASH_TYPE_AH_SPI_IPV6;
 
 	return hwrm_type;
 }
@@ -1327,7 +1332,9 @@ int bnxt_rte_flow_to_hwrm_ring_select_mode(enum rte_eth_hash_function hash_f,
 			/* Checksum mode cannot with hash func makes no sense */
 			vnic->ring_select_mode =
 				HWRM_VNIC_RSS_CFG_INPUT_RING_SELECT_MODE_TOEPLITZ_CHECKSUM;
+			vnic->hash_f_local = RTE_ETH_HASH_FUNCTION_TOEPLITZ;
 			/* shadow copy types as !hash_f is always true with default func */
+			vnic->rss_types_local = types;
 			return 0;
 		}
 		PMD_DRV_LOG(ERR, "Hash function not supported with checksun type\n");
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 12/18] net/bnxt: set allmulti mode if multicast filter fails
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (10 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 11/18] net/bnxt: add ESP and AH header based RSS support Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 13/18] net/bnxt: add VF FLR async event handler Ajit Khaparde
                   ` (5 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 1346 bytes --]

Fallback to all multicast mode if FW rejects multicast filter
programming.

The firmware can reject the MC filter programming request if
it is running low in resources when there is a large number of functions.
The driver must be prepared to fallback to the all-multicast mode
if the original MC filter programming request is rejected.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 5b775e7716..7aed6d3ab6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -2947,7 +2947,17 @@ bnxt_dev_set_mc_addr_list_op(struct rte_eth_dev *eth_dev,
 		vnic->flags &= ~BNXT_VNIC_INFO_MCAST;
 
 allmulti:
-	return bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	rc = bnxt_hwrm_cfa_l2_set_rx_mask(bp, vnic, 0, NULL);
+	if (rc == -ENOSPC && (vnic->flags & BNXT_VNIC_INFO_MCAST)) {
+		/* If MCAST addition failed because FW ran out of
+		 * multicast filters, enable all multicast mode.
+		 */
+		vnic->flags &= ~BNXT_VNIC_INFO_MCAST;
+		vnic->flags |= BNXT_VNIC_INFO_ALLMULTI;
+		goto allmulti;
+	}
+
+	return rc;
 }
 
 static int
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 13/18] net/bnxt: add VF FLR async event handler
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (11 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 12/18] net/bnxt: set allmulti mode if multicast filter fails Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 14/18] net/bnxt: add tunnel TPA support Ajit Khaparde
                   ` (4 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Jay Ding

[-- Attachment #1: Type: text/plain, Size: 3108 bytes --]

From: Jay Ding <jay.ding@broadcom.com>

When a VF undergoes an FLR, the firmware indicates this via
an async notification to the PF. Note that the PF driver
needs to register for the notification with the firmware.
Add support for VF_FLR async event handling when the driver
is running on a PF.

Signed-off-by: Jay Ding <jay.ding@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt_cpr.c  | 20 ++++++++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.c |  6 ++++--
 drivers/net/bnxt/bnxt_hwrm.h |  2 ++
 3 files changed, 26 insertions(+), 2 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 0733cf4df2..fb43bc58da 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -127,6 +127,23 @@ void bnxt_handle_vf_cfg_change(void *arg)
 	}
 }
 
+static void
+bnxt_process_vf_flr(struct bnxt *bp, uint32_t data1)
+{
+	uint16_t pfid, vfid;
+
+	if (!BNXT_TRUFLOW_EN(bp))
+		return;
+
+	pfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_MASK) >>
+		HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_PF_ID_SFT;
+	vfid = (data1 & HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_MASK) >>
+		HWRM_ASYNC_EVENT_CMPL_VF_FLR_EVENT_DATA1_VF_ID_SFT;
+
+	PMD_DRV_LOG(INFO, "VF FLR async event received pfid: %u, vfid: %u\n",
+		    pfid, vfid);
+}
+
 /*
  * Async event handling
  */
@@ -264,6 +281,9 @@ void bnxt_handle_async_event(struct bnxt *bp,
 	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_REPORT:
 		bnxt_handle_event_error_report(bp, data1, data2);
 		break;
+	case HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR:
+		bnxt_process_vf_flr(bp, data1);
+		break;
 	default:
 		PMD_DRV_LOG(DEBUG, "handle_async_event id = 0x%x\n", event_id);
 		break;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 1ac3f30074..3c16abea69 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1125,9 +1125,11 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp)
 		req.async_event_fwd[1] |=
 			rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_DBG_NOTIFICATION);
 
-	if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp))
+	if (BNXT_PF(bp) || BNXT_VF_IS_TRUSTED(bp)) {
 		req.async_event_fwd[1] |=
-		rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_DEFAULT_VNIC_CHANGE);
+		rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_DEFAULT_VNIC_CHANGE |
+				 ASYNC_CMPL_EVENT_ID_VF_FLR);
+	}
 
 	req.async_event_fwd[2] |=
 		rte_cpu_to_le_32(ASYNC_CMPL_EVENT_ID_ECHO_REQUEST |
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 56b232d7de..6116253787 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -29,6 +29,8 @@ struct hwrm_func_qstats_output;
 	(1 << HWRM_ASYNC_EVENT_CMPL_EVENT_ID_ERROR_RECOVERY)
 #define ASYNC_CMPL_EVENT_ID_PF_DRVR_UNLOAD	\
 	(1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_PF_DRVR_UNLOAD - 32))
+#define ASYNC_CMPL_EVENT_ID_VF_FLR \
+	(1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_FLR - 32))
 #define ASYNC_CMPL_EVENT_ID_VF_CFG_CHANGE	\
 	(1 << (HWRM_ASYNC_EVENT_CMPL_EVENT_ID_VF_CFG_CHANGE - 32))
 #define ASYNC_CMPL_EVENT_ID_DBG_NOTIFICATION	\
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 14/18] net/bnxt: add tunnel TPA support
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (12 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 13/18] net/bnxt: add VF FLR async event handler Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 15/18] net/bnxt: add 400G get support for P7 devices Ajit Khaparde
                   ` (3 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 8918 bytes --]

From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>

This patch adds support for tunnel TPA type.
The tunnel TPA support is brought in by the updated bit_field
tnl_tpa_en(4) in hwrm_vnic_tpa_cfg_input->enables,
which is used by the firmware to indicate the capability
of the underlying hardware.

This patch updates hwrm HWRM_VNIC_TPA_CFG request
for vxlan, geneve and default tunnel type bit_fields.

The patch also updates to use the V3 TPA completion which
the P7 devices support.

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h      | 13 +++++++
 drivers/net/bnxt/bnxt_hwrm.c | 71 ++++++++++++++++++++++++++++++++++++
 drivers/net/bnxt/bnxt_rxr.c  |  9 +++--
 drivers/net/bnxt/bnxt_vnic.c | 16 ++++++++
 4 files changed, 106 insertions(+), 3 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 576688bbff..eb3142cf09 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -119,6 +119,18 @@
 	(BNXT_CHIP_P5_P7(bp) ? TPA_MAX_SEGS_TH : \
 			      TPA_MAX_SEGS)
 
+/* Handle TPA aggs and segs dynamically as per spec & dpdk mbuf frags */
+#define MAX_PAGES		65536
+#define PAGE_SHIFT              12
+/* pagesize is 1UL << PAGE_SHIFT */
+#define PAGE_SIZE               BIT(12)
+#define PAGE_MASK               (~(PAGE_SIZE - 1))
+#if ((MAX_PAGES / PAGE_SIZE + 1) < 16)
+#define MAX_MBUF_FRAGS 16UL
+#else
+#define MAX_MBUF_FRAGS (MAX_PAGES / PAGE_SIZE + 1)
+#endif
+
 /*
  * Define the number of async completion rings to be used. Set to zero for
  * configurations in which the maximum number of packet completion rings
@@ -815,6 +827,7 @@ struct bnxt {
 #define BNXT_VNIC_CAP_ESP_SPI6_CAP	BIT(12)
 #define BNXT_VNIC_CAP_AH_SPI_CAP	(BNXT_VNIC_CAP_AH_SPI4_CAP | BNXT_VNIC_CAP_AH_SPI6_CAP)
 #define BNXT_VNIC_CAP_ESP_SPI_CAP	(BNXT_VNIC_CAP_ESP_SPI4_CAP | BNXT_VNIC_CAP_ESP_SPI6_CAP)
+#define BNXT_VNIC_CAP_VNIC_TUNNEL_TPA	BIT(13)
 
 	unsigned int		rx_nr_rings;
 	unsigned int		rx_cp_nr_rings;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 3c16abea69..0165a534af 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -1046,6 +1046,9 @@ int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
 	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_RSS_IPSEC_ESP_SPI_IPV6_CAP)
 		bp->vnic_cap_flags |= BNXT_VNIC_CAP_ESP_SPI6_CAP;
 
+	if (flags & HWRM_VNIC_QCAPS_OUTPUT_FLAGS_HW_TUNNEL_TPA_CAP)
+		bp->vnic_cap_flags |= BNXT_VNIC_CAP_VNIC_TUNNEL_TPA;
+
 	bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
 
 	HWRM_UNLOCK();
@@ -2666,6 +2669,30 @@ int bnxt_hwrm_vnic_plcmode_cfg(struct bnxt *bp,
 	return rc;
 }
 
+#define BNXT_DFLT_TUNL_TPA_BMAP					\
+	(HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_GRE |	\
+	 HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_IPV4 |	\
+	 HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_IPV6)
+
+static void bnxt_vnic_update_tunl_tpa_bmap(struct bnxt *bp,
+					   struct hwrm_vnic_tpa_cfg_input *req)
+{
+	uint32_t tunl_tpa_bmap = BNXT_DFLT_TUNL_TPA_BMAP;
+
+	if (!(bp->vnic_cap_flags & BNXT_VNIC_CAP_VNIC_TUNNEL_TPA))
+		return;
+
+	if (bp->vxlan_port_cnt)
+		tunl_tpa_bmap |= HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_VXLAN |
+			HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_VXLAN_GPE;
+
+	if (bp->geneve_port_cnt)
+		tunl_tpa_bmap |= HWRM_VNIC_TPA_CFG_INPUT_TNL_TPA_EN_BITMAP_GENEVE;
+
+	req->enables |= rte_cpu_to_le_32(HWRM_VNIC_TPA_CFG_INPUT_ENABLES_TNL_TPA_EN);
+	req->tnl_tpa_en_bitmap = rte_cpu_to_le_32(tunl_tpa_bmap);
+}
+
 int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
 			struct bnxt_vnic_info *vnic, bool enable)
 {
@@ -2714,6 +2741,26 @@ int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
 
 		if (BNXT_CHIP_P5_P7(bp))
 			req.max_aggs = rte_cpu_to_le_16(bp->max_tpa_v2);
+
+		/* For tpa v2 handle as per spec mss and log2 units */
+		if (BNXT_CHIP_P7(bp)) {
+			uint32_t nsegs, n, segs = 0;
+			uint16_t mss = bp->eth_dev->data->mtu - 40;
+
+			/* Calculate the number of segs based on mss */
+			if (mss <= PAGE_SIZE) {
+				n = PAGE_SIZE / mss;
+				nsegs = (MAX_MBUF_FRAGS - 1) * n;
+			} else {
+				n = mss / PAGE_SIZE;
+				if (mss & (PAGE_SIZE - 1))
+					n++;
+				nsegs = (MAX_MBUF_FRAGS - n) / n;
+			}
+			segs = rte_log2_u32(nsegs);
+			req.max_agg_segs = rte_cpu_to_le_16(segs);
+		}
+		bnxt_vnic_update_tunl_tpa_bmap(bp, &req);
 	}
 	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
 
@@ -4242,6 +4289,27 @@ int bnxt_hwrm_pf_evb_mode(struct bnxt *bp)
 	return rc;
 }
 
+static int bnxt_hwrm_set_tpa(struct bnxt *bp)
+{
+	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+	uint64_t rx_offloads = dev_conf->rxmode.offloads;
+	bool tpa_flags = 0;
+	int rc, i;
+
+	tpa_flags = (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?  true : false;
+	for (i = 0; i < bp->max_vnics; i++) {
+		struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
+
+		if (vnic->fw_vnic_id == INVALID_HW_RING_ID)
+			continue;
+
+		rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic, tpa_flags);
+		if (rc)
+			return rc;
+	}
+	return 0;
+}
+
 int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 				uint8_t tunnel_type)
 {
@@ -4278,6 +4346,8 @@ int bnxt_hwrm_tunnel_dst_port_alloc(struct bnxt *bp, uint16_t port,
 
 	HWRM_UNLOCK();
 
+	bnxt_hwrm_set_tpa(bp);
+
 	return rc;
 }
 
@@ -4346,6 +4416,7 @@ int bnxt_hwrm_tunnel_dst_port_free(struct bnxt *bp, uint16_t port,
 		bp->ecpri_port_cnt = 0;
 	}
 
+	bnxt_hwrm_set_tpa(bp);
 	return rc;
 }
 
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index d0706874a6..3542975600 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -153,7 +153,8 @@ static void bnxt_rx_ring_reset(void *arg)
 		rxr = rxq->rx_ring;
 		/* Disable and flush TPA before resetting the RX ring */
 		if (rxr->tpa_info)
-			bnxt_hwrm_vnic_tpa_cfg(bp, rxq->vnic, false);
+			bnxt_vnic_tpa_cfg(bp, rxq->queue_id, false);
+
 		rc = bnxt_hwrm_rx_ring_reset(bp, i);
 		if (rc) {
 			PMD_DRV_LOG(ERR, "Rx ring%d reset failed\n", i);
@@ -163,12 +164,13 @@ static void bnxt_rx_ring_reset(void *arg)
 		bnxt_rx_queue_release_mbufs(rxq);
 		rxr->rx_raw_prod = 0;
 		rxr->ag_raw_prod = 0;
+		rxr->ag_cons = 0;
 		rxr->rx_next_cons = 0;
 		bnxt_init_one_rx_ring(rxq);
 		bnxt_db_write(&rxr->rx_db, rxr->rx_raw_prod);
 		bnxt_db_write(&rxr->ag_db, rxr->ag_raw_prod);
 		if (rxr->tpa_info)
-			bnxt_hwrm_vnic_tpa_cfg(bp, rxq->vnic, true);
+			bnxt_vnic_tpa_cfg(bp, rxq->queue_id, true);
 
 		rxq->in_reset = 0;
 	}
@@ -1151,7 +1153,8 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		return -EBUSY;
 
 	if (cmp_type == RX_TPA_START_CMPL_TYPE_RX_TPA_START ||
-	    cmp_type == RX_TPA_START_V2_CMPL_TYPE_RX_TPA_START_V2) {
+	    cmp_type == RX_TPA_START_V2_CMPL_TYPE_RX_TPA_START_V2 ||
+	    cmp_type == RX_TPA_START_V3_CMPL_TYPE_RX_TPA_START_V3) {
 		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
 			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
 		rc = -EINVAL; /* Continue w/o new mbuf */
diff --git a/drivers/net/bnxt/bnxt_vnic.c b/drivers/net/bnxt/bnxt_vnic.c
index 5ea34f7cb6..5092a7d774 100644
--- a/drivers/net/bnxt/bnxt_vnic.c
+++ b/drivers/net/bnxt/bnxt_vnic.c
@@ -464,7 +464,9 @@ bnxt_vnic_queue_delete(struct bnxt *bp, uint16_t vnic_idx)
 static struct bnxt_vnic_info*
 bnxt_vnic_queue_create(struct bnxt *bp, int32_t vnic_id, uint16_t q_index)
 {
+	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
 	uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
+	uint64_t rx_offloads = dev_conf->rxmode.offloads;
 	struct bnxt_vnic_info *vnic;
 	struct bnxt_rx_queue *rxq = NULL;
 	int32_t rc = -EINVAL;
@@ -523,6 +525,12 @@ bnxt_vnic_queue_create(struct bnxt *bp, int32_t vnic_id, uint16_t q_index)
 		goto cleanup;
 	}
 
+	rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic,
+				   (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?
+				    true : false);
+	if (rc)
+		PMD_DRV_LOG(DEBUG, "Failed to configure TPA on this vnic %d\n", q_index);
+
 	rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
 	if (rc) {
 		PMD_DRV_LOG(DEBUG, "Failed to configure vnic plcmode %d\n",
@@ -658,7 +666,9 @@ bnxt_vnic_rss_create(struct bnxt *bp,
 		     struct bnxt_vnic_rss_info *rss_info,
 		     uint16_t vnic_id)
 {
+	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
 	uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
+	uint64_t rx_offloads = dev_conf->rxmode.offloads;
 	struct bnxt_vnic_info *vnic;
 	struct bnxt_rx_queue *rxq = NULL;
 	uint32_t idx, nr_ctxs, config_rss = 0;
@@ -741,6 +751,12 @@ bnxt_vnic_rss_create(struct bnxt *bp,
 		goto fail_cleanup;
 	}
 
+	rc = bnxt_hwrm_vnic_tpa_cfg(bp, vnic,
+				   (rx_offloads & RTE_ETH_RX_OFFLOAD_TCP_LRO) ?
+				    true : false);
+	if (rc)
+		PMD_DRV_LOG(DEBUG, "Failed to configure TPA on this vnic %d\n", idx);
+
 	rc = bnxt_hwrm_vnic_plcmode_cfg(bp, vnic);
 	if (rc) {
 		PMD_DRV_LOG(ERR, "Failed to configure vnic plcmode %d\n",
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 15/18] net/bnxt: add 400G get support for P7 devices
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (13 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 14/18] net/bnxt: add tunnel TPA support Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 16/18] net/bnxt: query extended stats from firmware Ajit Khaparde
                   ` (2 subsequent siblings)
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 27271 bytes --]

From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>

P7 devices report speeds over speeds2 hsi fields. Adding required
support to capture the capability from phy_qcap and save the
speeds2 fields into driver priv structure.
In fixed mode update the link_speed from force_link_speeds2 field.
Updates to logging to provide more info regarding numbers of lanes
and the link signal mode.

Some code refactoring done for PHY auto detect and displaying
XCVR information.

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h                |  15 +
 drivers/net/bnxt/bnxt_ethdev.c         |  57 ++-
 drivers/net/bnxt/bnxt_hwrm.c           | 493 ++++++++++++++++++++++++-
 drivers/net/bnxt/bnxt_hwrm.h           |   1 +
 drivers/net/bnxt/hsi_struct_def_dpdk.h |  10 +-
 5 files changed, 568 insertions(+), 8 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index eb3142cf09..2d871933e9 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -327,6 +327,16 @@ struct bnxt_link_info {
 	uint16_t		support_pam4_auto_speeds;
 	uint8_t			req_signal_mode;
 	uint8_t			module_status;
+	/* P7 speeds2 fields */
+	bool                    support_speeds_v2;
+	uint16_t                supported_speeds2_force_mode;
+	uint16_t                supported_speeds2_auto_mode;
+	uint16_t                support_speeds2;
+	uint16_t                force_link_speeds2;
+	uint16_t                auto_link_speeds2;
+	uint16_t                cfg_auto_link_speeds2_mask;
+	uint8_t                 active_lanes;
+	uint8_t			option_flags;
 };
 
 #define BNXT_COS_QUEUE_COUNT	8
@@ -1165,6 +1175,11 @@ extern int bnxt_logtype_driver;
 #define PMD_DRV_LOG(level, fmt, args...) \
 	  PMD_DRV_LOG_RAW(level, fmt, ## args)
 
+#define BNXT_LINK_SPEEDS_V2_OPTIONS(f) \
+	((f) & HWRM_PORT_PHY_QCFG_OUTPUT_OPTION_FLAGS_SPEEDS2_SUPPORTED)
+#define BNXT_LINK_SPEEDS_V2_VF(bp) (BNXT_VF((bp)) && ((bp)->link_info->option_flags))
+#define BNXT_LINK_SPEEDS_V2(bp) (((bp)->link_info) && (((bp)->link_info->support_speeds_v2) || \
+						       BNXT_LINK_SPEEDS_V2_VF((bp))))
 extern const struct rte_flow_ops bnxt_ulp_rte_flow_ops;
 int32_t bnxt_ulp_port_init(struct bnxt *bp);
 void bnxt_ulp_port_deinit(struct bnxt *bp);
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 7aed6d3ab6..625e5f1f9a 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -697,7 +697,10 @@ static inline bool bnxt_force_link_config(struct bnxt *bp)
 
 static int bnxt_update_phy_setting(struct bnxt *bp)
 {
+	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+	struct rte_eth_link *link = &bp->eth_dev->data->dev_link;
 	struct rte_eth_link new;
+	uint32_t curr_speed_bit;
 	int rc;
 
 	rc = bnxt_get_hwrm_link_config(bp, &new);
@@ -706,13 +709,17 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
 		return rc;
 	}
 
+	/* convert to speedbit flag */
+	curr_speed_bit = rte_eth_speed_bitflag((uint32_t)link->link_speed, 1);
+
 	/*
 	 * Device is not obliged link down in certain scenarios, even
 	 * when forced. When FW does not allow any user other than BMC
 	 * to shutdown the port, bnxt_get_hwrm_link_config() call always
 	 * returns link up. Force phy update always in that case.
 	 */
-	if (!new.link_status || bnxt_force_link_config(bp)) {
+	if (!new.link_status || bnxt_force_link_config(bp) ||
+	    (BNXT_LINK_SPEEDS_V2(bp) && dev_conf->link_speeds != curr_speed_bit)) {
 		rc = bnxt_set_hwrm_link_config(bp, true);
 		if (rc) {
 			PMD_DRV_LOG(ERR, "Failed to update PHY settings\n");
@@ -933,6 +940,50 @@ static int bnxt_shutdown_nic(struct bnxt *bp)
  * Device configuration and status function
  */
 
+static uint32_t bnxt_get_speed_capabilities_v2(struct bnxt *bp)
+{
+	uint32_t link_speed = 0;
+	uint32_t speed_capa = 0;
+
+	if (bp->link_info == NULL)
+		return 0;
+
+	link_speed = bp->link_info->support_speeds2;
+
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_1GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_1G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_10GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_10G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_25GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_25G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_40GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_40G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_50G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB)
+		speed_capa |= RTE_ETH_LINK_SPEED_100G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_50GB_PAM4_56)
+		speed_capa |= RTE_ETH_LINK_SPEED_50G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_56)
+		speed_capa |= RTE_ETH_LINK_SPEED_100G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_56)
+		speed_capa |= RTE_ETH_LINK_SPEED_200G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_56)
+		speed_capa |= RTE_ETH_LINK_SPEED_400G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_100GB_PAM4_112)
+		speed_capa |= RTE_ETH_LINK_SPEED_100G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_200GB_PAM4_112)
+		speed_capa |= RTE_ETH_LINK_SPEED_200G;
+	if (link_speed & HWRM_PORT_PHY_QCFG_OUTPUT_SUPPORT_SPEEDS2_400GB_PAM4_112)
+		speed_capa |= RTE_ETH_LINK_SPEED_400G;
+
+	if (bp->link_info->auto_mode ==
+	    HWRM_PORT_PHY_QCFG_OUTPUT_AUTO_MODE_NONE)
+		speed_capa |= RTE_ETH_LINK_SPEED_FIXED;
+
+	return speed_capa;
+}
+
 uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
 {
 	uint32_t pam4_link_speed = 0;
@@ -942,6 +993,10 @@ uint32_t bnxt_get_speed_capabilities(struct bnxt *bp)
 	if (bp->link_info == NULL)
 		return 0;
 
+	/* P7 uses speeds_v2 */
+	if (BNXT_LINK_SPEEDS_V2(bp))
+		return bnxt_get_speed_capabilities_v2(bp);
+
 	link_speed = bp->link_info->support_speeds;
 
 	/* If PAM4 is configured, use PAM4 supported speed */
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 0165a534af..98cb130fb2 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -68,6 +68,282 @@ const char *bnxt_backing_store_types[] = {
 	"Invalid type"
 };
 
+const char *media_type[] = { "Unknown", "Twisted Pair",
+	"Direct Attached Copper", "Fiber"
+};
+
+#define MAX_MEDIA_TYPE (sizeof(media_type) / sizeof(const char *))
+
+const char *link_status_str[] = { "Down. No link or cable detected.",
+	"Down. No link, but a cable has been detected.", "Up.",
+};
+
+#define MAX_LINK_STR (sizeof(link_status_str) / sizeof(const char *))
+
+const char *fec_mode[] = {
+	"No active FEC",
+	"FEC CLAUSE 74 (Fire Code).",
+	"FEC CLAUSE 91 RS(528,514).",
+	"FEC RS544_1XN",
+	"FEC RS(544,528)",
+	"FEC RS272_1XN",
+	"FEC RS(272,257)"
+};
+
+#define MAX_FEC_MODE (sizeof(fec_mode) / sizeof(const char *))
+
+const char *signal_mode[] = {
+	"NRZ", "PAM4", "PAM4_112"
+};
+
+#define MAX_SIG_MODE (sizeof(signal_mode) / sizeof(const char *))
+
+/* multi-purpose multi-key table container.
+ * Add a unique entry for a new PHY attribs as per HW CAS.
+ * Query it using a helper functions.
+ */
+struct link_speeds2_tbl {
+	uint16_t force_val;
+	uint16_t auto_val;
+	uint32_t rte_speed;
+	uint32_t rte_speed_num;
+	uint16_t hwrm_speed;
+	uint16_t sig_mode;
+	const char *desc;
+} link_speeds2_tbl[] = {
+	{
+		10,
+		0,
+		RTE_ETH_LINK_SPEED_1G,
+		RTE_ETH_SPEED_NUM_1G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_1GB,
+		BNXT_SIG_MODE_NRZ,
+		"1Gb NRZ",
+	}, {
+		100,
+		1,
+		RTE_ETH_LINK_SPEED_10G,
+		RTE_ETH_SPEED_NUM_10G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_10GB,
+		BNXT_SIG_MODE_NRZ,
+		"10Gb NRZ",
+	}, {
+		250,
+		2,
+		RTE_ETH_LINK_SPEED_25G,
+		RTE_ETH_SPEED_NUM_25G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_25GB,
+		BNXT_SIG_MODE_NRZ,
+		"25Gb NRZ",
+	}, {
+		400,
+		3,
+		RTE_ETH_LINK_SPEED_40G,
+		RTE_ETH_SPEED_NUM_40G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_40GB,
+		BNXT_SIG_MODE_NRZ,
+		"40Gb NRZ",
+	}, {
+		500,
+		4,
+		RTE_ETH_LINK_SPEED_50G,
+		RTE_ETH_SPEED_NUM_50G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB,
+		BNXT_SIG_MODE_NRZ,
+		"50Gb NRZ",
+	}, {
+		1000,
+		5,
+		RTE_ETH_LINK_SPEED_100G,
+		RTE_ETH_SPEED_NUM_100G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB,
+		BNXT_SIG_MODE_NRZ,
+		"100Gb NRZ",
+	}, {
+		501,
+		6,
+		RTE_ETH_LINK_SPEED_50G,
+		RTE_ETH_SPEED_NUM_50G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_50GB_PAM4_56,
+		BNXT_SIG_MODE_PAM4,
+		"50Gb (PAM4-56: 50G per lane)",
+	}, {
+		1001,
+		7,
+		RTE_ETH_LINK_SPEED_100G,
+		RTE_ETH_SPEED_NUM_100G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_56,
+		BNXT_SIG_MODE_PAM4,
+		"100Gb (PAM4-56: 50G per lane)",
+	}, {
+		2001,
+		8,
+		RTE_ETH_LINK_SPEED_200G,
+		RTE_ETH_SPEED_NUM_200G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_56,
+		BNXT_SIG_MODE_PAM4,
+		"200Gb (PAM4-56: 50G per lane)",
+	}, {
+		4001,
+		9,
+		RTE_ETH_LINK_SPEED_400G,
+		RTE_ETH_SPEED_NUM_400G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_56,
+		BNXT_SIG_MODE_PAM4,
+		"400Gb (PAM4-56: 50G per lane)",
+	}, {
+		1002,
+		10,
+		RTE_ETH_LINK_SPEED_100G,
+		RTE_ETH_SPEED_NUM_100G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_100GB_PAM4_112,
+		BNXT_SIG_MODE_PAM4_112,
+		"100Gb (PAM4-112: 100G per lane)",
+	}, {
+		2002,
+		11,
+		RTE_ETH_LINK_SPEED_200G,
+		RTE_ETH_SPEED_NUM_200G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_200GB_PAM4_112,
+		BNXT_SIG_MODE_PAM4_112,
+		"200Gb (PAM4-112: 100G per lane)",
+	}, {
+		4002,
+		12,
+		RTE_ETH_LINK_SPEED_400G,
+		RTE_ETH_SPEED_NUM_400G,
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_400GB_PAM4_112,
+		BNXT_SIG_MODE_PAM4_112,
+		"400Gb (PAM4-112: 100G per lane)",
+	}, {
+		0,
+		13,
+		RTE_ETH_LINK_SPEED_AUTONEG, /* None matches, AN is default 0 */
+		RTE_ETH_SPEED_NUM_NONE,	/* None matches, No speed */
+		HWRM_PORT_PHY_CFG_INPUT_FORCE_LINK_SPEEDS2_1GB, /* Placeholder for wrong HWRM */
+		BNXT_SIG_MODE_NRZ, /* default sig */
+		"Unknown",
+	},
+};
+
+#define BNXT_SPEEDS2_TBL_SZ (sizeof(link_speeds2_tbl) / sizeof(*link_speeds2_tbl))
+
+/* In hwrm_phy_qcfg reports trained up speeds in link_speed(offset:0x8[31:16]) */
+struct link_speeds_tbl {
+	uint16_t hwrm_speed;
+	uint32_t rte_speed_num;
+	const char *desc;
+} link_speeds_tbl[] = {
+	{
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB,
+		RTE_ETH_SPEED_NUM_100M, "100 MB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_1GB,
+		RTE_ETH_SPEED_NUM_1G, "1 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2_5GB,
+		RTE_ETH_SPEED_NUM_2_5G, "25 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_10GB,
+		RTE_ETH_SPEED_NUM_10G, "10 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_20GB,
+		RTE_ETH_SPEED_NUM_20G, "20 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_40GB,
+		RTE_ETH_SPEED_NUM_40G, "40 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_50GB,
+		RTE_ETH_SPEED_NUM_50G, "50 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100GB,
+		RTE_ETH_SPEED_NUM_100G, "100 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB,
+		RTE_ETH_SPEED_NUM_200G, "200 GB",
+	}, {
+		HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_400GB,
+		RTE_ETH_SPEED_NUM_400G, "400 GB",
+	}, {
+		0, RTE_ETH_SPEED_NUM_NONE, "None",
+	},
+};
+
+#define BNXT_SPEEDS_TBL_SZ (sizeof(link_speeds_tbl) / sizeof(*link_speeds_tbl))
+
+static const char *bnxt_get_xcvr_type(uint32_t xcvr_identifier_type_tx_lpi_timer)
+{
+	uint32_t xcvr_type = HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_MASK &
+		xcvr_identifier_type_tx_lpi_timer;
+
+	/* Addressing only known CMIS types */
+	switch (xcvr_type) {
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_SFP:
+		return "SFP";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP:
+		return "QSFP";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS:
+		return "QSFP+";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28:
+		return "QSFP28";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPDD:
+		return "QSFP112";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112:
+		return "QSFP-DD";
+	case HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_UNKNOWN:
+		return "Unknown";
+	default:
+		/* All other/new CMIS variants belong here */
+		return "QSFP-xx new CMIS variant";
+	}
+}
+
+/* Utility function to lookup speeds2 table and
+ * return a rte to hwrm speed matching row to the client
+ */
+static
+struct link_speeds2_tbl *bnxt_get_rte_hwrm_speeds2_entry(uint32_t speed)
+{
+	int i, max;
+
+	max = BNXT_SPEEDS2_TBL_SZ - 1;
+	speed &= ~RTE_ETH_LINK_SPEED_FIXED;
+	for (i = 0; i < max; i++) {
+		if (speed == link_speeds2_tbl[i].rte_speed)
+			break;
+	}
+	return (struct link_speeds2_tbl *)&link_speeds2_tbl[i];
+}
+
+/* Utility function to lookup speeds2 table and
+ * return a hwrm to rte speed matching row to the client
+ */
+static struct link_speeds2_tbl *bnxt_get_hwrm_to_rte_speeds2_entry(uint16_t speed)
+{
+	int i, max;
+
+	max = BNXT_SPEEDS2_TBL_SZ - 1;
+	for (i = 0; i < max; i++) {
+		if (speed == link_speeds2_tbl[i].hwrm_speed)
+			break;
+	}
+	return (struct link_speeds2_tbl *)&link_speeds2_tbl[i];
+}
+
+/* Helper function to lookup auto link_speed table */
+static struct link_speeds_tbl *bnxt_get_hwrm_to_rte_speeds_entry(uint16_t speed)
+{
+	int i, max;
+
+	max = BNXT_SPEEDS_TBL_SZ - 1;
+
+	for (i = 0; i < max ; i++) {
+		if (speed == link_speeds_tbl[i].hwrm_speed)
+			break;
+	}
+	return (struct link_speeds_tbl *)&link_speeds_tbl[i];
+}
+
 static int page_getenum(size_t size)
 {
 	if (size <= 1 << 4)
@@ -1564,15 +1840,64 @@ static int bnxt_hwrm_port_phy_qcfg(struct bnxt *bp,
 	link_info->phy_ver[2] = resp->phy_bld;
 	link_info->link_signal_mode =
 		resp->active_fec_signal_mode & HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_MASK;
+	link_info->option_flags = resp->option_flags;
 	link_info->force_pam4_link_speed =
 			rte_le_to_cpu_16(resp->force_pam4_link_speed);
 	link_info->support_pam4_speeds =
 			rte_le_to_cpu_16(resp->support_pam4_speeds);
 	link_info->auto_pam4_link_speed_mask =
 			rte_le_to_cpu_16(resp->auto_pam4_link_speed_mask);
+	/* P7 uses speeds2 fields */
+	if (BNXT_LINK_SPEEDS_V2(bp) && BNXT_LINK_SPEEDS_V2_OPTIONS(link_info->option_flags)) {
+		link_info->support_speeds2 = rte_le_to_cpu_16(resp->support_speeds2);
+		link_info->force_link_speeds2 = rte_le_to_cpu_16(resp->force_link_speeds2);
+		link_info->auto_link_speeds2 = rte_le_to_cpu_16(resp->auto_link_speeds2);
+		link_info->active_lanes = resp->active_lanes;
+		if (!link_info->auto_mode)
+			link_info->link_speed = link_info->force_link_speeds2;
+	}
 	link_info->module_status = resp->module_status;
 	HWRM_UNLOCK();
 
+	/* Display the captured P7 phy details */
+	if (BNXT_LINK_SPEEDS_V2(bp)) {
+		PMD_DRV_LOG(DEBUG, "Phytype:%d, Media_type:%d, Status: %d, Link Signal:%d\n"
+			    "Active Fec: %d Support_speeds2:%x, Force_link_speedsv2:%x\n"
+			    "Auto_link_speedsv2:%x, Active_lanes:%d\n",
+			    link_info->phy_type,
+			    link_info->media_type,
+			    link_info->phy_link_status,
+			    link_info->link_signal_mode,
+			    (resp->active_fec_signal_mode &
+				HWRM_PORT_PHY_QCFG_OUTPUT_ACTIVE_FEC_MASK) >> 4,
+			    link_info->support_speeds2, link_info->force_link_speeds2,
+			    link_info->auto_link_speeds2,
+			    link_info->active_lanes);
+
+		const char *desc;
+
+		if (link_info->auto_mode)
+			desc = ((struct link_speeds_tbl *)
+				bnxt_get_hwrm_to_rte_speeds_entry(link_info->link_speed))->desc;
+		else
+			desc = ((struct link_speeds2_tbl *)
+				bnxt_get_hwrm_to_rte_speeds2_entry(link_info->link_speed))->desc;
+
+		PMD_DRV_LOG(INFO, "Link Speed: %s %s, Status: %s Signal-mode: %s\n"
+			    "Media type: %s, Xcvr type: %s, Active FEC: %s Lanes: %d\n",
+			    desc,
+			    !(link_info->auto_mode) ? "Forced" : "AutoNegotiated",
+			    link_status_str[link_info->phy_link_status % MAX_LINK_STR],
+			    signal_mode[link_info->link_signal_mode % MAX_SIG_MODE],
+			    media_type[link_info->media_type % MAX_MEDIA_TYPE],
+			    bnxt_get_xcvr_type(rte_le_to_cpu_32
+					       (resp->xcvr_identifier_type_tx_lpi_timer)),
+			    fec_mode[((resp->active_fec_signal_mode &
+				       HWRM_PORT_PHY_QCFG_OUTPUT_ACTIVE_FEC_MASK) >> 4) %
+			    MAX_FEC_MODE], link_info->active_lanes);
+		return rc;
+	}
+
 	PMD_DRV_LOG(DEBUG, "Link Speed:%d,Auto:%d:%x:%x,Support:%x,Force:%x\n",
 		    link_info->link_speed, link_info->auto_mode,
 		    link_info->auto_link_speed, link_info->auto_link_speed_mask,
@@ -1608,6 +1933,15 @@ int bnxt_hwrm_port_phy_qcaps(struct bnxt *bp)
 	if (resp->supported_pam4_speeds_auto_mode)
 		link_info->support_pam4_auto_speeds =
 			rte_le_to_cpu_16(resp->supported_pam4_speeds_auto_mode);
+	/* P7 chips now report all speeds here */
+	if (resp->flags2 & HWRM_PORT_PHY_QCAPS_OUTPUT_FLAGS2_SPEEDS2_SUPPORTED)
+		link_info->support_speeds_v2 = true;
+	if (link_info->support_speeds_v2) {
+		link_info->supported_speeds2_force_mode =
+			rte_le_to_cpu_16(resp->supported_speeds2_force_mode);
+		link_info->supported_speeds2_auto_mode =
+			rte_le_to_cpu_16(resp->supported_speeds2_auto_mode);
+	}
 
 	HWRM_UNLOCK();
 
@@ -3265,7 +3599,14 @@ static uint16_t bnxt_check_eth_link_autoneg(uint32_t conf_link)
 	return !conf_link;
 }
 
-static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
+static uint16_t bnxt_parse_eth_link_speed_v2(uint32_t conf_link_speed)
+{
+	/* get bitmap value based on speed */
+	return ((struct link_speeds2_tbl *)
+		bnxt_get_rte_hwrm_speeds2_entry(conf_link_speed))->force_val;
+}
+
+static uint16_t bnxt_parse_eth_link_speed(struct bnxt *bp, uint32_t conf_link_speed,
 					  struct bnxt_link_info *link_info)
 {
 	uint16_t support_pam4_speeds = link_info->support_pam4_speeds;
@@ -3275,6 +3616,10 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 	if (conf_link_speed == RTE_ETH_LINK_SPEED_AUTONEG)
 		return RTE_ETH_LINK_SPEED_AUTONEG;
 
+	/* Handle P7 chips saperately. It got enhanced phy attribs to choose from */
+	if (BNXT_LINK_SPEEDS_V2(bp))
+		return bnxt_parse_eth_link_speed_v2(conf_link_speed);
+
 	switch (conf_link_speed & ~RTE_ETH_LINK_SPEED_FIXED) {
 	case RTE_ETH_LINK_SPEED_100M:
 	case RTE_ETH_LINK_SPEED_100M_HD:
@@ -3346,6 +3691,9 @@ static uint16_t bnxt_parse_eth_link_speed(uint32_t conf_link_speed,
 		RTE_ETH_LINK_SPEED_10G | RTE_ETH_LINK_SPEED_20G | RTE_ETH_LINK_SPEED_25G | \
 		RTE_ETH_LINK_SPEED_40G | RTE_ETH_LINK_SPEED_50G | \
 		RTE_ETH_LINK_SPEED_100G | RTE_ETH_LINK_SPEED_200G)
+#define BNXT_SUPPORTED_SPEEDS2 ((BNXT_SUPPORTED_SPEEDS | RTE_ETH_LINK_SPEED_400G) & \
+		~(RTE_ETH_LINK_SPEED_100M | RTE_ETH_LINK_SPEED_100M_HD | \
+		  RTE_ETH_LINK_SPEED_2_5G | RTE_ETH_LINK_SPEED_20G))
 
 static int bnxt_validate_link_speed(struct bnxt *bp)
 {
@@ -3385,11 +3733,25 @@ static int bnxt_validate_link_speed(struct bnxt *bp)
 	return 0;
 }
 
+static uint16_t
+bnxt_parse_eth_link_speed_mask_v2(struct bnxt *bp, uint32_t link_speed)
+{
+	uint16_t ret = 0;
+
+	if (link_speed == RTE_ETH_LINK_SPEED_AUTONEG)
+		return bp->link_info->supported_speeds2_auto_mode;
+
+	return ret;
+}
+
 static uint16_t
 bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed)
 {
 	uint16_t ret = 0;
 
+	if (BNXT_LINK_SPEEDS_V2(bp))
+		return bnxt_parse_eth_link_speed_mask_v2(bp, link_speed);
+
 	if (link_speed == RTE_ETH_LINK_SPEED_AUTONEG) {
 		if (bp->link_info->support_speeds)
 			return bp->link_info->support_speeds;
@@ -3421,10 +3783,21 @@ bnxt_parse_eth_link_speed_mask(struct bnxt *bp, uint32_t link_speed)
 	return ret;
 }
 
-static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
+static uint32_t bnxt_parse_hw_link_speed_v2(uint16_t hw_link_speed)
+{
+	return ((struct link_speeds2_tbl *)
+		bnxt_get_hwrm_to_rte_speeds2_entry(hw_link_speed))->rte_speed_num;
+}
+
+static uint32_t bnxt_parse_hw_link_speed(struct bnxt *bp, uint16_t hw_link_speed)
 {
 	uint32_t eth_link_speed = RTE_ETH_SPEED_NUM_NONE;
 
+	/* query fixed speed2 table if not autoneg */
+	if (BNXT_LINK_SPEEDS_V2(bp) && !bp->link_info->auto_mode)
+		return bnxt_parse_hw_link_speed_v2(hw_link_speed);
+
+	/* for P7 and earlier nics link_speed carries AN'd speed */
 	switch (hw_link_speed) {
 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_100MB:
 		eth_link_speed = RTE_ETH_SPEED_NUM_100M;
@@ -3456,6 +3829,9 @@ static uint32_t bnxt_parse_hw_link_speed(uint16_t hw_link_speed)
 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_200GB:
 		eth_link_speed = RTE_ETH_SPEED_NUM_200G;
 		break;
+	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_400GB:
+		eth_link_speed = RTE_ETH_SPEED_NUM_400G;
+		break;
 	case HWRM_PORT_PHY_QCFG_OUTPUT_LINK_SPEED_2GB:
 	default:
 		PMD_DRV_LOG(ERR, "HWRM link speed %d not defined\n",
@@ -3502,8 +3878,7 @@ int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link)
 	}
 
 	if (link_info->link_speed)
-		link->link_speed =
-			bnxt_parse_hw_link_speed(link_info->link_speed);
+		link->link_speed = bnxt_parse_hw_link_speed(bp, link_info->link_speed);
 	else
 		link->link_speed = RTE_ETH_SPEED_NUM_NONE;
 	link->link_duplex = bnxt_parse_hw_link_duplex(link_info->duplex);
@@ -3515,6 +3890,111 @@ int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link)
 	return rc;
 }
 
+static int bnxt_hwrm_port_phy_cfg_v2(struct bnxt *bp, struct bnxt_link_info *conf)
+{
+	struct hwrm_port_phy_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+	struct hwrm_port_phy_cfg_input req = {0};
+	uint32_t enables = 0;
+	int rc = 0;
+
+	HWRM_PREP(&req, HWRM_PORT_PHY_CFG, BNXT_USE_CHIMP_MB);
+
+	if (!conf->link_up) {
+		req.flags =
+		rte_cpu_to_le_32(HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE_LINK_DWN);
+		PMD_DRV_LOG(ERR, "Force Link Down\n");
+		goto link_down;
+	}
+
+	/* Setting Fixed Speed. But AutoNeg is ON, So disable it */
+	if (bp->link_info->auto_mode && conf->link_speed) {
+		req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_NONE;
+		PMD_DRV_LOG(DEBUG, "Disabling AutoNeg\n");
+	}
+	req.flags = rte_cpu_to_le_32(conf->phy_flags);
+	if (!conf->link_speed) {
+		/* No speeds specified. Enable AutoNeg - all speeds */
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_LINK_SPEEDS2_MASK;
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_MODE;
+		req.auto_mode = HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK;
+		req.auto_link_speeds2_mask =
+			rte_cpu_to_le_16(bp->link_info->supported_speeds2_auto_mode);
+	} else {
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_LINK_SPEEDS2;
+		req.force_link_speeds2 = rte_cpu_to_le_16(conf->link_speed);
+	}
+
+	/* Fill rest of the req message */
+	req.auto_duplex = conf->duplex;
+	if (req.auto_mode != HWRM_PORT_PHY_CFG_INPUT_AUTO_MODE_SPEED_MASK)
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_DUPLEX;
+	req.auto_pause = conf->auto_pause;
+	req.force_pause = conf->force_pause;
+	if (req.auto_pause)
+		req.force_pause = 0;
+	/* Set force_pause if there is no auto or if there is a force */
+	if (req.auto_pause && !req.force_pause)
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_AUTO_PAUSE;
+	else
+		enables |= HWRM_PORT_PHY_CFG_INPUT_ENABLES_FORCE_PAUSE;
+	req.enables = rte_cpu_to_le_32(enables);
+
+link_down:
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+	HWRM_CHECK_RESULT();
+	HWRM_UNLOCK();
+	return rc;
+}
+
+static int bnxt_set_hwrm_link_config_v2(struct bnxt *bp, bool link_up)
+{
+	struct rte_eth_conf *dev_conf = &bp->eth_dev->data->dev_conf;
+	struct bnxt_link_info link_req;
+	uint16_t speed, autoneg;
+	int rc = 0;
+
+	memset(&link_req, 0, sizeof(link_req));
+	link_req.link_up = link_up;
+	if (!link_up)
+		goto port_phy_cfg;
+
+	autoneg = bnxt_check_eth_link_autoneg(dev_conf->link_speeds);
+	speed = bnxt_parse_eth_link_speed(bp, dev_conf->link_speeds,
+					  bp->link_info);
+	link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
+	if (autoneg == 1) {
+		link_req.phy_flags |=
+			HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESTART_AUTONEG;
+		link_req.cfg_auto_link_speeds2_mask =
+			bnxt_parse_eth_link_speed_mask(bp, dev_conf->link_speeds);
+	} else {
+		if (bp->link_info->phy_type ==
+		    HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASET ||
+		    bp->link_info->phy_type ==
+		    HWRM_PORT_PHY_QCFG_OUTPUT_PHY_TYPE_BASETE ||
+		    bp->link_info->media_type ==
+		    HWRM_PORT_PHY_QCFG_OUTPUT_MEDIA_TYPE_TP) {
+			PMD_DRV_LOG(ERR, "10GBase-T devices must autoneg\n");
+			return -EINVAL;
+		}
+
+		link_req.phy_flags |= HWRM_PORT_PHY_CFG_INPUT_FLAGS_FORCE;
+		/* If user wants a particular speed try that first. */
+		link_req.link_speed = speed;
+	}
+	link_req.duplex = bnxt_parse_eth_link_duplex(dev_conf->link_speeds);
+	link_req.auto_pause = bp->link_info->auto_pause;
+	link_req.force_pause = bp->link_info->force_pause;
+
+port_phy_cfg:
+	rc = bnxt_hwrm_port_phy_cfg_v2(bp, &link_req);
+	if (rc)
+		PMD_DRV_LOG(ERR, "Set link config failed with rc %d\n", rc);
+
+	return rc;
+}
+
 int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 {
 	int rc = 0;
@@ -3529,6 +4009,9 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 	if (rc)
 		goto error;
 
+	if (BNXT_LINK_SPEEDS_V2(bp))
+		return bnxt_set_hwrm_link_config_v2(bp, link_up);
+
 	memset(&link_req, 0, sizeof(link_req));
 	link_req.link_up = link_up;
 	if (!link_up)
@@ -3554,7 +4037,7 @@ int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up)
 		PMD_DRV_LOG(DEBUG, "Disabling autoneg for 200G\n");
 	}
 
-	speed = bnxt_parse_eth_link_speed(dev_conf->link_speeds,
+	speed = bnxt_parse_eth_link_speed(bp, dev_conf->link_speeds,
 					  bp->link_info);
 	link_req.phy_flags = HWRM_PORT_PHY_CFG_INPUT_FLAGS_RESET_PHY;
 	/* Autoneg can be done only when the FW allows. */
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 6116253787..179d5dc1f0 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -145,6 +145,7 @@ struct bnxt_pf_resource_info {
 
 #define BNXT_SIG_MODE_NRZ	HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_NRZ
 #define BNXT_SIG_MODE_PAM4	HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4
+#define BNXT_SIG_MODE_PAM4_112	HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4_112
 
 #define BNXT_TUNNELED_OFFLOADS_CAP_VXLAN_EN(bp)		\
 	(!((bp)->tunnel_disable_flag & HWRM_FUNC_QCAPS_OUTPUT_TUNNEL_DISABLE_FLAG_DISABLE_VXLAN))
diff --git a/drivers/net/bnxt/hsi_struct_def_dpdk.h b/drivers/net/bnxt/hsi_struct_def_dpdk.h
index 65f3f0576b..b012a84d36 100644
--- a/drivers/net/bnxt/hsi_struct_def_dpdk.h
+++ b/drivers/net/bnxt/hsi_struct_def_dpdk.h
@@ -27273,11 +27273,17 @@ struct hwrm_port_phy_qcfg_output {
 	/* QSFP+ */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPPLUS \
 		(UINT32_C(0xd) << 24)
-	/* QSFP28 */
+	/* QSFP28/QSFP56 or later */
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28 \
 		(UINT32_C(0x11) << 24)
+	/* QSFP-DD */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFPDD \
+		(UINT32_C(0x18) << 24)
+	/* QSFP112 */
+	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112 \
+		(UINT32_C(0x1e) << 24)
 	#define HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_LAST \
-		HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP28
+		HWRM_PORT_PHY_QCFG_OUTPUT_XCVR_IDENTIFIER_TYPE_QSFP112
 	/*
 	 * This value represents the current configuration of
 	 * Forward Error Correction (FEC) on the port.
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 16/18] net/bnxt: query extended stats from firmware
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (14 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 15/18] net/bnxt: add 400G get support for P7 devices Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 17/18] net/bnxt: add AVX2 support for compressed CQE Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 18/18] net/bnxt: enable SSE mode " Ajit Khaparde
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 28237 bytes --]

From: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>

Add the driver support for HWRM_STAT_EXT_CTX_QUERY HWRM
msg. In this patch only P7 chipset is enabled for this HWRM
while P5 and previous generation remain with HWRM_STAT_CTX_QUERY.

Signed-off-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
Reviewed-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        |  49 ++++++
 drivers/net/bnxt/bnxt_cpr.h    |   3 +-
 drivers/net/bnxt/bnxt_ethdev.c |  36 ++++-
 drivers/net/bnxt/bnxt_hwrm.c   | 117 ++++++++++++++
 drivers/net/bnxt/bnxt_hwrm.h   |  12 +-
 drivers/net/bnxt/bnxt_ring.c   |   6 +-
 drivers/net/bnxt/bnxt_rxq.c    |   8 +-
 drivers/net/bnxt/bnxt_stats.c  | 279 ++++++++++++++++++++++++++++++---
 8 files changed, 483 insertions(+), 27 deletions(-)

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 2d871933e9..5919d219f7 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -714,6 +714,53 @@ struct bnxt_ring_stats {
 	uint64_t	rx_agg_aborts;
 };
 
+struct bnxt_ring_stats_ext {
+	/* Number of received unicast packets */
+	uint64_t        rx_ucast_pkts;
+	/* Number of received multicast packets */
+	uint64_t        rx_mcast_pkts;
+	/* Number of received broadcast packets */
+	uint64_t        rx_bcast_pkts;
+	/* Number of discarded packets on receive path */
+	uint64_t        rx_discard_pkts;
+	/* Number of packets on receive path with error */
+	uint64_t        rx_error_pkts;
+	/* Number of received bytes for unicast traffic */
+	uint64_t        rx_ucast_bytes;
+	/* Number of received bytes for multicast traffic */
+	uint64_t        rx_mcast_bytes;
+	/* Number of received bytes for broadcast traffic */
+	uint64_t        rx_bcast_bytes;
+	/* Number of transmitted unicast packets */
+	uint64_t        tx_ucast_pkts;
+	/* Number of transmitted multicast packets */
+	uint64_t        tx_mcast_pkts;
+	/* Number of transmitted broadcast packets */
+	uint64_t        tx_bcast_pkts;
+	/* Number of packets on transmit path with error */
+	uint64_t        tx_error_pkts;
+	/* Number of discarded packets on transmit path */
+	uint64_t        tx_discard_pkts;
+	/* Number of transmitted bytes for unicast traffic */
+	uint64_t        tx_ucast_bytes;
+	/* Number of transmitted bytes for multicast traffic */
+	uint64_t        tx_mcast_bytes;
+	/* Number of transmitted bytes for broadcast traffic */
+	uint64_t        tx_bcast_bytes;
+	/* Number of TPA eligible packets */
+	uint64_t        rx_tpa_eligible_pkt;
+	/* Number of TPA eligible bytes */
+	uint64_t        rx_tpa_eligible_bytes;
+	/* Number of TPA packets */
+	uint64_t        rx_tpa_pkt;
+	/* Number of TPA bytes */
+	uint64_t        rx_tpa_bytes;
+	/* Number of TPA errors */
+	uint64_t        rx_tpa_errors;
+	/* Number of TPA events */
+	uint64_t        rx_tpa_events;
+};
+
 enum bnxt_session_type {
 	BNXT_SESSION_TYPE_REGULAR = 0,
 	BNXT_SESSION_TYPE_SHARED_COMMON,
@@ -991,6 +1038,8 @@ struct bnxt {
 	uint16_t		tx_cfa_action;
 	struct bnxt_ring_stats	*prev_rx_ring_stats;
 	struct bnxt_ring_stats	*prev_tx_ring_stats;
+	struct bnxt_ring_stats_ext	*prev_rx_ring_stats_ext;
+	struct bnxt_ring_stats_ext	*prev_tx_ring_stats_ext;
 	struct bnxt_vnic_queue_db vnic_queue_db;
 
 #define BNXT_MAX_MC_ADDRS	((bp)->max_mcast_addr)
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 26e81a6a7e..c7b3480dc9 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h
@@ -68,7 +68,8 @@ struct bnxt_cp_ring_info {
 	struct bnxt_db_info     cp_db;
 	rte_iova_t		cp_desc_mapping;
 
-	struct ctx_hw_stats	*hw_stats;
+	char			*hw_stats;
+	uint16_t		hw_ring_stats_size;
 	rte_iova_t		hw_stats_map;
 	uint32_t		hw_stats_ctx_id;
 
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 625e5f1f9a..031028eda1 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -732,15 +732,49 @@ static int bnxt_update_phy_setting(struct bnxt *bp)
 
 static void bnxt_free_prev_ring_stats(struct bnxt *bp)
 {
+	/* tpa v2 devices use ext variant local struct */
+	if (BNXT_TPA_V2_P7(bp)) {
+		rte_free(bp->prev_rx_ring_stats_ext);
+		rte_free(bp->prev_tx_ring_stats_ext);
+		bp->prev_rx_ring_stats_ext = NULL;
+		bp->prev_tx_ring_stats_ext = NULL;
+		return;
+	}
 	rte_free(bp->prev_rx_ring_stats);
 	rte_free(bp->prev_tx_ring_stats);
-
 	bp->prev_rx_ring_stats = NULL;
 	bp->prev_tx_ring_stats = NULL;
 }
 
+static int bnxt_alloc_prev_ring_ext_stats(struct bnxt *bp)
+{
+	bp->prev_rx_ring_stats_ext = rte_zmalloc("bnxt_prev_rx_ring_stats_ext",
+						 sizeof(struct bnxt_ring_stats_ext) *
+						 bp->rx_cp_nr_rings,
+						 0);
+	if (bp->prev_rx_ring_stats_ext == NULL)
+		return -ENOMEM;
+
+	bp->prev_tx_ring_stats_ext = rte_zmalloc("bnxt_prev_tx_ring_stats_ext",
+						 sizeof(struct bnxt_ring_stats_ext) *
+						 bp->tx_cp_nr_rings,
+						 0);
+
+	if (bp->tx_cp_nr_rings > 0 && bp->prev_tx_ring_stats_ext == NULL)
+		goto error;
+
+	return 0;
+
+error:
+	bnxt_free_prev_ring_stats(bp);
+	return -ENOMEM;
+}
+
 static int bnxt_alloc_prev_ring_stats(struct bnxt *bp)
 {
+	if (BNXT_TPA_V2_P7(bp))
+		return bnxt_alloc_prev_ring_ext_stats(bp);
+
 	bp->prev_rx_ring_stats =  rte_zmalloc("bnxt_prev_rx_ring_stats",
 					      sizeof(struct bnxt_ring_stats) *
 					      bp->rx_cp_nr_rings,
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 98cb130fb2..d61446dd7c 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -2386,6 +2386,8 @@ int bnxt_hwrm_stat_ctx_alloc(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 
 	HWRM_PREP(&req, HWRM_STAT_CTX_ALLOC, BNXT_USE_CHIMP_MB);
 
+	req.stats_dma_length = rte_cpu_to_le_16(BNXT_HWRM_CTX_GET_SIZE(bp));
+
 	req.update_period_ms = rte_cpu_to_le_32(0);
 
 	req.stats_dma_addr = rte_cpu_to_le_64(cpr->hw_stats_map);
@@ -5184,6 +5186,8 @@ static void bnxt_update_prev_stat(uint64_t *cntr, uint64_t *prev_cntr)
 	 * returned by HW in this iteration, so use the previous
 	 * iteration's counter value
 	 */
+	if (!cntr || !prev_cntr)
+		return;
 	if (*prev_cntr && *cntr == 0)
 		*cntr = *prev_cntr;
 	else
@@ -5292,6 +5296,119 @@ int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
 	return rc;
 }
 
+int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
+			     struct bnxt_ring_stats_ext *ring_stats, bool rx)
+{
+	int rc = 0;
+	struct hwrm_stat_ext_ctx_query_input req = {.req_type = 0};
+	struct hwrm_stat_ext_ctx_query_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(&req, HWRM_STAT_EXT_CTX_QUERY, BNXT_USE_CHIMP_MB);
+
+	req.stat_ctx_id = rte_cpu_to_le_32(cid);
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+	HWRM_CHECK_RESULT();
+
+	if (rx) {
+		struct bnxt_ring_stats_ext *prev_stats = &bp->prev_rx_ring_stats_ext[idx];
+
+		ring_stats->rx_ucast_pkts = rte_le_to_cpu_64(resp->rx_ucast_pkts);
+		bnxt_update_prev_stat(&ring_stats->rx_ucast_pkts,
+				      &prev_stats->rx_ucast_pkts);
+
+		ring_stats->rx_mcast_pkts = rte_le_to_cpu_64(resp->rx_mcast_pkts);
+		bnxt_update_prev_stat(&ring_stats->rx_mcast_pkts,
+				      &prev_stats->rx_mcast_pkts);
+
+		ring_stats->rx_bcast_pkts = rte_le_to_cpu_64(resp->rx_bcast_pkts);
+		bnxt_update_prev_stat(&ring_stats->rx_bcast_pkts,
+				      &prev_stats->rx_bcast_pkts);
+
+		ring_stats->rx_ucast_bytes = rte_le_to_cpu_64(resp->rx_ucast_bytes);
+		bnxt_update_prev_stat(&ring_stats->rx_ucast_bytes,
+				      &prev_stats->rx_ucast_bytes);
+
+		ring_stats->rx_mcast_bytes = rte_le_to_cpu_64(resp->rx_mcast_bytes);
+		bnxt_update_prev_stat(&ring_stats->rx_mcast_bytes,
+				      &prev_stats->rx_mcast_bytes);
+
+		ring_stats->rx_bcast_bytes = rte_le_to_cpu_64(resp->rx_bcast_bytes);
+		bnxt_update_prev_stat(&ring_stats->rx_bcast_bytes,
+				      &prev_stats->rx_bcast_bytes);
+
+		ring_stats->rx_discard_pkts = rte_le_to_cpu_64(resp->rx_discard_pkts);
+		bnxt_update_prev_stat(&ring_stats->rx_discard_pkts,
+				      &prev_stats->rx_discard_pkts);
+
+		ring_stats->rx_error_pkts = rte_le_to_cpu_64(resp->rx_error_pkts);
+		bnxt_update_prev_stat(&ring_stats->rx_error_pkts,
+				      &prev_stats->rx_error_pkts);
+
+		ring_stats->rx_tpa_eligible_pkt = rte_le_to_cpu_64(resp->rx_tpa_eligible_pkt);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_eligible_pkt,
+				      &prev_stats->rx_tpa_eligible_pkt);
+
+		ring_stats->rx_tpa_eligible_bytes = rte_le_to_cpu_64(resp->rx_tpa_eligible_bytes);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_eligible_bytes,
+				      &prev_stats->rx_tpa_eligible_bytes);
+
+		ring_stats->rx_tpa_pkt = rte_le_to_cpu_64(resp->rx_tpa_pkt);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_pkt,
+				      &prev_stats->rx_tpa_pkt);
+
+		ring_stats->rx_tpa_bytes = rte_le_to_cpu_64(resp->rx_tpa_bytes);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_bytes,
+				      &prev_stats->rx_tpa_bytes);
+
+		ring_stats->rx_tpa_errors = rte_le_to_cpu_64(resp->rx_tpa_errors);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_errors,
+				      &prev_stats->rx_tpa_errors);
+
+		ring_stats->rx_tpa_events = rte_le_to_cpu_64(resp->rx_tpa_events);
+		bnxt_update_prev_stat(&ring_stats->rx_tpa_events,
+				      &prev_stats->rx_tpa_events);
+	} else {
+		struct bnxt_ring_stats_ext *prev_stats = &bp->prev_tx_ring_stats_ext[idx];
+
+		ring_stats->tx_ucast_pkts = rte_le_to_cpu_64(resp->tx_ucast_pkts);
+		bnxt_update_prev_stat(&ring_stats->tx_ucast_pkts,
+				      &prev_stats->tx_ucast_pkts);
+
+		ring_stats->tx_mcast_pkts = rte_le_to_cpu_64(resp->tx_mcast_pkts);
+		bnxt_update_prev_stat(&ring_stats->tx_mcast_pkts,
+				      &prev_stats->tx_mcast_pkts);
+
+		ring_stats->tx_bcast_pkts = rte_le_to_cpu_64(resp->tx_bcast_pkts);
+		bnxt_update_prev_stat(&ring_stats->tx_bcast_pkts,
+				      &prev_stats->tx_bcast_pkts);
+
+		ring_stats->tx_ucast_bytes = rte_le_to_cpu_64(resp->tx_ucast_bytes);
+		bnxt_update_prev_stat(&ring_stats->tx_ucast_bytes,
+				      &prev_stats->tx_ucast_bytes);
+
+		ring_stats->tx_mcast_bytes = rte_le_to_cpu_64(resp->tx_mcast_bytes);
+		bnxt_update_prev_stat(&ring_stats->tx_mcast_bytes,
+				      &prev_stats->tx_mcast_bytes);
+
+		ring_stats->tx_bcast_bytes = rte_le_to_cpu_64(resp->tx_bcast_bytes);
+		bnxt_update_prev_stat(&ring_stats->tx_bcast_bytes,
+				      &prev_stats->tx_bcast_bytes);
+
+		ring_stats->tx_discard_pkts = rte_le_to_cpu_64(resp->tx_discard_pkts);
+		bnxt_update_prev_stat(&ring_stats->tx_discard_pkts,
+				      &prev_stats->tx_discard_pkts);
+
+		ring_stats->tx_error_pkts = rte_le_to_cpu_64(resp->tx_error_pkts);
+		bnxt_update_prev_stat(&ring_stats->tx_error_pkts,
+				      &prev_stats->tx_error_pkts);
+	}
+
+	HWRM_UNLOCK();
+
+	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 179d5dc1f0..19fb35f223 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -167,8 +167,14 @@ struct bnxt_pf_resource_info {
 	 BNXT_TUNNELED_OFFLOADS_CAP_GRE_EN(bp)   &&		\
 	 BNXT_TUNNELED_OFFLOADS_CAP_IPINIP_EN(bp))
 
-#define BNXT_SIG_MODE_NRZ	HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_NRZ
-#define BNXT_SIG_MODE_PAM4	HWRM_PORT_PHY_QCFG_OUTPUT_SIGNAL_MODE_PAM4
+/* Is this tpa_v2 and P7
+ * Just add P5 to this once we validate on Thor FW
+ */
+#define BNXT_TPA_V2_P7(bp) ((bp)->max_tpa_v2 && BNXT_CHIP_P7(bp))
+/* Get the size of the stat context size for DMA from HW */
+#define BNXT_HWRM_CTX_GET_SIZE(bp)  (BNXT_TPA_V2_P7(bp) ?	\
+	sizeof(struct ctx_hw_stats_ext) :			\
+	sizeof(struct ctx_hw_stats))
 
 int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp,
 				   struct bnxt_vnic_info *vnic);
@@ -352,6 +358,8 @@ int bnxt_hwrm_poll_ver_get(struct bnxt *bp);
 int bnxt_hwrm_rx_ring_reset(struct bnxt *bp, int queue_index);
 int bnxt_hwrm_ring_stats(struct bnxt *bp, uint32_t cid, int idx,
 			 struct bnxt_ring_stats *stats, bool rx);
+int bnxt_hwrm_ring_stats_ext(struct bnxt *bp, uint32_t cid, int idx,
+			     struct bnxt_ring_stats_ext *ring_stats, bool rx);
 int bnxt_hwrm_read_sfp_module_eeprom_info(struct bnxt *bp, uint16_t i2c_addr,
 					  uint16_t page_number, uint16_t start_addr,
 					  uint16_t data_length, uint8_t *buf);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 4bf0b9c6ed..9e512321d9 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -119,8 +119,7 @@ int bnxt_alloc_rings(struct bnxt *bp, unsigned int socket_id, uint16_t qidx,
 	int ag_ring_len = 0;
 
 	int stats_len = (tx_ring_info || rx_ring_info) ?
-	    RTE_CACHE_LINE_ROUNDUP(sizeof(struct hwrm_stat_ctx_query_output) -
-				   sizeof (struct hwrm_resp_hdr)) : 0;
+	    RTE_CACHE_LINE_ROUNDUP(BNXT_HWRM_CTX_GET_SIZE(bp)) : 0;
 	stats_len = RTE_ALIGN(stats_len, 128);
 
 	int cp_vmem_start = stats_len;
@@ -305,8 +304,9 @@ int bnxt_alloc_rings(struct bnxt *bp, unsigned int socket_id, 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;
 
 	if (nq_ring_info) {
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 575e7f193f..913856e6eb 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -483,8 +483,12 @@ int bnxt_rx_queue_start(struct rte_eth_dev *dev, uint16_t rx_queue_id)
 	/* reset the previous stats for the rx_queue since the counters
 	 * will be cleared when the queue is started.
 	 */
-	memset(&bp->prev_rx_ring_stats[rx_queue_id], 0,
-	       sizeof(struct bnxt_ring_stats));
+	if (BNXT_TPA_V2_P7(bp))
+		memset(&bp->prev_rx_ring_stats_ext[rx_queue_id], 0,
+		       sizeof(struct bnxt_ring_stats_ext));
+	else
+		memset(&bp->prev_rx_ring_stats[rx_queue_id], 0,
+		       sizeof(struct bnxt_ring_stats));
 
 	/* Set the queue state to started here.
 	 * We check the status of the queue while posting buffer.
diff --git a/drivers/net/bnxt/bnxt_stats.c b/drivers/net/bnxt/bnxt_stats.c
index 0e25207fc3..ee10fe0360 100644
--- a/drivers/net/bnxt/bnxt_stats.c
+++ b/drivers/net/bnxt/bnxt_stats.c
@@ -258,6 +258,53 @@ static const struct bnxt_xstats_name_off bnxt_tx_stats_strings[] = {
 				tx_stat_error)},
 };
 
+static const struct bnxt_xstats_name_off bnxt_func_stats_ext_strings[] = {
+	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_ucast_pkts)},
+	{"tx_mcast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_mcast_pkts)},
+	{"tx_bcast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_bcast_pkts)},
+	{"tx_discard_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_discard_pkts)},
+	{"tx_drop_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_error_pkts)},
+	{"tx_ucast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_ucast_bytes)},
+	{"tx_mcast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_mcast_bytes)},
+	{"tx_bcast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				tx_bcast_bytes)},
+	{"rx_ucast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_ucast_pkts)},
+	{"rx_mcast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_mcast_pkts)},
+	{"rx_bcast_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_bcast_pkts)},
+	{"rx_discard_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_discard_pkts)},
+	{"rx_drop_pkts", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_error_pkts)},
+	{"rx_ucast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_ucast_bytes)},
+	{"rx_mcast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_mcast_bytes)},
+	{"rx_bcast_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_bcast_bytes)},
+	{"rx_tpa_eligible_pkt", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_eligible_pkt)},
+	{"rx_tpa_eligible_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_eligible_bytes)},
+	{"rx_tpa_pkt", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_pkt)},
+	{"rx_tpa_bytes", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_bytes)},
+	{"rx_tpa_errors", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_errors)},
+	{"rx_tpa_events", offsetof(struct hwrm_func_qstats_ext_output,
+				rx_tpa_events)},
+};
+
 static const struct bnxt_xstats_name_off bnxt_func_stats_strings[] = {
 	{"tx_ucast_pkts", offsetof(struct hwrm_func_qstats_output,
 				tx_ucast_pkts)},
@@ -417,6 +464,12 @@ static const struct bnxt_xstats_name_off bnxt_rx_ext_stats_strings[] = {
 				rx_discard_packets_cos6)},
 	{"rx_discard_packets_cos7", offsetof(struct rx_port_stats_ext,
 				rx_discard_packets_cos7)},
+	{"rx_fec_corrected_blocks", offsetof(struct rx_port_stats_ext,
+				rx_fec_corrected_blocks)},
+	{"rx_fec_uncorrectable_blocks", offsetof(struct rx_port_stats_ext,
+				rx_fec_uncorrectable_blocks)},
+	{"rx_filter_miss", offsetof(struct rx_port_stats_ext,
+				rx_filter_miss)},
 };
 
 static const struct bnxt_xstats_name_off bnxt_tx_ext_stats_strings[] = {
@@ -506,6 +559,45 @@ void bnxt_free_stats(struct bnxt *bp)
 	}
 }
 
+static void bnxt_fill_rte_eth_stats_ext(struct rte_eth_stats *stats,
+					struct bnxt_ring_stats_ext *ring_stats,
+					unsigned int i, bool rx)
+{
+	if (rx) {
+		stats->q_ipackets[i] = ring_stats->rx_ucast_pkts;
+		stats->q_ipackets[i] += ring_stats->rx_mcast_pkts;
+		stats->q_ipackets[i] += ring_stats->rx_bcast_pkts;
+
+		stats->ipackets += stats->q_ipackets[i];
+
+		stats->q_ibytes[i] = ring_stats->rx_ucast_bytes;
+		stats->q_ibytes[i] += ring_stats->rx_mcast_bytes;
+		stats->q_ibytes[i] += ring_stats->rx_bcast_bytes;
+
+		stats->ibytes += stats->q_ibytes[i];
+
+		stats->q_errors[i] = ring_stats->rx_discard_pkts;
+		stats->q_errors[i] += ring_stats->rx_error_pkts;
+
+		stats->imissed += ring_stats->rx_discard_pkts;
+		stats->ierrors += ring_stats->rx_error_pkts;
+	} else {
+		stats->q_opackets[i] = ring_stats->tx_ucast_pkts;
+		stats->q_opackets[i] += ring_stats->tx_mcast_pkts;
+		stats->q_opackets[i] += ring_stats->tx_bcast_pkts;
+
+		stats->opackets += stats->q_opackets[i];
+
+		stats->q_obytes[i] = ring_stats->tx_ucast_bytes;
+		stats->q_obytes[i] += ring_stats->tx_mcast_bytes;
+		stats->q_obytes[i] += ring_stats->tx_bcast_bytes;
+
+		stats->obytes += stats->q_obytes[i];
+
+		stats->oerrors += ring_stats->tx_discard_pkts;
+	}
+}
+
 static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats,
 				    struct bnxt_ring_stats *ring_stats,
 				    unsigned int i, bool rx)
@@ -545,6 +637,57 @@ static void bnxt_fill_rte_eth_stats(struct rte_eth_stats *stats,
 	}
 }
 
+static int bnxt_stats_get_op_ext(struct rte_eth_dev *eth_dev,
+				 struct rte_eth_stats *bnxt_stats)
+{
+	int rc = 0;
+	unsigned int i;
+	struct bnxt *bp = eth_dev->data->dev_private;
+	unsigned int num_q_stats;
+
+	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
+			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+	for (i = 0; i < num_q_stats; i++) {
+		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
+		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+		struct bnxt_ring_stats_ext ring_stats = {0};
+
+		if (!rxq->rx_started)
+			continue;
+
+		rc = bnxt_hwrm_ring_stats_ext(bp, cpr->hw_stats_ctx_id, i,
+					      &ring_stats, true);
+		if (unlikely(rc))
+			return rc;
+
+		bnxt_fill_rte_eth_stats_ext(bnxt_stats, &ring_stats, i, true);
+		bnxt_stats->rx_nombuf +=
+				__atomic_load_n(&rxq->rx_mbuf_alloc_fail, __ATOMIC_RELAXED);
+	}
+
+	num_q_stats = RTE_MIN(bp->tx_cp_nr_rings,
+			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
+
+	for (i = 0; i < num_q_stats; i++) {
+		struct bnxt_tx_queue *txq = bp->tx_queues[i];
+		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
+		struct bnxt_ring_stats_ext ring_stats = {0};
+
+		if (!txq->tx_started)
+			continue;
+
+		rc = bnxt_hwrm_ring_stats_ext(bp, cpr->hw_stats_ctx_id, i,
+					      &ring_stats, false);
+		if (unlikely(rc))
+			return rc;
+
+		bnxt_fill_rte_eth_stats_ext(bnxt_stats, &ring_stats, i, false);
+	}
+
+	return rc;
+}
+
 int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 		      struct rte_eth_stats *bnxt_stats)
 {
@@ -560,6 +703,9 @@ int bnxt_stats_get_op(struct rte_eth_dev *eth_dev,
 	if (!eth_dev->data->dev_started)
 		return -EIO;
 
+	if (BNXT_TPA_V2_P7(bp))
+		return bnxt_stats_get_op_ext(eth_dev, bnxt_stats);
+
 	num_q_stats = RTE_MIN(bp->rx_cp_nr_rings,
 			      (unsigned int)RTE_ETHDEV_QUEUE_STAT_CNTRS);
 
@@ -609,8 +755,17 @@ static void bnxt_clear_prev_stat(struct bnxt *bp)
 	 * Clear the cached values of stats returned by HW in the previous
 	 * get operation.
 	 */
-	memset(bp->prev_rx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->rx_cp_nr_rings);
-	memset(bp->prev_tx_ring_stats, 0, sizeof(struct bnxt_ring_stats) * bp->tx_cp_nr_rings);
+	if (BNXT_TPA_V2_P7(bp)) {
+		memset(bp->prev_rx_ring_stats_ext, 0,
+		       sizeof(struct bnxt_ring_stats_ext) * bp->rx_cp_nr_rings);
+		memset(bp->prev_tx_ring_stats_ext, 0,
+		       sizeof(struct bnxt_ring_stats_ext) * bp->tx_cp_nr_rings);
+	} else {
+		memset(bp->prev_rx_ring_stats, 0,
+		       sizeof(struct bnxt_ring_stats) * bp->rx_cp_nr_rings);
+		memset(bp->prev_tx_ring_stats, 0,
+		       sizeof(struct bnxt_ring_stats) * bp->tx_cp_nr_rings);
+	}
 }
 
 int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
@@ -640,6 +795,42 @@ int bnxt_stats_reset_op(struct rte_eth_dev *eth_dev)
 	return ret;
 }
 
+static void bnxt_fill_func_qstats_ext(struct hwrm_func_qstats_ext_output *func_qstats,
+				      struct bnxt_ring_stats_ext *ring_stats,
+				      bool rx)
+{
+	if (rx) {
+		func_qstats->rx_ucast_pkts += ring_stats->rx_ucast_pkts;
+		func_qstats->rx_mcast_pkts += ring_stats->rx_mcast_pkts;
+		func_qstats->rx_bcast_pkts += ring_stats->rx_bcast_pkts;
+
+		func_qstats->rx_ucast_bytes += ring_stats->rx_ucast_bytes;
+		func_qstats->rx_mcast_bytes += ring_stats->rx_mcast_bytes;
+		func_qstats->rx_bcast_bytes += ring_stats->rx_bcast_bytes;
+
+		func_qstats->rx_discard_pkts += ring_stats->rx_discard_pkts;
+		func_qstats->rx_error_pkts += ring_stats->rx_error_pkts;
+
+		func_qstats->rx_tpa_eligible_pkt += ring_stats->rx_tpa_eligible_pkt;
+		func_qstats->rx_tpa_eligible_bytes += ring_stats->rx_tpa_eligible_bytes;
+		func_qstats->rx_tpa_pkt += ring_stats->rx_tpa_pkt;
+		func_qstats->rx_tpa_bytes += ring_stats->rx_tpa_bytes;
+		func_qstats->rx_tpa_errors += ring_stats->rx_tpa_errors;
+		func_qstats->rx_tpa_events += ring_stats->rx_tpa_events;
+	} else {
+		func_qstats->tx_ucast_pkts += ring_stats->tx_ucast_pkts;
+		func_qstats->tx_mcast_pkts += ring_stats->tx_mcast_pkts;
+		func_qstats->tx_bcast_pkts += ring_stats->tx_bcast_pkts;
+
+		func_qstats->tx_ucast_bytes += ring_stats->tx_ucast_bytes;
+		func_qstats->tx_mcast_bytes += ring_stats->tx_mcast_bytes;
+		func_qstats->tx_bcast_bytes += ring_stats->tx_bcast_bytes;
+
+		func_qstats->tx_error_pkts += ring_stats->tx_error_pkts;
+		func_qstats->tx_discard_pkts += ring_stats->tx_discard_pkts;
+	}
+}
+
 static void bnxt_fill_func_qstats(struct hwrm_func_qstats_output *func_qstats,
 				  struct bnxt_ring_stats *ring_stats,
 				  bool rx)
@@ -683,16 +874,21 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 	unsigned int tx_port_stats_ext_cnt;
 	unsigned int stat_size = sizeof(uint64_t);
 	struct hwrm_func_qstats_output func_qstats = {0};
-	unsigned int stat_count;
+	struct hwrm_func_qstats_ext_output func_qstats_ext = {0};
+	unsigned int stat_count, sz;
 	int rc;
 
 	rc = is_bnxt_in_error(bp);
 	if (rc)
 		return rc;
 
+	if (BNXT_TPA_V2_P7(bp))
+		sz = RTE_DIM(bnxt_func_stats_ext_strings);
+	else
+		sz = RTE_DIM(bnxt_func_stats_strings);
+
 	stat_count = RTE_DIM(bnxt_rx_stats_strings) +
-		RTE_DIM(bnxt_tx_stats_strings) +
-		RTE_DIM(bnxt_func_stats_strings) +
+		RTE_DIM(bnxt_tx_stats_strings) + sz +
 		RTE_DIM(bnxt_rx_ext_stats_strings) +
 		RTE_DIM(bnxt_tx_ext_stats_strings) +
 		bnxt_flow_stats_cnt(bp);
@@ -704,32 +900,51 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		struct bnxt_rx_queue *rxq = bp->rx_queues[i];
 		struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
 		struct bnxt_ring_stats ring_stats = {0};
+		struct bnxt_ring_stats_ext ring_stats_ext = {0};
 
 		if (!rxq->rx_started)
 			continue;
 
-		rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
-					  &ring_stats, true);
+		if (BNXT_TPA_V2_P7(bp))
+			rc = bnxt_hwrm_ring_stats_ext(bp, cpr->hw_stats_ctx_id, i,
+						      &ring_stats_ext, true);
+		else
+			rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+						  &ring_stats, true);
+
 		if (unlikely(rc))
 			return rc;
 
-		bnxt_fill_func_qstats(&func_qstats, &ring_stats, true);
+		if (BNXT_TPA_V2_P7(bp))
+			bnxt_fill_func_qstats_ext(&func_qstats_ext,
+						  &ring_stats_ext, true);
+		else
+			bnxt_fill_func_qstats(&func_qstats, &ring_stats, true);
 	}
 
 	for (i = 0; i < bp->tx_cp_nr_rings; i++) {
 		struct bnxt_tx_queue *txq = bp->tx_queues[i];
 		struct bnxt_cp_ring_info *cpr = txq->cp_ring;
 		struct bnxt_ring_stats ring_stats = {0};
+		struct bnxt_ring_stats_ext ring_stats_ext = {0};
 
 		if (!txq->tx_started)
 			continue;
 
-		rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
-					  &ring_stats, false);
+		if (BNXT_TPA_V2_P7(bp))
+			rc = bnxt_hwrm_ring_stats_ext(bp, cpr->hw_stats_ctx_id, i,
+						      &ring_stats_ext, false);
+		else
+			rc = bnxt_hwrm_ring_stats(bp, cpr->hw_stats_ctx_id, i,
+						  &ring_stats, false);
 		if (unlikely(rc))
 			return rc;
 
-		bnxt_fill_func_qstats(&func_qstats, &ring_stats, false);
+		if (BNXT_TPA_V2_P7(bp))
+			bnxt_fill_func_qstats_ext(&func_qstats_ext,
+						  &ring_stats_ext, false);
+		else
+			bnxt_fill_func_qstats(&func_qstats, &ring_stats, false);
 	}
 
 	bnxt_hwrm_port_qstats(bp);
@@ -762,6 +977,15 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+	if (BNXT_TPA_V2_P7(bp)) {
+		for (i = 0; i < RTE_DIM(bnxt_func_stats_ext_strings); i++) {
+			xstats[count].id = count;
+			xstats[count].value = *(uint64_t *)((char *)&func_qstats_ext +
+							    bnxt_func_stats_ext_strings[i].offset);
+			count++;
+		}
+		goto skip_func_stats;
+	}
 	for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
 		xstats[count].id = count;
 		xstats[count].value = *(uint64_t *)((char *)&func_qstats +
@@ -769,6 +993,7 @@ int bnxt_dev_xstats_get_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+skip_func_stats:
 	for (i = 0; i < rx_port_stats_ext_cnt; i++) {
 		uint64_t *rx_stats_ext = (uint64_t *)bp->hw_rx_port_stats_ext;
 
@@ -849,19 +1074,26 @@ int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
 		unsigned int size)
 {
 	struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private;
-	const unsigned int stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
-				RTE_DIM(bnxt_tx_stats_strings) +
-				RTE_DIM(bnxt_func_stats_strings) +
-				RTE_DIM(bnxt_rx_ext_stats_strings) +
-				RTE_DIM(bnxt_tx_ext_stats_strings) +
-				bnxt_flow_stats_cnt(bp);
-	unsigned int i, count = 0;
+	unsigned int stat_cnt;
+	unsigned int i, count = 0, sz;
 	int rc;
 
 	rc = is_bnxt_in_error(bp);
 	if (rc)
 		return rc;
 
+	if (BNXT_TPA_V2_P7(bp))
+		sz = RTE_DIM(bnxt_func_stats_ext_strings);
+	else
+		sz = RTE_DIM(bnxt_func_stats_strings);
+
+	stat_cnt = RTE_DIM(bnxt_rx_stats_strings) +
+				RTE_DIM(bnxt_tx_stats_strings) +
+				sz +
+				RTE_DIM(bnxt_rx_ext_stats_strings) +
+				RTE_DIM(bnxt_tx_ext_stats_strings) +
+				bnxt_flow_stats_cnt(bp);
+
 	if (xstats_names == NULL || size < stat_cnt)
 		return stat_cnt;
 
@@ -879,6 +1111,16 @@ int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+	if (BNXT_TPA_V2_P7(bp)) {
+		for (i = 0; i < RTE_DIM(bnxt_func_stats_ext_strings); i++) {
+			strlcpy(xstats_names[count].name,
+				bnxt_func_stats_ext_strings[i].name,
+				sizeof(xstats_names[count].name));
+			count++;
+		}
+		goto skip_func_stats;
+	}
+
 	for (i = 0; i < RTE_DIM(bnxt_func_stats_strings); i++) {
 		strlcpy(xstats_names[count].name,
 			bnxt_func_stats_strings[i].name,
@@ -886,6 +1128,7 @@ int bnxt_dev_xstats_get_names_op(struct rte_eth_dev *eth_dev,
 		count++;
 	}
 
+skip_func_stats:
 	for (i = 0; i < RTE_DIM(bnxt_rx_ext_stats_strings); i++) {
 		strlcpy(xstats_names[count].name,
 			bnxt_rx_ext_stats_strings[i].name,
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 17/18] net/bnxt: add AVX2 support for compressed CQE
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (15 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 16/18] net/bnxt: query extended stats from firmware Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  2023-12-21 18:05 ` [PATCH 18/18] net/bnxt: enable SSE mode " Ajit Khaparde
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 13849 bytes --]

P7 device family supports 16 byte Rx completions.
Add AVX2 vector mode for compressed Rx CQE.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c        |   5 +
 drivers/net/bnxt/bnxt_rxr.h           |   2 +
 drivers/net/bnxt/bnxt_rxtx_vec_avx2.c | 309 ++++++++++++++++++++++++++
 3 files changed, 316 insertions(+)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 031028eda1..bd8c7557dd 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1406,6 +1406,8 @@ bnxt_receive_function(struct rte_eth_dev *eth_dev)
 			    "Using AVX2 vector mode receive for port %d\n",
 			    eth_dev->data->port_id);
 		bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE;
+		if (bnxt_compressed_rx_cqe_mode_enabled(bp))
+			return bnxt_crx_pkts_vec_avx2;
 		return bnxt_recv_pkts_vec_avx2;
 	}
  #endif
@@ -3124,6 +3126,9 @@ static const struct {
 	{bnxt_recv_pkts,		"Scalar"},
 #if defined(RTE_ARCH_X86)
 	{bnxt_recv_pkts_vec,		"Vector SSE"},
+#endif
+#if defined(RTE_ARCH_X86) && defined(CC_AVX2_SUPPORT)
+	{bnxt_crx_pkts_vec_avx2,	"Vector AVX2"},
 	{bnxt_recv_pkts_vec_avx2,	"Vector AVX2"},
 #endif
 #if defined(RTE_ARCH_ARM64)
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index c51bb2d62c..a474a69ae3 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -162,6 +162,8 @@ int bnxt_rxq_vec_setup(struct bnxt_rx_queue *rxq);
 #if defined(RTE_ARCH_X86)
 uint16_t bnxt_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
 				 uint16_t nb_pkts);
+uint16_t bnxt_crx_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
+				uint16_t nb_pkts);
 #endif
 void bnxt_set_mark_in_mbuf(struct bnxt *bp,
 			   struct rx_pkt_cmpl_hi *rxcmp1,
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
index ea8dbaffba..e4d84bc9b6 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_avx2.c
@@ -361,6 +361,294 @@ recv_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return nb_rx_pkts;
 }
 
+static uint16_t
+crx_burst_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+	struct bnxt_rx_queue *rxq = rx_queue;
+	const __m256i mbuf_init =
+		_mm256_set_epi64x(0, 0, 0, rxq->mbuf_initializer);
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t cp_ring_size = cpr->cp_ring_struct->ring_size;
+	uint16_t rx_ring_size = rxr->rx_ring_struct->ring_size;
+	struct cmpl_base *cp_desc_ring = cpr->cp_desc_ring;
+	uint64_t valid, desc_valid_mask = ~0ULL;
+	const __m256i info3_v_mask = _mm256_set1_epi32(CMPL_BASE_V);
+	uint32_t raw_cons = cpr->cp_raw_cons;
+	uint32_t cons, mbcons;
+	int nb_rx_pkts = 0;
+	int i;
+	const __m256i valid_target =
+		_mm256_set1_epi32(!!(raw_cons & cp_ring_size));
+	const __m256i shuf_msk =
+		_mm256_set_epi8(15, 14, 13, 12,          /* rss */
+				7, 6,                    /* vlan_tci */
+				3, 2,                    /* data_len */
+				0xFF, 0xFF, 3, 2,        /* pkt_len */
+				0xFF, 0xFF, 0xFF, 0xFF,  /* pkt_type (zeroes) */
+				15, 14, 13, 12,          /* rss */
+				7, 6,                    /* vlan_tci */
+				3, 2,                    /* data_len */
+				0xFF, 0xFF, 3, 2,        /* pkt_len */
+				0xFF, 0xFF, 0xFF, 0xFF); /* pkt_type (zeroes) */
+	const __m256i flags_type_mask =
+		_mm256_set1_epi32(RX_PKT_CMPL_FLAGS_ITYPE_MASK);
+	const __m256i flags2_mask1 =
+		_mm256_set1_epi32(CMPL_FLAGS2_VLAN_TUN_MSK);
+	const __m256i flags2_mask2 =
+		_mm256_set1_epi32(RX_PKT_CMPL_FLAGS2_IP_TYPE);
+	const __m256i rss_mask =
+		_mm256_set1_epi32(RX_PKT_CMPL_FLAGS_RSS_VALID);
+	__m256i t0, t1, flags_type, flags2, index, errors;
+	__m256i ptype_idx, ptypes, is_tunnel;
+	__m256i mbuf01, mbuf23, mbuf45, mbuf67;
+	__m256i rearm0, rearm1, rearm2, rearm3, rearm4, rearm5, rearm6, rearm7;
+	__m256i ol_flags, ol_flags_hi;
+	__m256i rss_flags;
+
+	/* Validate ptype table indexing at build time. */
+	bnxt_check_ptype_constants();
+
+	/* If Rx Q was stopped return */
+	if (unlikely(!rxq->rx_started))
+		return 0;
+
+	if (rxq->rxrearm_nb >= rxq->rx_free_thresh)
+		bnxt_rxq_rearm(rxq, rxr);
+
+	nb_pkts = RTE_ALIGN_FLOOR(nb_pkts, BNXT_RX_DESCS_PER_LOOP_VEC256);
+
+	cons = raw_cons & (cp_ring_size - 1);
+	mbcons = raw_cons & (rx_ring_size - 1);
+
+	/* Return immediately if there is not at least one completed packet. */
+	if (!bnxt_cpr_cmp_valid(&cp_desc_ring[cons], raw_cons, cp_ring_size))
+		return 0;
+
+	/* Ensure that we do not go past the ends of the rings. */
+	nb_pkts = RTE_MIN(nb_pkts, RTE_MIN(rx_ring_size - mbcons,
+					   cp_ring_size - cons));
+	/*
+	 * If we are at the end of the ring, ensure that descriptors after the
+	 * last valid entry are not treated as valid. Otherwise, force the
+	 * maximum number of packets to receive to be a multiple of the per-
+	 * loop count.
+	 */
+	if (nb_pkts < BNXT_RX_DESCS_PER_LOOP_VEC256) {
+		desc_valid_mask >>=
+			CHAR_BIT * (BNXT_RX_DESCS_PER_LOOP_VEC256 - nb_pkts);
+	} else {
+		nb_pkts =
+			RTE_ALIGN_FLOOR(nb_pkts, BNXT_RX_DESCS_PER_LOOP_VEC256);
+	}
+
+	/* Handle RX burst request */
+	for (i = 0; i < nb_pkts; i += BNXT_RX_DESCS_PER_LOOP_VEC256,
+				  cons += BNXT_RX_DESCS_PER_LOOP_VEC256,
+				  mbcons += BNXT_RX_DESCS_PER_LOOP_VEC256) {
+		__m256i rxcmp0_1, rxcmp2_3, rxcmp4_5, rxcmp6_7, info3_v;
+		__m256i errors_v2;
+		uint32_t num_valid;
+
+		/* Copy eight mbuf pointers to output array. */
+		t0 = _mm256_loadu_si256((void *)&rxr->rx_buf_ring[mbcons]);
+		_mm256_storeu_si256((void *)&rx_pkts[i], t0);
+#ifdef RTE_ARCH_X86_64
+		t0 = _mm256_loadu_si256((void *)&rxr->rx_buf_ring[mbcons + 4]);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 4], t0);
+#endif
+
+		/*
+		 * Load eight receive completion descriptors into 256-bit
+		 * registers. Loads are issued in reverse order in order to
+		 * ensure consistent state.
+		 */
+		rxcmp6_7 = _mm256_loadu_si256((void *)&cp_desc_ring[cons + 6]);
+		rte_compiler_barrier();
+		rxcmp4_5 = _mm256_loadu_si256((void *)&cp_desc_ring[cons + 4]);
+		rte_compiler_barrier();
+		rxcmp2_3 = _mm256_loadu_si256((void *)&cp_desc_ring[cons + 2]);
+		rte_compiler_barrier();
+		rxcmp0_1 = _mm256_loadu_si256((void *)&cp_desc_ring[cons + 0]);
+
+		/* Compute packet type table indices for eight packets. */
+		t0 = _mm256_unpacklo_epi32(rxcmp0_1, rxcmp2_3);
+		t1 = _mm256_unpacklo_epi32(rxcmp4_5, rxcmp6_7);
+		flags_type = _mm256_unpacklo_epi64(t0, t1);
+		ptype_idx = _mm256_and_si256(flags_type, flags_type_mask);
+		ptype_idx = _mm256_srli_epi32(ptype_idx,
+					      RX_PKT_CMPL_FLAGS_ITYPE_SFT -
+					      BNXT_PTYPE_TBL_TYPE_SFT);
+
+		t0 = _mm256_unpacklo_epi32(rxcmp0_1, rxcmp2_3);
+		t1 = _mm256_unpacklo_epi32(rxcmp4_5, rxcmp6_7);
+		flags2 = _mm256_unpackhi_epi64(t0, t1);
+
+		t0 = _mm256_srli_epi32(_mm256_and_si256(flags2, flags2_mask1),
+				       RX_PKT_CMPL_FLAGS2_META_FORMAT_SFT -
+				       BNXT_PTYPE_TBL_VLAN_SFT);
+		ptype_idx = _mm256_or_si256(ptype_idx, t0);
+
+		t0 = _mm256_srli_epi32(_mm256_and_si256(flags2, flags2_mask2),
+				       RX_PKT_CMPL_FLAGS2_IP_TYPE_SFT -
+				       BNXT_PTYPE_TBL_IP_VER_SFT);
+		ptype_idx = _mm256_or_si256(ptype_idx, t0);
+
+		/*
+		 * Load ptypes for eight packets using gather. Gather operations
+		 * have extremely high latency (~19 cycles), execution and use
+		 * of result should be separated as much as possible.
+		 */
+		ptypes = _mm256_i32gather_epi32((int *)bnxt_ptype_table,
+						ptype_idx, sizeof(uint32_t));
+		/*
+		 * Compute ol_flags and checksum error table indices for eight
+		 * packets.
+		 */
+		is_tunnel = _mm256_and_si256(flags2, _mm256_set1_epi32(4));
+		is_tunnel = _mm256_slli_epi32(is_tunnel, 3);
+		flags2 = _mm256_and_si256(flags2, _mm256_set1_epi32(0x1F));
+
+		/* Extract errors_v2 fields for eight packets. */
+		t0 = _mm256_unpackhi_epi32(rxcmp0_1, rxcmp2_3);
+		t1 = _mm256_unpackhi_epi32(rxcmp4_5, rxcmp6_7);
+		errors_v2 = _mm256_unpacklo_epi64(t0, t1);
+
+		errors = _mm256_srli_epi32(errors_v2, 4);
+		errors = _mm256_and_si256(errors, _mm256_set1_epi32(0xF));
+		errors = _mm256_and_si256(errors, flags2);
+
+		index = _mm256_andnot_si256(errors, flags2);
+		errors = _mm256_or_si256(errors,
+					 _mm256_srli_epi32(is_tunnel, 1));
+		index = _mm256_or_si256(index, is_tunnel);
+
+		/*
+		 * Load ol_flags for eight packets using gather. Gather
+		 * operations have extremely high latency (~19 cycles),
+		 * execution and use of result should be separated as much
+		 * as possible.
+		 */
+		ol_flags = _mm256_i32gather_epi32((int *)rxr->ol_flags_table,
+						  index, sizeof(uint32_t));
+		errors = _mm256_i32gather_epi32((int *)rxr->ol_flags_err_table,
+						errors, sizeof(uint32_t));
+
+		/*
+		 * Pack the 128-bit array of valid descriptor flags into 64
+		 * bits and count the number of set bits in order to determine
+		 * the number of valid descriptors.
+		 */
+		const __m256i perm_msk =
+				_mm256_set_epi32(7, 3, 6, 2, 5, 1, 4, 0);
+		info3_v = _mm256_permutevar8x32_epi32(errors_v2, perm_msk);
+		info3_v = _mm256_and_si256(errors_v2, info3_v_mask);
+		info3_v = _mm256_xor_si256(info3_v, valid_target);
+
+		info3_v = _mm256_packs_epi32(info3_v, _mm256_setzero_si256());
+		valid = _mm_cvtsi128_si64(_mm256_extracti128_si256(info3_v, 1));
+		valid = (valid << CHAR_BIT) |
+			_mm_cvtsi128_si64(_mm256_castsi256_si128(info3_v));
+		num_valid = __builtin_popcountll(valid & desc_valid_mask);
+
+		if (num_valid == 0)
+			break;
+
+		/* Update mbuf rearm_data for eight packets. */
+		mbuf01 = _mm256_shuffle_epi8(rxcmp0_1, shuf_msk);
+		mbuf23 = _mm256_shuffle_epi8(rxcmp2_3, shuf_msk);
+		mbuf45 = _mm256_shuffle_epi8(rxcmp4_5, shuf_msk);
+		mbuf67 = _mm256_shuffle_epi8(rxcmp6_7, shuf_msk);
+
+		/* Blend in ptype field for two mbufs at a time. */
+		mbuf01 = _mm256_blend_epi32(mbuf01, ptypes, 0x11);
+		mbuf23 = _mm256_blend_epi32(mbuf23,
+					_mm256_srli_si256(ptypes, 4), 0x11);
+		mbuf45 = _mm256_blend_epi32(mbuf45,
+					_mm256_srli_si256(ptypes, 8), 0x11);
+		mbuf67 = _mm256_blend_epi32(mbuf67,
+					_mm256_srli_si256(ptypes, 12), 0x11);
+
+		/* Unpack rearm data, set fixed fields for first four mbufs. */
+		rearm0 = _mm256_permute2f128_si256(mbuf_init, mbuf01, 0x20);
+		rearm1 = _mm256_blend_epi32(mbuf_init, mbuf01, 0xF0);
+		rearm2 = _mm256_permute2f128_si256(mbuf_init, mbuf23, 0x20);
+		rearm3 = _mm256_blend_epi32(mbuf_init, mbuf23, 0xF0);
+
+		/* Compute final ol_flags values for eight packets. */
+		rss_flags = _mm256_and_si256(flags_type, rss_mask);
+		rss_flags = _mm256_srli_epi32(rss_flags, 9);
+		ol_flags = _mm256_or_si256(ol_flags, errors);
+		ol_flags = _mm256_or_si256(ol_flags, rss_flags);
+		ol_flags_hi = _mm256_permute2f128_si256(ol_flags,
+							ol_flags, 0x11);
+
+		/* Set ol_flags fields for first four packets. */
+		rearm0 = _mm256_blend_epi32(rearm0,
+					    _mm256_slli_si256(ol_flags, 8),
+					    0x04);
+		rearm1 = _mm256_blend_epi32(rearm1,
+					    _mm256_slli_si256(ol_flags_hi, 8),
+					    0x04);
+		rearm2 = _mm256_blend_epi32(rearm2,
+					    _mm256_slli_si256(ol_flags, 4),
+					    0x04);
+		rearm3 = _mm256_blend_epi32(rearm3,
+					    _mm256_slli_si256(ol_flags_hi, 4),
+					    0x04);
+
+		/* Store all mbuf fields for first four packets. */
+		_mm256_storeu_si256((void *)&rx_pkts[i + 0]->rearm_data,
+				    rearm0);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 1]->rearm_data,
+				    rearm1);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 2]->rearm_data,
+				    rearm2);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 3]->rearm_data,
+				    rearm3);
+
+		/* Unpack rearm data, set fixed fields for final four mbufs. */
+		rearm4 = _mm256_permute2f128_si256(mbuf_init, mbuf45, 0x20);
+		rearm5 = _mm256_blend_epi32(mbuf_init, mbuf45, 0xF0);
+		rearm6 = _mm256_permute2f128_si256(mbuf_init, mbuf67, 0x20);
+		rearm7 = _mm256_blend_epi32(mbuf_init, mbuf67, 0xF0);
+
+		/* Set ol_flags fields for final four packets. */
+		rearm4 = _mm256_blend_epi32(rearm4, ol_flags, 0x04);
+		rearm5 = _mm256_blend_epi32(rearm5, ol_flags_hi, 0x04);
+		rearm6 = _mm256_blend_epi32(rearm6,
+					    _mm256_srli_si256(ol_flags, 4),
+					    0x04);
+		rearm7 = _mm256_blend_epi32(rearm7,
+					    _mm256_srli_si256(ol_flags_hi, 4),
+					    0x04);
+
+		/* Store all mbuf fields for final four packets. */
+		_mm256_storeu_si256((void *)&rx_pkts[i + 4]->rearm_data,
+				    rearm4);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 5]->rearm_data,
+				    rearm5);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 6]->rearm_data,
+				    rearm6);
+		_mm256_storeu_si256((void *)&rx_pkts[i + 7]->rearm_data,
+				    rearm7);
+
+		nb_rx_pkts += num_valid;
+		if (num_valid < BNXT_RX_DESCS_PER_LOOP_VEC256)
+			break;
+	}
+
+	if (nb_rx_pkts) {
+		rxr->rx_raw_prod = RING_ADV(rxr->rx_raw_prod, nb_rx_pkts);
+
+		rxq->rxrearm_nb += nb_rx_pkts;
+		cpr->cp_raw_cons += nb_rx_pkts;
+		bnxt_db_cq(cpr);
+	}
+
+	return nb_rx_pkts;
+}
+
 uint16_t
 bnxt_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
 			 uint16_t nb_pkts)
@@ -382,6 +670,27 @@ bnxt_recv_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
 	return cnt + recv_burst_vec_avx2(rx_queue, rx_pkts + cnt, nb_pkts);
 }
 
+uint16_t
+bnxt_crx_pkts_vec_avx2(void *rx_queue, struct rte_mbuf **rx_pkts,
+		       uint16_t nb_pkts)
+{
+	uint16_t cnt = 0;
+
+	while (nb_pkts > RTE_BNXT_MAX_RX_BURST) {
+		uint16_t burst;
+
+		burst = crx_burst_vec_avx2(rx_queue, rx_pkts + cnt,
+					     RTE_BNXT_MAX_RX_BURST);
+
+		cnt += burst;
+		nb_pkts -= burst;
+
+		if (burst < RTE_BNXT_MAX_RX_BURST)
+			return cnt;
+	}
+	return cnt + crx_burst_vec_avx2(rx_queue, rx_pkts + cnt, nb_pkts);
+}
+
 static void
 bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq)
 {
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

* [PATCH 18/18] net/bnxt: enable SSE mode for compressed CQE
  2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
                   ` (16 preceding siblings ...)
  2023-12-21 18:05 ` [PATCH 17/18] net/bnxt: add AVX2 support for compressed CQE Ajit Khaparde
@ 2023-12-21 18:05 ` Ajit Khaparde
  17 siblings, 0 replies; 19+ messages in thread
From: Ajit Khaparde @ 2023-12-21 18:05 UTC (permalink / raw)
  To: dev; +Cc: Damodharam Ammepalli

[-- Attachment #1: Type: text/plain, Size: 9786 bytes --]

P7 device family supports 16 byte Rx completions.
Enable SSE vector mode for compressed Rx CQE processing.

Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
Reviewed-by: Damodharam Ammepalli <damodharam.ammepalli@broadcom.com>
---
 drivers/net/bnxt/bnxt_ethdev.c       |  16 ++-
 drivers/net/bnxt/bnxt_rxr.h          |   2 +
 drivers/net/bnxt/bnxt_rxtx_vec_sse.c | 167 +++++++++++++++++++++++++--
 3 files changed, 173 insertions(+), 12 deletions(-)

diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index bd8c7557dd..f9cd234bb6 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -1377,7 +1377,8 @@ bnxt_receive_function(struct rte_eth_dev *eth_dev)
 	 * asynchronous completions and receive completions can be placed in
 	 * the same completion ring.
 	 */
-	if (BNXT_TRUFLOW_EN(bp) || !BNXT_NUM_ASYNC_CPR(bp))
+	if ((BNXT_TRUFLOW_EN(bp) && !BNXT_CHIP_P7(bp)) ||
+	    !BNXT_NUM_ASYNC_CPR(bp))
 		goto use_scalar_rx;
 
 	/*
@@ -1410,12 +1411,19 @@ bnxt_receive_function(struct rte_eth_dev *eth_dev)
 			return bnxt_crx_pkts_vec_avx2;
 		return bnxt_recv_pkts_vec_avx2;
 	}
- #endif
+#endif
 	if (rte_vect_get_max_simd_bitwidth() >= RTE_VECT_SIMD_128) {
 		PMD_DRV_LOG(INFO,
 			    "Using SSE vector mode receive for port %d\n",
 			    eth_dev->data->port_id);
 		bp->flags |= BNXT_FLAG_RX_VECTOR_PKT_MODE;
+		if (bnxt_compressed_rx_cqe_mode_enabled(bp)) {
+#if defined(RTE_ARCH_ARM64)
+			goto use_scalar_rx;
+#else
+			return bnxt_crx_pkts_vec;
+#endif
+		}
 		return bnxt_recv_pkts_vec;
 	}
 
@@ -1445,7 +1453,8 @@ bnxt_transmit_function(__rte_unused struct rte_eth_dev *eth_dev)
 	 */
 	if (eth_dev->data->scattered_rx ||
 	    (offloads & ~RTE_ETH_TX_OFFLOAD_MBUF_FAST_FREE) ||
-	    BNXT_TRUFLOW_EN(bp) || bp->ieee_1588)
+	    (BNXT_TRUFLOW_EN(bp) && !BNXT_CHIP_P7(bp)) ||
+	    bp->ieee_1588)
 		goto use_scalar_tx;
 
 #if defined(RTE_ARCH_X86)
@@ -3125,6 +3134,7 @@ static const struct {
 } bnxt_rx_burst_info[] = {
 	{bnxt_recv_pkts,		"Scalar"},
 #if defined(RTE_ARCH_X86)
+	{bnxt_crx_pkts_vec,		"Vector SSE"},
 	{bnxt_recv_pkts_vec,		"Vector SSE"},
 #endif
 #if defined(RTE_ARCH_X86) && defined(CC_AVX2_SUPPORT)
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index a474a69ae3..d36cbded1d 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -156,6 +156,8 @@ int bnxt_flush_rx_cmp(struct bnxt_cp_ring_info *cpr);
 #if defined(RTE_ARCH_X86) || defined(RTE_ARCH_ARM64)
 uint16_t bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
 			    uint16_t nb_pkts);
+uint16_t bnxt_crx_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts,
+			   uint16_t nb_pkts);
 int bnxt_rxq_vec_setup(struct bnxt_rx_queue *rxq);
 #endif
 
diff --git a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
index e99a547f58..c04b33a382 100644
--- a/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
+++ b/drivers/net/bnxt/bnxt_rxtx_vec_sse.c
@@ -54,15 +54,9 @@
 
 static inline void
 descs_to_mbufs(__m128i mm_rxcmp[4], __m128i mm_rxcmp1[4],
-	       __m128i mbuf_init, struct rte_mbuf **mbuf,
-	       struct bnxt_rx_ring_info *rxr)
+	       __m128i mbuf_init, const __m128i shuf_msk,
+	       struct rte_mbuf **mbuf, struct bnxt_rx_ring_info *rxr)
 {
-	const __m128i shuf_msk =
-		_mm_set_epi8(15, 14, 13, 12,          /* rss */
-			     0xFF, 0xFF,              /* vlan_tci (zeroes) */
-			     3, 2,                    /* data_len */
-			     0xFF, 0xFF, 3, 2,        /* pkt_len */
-			     0xFF, 0xFF, 0xFF, 0xFF); /* pkt_type (zeroes) */
 	const __m128i flags_type_mask =
 		_mm_set1_epi32(RX_PKT_CMPL_FLAGS_ITYPE_MASK);
 	const __m128i flags2_mask1 =
@@ -166,6 +160,12 @@ recv_burst_vec_sse(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	int nb_rx_pkts = 0;
 	const __m128i valid_target =
 		_mm_set1_epi32(!!(raw_cons & cp_ring_size));
+	const __m128i shuf_msk =
+		_mm_set_epi8(15, 14, 13, 12,          /* rss */
+			     0xFF, 0xFF,              /* vlan_tci (zeroes) */
+			     3, 2,                    /* data_len */
+			     0xFF, 0xFF, 3, 2,        /* pkt_len */
+			     0xFF, 0xFF, 0xFF, 0xFF); /* pkt_type (zeroes) */
 	int i;
 
 	/* If Rx Q was stopped return */
@@ -264,7 +264,7 @@ recv_burst_vec_sse(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 		if (num_valid == 0)
 			break;
 
-		descs_to_mbufs(rxcmp, rxcmp1, mbuf_init, &rx_pkts[nb_rx_pkts],
+		descs_to_mbufs(rxcmp, rxcmp1, mbuf_init, shuf_msk, &rx_pkts[nb_rx_pkts],
 			       rxr);
 		nb_rx_pkts += num_valid;
 
@@ -283,6 +283,134 @@ recv_burst_vec_sse(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return nb_rx_pkts;
 }
 
+static uint16_t
+crx_burst_vec_sse(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+	struct bnxt_rx_queue *rxq = rx_queue;
+	const __m128i mbuf_init = _mm_set_epi64x(0, rxq->mbuf_initializer);
+	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
+	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
+	uint16_t cp_ring_size = cpr->cp_ring_struct->ring_size;
+	uint16_t rx_ring_size = rxr->rx_ring_struct->ring_size;
+	struct cmpl_base *cp_desc_ring = cpr->cp_desc_ring;
+	uint64_t valid, desc_valid_mask = ~0ULL;
+	const __m128i info3_v_mask = _mm_set1_epi32(CMPL_BASE_V);
+	uint32_t raw_cons = cpr->cp_raw_cons;
+	uint32_t cons, mbcons;
+	int nb_rx_pkts = 0;
+	const __m128i valid_target =
+		_mm_set1_epi32(!!(raw_cons & cp_ring_size));
+	const __m128i shuf_msk =
+		_mm_set_epi8(7, 6, 5, 4,          /* rss */
+			     0xFF, 0xFF,              /* vlan_tci (zeroes) */
+			     3, 2,                    /* data_len */
+			     0xFF, 0xFF, 3, 2,        /* pkt_len */
+			     0xFF, 0xFF, 0xFF, 0xFF); /* pkt_type (zeroes) */
+	int i;
+
+	/* If Rx Q was stopped return */
+	if (unlikely(!rxq->rx_started))
+		return 0;
+
+	if (rxq->rxrearm_nb >= rxq->rx_free_thresh)
+		bnxt_rxq_rearm(rxq, rxr);
+
+	cons = raw_cons & (cp_ring_size - 1);
+	mbcons = raw_cons & (rx_ring_size - 1);
+
+	/* Prefetch first four descriptor pairs. */
+	rte_prefetch0(&cp_desc_ring[cons]);
+
+	/* Ensure that we do not go past the ends of the rings. */
+	nb_pkts = RTE_MIN(nb_pkts, RTE_MIN(rx_ring_size - mbcons,
+					   cp_ring_size - cons));
+	/*
+	 * If we are at the end of the ring, ensure that descriptors after the
+	 * last valid entry are not treated as valid. Otherwise, force the
+	 * maximum number of packets to receive to be a multiple of the per-
+	 * loop count.
+	 */
+	if (nb_pkts < BNXT_RX_DESCS_PER_LOOP_VEC128) {
+		desc_valid_mask >>=
+			16 * (BNXT_RX_DESCS_PER_LOOP_VEC128 - nb_pkts);
+	} else {
+		nb_pkts =
+			RTE_ALIGN_FLOOR(nb_pkts, BNXT_RX_DESCS_PER_LOOP_VEC128);
+	}
+
+	/* Handle RX burst request */
+	for (i = 0; i < nb_pkts; i += BNXT_RX_DESCS_PER_LOOP_VEC128,
+				  cons += BNXT_RX_DESCS_PER_LOOP_VEC128,
+				  mbcons += BNXT_RX_DESCS_PER_LOOP_VEC128) {
+		__m128i rxcmp1[BNXT_RX_DESCS_PER_LOOP_VEC128];
+		__m128i rxcmp[BNXT_RX_DESCS_PER_LOOP_VEC128];
+		__m128i tmp0, tmp1, info3_v;
+		uint32_t num_valid;
+
+		/* Copy four mbuf pointers to output array. */
+		tmp0 = _mm_loadu_si128((void *)&rxr->rx_buf_ring[mbcons]);
+#ifdef RTE_ARCH_X86_64
+		tmp1 = _mm_loadu_si128((void *)&rxr->rx_buf_ring[mbcons + 2]);
+#endif
+		_mm_storeu_si128((void *)&rx_pkts[i], tmp0);
+#ifdef RTE_ARCH_X86_64
+		_mm_storeu_si128((void *)&rx_pkts[i + 2], tmp1);
+#endif
+
+		/* Prefetch four descriptor pairs for next iteration. */
+		if (i + BNXT_RX_DESCS_PER_LOOP_VEC128 < nb_pkts)
+			rte_prefetch0(&cp_desc_ring[cons + 4]);
+
+		/*
+		 * Load the four current descriptors into SSE registers in
+		 * reverse order to ensure consistent state.
+		 */
+		rxcmp[3] = _mm_load_si128((void *)&cp_desc_ring[cons + 3]);
+		rte_compiler_barrier();
+		rxcmp[2] = _mm_load_si128((void *)&cp_desc_ring[cons + 2]);
+		rte_compiler_barrier();
+		rxcmp[1] = _mm_load_si128((void *)&cp_desc_ring[cons + 1]);
+		rte_compiler_barrier();
+		rxcmp[0] = _mm_load_si128((void *)&cp_desc_ring[cons + 0]);
+
+		tmp1 = _mm_unpackhi_epi32(rxcmp[2], rxcmp[3]);
+		tmp0 = _mm_unpackhi_epi32(rxcmp[0], rxcmp[1]);
+
+		/* Isolate descriptor valid flags. */
+		info3_v = _mm_and_si128(_mm_unpacklo_epi64(tmp0, tmp1),
+					info3_v_mask);
+		info3_v = _mm_xor_si128(info3_v, valid_target);
+
+		/*
+		 * Pack the 128-bit array of valid descriptor flags into 64
+		 * bits and count the number of set bits in order to determine
+		 * the number of valid descriptors.
+		 */
+		valid = _mm_cvtsi128_si64(_mm_packs_epi32(info3_v, info3_v));
+		num_valid = __builtin_popcountll(valid & desc_valid_mask);
+
+		if (num_valid == 0)
+			break;
+
+		descs_to_mbufs(rxcmp, rxcmp1, mbuf_init, shuf_msk, &rx_pkts[nb_rx_pkts],
+			       rxr);
+		nb_rx_pkts += num_valid;
+
+		if (num_valid < BNXT_RX_DESCS_PER_LOOP_VEC128)
+			break;
+	}
+
+	if (nb_rx_pkts) {
+		rxr->rx_raw_prod = RING_ADV(rxr->rx_raw_prod, nb_rx_pkts);
+
+		rxq->rxrearm_nb += nb_rx_pkts;
+		cpr->cp_raw_cons += nb_rx_pkts;
+		bnxt_db_cq(cpr);
+	}
+
+	return nb_rx_pkts;
+}
+
 uint16_t
 bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 {
@@ -304,6 +432,27 @@ bnxt_recv_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
 	return cnt + recv_burst_vec_sse(rx_queue, rx_pkts + cnt, nb_pkts);
 }
 
+uint16_t
+bnxt_crx_pkts_vec(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t nb_pkts)
+{
+	uint16_t cnt = 0;
+
+	while (nb_pkts > RTE_BNXT_MAX_RX_BURST) {
+		uint16_t burst;
+
+		burst = crx_burst_vec_sse(rx_queue, rx_pkts + cnt,
+					   RTE_BNXT_MAX_RX_BURST);
+
+		cnt += burst;
+		nb_pkts -= burst;
+
+		if (burst < RTE_BNXT_MAX_RX_BURST)
+			return cnt;
+	}
+
+	return cnt + crx_burst_vec_sse(rx_queue, rx_pkts + cnt, nb_pkts);
+}
+
 static void
 bnxt_handle_tx_cp_vec(struct bnxt_tx_queue *txq)
 {
-- 
2.39.2 (Apple Git-143)


[-- Attachment #2: S/MIME Cryptographic Signature --]
[-- Type: application/pkcs7-signature, Size: 4218 bytes --]

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

end of thread, other threads:[~2023-12-21 18:08 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-12-21 18:05 [PATCH 00/18] bnxt patchset Ajit Khaparde
2023-12-21 18:05 ` [PATCH 01/18] net/bnxt: add support for UDP GSO Ajit Khaparde
2023-12-21 18:05 ` [PATCH 02/18] net/bnxt: add support for compressed Rx CQE Ajit Khaparde
2023-12-21 18:05 ` [PATCH 03/18] net/bnxt: fix a typo while parsing link speed Ajit Khaparde
2023-12-21 18:05 ` [PATCH 04/18] net/bnxt: fix setting 50G and 100G forced speed Ajit Khaparde
2023-12-21 18:05 ` [PATCH 05/18] net/bnxt: fix speed change from 200G to 25G on Thor Ajit Khaparde
2023-12-21 18:05 ` [PATCH 06/18] net/bnxt: support backward compatibility Ajit Khaparde
2023-12-21 18:05 ` [PATCH 07/18] net/bnxt: reattempt mbuf allocation for Rx and AGG rings Ajit Khaparde
2023-12-21 18:05 ` [PATCH 08/18] net/bnxt: refactor Rx doorbell during Rx flush Ajit Khaparde
2023-12-21 18:05 ` [PATCH 09/18] net/bnxt: extend RSS hash support for P7 devices Ajit Khaparde
2023-12-21 18:05 ` [PATCH 10/18] net/bnxt: add flow query callback Ajit Khaparde
2023-12-21 18:05 ` [PATCH 11/18] net/bnxt: add ESP and AH header based RSS support Ajit Khaparde
2023-12-21 18:05 ` [PATCH 12/18] net/bnxt: set allmulti mode if multicast filter fails Ajit Khaparde
2023-12-21 18:05 ` [PATCH 13/18] net/bnxt: add VF FLR async event handler Ajit Khaparde
2023-12-21 18:05 ` [PATCH 14/18] net/bnxt: add tunnel TPA support Ajit Khaparde
2023-12-21 18:05 ` [PATCH 15/18] net/bnxt: add 400G get support for P7 devices Ajit Khaparde
2023-12-21 18:05 ` [PATCH 16/18] net/bnxt: query extended stats from firmware Ajit Khaparde
2023-12-21 18:05 ` [PATCH 17/18] net/bnxt: add AVX2 support for compressed CQE Ajit Khaparde
2023-12-21 18:05 ` [PATCH 18/18] net/bnxt: enable SSE mode " Ajit Khaparde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).