[v2,3/9] net/bnxt: add support for LRO on thor adapters
diff mbox series

Message ID 20191004034903.85233-4-ajit.khaparde@broadcom.com
State Accepted, archived
Delegated to: Ferruh Yigit
Headers show
Series
  • bnxt patchset
Related show

Checks

Context Check Description
ci/checkpatch success coding style OK
ci/Intel-compilation success Compilation OK

Commit Message

Ajit Khaparde Oct. 4, 2019, 3:48 a.m. UTC
From: Lance Richardson <lance.richardson@broadcom.com>

Add support for LRO for adapters based on Thor (BCM57508).

Reviewed-by: Kalesh Anakkur Purayil <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Lance Richardson <lance.richardson@broadcom.com>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
---
 drivers/net/bnxt/bnxt.h        | 16 ++++++++
 drivers/net/bnxt/bnxt_ethdev.c |  4 ++
 drivers/net/bnxt/bnxt_hwrm.c   | 33 +++++++++++++---
 drivers/net/bnxt/bnxt_hwrm.h   |  1 +
 drivers/net/bnxt/bnxt_ring.c   | 14 ++++---
 drivers/net/bnxt/bnxt_ring.h   |  1 -
 drivers/net/bnxt/bnxt_rxq.c    |  4 +-
 drivers/net/bnxt/bnxt_rxr.c    | 72 +++++++++++++++++++++++++---------
 drivers/net/bnxt/bnxt_rxr.h    | 41 +++++++++++++++----
 9 files changed, 149 insertions(+), 37 deletions(-)

Patch
diff mbox series

diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index c34582c0ad..ad97e0e593 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -37,6 +37,21 @@ 
 #define BNXT_MAX_RX_RING_DESC	8192
 #define BNXT_DB_SIZE		0x80
 
+#define TPA_MAX_AGGS		64
+#define TPA_MAX_AGGS_TH		1024
+
+#define TPA_MAX_NUM_SEGS	32
+#define TPA_MAX_SEGS_TH		8 /* 32 segments in 4-segment units */
+#define TPA_MAX_SEGS		5 /* 32 segments in log2 units */
+
+#define BNXT_TPA_MAX_AGGS(bp) \
+	(BNXT_CHIP_THOR(bp) ? TPA_MAX_AGGS_TH : \
+			     TPA_MAX_AGGS)
+
+#define BNXT_TPA_MAX_SEGS(bp) \
+	(BNXT_CHIP_THOR(bp) ? TPA_MAX_SEGS_TH : \
+			      TPA_MAX_SEGS)
+
 #ifdef RTE_ARCH_ARM64
 #define BNXT_NUM_ASYNC_CPR(bp) (BNXT_STINGRAY(bp) ? 0 : 1)
 #else
@@ -525,6 +540,7 @@  struct bnxt {
 	uint16_t		max_rx_em_flows;
 	uint16_t		max_vnics;
 	uint16_t		max_stat_ctx;
+	uint16_t		max_tpa_v2;
 	uint16_t		first_vf_id;
 	uint16_t		vlan;
 #define BNXT_OUTER_TPID_MASK	0x0000ffff
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index 0e893cc956..4fc182b8cc 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -4553,6 +4553,10 @@  static int bnxt_init_fw(struct bnxt *bp)
 	if (rc)
 		return rc;
 
+	rc = bnxt_hwrm_vnic_qcaps(bp);
+	if (rc)
+		return rc;
+
 	rc = bnxt_hwrm_func_qcfg(bp, &mtu);
 	if (rc)
 		return rc;
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index 011cd05ae0..9f30214c99 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -700,6 +700,27 @@  int bnxt_hwrm_func_qcaps(struct bnxt *bp)
 	return rc;
 }
 
+int bnxt_hwrm_vnic_qcaps(struct bnxt *bp)
+{
+	int rc = 0;
+	struct hwrm_vnic_qcaps_input req = {.req_type = 0 };
+	struct hwrm_vnic_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+
+	HWRM_PREP(req, VNIC_QCAPS, BNXT_USE_CHIMP_MB);
+
+	req.target_id = rte_cpu_to_le_16(0xffff);
+
+	rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+	HWRM_CHECK_RESULT();
+
+	bp->max_tpa_v2 = rte_le_to_cpu_16(resp->max_aggs_supported);
+
+	HWRM_UNLOCK();
+
+	return rc;
+}
+
 int bnxt_hwrm_func_reset(struct bnxt *bp)
 {
 	int rc = 0;
@@ -1959,8 +1980,11 @@  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_CHIP_THOR(bp))
-		return 0;
+	if (BNXT_CHIP_THOR(bp) && !bp->max_tpa_v2) {
+		if (enable)
+			PMD_DRV_LOG(ERR, "No HW support for LRO\n");
+		return -ENOTSUP;
+	}
 
 	if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
 		PMD_DRV_LOG(DEBUG, "Invalid vNIC ID\n");
@@ -1981,9 +2005,8 @@  int bnxt_hwrm_vnic_tpa_cfg(struct bnxt *bp,
 				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_GRO |
 				HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_ECN |
 			HWRM_VNIC_TPA_CFG_INPUT_FLAGS_AGG_WITH_SAME_GRE_SEQ);
-		req.max_agg_segs = rte_cpu_to_le_16(5);
-		req.max_aggs =
-			rte_cpu_to_le_16(HWRM_VNIC_TPA_CFG_INPUT_MAX_AGGS_MAX);
+		req.max_agg_segs = rte_cpu_to_le_16(BNXT_TPA_MAX_AGGS(bp));
+		req.max_aggs = rte_cpu_to_le_16(BNXT_TPA_MAX_SEGS(bp));
 		req.min_agg_len = rte_cpu_to_le_32(512);
 	}
 	req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 07181d4020..8912a4ed3e 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -110,6 +110,7 @@  int bnxt_hwrm_vnic_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic);
 int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
 				int16_t fw_vf_id);
+int bnxt_hwrm_vnic_qcaps(struct bnxt *bp);
 int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic,
 			     uint16_t ctx_idx);
 int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic);
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 4662e94132..14cfb8c155 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c
@@ -187,13 +187,17 @@  int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx,
 			AGG_RING_SIZE_FACTOR)) : 0;
 
 	int tpa_info_start = ag_bitmap_start + ag_bitmap_len;
-	int tpa_info_len = rx_ring_info ?
-		RTE_CACHE_LINE_ROUNDUP(BNXT_TPA_MAX *
-				       sizeof(struct bnxt_tpa_info)) : 0;
+	int tpa_info_len = 0;
+
+	if (rx_ring_info && (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO)) {
+		int tpa_max = BNXT_TPA_MAX_AGGS(bp);
+
+		tpa_info_len = tpa_max * sizeof(struct bnxt_tpa_info);
+		tpa_info_len = RTE_CACHE_LINE_ROUNDUP(tpa_info_len);
+	}
 
 	int total_alloc_len = tpa_info_start;
-	if (rx_offloads & DEV_RX_OFFLOAD_TCP_LRO)
-		total_alloc_len += tpa_info_len;
+	total_alloc_len += tpa_info_len;
 
 	snprintf(mz_name, RTE_MEMZONE_NAMESIZE,
 		 "bnxt_%04x:%02x:%02x:%02x-%04x_%s", pdev->addr.domain,
diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h
index a31d59ea39..a5d5106986 100644
--- a/drivers/net/bnxt/bnxt_ring.h
+++ b/drivers/net/bnxt/bnxt_ring.h
@@ -27,7 +27,6 @@ 
 #define DEFAULT_RX_RING_SIZE	256
 #define DEFAULT_TX_RING_SIZE	256
 
-#define BNXT_TPA_MAX		64
 #define AGG_RING_SIZE_FACTOR	2
 #define AGG_RING_MULTIPLIER	2
 
diff --git a/drivers/net/bnxt/bnxt_rxq.c b/drivers/net/bnxt/bnxt_rxq.c
index 371534db6b..03b115dbaf 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -227,7 +227,9 @@  void bnxt_rx_queue_release_mbufs(struct bnxt_rx_queue *rxq)
 	/* Free up mbufs in TPA */
 	tpa_info = rxq->rx_ring->tpa_info;
 	if (tpa_info) {
-		for (i = 0; i < BNXT_TPA_MAX; i++) {
+		int max_aggs = BNXT_TPA_MAX_AGGS(rxq->bp);
+
+		for (i = 0; i < max_aggs; i++) {
 			if (tpa_info[i].mbuf) {
 				rte_pktmbuf_free_seg(tpa_info[i].mbuf);
 				tpa_info[i].mbuf = NULL;
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index b3cc0d8a04..1a6fb7944b 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -124,12 +124,13 @@  static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
 			   struct rx_tpa_start_cmpl_hi *tpa_start1)
 {
 	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
-	uint8_t agg_id = rte_le_to_cpu_32(tpa_start->agg_id &
-		RX_TPA_START_CMPL_AGG_ID_MASK) >> RX_TPA_START_CMPL_AGG_ID_SFT;
+	uint16_t agg_id;
 	uint16_t data_cons;
 	struct bnxt_tpa_info *tpa_info;
 	struct rte_mbuf *mbuf;
 
+	agg_id = bnxt_tpa_start_agg_id(rxq->bp, tpa_start);
+
 	data_cons = tpa_start->opaque;
 	tpa_info = &rxr->tpa_info[agg_id];
 
@@ -137,6 +138,7 @@  static void bnxt_tpa_start(struct bnxt_rx_queue *rxq,
 
 	bnxt_reuse_rx_mbuf(rxr, tpa_info->mbuf);
 
+	tpa_info->agg_count = 0;
 	tpa_info->mbuf = mbuf;
 	tpa_info->len = rte_le_to_cpu_32(tpa_start->len);
 
@@ -206,7 +208,7 @@  static int bnxt_prod_ag_mbuf(struct bnxt_rx_queue *rxq)
 
 static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
 			 struct rte_mbuf *mbuf, uint32_t *tmp_raw_cons,
-			 uint8_t agg_buf)
+			 uint8_t agg_buf, struct bnxt_tpa_info *tpa_info)
 {
 	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
 	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
@@ -214,14 +216,20 @@  static int bnxt_rx_pages(struct bnxt_rx_queue *rxq,
 	uint16_t cp_cons, ag_cons;
 	struct rx_pkt_cmpl *rxcmp;
 	struct rte_mbuf *last = mbuf;
+	bool is_thor_tpa = tpa_info && BNXT_CHIP_THOR(rxq->bp);
 
 	for (i = 0; i < agg_buf; i++) {
 		struct bnxt_sw_rx_bd *ag_buf;
 		struct rte_mbuf *ag_mbuf;
-		*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
-		cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
-		rxcmp = (struct rx_pkt_cmpl *)
+
+		if (is_thor_tpa) {
+			rxcmp = (void *)&tpa_info->agg_arr[i];
+		} else {
+			*tmp_raw_cons = NEXT_RAW_CMP(*tmp_raw_cons);
+			cp_cons = RING_CMP(cpr->cp_ring_struct, *tmp_raw_cons);
+			rxcmp = (struct rx_pkt_cmpl *)
 					&cpr->cp_desc_ring[cp_cons];
+		}
 
 #ifdef BNXT_DEBUG
 		bnxt_dump_cmpl(cp_cons, rxcmp);
@@ -258,29 +266,42 @@  static inline struct rte_mbuf *bnxt_tpa_end(
 		struct bnxt_rx_queue *rxq,
 		uint32_t *raw_cp_cons,
 		struct rx_tpa_end_cmpl *tpa_end,
-		struct rx_tpa_end_cmpl_hi *tpa_end1 __rte_unused)
+		struct rx_tpa_end_cmpl_hi *tpa_end1)
 {
 	struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
 	struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
-	uint8_t agg_id = (tpa_end->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK)
-			>> RX_TPA_END_CMPL_AGG_ID_SFT;
+	uint16_t agg_id;
 	struct rte_mbuf *mbuf;
 	uint8_t agg_bufs;
+	uint8_t payload_offset;
 	struct bnxt_tpa_info *tpa_info;
 
+	if (BNXT_CHIP_THOR(rxq->bp)) {
+		struct rx_tpa_v2_end_cmpl *th_tpa_end;
+		struct rx_tpa_v2_end_cmpl_hi *th_tpa_end1;
+
+		th_tpa_end = (void *)tpa_end;
+		th_tpa_end1 = (void *)tpa_end1;
+		agg_id = BNXT_TPA_END_AGG_ID_TH(th_tpa_end);
+		agg_bufs = BNXT_TPA_END_AGG_BUFS_TH(th_tpa_end1);
+		payload_offset = th_tpa_end1->payload_offset;
+	} else {
+		agg_id = BNXT_TPA_END_AGG_ID(tpa_end);
+		agg_bufs = BNXT_TPA_END_AGG_BUFS(tpa_end);
+		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
+			return NULL;
+		payload_offset = tpa_end->payload_offset;
+	}
+
 	tpa_info = &rxr->tpa_info[agg_id];
 	mbuf = tpa_info->mbuf;
 	RTE_ASSERT(mbuf != NULL);
 
 	rte_prefetch0(mbuf);
-	agg_bufs = (rte_le_to_cpu_32(tpa_end->agg_bufs_v1) &
-		RX_TPA_END_CMPL_AGG_BUFS_MASK) >> RX_TPA_END_CMPL_AGG_BUFS_SFT;
 	if (agg_bufs) {
-		if (!bnxt_agg_bufs_valid(cpr, agg_bufs, *raw_cp_cons))
-			return NULL;
-		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs);
+		bnxt_rx_pages(rxq, mbuf, raw_cp_cons, agg_bufs, tpa_info);
 	}
-	mbuf->l4_len = tpa_end->payload_offset;
+	mbuf->l4_len = payload_offset;
 
 	struct rte_mbuf *new_data = __bnxt_alloc_rx_data(rxq->mb_pool);
 	RTE_ASSERT(new_data != NULL);
@@ -395,6 +416,20 @@  static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	rxcmp = (struct rx_pkt_cmpl *)
 	    &cpr->cp_desc_ring[cp_cons];
 
+	cmp_type = CMP_TYPE(rxcmp);
+
+	if (cmp_type == RX_TPA_V2_ABUF_CMPL_TYPE_RX_TPA_AGG) {
+		struct rx_tpa_v2_abuf_cmpl *rx_agg = (void *)rxcmp;
+		uint16_t agg_id = rte_cpu_to_le_16(rx_agg->agg_id);
+		struct bnxt_tpa_info *tpa_info;
+
+		tpa_info = &rxr->tpa_info[agg_id];
+		RTE_ASSERT(tpa_info->agg_count < 16);
+		tpa_info->agg_arr[tpa_info->agg_count++] = *rx_agg;
+		rc = -EINVAL; /* Continue w/o new mbuf */
+		goto next_rx;
+	}
+
 	tmp_raw_cons = NEXT_RAW_CMP(tmp_raw_cons);
 	cp_cons = RING_CMP(cpr->cp_ring_struct, tmp_raw_cons);
 	rxcmp1 = (struct rx_pkt_cmpl_hi *)&cpr->cp_desc_ring[cp_cons];
@@ -406,7 +441,6 @@  static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 				cpr->cp_ring_struct->ring_mask,
 				cpr->valid);
 
-	cmp_type = CMP_TYPE(rxcmp);
 	if (cmp_type == RX_TPA_START_CMPL_TYPE_RX_TPA_START) {
 		bnxt_tpa_start(rxq, (struct rx_tpa_start_cmpl *)rxcmp,
 			       (struct rx_tpa_start_cmpl_hi *)rxcmp1);
@@ -463,7 +497,7 @@  static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 	}
 #endif
 	if (agg_buf)
-		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf);
+		bnxt_rx_pages(rxq, mbuf, &tmp_raw_cons, agg_buf, NULL);
 
 	if (rxcmp1->flags2 & RX_PKT_CMPL_FLAGS2_META_FORMAT_VLAN) {
 		mbuf->vlan_tci = rxcmp1->metadata &
@@ -861,7 +895,9 @@  int bnxt_init_one_rx_ring(struct bnxt_rx_queue *rxq)
 	PMD_DRV_LOG(DEBUG, "AGG Done!\n");
 
 	if (rxr->tpa_info) {
-		for (i = 0; i < BNXT_TPA_MAX; i++) {
+		unsigned int max_aggs = BNXT_TPA_MAX_AGGS(rxq->bp);
+
+		for (i = 0; i < max_aggs; i++) {
 			rxr->tpa_info[i].mbuf =
 				__bnxt_alloc_rx_data(rxq->mb_pool);
 			if (!rxr->tpa_info[i].mbuf) {
diff --git a/drivers/net/bnxt/bnxt_rxr.h b/drivers/net/bnxt/bnxt_rxr.h
index 493b754066..76bf88d707 100644
--- a/drivers/net/bnxt/bnxt_rxr.h
+++ b/drivers/net/bnxt/bnxt_rxr.h
@@ -5,6 +5,7 @@ 
 
 #ifndef _BNXT_RXR_H_
 #define _BNXT_RXR_H_
+#include "hsi_struct_def_dpdk.h"
 
 #define B_RX_DB(db, prod)						\
 		(*(uint32_t *)db = (DB_KEY_RX | (prod)))
@@ -110,6 +111,36 @@ 
 		IS_L4_TUNNEL_PKT_ONLY_INNER_L4_CS(flags2_f)	\
 	)
 
+#define BNXT_TPA_START_AGG_ID_PRE_TH(cmp) \
+	((rte_le_to_cpu_16((cmp)->agg_id) & RX_TPA_START_CMPL_AGG_ID_MASK) >> \
+	 RX_TPA_START_CMPL_AGG_ID_SFT)
+
+#define BNXT_TPA_START_AGG_ID_TH(cmp) \
+	rte_le_to_cpu_16((cmp)->agg_id)
+
+static inline uint16_t bnxt_tpa_start_agg_id(struct bnxt *bp,
+					     struct rx_tpa_start_cmpl *cmp)
+{
+	if (BNXT_CHIP_THOR(bp))
+		return BNXT_TPA_START_AGG_ID_TH(cmp);
+	else
+		return BNXT_TPA_START_AGG_ID_PRE_TH(cmp);
+}
+
+#define BNXT_TPA_END_AGG_BUFS(cmp) \
+	(((cmp)->agg_bufs_v1 & RX_TPA_END_CMPL_AGG_BUFS_MASK) \
+	 >> RX_TPA_END_CMPL_AGG_BUFS_SFT)
+
+#define BNXT_TPA_END_AGG_BUFS_TH(cmp) \
+	((cmp)->tpa_agg_bufs)
+
+#define BNXT_TPA_END_AGG_ID(cmp) \
+	(((cmp)->agg_id & RX_TPA_END_CMPL_AGG_ID_MASK) >> \
+	 RX_TPA_END_CMPL_AGG_ID_SFT)
+
+#define BNXT_TPA_END_AGG_ID_TH(cmp) \
+	rte_le_to_cpu_16((cmp)->agg_id)
+
 #define RX_CMP_L4_CS_BITS	\
 	rte_cpu_to_le_32(RX_PKT_CMPL_FLAGS2_L4_CS_CALC)
 
@@ -144,14 +175,10 @@  enum pkt_hash_types {
 };
 
 struct bnxt_tpa_info {
-	struct rte_mbuf		*mbuf;
+	struct rte_mbuf			*mbuf;
 	uint16_t			len;
-	unsigned short		gso_type;
-	uint32_t			flags2;
-	uint32_t			metadata;
-	enum pkt_hash_types	hash_type;
-	uint32_t			rss_hash;
-	uint32_t			hdr_info;
+	uint32_t			agg_count;
+	struct rx_tpa_v2_abuf_cmpl	agg_arr[TPA_MAX_NUM_SEGS];
 };
 
 struct bnxt_sw_rx_bd {