diff --git a/doc/guides/rel_notes/release_19_11.rst b/doc/guides/rel_notes/release_19_11.rst
index 27cfbd9e3..a044db46f 100644
--- a/doc/guides/rel_notes/release_19_11.rst
+++ b/doc/guides/rel_notes/release_19_11.rst
@@ -56,6 +56,12 @@ New Features
      Also, make sure to start the actual text at the margin.
      =========================================================
 
+* **Updated the Broadcom bnxt PMD.**
+
+  Updated the Broadcom bnxt PMD. The major enhancements include:
+
+  * Added LRO support for BCM57500 adapters.
+
 
 Removed Items
 -------------
diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h
index 3e508ca1f..6da5126a8 100644
--- a/drivers/net/bnxt/bnxt.h
+++ b/drivers/net/bnxt/bnxt.h
@@ -34,6 +34,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
@@ -506,6 +521,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;
 	struct bnxt_pf_info	pf;
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index c2ab8df7b..227960d4e 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c
@@ -4303,6 +4303,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 4d8866ac1..404e52491 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c
@@ -656,6 +656,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;
@@ -1878,8 +1899,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;
+	}
 
 	HWRM_PREP(req, VNIC_TPA_CFG, BNXT_USE_CHIMP_MB);
 
@@ -1895,9 +1919,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 db25ad591..a26698ce3 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h
@@ -105,6 +105,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 85a10c584..77a3c8ba1 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 200d85532..833118391 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 eb45436c3..d2f899106 100644
--- a/drivers/net/bnxt/bnxt_rxq.c
+++ b/drivers/net/bnxt/bnxt_rxq.c
@@ -235,7 +235,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 95750367d..3b98e26d8 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c
@@ -121,12 +121,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];
 
@@ -134,6 +135,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);
 
@@ -203,7 +205,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;
@@ -211,14 +213,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);
@@ -255,29 +263,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);
@@ -367,6 +388,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];
@@ -378,7 +413,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);
@@ -431,7 +465,7 @@ static int bnxt_rx_pkt(struct rte_mbuf **rx_pkt,
 		mbuf->ol_flags |= PKT_RX_IEEE1588_PTP | PKT_RX_IEEE1588_TMST;
 
 	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 &
@@ -806,7 +840,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 493b75406..76bf88d70 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 {
