From: Lance Richardson Date: Fri, 4 Oct 2019 03:48:57 +0000 (-0700) Subject: net/bnxt: support LRO on Thor adapters X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=b150a7e7ee66;p=dpdk.git net/bnxt: support LRO on Thor adapters Add support for LRO for adapters based on Thor (BCM57508). Reviewed-by: Kalesh AP Signed-off-by: Lance Richardson Signed-off-by: Ajit Khaparde --- 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 b4c114de86..7b6d87c334 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 {