net/bnxt: use dedicated CPR for async events
[dpdk.git] / drivers / net / bnxt / bnxt_hwrm.c
index 29f2701..6437747 100644 (file)
@@ -152,14 +152,11 @@ static int bnxt_hwrm_send_message(struct bnxt *bp, void *msg,
        }
 
        if (i >= HWRM_CMD_TIMEOUT) {
-               PMD_DRV_LOG(ERR, "Error sending msg 0x%04x\n",
-                       req->req_type);
-               goto err_ret;
+               PMD_DRV_LOG(ERR, "Error(timeout) sending msg 0x%04x\n",
+                           req->req_type);
+               return -ETIMEDOUT;
        }
        return 0;
-
-err_ret:
-       return -1;
 }
 
 /*
@@ -589,7 +586,10 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
        bp->max_cp_rings = rte_le_to_cpu_16(resp->max_cmpl_rings);
        bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
        bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
-       bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+       bp->first_vf_id = rte_le_to_cpu_16(resp->first_vf_id);
+       bp->max_rx_em_flows = rte_le_to_cpu_16(resp->max_rx_em_flows);
+       bp->max_l2_ctx =
+               rte_le_to_cpu_16(resp->max_l2_ctxs) + bp->max_rx_em_flows;
        /* TODO: For now, do not support VMDq/RFS on VFs. */
        if (BNXT_PF(bp)) {
                if (bp->pf.max_vfs)
@@ -610,6 +610,9 @@ static int __bnxt_hwrm_func_qcaps(struct bnxt *bp)
                }
        }
 
+       if (flags & HWRM_FUNC_QCAPS_OUTPUT_FLAGS_EXT_STATS_SUPPORTED)
+               bp->flags |= BNXT_FLAG_EXT_STATS_SUPPORTED;
+
        HWRM_UNLOCK();
 
        return rc;
@@ -734,9 +737,12 @@ int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test)
        req.num_tx_rings = rte_cpu_to_le_16(bp->tx_nr_rings);
        req.num_rx_rings = rte_cpu_to_le_16(bp->rx_nr_rings *
                                            AGG_RING_MULTIPLIER);
-       req.num_stat_ctxs = rte_cpu_to_le_16(bp->rx_nr_rings + bp->tx_nr_rings);
+       req.num_stat_ctxs = rte_cpu_to_le_16(bp->rx_nr_rings +
+                                            bp->tx_nr_rings +
+                                            BNXT_NUM_ASYNC_CPR(bp));
        req.num_cmpl_rings = rte_cpu_to_le_16(bp->rx_nr_rings +
-                                             bp->tx_nr_rings);
+                                             bp->tx_nr_rings +
+                                             BNXT_NUM_ASYNC_CPR(bp));
        req.num_vnics = rte_cpu_to_le_16(bp->rx_nr_rings);
        if (bp->vf_resv_strategy ==
            HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC) {
@@ -792,7 +798,12 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp)
                bp->max_tx_rings = rte_le_to_cpu_16(resp->max_tx_rings);
                bp->max_rx_rings = rte_le_to_cpu_16(resp->max_rx_rings);
                bp->max_ring_grps = rte_le_to_cpu_32(resp->max_hw_ring_grps);
-               bp->max_l2_ctx = rte_le_to_cpu_16(resp->max_l2_ctxs);
+               /* func_resource_qcaps does not return max_rx_em_flows.
+                * So use the value provided by func_qcaps.
+                */
+               bp->max_l2_ctx =
+                       rte_le_to_cpu_16(resp->max_l2_ctxs) +
+                       bp->max_rx_em_flows;
                bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics);
                bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx);
        }
@@ -877,7 +888,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
                rte_mem_lock_page(bp->hwrm_cmd_resp_addr);
                bp->hwrm_cmd_resp_dma_addr =
                        rte_mem_virt2iova(bp->hwrm_cmd_resp_addr);
-               if (bp->hwrm_cmd_resp_dma_addr == 0) {
+               if (bp->hwrm_cmd_resp_dma_addr == RTE_BAD_IOVA) {
                        PMD_DRV_LOG(ERR,
                        "Unable to map response buffer to physical memory.\n");
                        rc = -ENOMEM;
@@ -914,7 +925,7 @@ int bnxt_hwrm_ver_get(struct bnxt *bp)
                rte_mem_lock_page(bp->hwrm_short_cmd_req_addr);
                bp->hwrm_short_cmd_req_dma_addr =
                        rte_mem_virt2iova(bp->hwrm_short_cmd_req_addr);
-               if (bp->hwrm_short_cmd_req_dma_addr == 0) {
+               if (bp->hwrm_short_cmd_req_dma_addr == RTE_BAD_IOVA) {
                        rte_free(bp->hwrm_short_cmd_req_addr);
                        PMD_DRV_LOG(ERR,
                                "Unable to map buffer to physical memory.\n");
@@ -1206,7 +1217,7 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp,
                PMD_DRV_LOG(ERR, "hwrm alloc invalid ring type %d\n",
                        ring_type);
                HWRM_UNLOCK();
-               return -1;
+               return -EINVAL;
        }
        req.enables = rte_cpu_to_le_32(enables);
 
@@ -1486,6 +1497,11 @@ static int bnxt_hwrm_vnic_plcmodes_cfg(struct bnxt *bp,
        struct hwrm_vnic_plcmodes_cfg_input req = {.req_type = 0 };
        struct hwrm_vnic_plcmodes_cfg_output *resp = bp->hwrm_cmd_resp_addr;
 
+       if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+               PMD_DRV_LOG(DEBUG, "VNIC ID %x\n", vnic->fw_vnic_id);
+               return rc;
+       }
+
        HWRM_PREP(req, VNIC_PLCMODES_CFG, BNXT_USE_CHIMP_MB);
 
        req.vnic_id = rte_cpu_to_le_16(vnic->fw_vnic_id);
@@ -1512,8 +1528,8 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
        int rc = 0;
        struct hwrm_vnic_cfg_input req = {.req_type = 0 };
        struct hwrm_vnic_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+       struct bnxt_plcmodes_cfg pmodes = { 0 };
        uint32_t ctx_enable_flag = 0;
-       struct bnxt_plcmodes_cfg pmodes;
        uint32_t enables = 0;
 
        if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
@@ -1530,7 +1546,7 @@ int bnxt_hwrm_vnic_cfg(struct bnxt *bp, struct bnxt_vnic_info *vnic)
        if (BNXT_CHIP_THOR(bp)) {
                struct bnxt_rx_queue *rxq = bp->eth_dev->data->rx_queues[0];
                struct bnxt_rx_ring_info *rxr = rxq->rx_ring;
-               struct bnxt_cp_ring_info *cpr = bp->def_cp_ring;
+               struct bnxt_cp_ring_info *cpr = rxq->cp_ring;
 
                req.default_rx_ring_id =
                        rte_cpu_to_le_16(rxr->rx_ring_struct->fw_ring_id);
@@ -1638,9 +1654,11 @@ int bnxt_hwrm_vnic_qcfg(struct bnxt *bp, struct bnxt_vnic_info *vnic,
        return rc;
 }
 
-int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp,
+                            struct bnxt_vnic_info *vnic, uint16_t ctx_idx)
 {
        int rc = 0;
+       uint16_t ctx_id;
        struct hwrm_vnic_rss_cos_lb_ctx_alloc_input req = {.req_type = 0 };
        struct hwrm_vnic_rss_cos_lb_ctx_alloc_output *resp =
                                                bp->hwrm_cmd_resp_addr;
@@ -1648,38 +1666,40 @@ int bnxt_hwrm_vnic_ctx_alloc(struct bnxt *bp, struct bnxt_vnic_info *vnic)
        HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_ALLOC, BNXT_USE_CHIMP_MB);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
-
        HWRM_CHECK_RESULT();
 
-       vnic->rss_rule = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+       ctx_id = rte_le_to_cpu_16(resp->rss_cos_lb_ctx_id);
+       if (!BNXT_HAS_RING_GRPS(bp))
+               vnic->fw_grp_ids[ctx_idx] = ctx_id;
+       else if (ctx_idx == 0)
+               vnic->rss_rule = ctx_id;
+
        HWRM_UNLOCK();
-       PMD_DRV_LOG(DEBUG, "VNIC RSS Rule %x\n", vnic->rss_rule);
 
        return rc;
 }
 
-int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+int bnxt_hwrm_vnic_ctx_free(struct bnxt *bp,
+                           struct bnxt_vnic_info *vnic, uint16_t ctx_idx)
 {
        int rc = 0;
        struct hwrm_vnic_rss_cos_lb_ctx_free_input req = {.req_type = 0 };
        struct hwrm_vnic_rss_cos_lb_ctx_free_output *resp =
                                                bp->hwrm_cmd_resp_addr;
 
-       if (vnic->rss_rule == (uint16_t)HWRM_NA_SIGNATURE) {
+       if (ctx_idx == (uint16_t)HWRM_NA_SIGNATURE) {
                PMD_DRV_LOG(DEBUG, "VNIC RSS Rule %x\n", vnic->rss_rule);
                return rc;
        }
        HWRM_PREP(req, VNIC_RSS_COS_LB_CTX_FREE, BNXT_USE_CHIMP_MB);
 
-       req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(vnic->rss_rule);
+       req.rss_cos_lb_ctx_id = rte_cpu_to_le_16(ctx_idx);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
 
        HWRM_CHECK_RESULT();
        HWRM_UNLOCK();
 
-       vnic->rss_rule = (uint16_t)HWRM_NA_SIGNATURE;
-
        return rc;
 }
 
@@ -1711,6 +1731,41 @@ int bnxt_hwrm_vnic_free(struct bnxt *bp, struct bnxt_vnic_info *vnic)
        return rc;
 }
 
+static int
+bnxt_hwrm_vnic_rss_cfg_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+       int i;
+       int rc = 0;
+       int nr_ctxs = vnic->num_lb_ctxts;
+       struct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };
+       struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+
+       for (i = 0; i < nr_ctxs; i++) {
+               HWRM_PREP(req, 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_mode_flags = vnic->hash_mode;
+
+               req.hash_key_tbl_addr =
+                       rte_cpu_to_le_64(vnic->rss_hash_key_dma_addr);
+
+               req.ring_grp_tbl_addr =
+                       rte_cpu_to_le_64(vnic->rss_table_dma_addr +
+                                        i * HW_HASH_INDEX_SIZE);
+               req.ring_table_pair_index = i;
+               req.rss_ctx_idx = rte_cpu_to_le_16(vnic->fw_grp_ids[i]);
+
+               rc = bnxt_hwrm_send_message(bp, &req, sizeof(req),
+                                           BNXT_USE_CHIMP_MB);
+
+               HWRM_CHECK_RESULT();
+               HWRM_UNLOCK();
+       }
+
+       return rc;
+}
+
 int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
                           struct bnxt_vnic_info *vnic)
 {
@@ -1718,6 +1773,12 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp,
        struct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };
        struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
 
+       if (!vnic->rss_table)
+               return 0;
+
+       if (BNXT_CHIP_THOR(bp))
+               return bnxt_hwrm_vnic_rss_cfg_thor(bp, vnic);
+
        HWRM_PREP(req, VNIC_RSS_CFG, BNXT_USE_CHIMP_MB);
 
        req.hash_type = rte_cpu_to_le_32(vnic->hash_type);
@@ -1955,7 +2016,8 @@ int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp)
                        cpr = bp->tx_queues[i - bp->rx_cp_nr_rings]->cp_ring;
                } else {
                        cpr = bp->rx_queues[i]->cp_ring;
-                       bp->grp_info[i].fw_stats_ctx = -1;
+                       if (BNXT_HAS_RING_GRPS(bp))
+                               bp->grp_info[i].fw_stats_ctx = -1;
                }
                if (cpr->hw_stats_ctx_id != HWRM_NA_SIGNATURE) {
                        rc = bnxt_hwrm_stat_ctx_free(bp, cpr, i);
@@ -2014,7 +2076,7 @@ int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp)
        return rc;
 }
 
-static void bnxt_free_nq_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
+void bnxt_free_nq_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
        struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
@@ -2024,9 +2086,10 @@ static void bnxt_free_nq_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
        memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *
                                     sizeof(*cpr->cp_desc_ring));
        cpr->cp_raw_cons = 0;
+       cpr->valid = 0;
 }
 
-static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
+void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
 {
        struct bnxt_ring *cp_ring = cpr->cp_ring_struct;
 
@@ -2036,6 +2099,7 @@ static void bnxt_free_cp_ring(struct bnxt *bp, struct bnxt_cp_ring_info *cpr)
        memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size *
                        sizeof(*cpr->cp_desc_ring));
        cpr->cp_raw_cons = 0;
+       cpr->valid = 0;
 }
 
 void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
@@ -2049,7 +2113,9 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
                bnxt_hwrm_ring_free(bp, ring,
                                    HWRM_RING_FREE_INPUT_RING_TYPE_RX);
                ring->fw_ring_id = INVALID_HW_RING_ID;
-               bp->grp_info[queue_index].rx_fw_ring_id = INVALID_HW_RING_ID;
+               if (BNXT_HAS_RING_GRPS(bp))
+                       bp->grp_info[queue_index].rx_fw_ring_id =
+                                                       INVALID_HW_RING_ID;
                memset(rxr->rx_desc_ring, 0,
                       rxr->rx_ring_struct->ring_size *
                       sizeof(*rxr->rx_desc_ring));
@@ -2069,7 +2135,9 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
                       rxr->ag_ring_struct->ring_size *
                       sizeof(*rxr->ag_buf_ring));
                rxr->ag_prod = 0;
-               bp->grp_info[queue_index].ag_fw_ring_id = INVALID_HW_RING_ID;
+               if (BNXT_HAS_RING_GRPS(bp))
+                       bp->grp_info[queue_index].ag_fw_ring_id =
+                                                       INVALID_HW_RING_ID;
        }
        if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) {
                bnxt_free_cp_ring(bp, cpr);
@@ -2077,7 +2145,8 @@ void bnxt_free_hwrm_rx_ring(struct bnxt *bp, int queue_index)
                        bnxt_free_nq_ring(bp, rxq->nq_ring);
        }
 
-       bp->grp_info[queue_index].cp_fw_ring_id = INVALID_HW_RING_ID;
+       if (BNXT_HAS_RING_GRPS(bp))
+               bp->grp_info[queue_index].cp_fw_ring_id = INVALID_HW_RING_ID;
 }
 
 int bnxt_free_all_hwrm_rings(struct bnxt *bp)
@@ -2158,7 +2227,7 @@ int bnxt_alloc_hwrm_resources(struct bnxt *bp)
                return -ENOMEM;
        bp->hwrm_cmd_resp_dma_addr =
                rte_mem_virt2iova(bp->hwrm_cmd_resp_addr);
-       if (bp->hwrm_cmd_resp_dma_addr == 0) {
+       if (bp->hwrm_cmd_resp_dma_addr == RTE_BAD_IOVA) {
                PMD_DRV_LOG(ERR,
                        "unable to map response address to physical memory\n");
                return -ENOMEM;
@@ -2247,7 +2316,7 @@ void bnxt_free_tunnel_ports(struct bnxt *bp)
 
 void bnxt_free_all_hwrm_resources(struct bnxt *bp)
 {
-       int i;
+       int i, j;
 
        if (bp->vnic_info == NULL)
                return;
@@ -2259,11 +2328,26 @@ void bnxt_free_all_hwrm_resources(struct bnxt *bp)
        for (i = bp->nr_vnics - 1; i >= 0; i--) {
                struct bnxt_vnic_info *vnic = &bp->vnic_info[i];
 
+               if (vnic->fw_vnic_id == INVALID_HW_RING_ID) {
+                       PMD_DRV_LOG(DEBUG, "Invalid vNIC ID\n");
+                       return;
+               }
+
                bnxt_clear_hwrm_vnic_flows(bp, vnic);
 
                bnxt_clear_hwrm_vnic_filters(bp, vnic);
 
-               bnxt_hwrm_vnic_ctx_free(bp, vnic);
+               if (BNXT_CHIP_THOR(bp)) {
+                       for (j = 0; j < vnic->num_lb_ctxts; j++) {
+                               bnxt_hwrm_vnic_ctx_free(bp, vnic,
+                                                       vnic->fw_grp_ids[j]);
+                               vnic->fw_grp_ids[j] = INVALID_HW_RING_ID;
+                       }
+                       vnic->num_lb_ctxts = 0;
+               } else {
+                       bnxt_hwrm_vnic_ctx_free(bp, vnic, vnic->rss_rule);
+                       vnic->rss_rule = INVALID_HW_RING_ID;
+               }
 
                bnxt_hwrm_vnic_tpa_cfg(bp, vnic, false);
 
@@ -2580,7 +2664,7 @@ error:
 }
 
 /* JIRA 22088 */
-int bnxt_hwrm_func_qcfg(struct bnxt *bp)
+int bnxt_hwrm_func_qcfg(struct bnxt *bp, uint16_t *mtu)
 {
        struct hwrm_func_qcfg_input req = {0};
        struct hwrm_func_qcfg_output *resp = bp->hwrm_cmd_resp_addr;
@@ -2605,6 +2689,9 @@ int bnxt_hwrm_func_qcfg(struct bnxt *bp)
                PMD_DRV_LOG(INFO, "Trusted VF cap enabled\n");
        }
 
+       if (mtu)
+               *mtu = resp->mtu;
+
        switch (resp->port_partition_type) {
        case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_0:
        case HWRM_FUNC_QCFG_OUTPUT_PORT_PARTITION_TYPE_NPAR1_5:
@@ -2801,14 +2888,7 @@ int bnxt_hwrm_func_qcfg_current_vf_vlan(struct bnxt *bp, int vf)
        HWRM_PREP(req, FUNC_QCFG, BNXT_USE_CHIMP_MB);
        req.fid = rte_cpu_to_le_16(bp->pf.vf_info[vf].fid);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
-       if (rc) {
-               PMD_DRV_LOG(ERR, "hwrm_func_qcfg failed rc:%d\n", rc);
-               return -1;
-       } else if (resp->error_code) {
-               rc = rte_le_to_cpu_16(resp->error_code);
-               PMD_DRV_LOG(ERR, "hwrm_func_qcfg error %d\n", rc);
-               return -1;
-       }
+       HWRM_CHECK_RESULT();
        rc = rte_le_to_cpu_16(resp->vlan);
 
        HWRM_UNLOCK();
@@ -2843,7 +2923,7 @@ int bnxt_hwrm_allocate_pf_only(struct bnxt *bp)
 
        if (!BNXT_PF(bp)) {
                PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n");
-               return -1;
+               return -EINVAL;
        }
 
        rc = bnxt_hwrm_func_qcaps(bp);
@@ -2871,7 +2951,7 @@ int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs)
 
        if (!BNXT_PF(bp)) {
                PMD_DRV_LOG(ERR, "Attempt to allcoate VFs on a VF!\n");
-               return -1;
+               return -EINVAL;
        }
 
        rc = bnxt_hwrm_func_qcaps(bp);
@@ -3090,7 +3170,7 @@ int bnxt_hwrm_func_buf_rgtr(struct bnxt *bp)
        req.req_buf_len = rte_cpu_to_le_16(HWRM_MAX_REQ_LEN);
        req.req_buf_page_addr0 =
                rte_cpu_to_le_64(rte_mem_virt2iova(bp->pf.vf_req_buf));
-       if (req.req_buf_page_addr0 == 0) {
+       if (req.req_buf_page_addr0 == RTE_BAD_IOVA) {
                PMD_DRV_LOG(ERR,
                        "unable to map buffer address to physical memory\n");
                return -ENOMEM;
@@ -3110,6 +3190,9 @@ int bnxt_hwrm_func_buf_unrgtr(struct bnxt *bp)
        struct hwrm_func_buf_unrgtr_input req = {.req_type = 0 };
        struct hwrm_func_buf_unrgtr_output *resp = bp->hwrm_cmd_resp_addr;
 
+       if (!(BNXT_PF(bp) && bp->pdev->max_vfs))
+               return 0;
+
        HWRM_PREP(req, FUNC_BUF_UNRGTR, BNXT_USE_CHIMP_MB);
 
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
@@ -3133,7 +3216,7 @@ int bnxt_hwrm_func_cfg_def_cp(struct bnxt *bp)
        req.enables = rte_cpu_to_le_32(
                        HWRM_FUNC_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
        req.async_event_cr = rte_cpu_to_le_16(
-                       bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+                       bp->async_cp_ring->cp_ring_struct->fw_ring_id);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
 
        HWRM_CHECK_RESULT();
@@ -3153,7 +3236,7 @@ int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp)
        req.enables = rte_cpu_to_le_32(
                        HWRM_FUNC_VF_CFG_INPUT_ENABLES_ASYNC_EVENT_CR);
        req.async_event_cr = rte_cpu_to_le_16(
-                       bp->def_cp_ring->cp_ring_struct->fw_ring_id);
+                       bp->async_cp_ring->cp_ring_struct->fw_ring_id);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
 
        HWRM_CHECK_RESULT();
@@ -3487,12 +3570,11 @@ int bnxt_hwrm_nvm_get_dir_info(struct bnxt *bp, uint32_t *entries,
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
 
        HWRM_CHECK_RESULT();
-       HWRM_UNLOCK();
 
-       if (!rc) {
-               *entries = rte_le_to_cpu_32(resp->entries);
-               *length = rte_le_to_cpu_32(resp->entry_length);
-       }
+       *entries = rte_le_to_cpu_32(resp->entries);
+       *length = rte_le_to_cpu_32(resp->entry_length);
+
+       HWRM_UNLOCK();
        return rc;
 }
 
@@ -3522,7 +3604,7 @@ int bnxt_get_nvram_directory(struct bnxt *bp, uint32_t len, uint8_t *data)
        if (buf == NULL)
                return -ENOMEM;
        dma_handle = rte_mem_virt2iova(buf);
-       if (dma_handle == 0) {
+       if (dma_handle == RTE_BAD_IOVA) {
                PMD_DRV_LOG(ERR,
                        "unable to map response address to physical memory\n");
                return -ENOMEM;
@@ -3557,7 +3639,7 @@ int bnxt_hwrm_get_nvram_item(struct bnxt *bp, uint32_t index,
                return -ENOMEM;
 
        dma_handle = rte_mem_virt2iova(buf);
-       if (dma_handle == 0) {
+       if (dma_handle == RTE_BAD_IOVA) {
                PMD_DRV_LOG(ERR,
                        "unable to map response address to physical memory\n");
                return -ENOMEM;
@@ -3611,7 +3693,7 @@ int bnxt_hwrm_flash_nvram(struct bnxt *bp, uint16_t dir_type,
                return -ENOMEM;
 
        dma_handle = rte_mem_virt2iova(buf);
-       if (dma_handle == 0) {
+       if (dma_handle == RTE_BAD_IOVA) {
                PMD_DRV_LOG(ERR,
                        "unable to map response address to physical memory\n");
                return -ENOMEM;
@@ -3675,23 +3757,14 @@ static int bnxt_hwrm_func_vf_vnic_query(struct bnxt *bp, uint16_t vf,
        req.max_vnic_id_cnt = rte_cpu_to_le_32(bp->pf.total_vnics);
        req.vnic_id_tbl_addr = rte_cpu_to_le_64(rte_mem_virt2iova(vnic_ids));
 
-       if (req.vnic_id_tbl_addr == 0) {
+       if (req.vnic_id_tbl_addr == RTE_BAD_IOVA) {
                HWRM_UNLOCK();
                PMD_DRV_LOG(ERR,
                "unable to map VNIC ID table address to physical memory\n");
                return -ENOMEM;
        }
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
-       if (rc) {
-               HWRM_UNLOCK();
-               PMD_DRV_LOG(ERR, "hwrm_func_vf_vnic_query failed rc:%d\n", rc);
-               return -1;
-       } else if (resp->error_code) {
-               rc = rte_le_to_cpu_16(resp->error_code);
-               HWRM_UNLOCK();
-               PMD_DRV_LOG(ERR, "hwrm_func_vf_vnic_query error %d\n", rc);
-               return -1;
-       }
+       HWRM_CHECK_RESULT();
        rc = rte_le_to_cpu_32(resp->vnic_id_cnt);
 
        HWRM_UNLOCK();
@@ -3719,10 +3792,9 @@ int bnxt_hwrm_func_vf_vnic_query_and_config(struct bnxt *bp, uint16_t vf,
        vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
        vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
                        RTE_CACHE_LINE_SIZE);
-       if (vnic_ids == NULL) {
-               rc = -ENOMEM;
-               return rc;
-       }
+       if (vnic_ids == NULL)
+               return -ENOMEM;
+
        for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
                rte_mem_lock_page(((char *)vnic_ids) + sz);
 
@@ -3789,10 +3861,8 @@ int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
        vnic_id_sz = bp->pf.total_vnics * sizeof(*vnic_ids);
        vnic_ids = rte_malloc("bnxt_hwrm_vf_vnic_ids_query", vnic_id_sz,
                        RTE_CACHE_LINE_SIZE);
-       if (vnic_ids == NULL) {
-               rc = -ENOMEM;
-               return rc;
-       }
+       if (vnic_ids == NULL)
+               return -ENOMEM;
 
        for (sz = 0; sz < vnic_id_sz; sz += getpagesize())
                rte_mem_lock_page(((char *)vnic_ids) + sz);
@@ -3823,7 +3893,7 @@ int bnxt_hwrm_func_qcfg_vf_dflt_vnic_id(struct bnxt *bp, int vf)
        PMD_DRV_LOG(ERR, "No default VNIC\n");
 exit:
        rte_free(vnic_ids);
-       return -1;
+       return rc;
 }
 
 int bnxt_hwrm_set_em_filter(struct bnxt *bp,
@@ -4037,32 +4107,104 @@ int bnxt_hwrm_clear_ntuple_filter(struct bnxt *bp,
        return 0;
 }
 
-int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+static int
+bnxt_vnic_rss_configure_thor(struct bnxt *bp, struct bnxt_vnic_info *vnic)
 {
-       unsigned int rss_idx, fw_idx, i;
+       struct hwrm_vnic_rss_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+       uint8_t *rx_queue_state = bp->eth_dev->data->rx_queue_state;
+       struct hwrm_vnic_rss_cfg_input req = {.req_type = 0 };
+       struct bnxt_rx_queue **rxqs = bp->rx_queues;
+       uint16_t *ring_tbl = vnic->rss_table;
+       int nr_ctxs = vnic->num_lb_ctxts;
+       int max_rings = bp->rx_nr_rings;
+       int i, j, k, cnt;
+       int rc = 0;
 
-       if (vnic->rss_table && vnic->hash_type) {
-               /*
-                * Fill the RSS hash & redirection table with
-                * ring group ids for all VNICs
-                */
-               for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE;
-                       rss_idx++, fw_idx++) {
-                       for (i = 0; i < bp->rx_cp_nr_rings; i++) {
-                               fw_idx %= bp->rx_cp_nr_rings;
-                               if (vnic->fw_grp_ids[fw_idx] !=
-                                   INVALID_HW_RING_ID)
+       for (i = 0, k = 0; i < nr_ctxs; i++) {
+               struct bnxt_rx_ring_info *rxr;
+               struct bnxt_cp_ring_info *cpr;
+
+               HWRM_PREP(req, 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_mode_flags = vnic->hash_mode;
+
+               req.ring_grp_tbl_addr =
+                   rte_cpu_to_le_64(vnic->rss_table_dma_addr +
+                                    i * BNXT_RSS_ENTRIES_PER_CTX_THOR *
+                                    2 * sizeof(*ring_tbl));
+               req.hash_key_tbl_addr =
+                   rte_cpu_to_le_64(vnic->rss_hash_key_dma_addr);
+
+               req.ring_table_pair_index = i;
+               req.rss_ctx_idx = rte_cpu_to_le_16(vnic->fw_grp_ids[i]);
+
+               for (j = 0; j < 64; j++) {
+                       uint16_t ring_id;
+
+                       /* Find next active ring. */
+                       for (cnt = 0; cnt < max_rings; cnt++) {
+                               if (rx_queue_state[k] !=
+                                               RTE_ETH_QUEUE_STATE_STOPPED)
                                        break;
-                               fw_idx++;
+                               if (++k == max_rings)
+                                       k = 0;
                        }
-                       if (i == bp->rx_cp_nr_rings)
+
+                       /* Return if no rings are active. */
+                       if (cnt == max_rings)
                                return 0;
-                       vnic->rss_table[rss_idx] =
-                               vnic->fw_grp_ids[fw_idx];
+
+                       /* Add rx/cp ring pair to RSS table. */
+                       rxr = rxqs[k]->rx_ring;
+                       cpr = rxqs[k]->cp_ring;
+
+                       ring_id = rxr->rx_ring_struct->fw_ring_id;
+                       *ring_tbl++ = rte_cpu_to_le_16(ring_id);
+                       ring_id = cpr->cp_ring_struct->fw_ring_id;
+                       *ring_tbl++ = rte_cpu_to_le_16(ring_id);
+
+                       if (++k == max_rings)
+                               k = 0;
                }
-               return bnxt_hwrm_vnic_rss_cfg(bp, vnic);
+               rc = bnxt_hwrm_send_message(bp, &req, sizeof(req),
+                                           BNXT_USE_CHIMP_MB);
+
+               HWRM_CHECK_RESULT();
+               HWRM_UNLOCK();
        }
-       return 0;
+
+       return rc;
+}
+
+int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic)
+{
+       unsigned int rss_idx, fw_idx, i;
+
+       if (!(vnic->rss_table && vnic->hash_type))
+               return 0;
+
+       if (BNXT_CHIP_THOR(bp))
+               return bnxt_vnic_rss_configure_thor(bp, vnic);
+
+       /*
+        * Fill the RSS hash & redirection table with
+        * ring group ids for all VNICs
+        */
+       for (rss_idx = 0, fw_idx = 0; rss_idx < HW_HASH_INDEX_SIZE;
+               rss_idx++, fw_idx++) {
+               for (i = 0; i < bp->rx_cp_nr_rings; i++) {
+                       fw_idx %= bp->rx_cp_nr_rings;
+                       if (vnic->fw_grp_ids[fw_idx] != INVALID_HW_RING_ID)
+                               break;
+                       fw_idx++;
+               }
+               if (i == bp->rx_cp_nr_rings)
+                       return 0;
+               vnic->rss_table[rss_idx] = vnic->fw_grp_ids[fw_idx];
+       }
+       return bnxt_hwrm_vnic_rss_cfg(bp, vnic);
 }
 
 static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
@@ -4095,6 +4237,34 @@ static void bnxt_hwrm_set_coal_params(struct bnxt_coal *hw_coal,
        req->flags = rte_cpu_to_le_16(flags);
 }
 
+static int bnxt_hwrm_set_coal_params_thor(struct bnxt *bp,
+               struct hwrm_ring_cmpl_ring_cfg_aggint_params_input *agg_req)
+{
+       struct hwrm_ring_aggint_qcaps_input req = {0};
+       struct hwrm_ring_aggint_qcaps_output *resp = bp->hwrm_cmd_resp_addr;
+       uint32_t enables;
+       uint16_t flags;
+       int rc;
+
+       HWRM_PREP(req, RING_AGGINT_QCAPS, BNXT_USE_CHIMP_MB);
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+       HWRM_CHECK_RESULT();
+
+       agg_req->num_cmpl_dma_aggr = resp->num_cmpl_dma_aggr_max;
+       agg_req->cmpl_aggr_dma_tmr = resp->cmpl_aggr_dma_tmr_min;
+
+       flags = HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_TIMER_RESET |
+               HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_FLAGS_RING_IDLE;
+       agg_req->flags = rte_cpu_to_le_16(flags);
+       enables =
+        HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_CMPL_AGGR_DMA_TMR |
+        HWRM_RING_CMPL_RING_CFG_AGGINT_PARAMS_INPUT_ENABLES_NUM_CMPL_DMA_AGGR;
+       agg_req->enables = rte_cpu_to_le_32(enables);
+
+       HWRM_UNLOCK();
+       return rc;
+}
+
 int bnxt_hwrm_set_ring_coal(struct bnxt *bp,
                        struct bnxt_coal *coal, uint16_t ring_id)
 {
@@ -4103,12 +4273,17 @@ int bnxt_hwrm_set_ring_coal(struct bnxt *bp,
                                                bp->hwrm_cmd_resp_addr;
        int rc;
 
-       /* Set ring coalesce parameters only for Stratus 100G NIC */
-       if (!bnxt_stratus_device(bp))
+       /* Set ring coalesce parameters only for 100G NICs */
+       if (BNXT_CHIP_THOR(bp)) {
+               if (bnxt_hwrm_set_coal_params_thor(bp, &req))
+                       return -1;
+       } else if (bnxt_stratus_device(bp)) {
+               bnxt_hwrm_set_coal_params(coal, &req);
+       } else {
                return 0;
+       }
 
        HWRM_PREP(req, RING_CMPL_RING_CFG_AGGINT_PARAMS, BNXT_USE_CHIMP_MB);
-       bnxt_hwrm_set_coal_params(coal, &req);
        req.ring_id = rte_cpu_to_le_16(ring_id);
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
        HWRM_CHECK_RESULT();
@@ -4297,8 +4472,7 @@ int bnxt_hwrm_func_backing_store_cfg(struct bnxt *bp, uint32_t enables)
        rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
        HWRM_CHECK_RESULT();
        HWRM_UNLOCK();
-       if (rc)
-               rc = -EIO;
+
        return rc;
 }
 
@@ -4318,13 +4492,13 @@ int bnxt_hwrm_ext_port_qstats(struct bnxt *bp)
        req.port_id = rte_cpu_to_le_16(pf->port_id);
        if (bp->flags & BNXT_FLAG_EXT_TX_PORT_STATS) {
                req.tx_stat_host_addr =
-                       rte_cpu_to_le_64(bp->hw_tx_port_stats_map);
+                       rte_cpu_to_le_64(bp->hw_tx_port_stats_ext_map);
                req.tx_stat_size =
                        rte_cpu_to_le_16(sizeof(struct tx_port_stats_ext));
        }
        if (bp->flags & BNXT_FLAG_EXT_RX_PORT_STATS) {
                req.rx_stat_host_addr =
-                       rte_cpu_to_le_64(bp->hw_rx_port_stats_map);
+                       rte_cpu_to_le_64(bp->hw_rx_port_stats_ext_map);
                req.rx_stat_size =
                        rte_cpu_to_le_16(sizeof(struct rx_port_stats_ext));
        }
@@ -4345,3 +4519,110 @@ int bnxt_hwrm_ext_port_qstats(struct bnxt *bp)
 
        return rc;
 }
+
+int
+bnxt_hwrm_tunnel_redirect(struct bnxt *bp, uint8_t type)
+{
+       struct hwrm_cfa_redirect_tunnel_type_alloc_input req = {0};
+       struct hwrm_cfa_redirect_tunnel_type_alloc_output *resp =
+               bp->hwrm_cmd_resp_addr;
+       int rc = 0;
+
+       HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_ALLOC, BNXT_USE_KONG(bp));
+       req.tunnel_type = type;
+       req.dest_fid = bp->fw_fid;
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+       HWRM_CHECK_RESULT();
+
+       HWRM_UNLOCK();
+
+       return rc;
+}
+
+int
+bnxt_hwrm_tunnel_redirect_free(struct bnxt *bp, uint8_t type)
+{
+       struct hwrm_cfa_redirect_tunnel_type_free_input req = {0};
+       struct hwrm_cfa_redirect_tunnel_type_free_output *resp =
+               bp->hwrm_cmd_resp_addr;
+       int rc = 0;
+
+       HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_FREE, BNXT_USE_KONG(bp));
+       req.tunnel_type = type;
+       req.dest_fid = bp->fw_fid;
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+       HWRM_CHECK_RESULT();
+
+       HWRM_UNLOCK();
+
+       return rc;
+}
+
+int bnxt_hwrm_tunnel_redirect_query(struct bnxt *bp, uint32_t *type)
+{
+       struct hwrm_cfa_redirect_query_tunnel_type_input req = {0};
+       struct hwrm_cfa_redirect_query_tunnel_type_output *resp =
+               bp->hwrm_cmd_resp_addr;
+       int rc = 0;
+
+       HWRM_PREP(req, CFA_REDIRECT_QUERY_TUNNEL_TYPE, BNXT_USE_KONG(bp));
+       req.src_fid = bp->fw_fid;
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+       HWRM_CHECK_RESULT();
+
+       if (type)
+               *type = resp->tunnel_mask;
+
+       HWRM_UNLOCK();
+
+       return rc;
+}
+
+int bnxt_hwrm_tunnel_redirect_info(struct bnxt *bp, uint8_t tun_type,
+                                  uint16_t *dst_fid)
+{
+       struct hwrm_cfa_redirect_tunnel_type_info_input req = {0};
+       struct hwrm_cfa_redirect_tunnel_type_info_output *resp =
+               bp->hwrm_cmd_resp_addr;
+       int rc = 0;
+
+       HWRM_PREP(req, CFA_REDIRECT_TUNNEL_TYPE_INFO, BNXT_USE_KONG(bp));
+       req.src_fid = bp->fw_fid;
+       req.tunnel_type = tun_type;
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_KONG(bp));
+       HWRM_CHECK_RESULT();
+
+       if (dst_fid)
+               *dst_fid = resp->dest_fid;
+
+       PMD_DRV_LOG(DEBUG, "dst_fid: %x\n", resp->dest_fid);
+
+       HWRM_UNLOCK();
+
+       return rc;
+}
+
+int bnxt_hwrm_set_mac(struct bnxt *bp)
+{
+       struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr;
+       struct hwrm_func_vf_cfg_input req = {0};
+       int rc = 0;
+
+       if (!BNXT_VF(bp))
+               return 0;
+
+       HWRM_PREP(req, FUNC_VF_CFG, BNXT_USE_CHIMP_MB);
+
+       req.enables =
+               rte_cpu_to_le_32(HWRM_FUNC_VF_CFG_INPUT_ENABLES_DFLT_MAC_ADDR);
+       memcpy(req.dflt_mac_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
+
+       rc = bnxt_hwrm_send_message(bp, &req, sizeof(req), BNXT_USE_CHIMP_MB);
+
+       HWRM_CHECK_RESULT();
+
+       memcpy(bp->dflt_mac_addr, bp->mac_addr, RTE_ETHER_ADDR_LEN);
+       HWRM_UNLOCK();
+
+       return rc;
+}