net/bnxt: support LRO on Thor adapters
authorLance Richardson <lance.richardson@broadcom.com>
Fri, 4 Oct 2019 03:48:57 +0000 (20:48 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 8 Oct 2019 10:14:32 +0000 (12:14 +0200)
Add support for LRO for adapters based on Thor (BCM57508).

Reviewed-by: Kalesh AP <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
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_hwrm.h
drivers/net/bnxt/bnxt_ring.c
drivers/net/bnxt/bnxt_ring.h
drivers/net/bnxt/bnxt_rxq.c
drivers/net/bnxt/bnxt_rxr.c
drivers/net/bnxt/bnxt_rxr.h

index c34582c..ad97e0e 100644 (file)
 #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
index 0e893cc..4fc182b 100644 (file)
@@ -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;
index 011cd05..9f30214 100644 (file)
@@ -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);
index 07181d4..8912a4e 100644 (file)
@@ -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);
index b4c114d..7b6d87c 100644 (file)
@@ -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,
index a31d59e..a5d5106 100644 (file)
@@ -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
 
index 371534d..03b115d 100644 (file)
@@ -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;
index b3cc0d8..1a6fb79 100644 (file)
@@ -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) {
index 493b754..76bf88d 100644 (file)
@@ -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)))
                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 {