From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-gw1-out.broadcom.com (mail-gw1-out.broadcom.com [216.31.210.62]) by dpdk.org (Postfix) with ESMTP id 06C8D685C for ; Tue, 7 Jun 2016 00:09:31 +0200 (CEST) X-IronPort-AV: E=Sophos;i="5.26,429,1459839600"; d="scan'208";a="96627878" Received: from mail-irv-18.broadcom.com ([10.15.198.37]) by mail-gw1-out.broadcom.com with ESMTP; 06 Jun 2016 16:16:30 -0700 Received: from mail-irva-12.broadcom.com (mail-irva-12.broadcom.com [10.11.16.101]) by mail-irv-18.broadcom.com (Postfix) with ESMTP id 15C2C82026; Mon, 6 Jun 2016 15:09:31 -0700 (PDT) Received: from DPDK-C1.broadcom.com (dhcp-10-13-115-104.irv.broadcom.com [10.13.115.104]) by mail-irva-12.broadcom.com (Postfix) with ESMTP id CDEAF12762C; Mon, 6 Jun 2016 15:09:28 -0700 (PDT) From: Stephen Hurd To: dev@dpdk.org, ajit.khaparde@broadcom.com, bruce.richardson@intel.com Date: Mon, 6 Jun 2016 15:08:32 -0700 Message-Id: <1465250923-78695-28-git-send-email-stephen.hurd@broadcom.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1465250923-78695-1-git-send-email-stephen.hurd@broadcom.com> References: <1465250923-78695-1-git-send-email-stephen.hurd@broadcom.com> Subject: [dpdk-dev] [PATCH v4 28/39] bnxt: add ring alloc, free and group init X-BeenThere: dev@dpdk.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: patches and discussions about DPDK List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 06 Jun 2016 22:09:33 -0000 From: Ajit Khaparde Add a function to initialize ring groups, and a function to allocate and free the rings via HWRM. This should be the last functionality needed to add start/stop device operations. v4: Address review comment to merge another patch into this to avoid a compilation issue. Fix issues pointed out by checkpatch. Signed-off-by: Ajit Khaparde Reviewed-by: David Christensen Signed-off-by: Stephen Hurd --- drivers/net/bnxt/bnxt_hwrm.c | 112 +++++++++++++++++++++++++++++++++++++++- drivers/net/bnxt/bnxt_hwrm.h | 1 + drivers/net/bnxt/bnxt_ring.c | 119 +++++++++++++++++++++++++++++++++++++++++++ drivers/net/bnxt/bnxt_ring.h | 2 + 4 files changed, 233 insertions(+), 1 deletion(-) diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index f8e9d20..dc1bce7 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -43,8 +43,10 @@ #include "bnxt_filter.h" #include "bnxt_hwrm.h" #include "bnxt_rxq.h" +#include "bnxt_rxr.h" #include "bnxt_ring.h" #include "bnxt_txq.h" +#include "bnxt_txr.h" #include "bnxt_vnic.h" #include "hsi_struct_def_dpdk.h" @@ -579,7 +581,11 @@ int bnxt_hwrm_ring_alloc(struct bnxt *bp, break; case HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL: req.ring_type = ring_type; - req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_POLL; + /* + * TODO: Some HWRM versions crash with + * HWRM_RING_ALLOC_INPUT_INT_MODE_POLL + */ + req.int_mode = HWRM_RING_ALLOC_INPUT_INT_MODE_MSIX; req.length = rte_cpu_to_le_32(ring->ring_size); break; default: @@ -1012,6 +1018,84 @@ int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp) return rc; } +static void bnxt_free_cp_ring(struct bnxt *bp, + struct bnxt_cp_ring_info *cpr, unsigned int idx) +{ + struct bnxt_ring_struct *cp_ring = cpr->cp_ring_struct; + + bnxt_hwrm_ring_free(bp, cp_ring, + HWRM_RING_FREE_INPUT_RING_TYPE_CMPL); + cp_ring->fw_ring_id = INVALID_HW_RING_ID; + bp->grp_info[idx].cp_fw_ring_id = INVALID_HW_RING_ID; + memset(cpr->cp_desc_ring, 0, cpr->cp_ring_struct->ring_size * + sizeof(*cpr->cp_desc_ring)); + cpr->cp_raw_cons = 0; +} + +int bnxt_free_all_hwrm_rings(struct bnxt *bp) +{ + unsigned int i; + int rc = 0; + + for (i = 0; i < bp->tx_cp_nr_rings; i++) { + struct bnxt_tx_queue *txq = bp->tx_queues[i]; + struct bnxt_tx_ring_info *txr = txq->tx_ring; + struct bnxt_ring_struct *ring = txr->tx_ring_struct; + struct bnxt_cp_ring_info *cpr = txq->cp_ring; + unsigned int idx = bp->rx_cp_nr_rings + i + 1; + + if (ring->fw_ring_id != INVALID_HW_RING_ID) { + bnxt_hwrm_ring_free(bp, ring, + HWRM_RING_FREE_INPUT_RING_TYPE_TX); + ring->fw_ring_id = INVALID_HW_RING_ID; + memset(txr->tx_desc_ring, 0, + txr->tx_ring_struct->ring_size * + sizeof(*txr->tx_desc_ring)); + memset(txr->tx_buf_ring, 0, + txr->tx_ring_struct->ring_size * + sizeof(*txr->tx_buf_ring)); + txr->tx_prod = 0; + txr->tx_cons = 0; + } + if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) + bnxt_free_cp_ring(bp, cpr, idx); + } + + for (i = 0; i < bp->rx_cp_nr_rings; i++) { + struct bnxt_rx_queue *rxq = bp->rx_queues[i]; + struct bnxt_rx_ring_info *rxr = rxq->rx_ring; + struct bnxt_ring_struct *ring = rxr->rx_ring_struct; + struct bnxt_cp_ring_info *cpr = rxq->cp_ring; + unsigned int idx = i + 1; + + if (ring->fw_ring_id != INVALID_HW_RING_ID) { + bnxt_hwrm_ring_free(bp, ring, + HWRM_RING_FREE_INPUT_RING_TYPE_RX); + ring->fw_ring_id = INVALID_HW_RING_ID; + bp->grp_info[idx].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)); + memset(rxr->rx_buf_ring, 0, + rxr->rx_ring_struct->ring_size * + sizeof(*rxr->rx_buf_ring)); + rxr->rx_prod = 0; + } + if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) + bnxt_free_cp_ring(bp, cpr, idx); + } + + /* Default completion ring */ + { + struct bnxt_cp_ring_info *cpr = bp->def_cp_ring; + + if (cpr->cp_ring_struct->fw_ring_id != INVALID_HW_RING_ID) + bnxt_free_cp_ring(bp, cpr, 0); + } + + return rc; +} + int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp) { uint16_t i; @@ -1085,6 +1169,32 @@ int bnxt_set_hwrm_vnic_filters(struct bnxt *bp, struct bnxt_vnic_info *vnic) return rc; } +void bnxt_free_all_hwrm_resources(struct bnxt *bp) +{ + struct bnxt_vnic_info *vnic; + unsigned int i; + + if (bp->vnic_info == NULL) + return; + + vnic = &bp->vnic_info[0]; + bnxt_hwrm_cfa_l2_clear_rx_mask(bp, vnic); + + /* VNIC resources */ + for (i = 0; i < bp->nr_vnics; i++) { + struct bnxt_vnic_info *vnic = &bp->vnic_info[i]; + + bnxt_clear_hwrm_vnic_filters(bp, vnic); + + bnxt_hwrm_vnic_ctx_free(bp, vnic); + bnxt_hwrm_vnic_free(bp, vnic); + } + /* Ring resources */ + bnxt_free_all_hwrm_rings(bp); + bnxt_free_all_hwrm_ring_grps(bp); + bnxt_free_all_hwrm_stat_ctxs(bp); +} + static uint16_t bnxt_parse_eth_link_duplex(uint32_t conf_link_speed) { uint8_t hw_link_duplex = HWRM_PORT_PHY_CFG_INPUT_AUTO_DUPLEX_BOTH; diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 55728df..abf81fb 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -89,6 +89,7 @@ int bnxt_hwrm_vnic_rss_cfg(struct bnxt *bp, int bnxt_alloc_all_hwrm_stat_ctxs(struct bnxt *bp); int bnxt_clear_all_hwrm_stat_ctxs(struct bnxt *bp); int bnxt_free_all_hwrm_stat_ctxs(struct bnxt *bp); +int bnxt_free_all_hwrm_rings(struct bnxt *bp); int bnxt_free_all_hwrm_ring_grps(struct bnxt *bp); int bnxt_alloc_all_hwrm_ring_grps(struct bnxt *bp); int bnxt_set_hwrm_vnic_filters(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 675c5b8..49cfab9 100644 --- a/drivers/net/bnxt/bnxt_ring.c +++ b/drivers/net/bnxt/bnxt_ring.c @@ -35,8 +35,11 @@ #include "bnxt.h" #include "bnxt_cpr.h" +#include "bnxt_hwrm.h" #include "bnxt_ring.h" +#include "bnxt_rxq.h" #include "bnxt_rxr.h" +#include "bnxt_txq.h" #include "bnxt_txr.h" #include "hsi_struct_def_dpdk.h" @@ -55,6 +58,19 @@ void bnxt_free_ring(struct bnxt_ring_struct *ring) } /* + * Ring groups + */ + +void bnxt_init_ring_grps(struct bnxt *bp) +{ + unsigned int i; + + for (i = 0; i < bp->max_ring_grps; i++) + memset(&bp->grp_info[i], (uint8_t)HWRM_NA_SIGNATURE, + sizeof(struct bnxt_ring_grp_info)); +} + +/* * Allocates a completion ring with vmem and stats optionally also allocating * a TX and/or RX ring. Passing NULL as tx_ring_info and/or rx_ring_info * to not allocate them. @@ -184,3 +200,106 @@ int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, cp_ring_info->hw_stats_ctx_id = HWRM_NA_SIGNATURE; return 0; } + +/* ring_grp usage: + * [0] = default completion ring + * [1 -> +rx_cp_nr_rings] = rx_cp, rx rings + * [1+rx_cp_nr_rings + 1 -> +tx_cp_nr_rings] = tx_cp, tx rings + */ +int bnxt_alloc_hwrm_rings(struct bnxt *bp) +{ + unsigned int i; + int rc = 0; + + /* Default completion ring */ + { + struct bnxt_cp_ring_info *cpr = bp->def_cp_ring; + struct bnxt_ring_struct *cp_ring = cpr->cp_ring_struct; + + rc = bnxt_hwrm_ring_alloc(bp, cp_ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, + 0, HWRM_NA_SIGNATURE); + if (rc) + goto err_out; + cpr->cp_doorbell = + (char *)bp->eth_dev->pci_dev->mem_resource[2].addr; + B_CP_DIS_DB(cpr, cpr->cp_raw_cons); + bp->grp_info[0].cp_fw_ring_id = cp_ring->fw_ring_id; + } + + for (i = 0; i < bp->rx_cp_nr_rings; i++) { + struct bnxt_rx_queue *rxq = bp->rx_queues[i]; + struct bnxt_cp_ring_info *cpr = rxq->cp_ring; + struct bnxt_ring_struct *cp_ring = cpr->cp_ring_struct; + struct bnxt_rx_ring_info *rxr = rxq->rx_ring; + struct bnxt_ring_struct *ring = rxr->rx_ring_struct; + unsigned int idx = i + 1; + + /* Rx cmpl */ + rc = bnxt_hwrm_ring_alloc(bp, cp_ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, + idx, HWRM_NA_SIGNATURE); + if (rc) + goto err_out; + cpr->cp_doorbell = + (char *)bp->eth_dev->pci_dev->mem_resource[2].addr + + idx * 0x80; + bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id; + B_CP_DIS_DB(cpr, cpr->cp_raw_cons); + + /* Rx ring */ + rc = bnxt_hwrm_ring_alloc(bp, ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, + idx, cpr->hw_stats_ctx_id); + if (rc) + goto err_out; + rxr->rx_prod = 0; + rxr->rx_doorbell = + (char *)bp->eth_dev->pci_dev->mem_resource[2].addr + + idx * 0x80; + bp->grp_info[idx].rx_fw_ring_id = ring->fw_ring_id; + B_RX_DB(rxr->rx_doorbell, rxr->rx_prod); + if (bnxt_init_one_rx_ring(rxq)) { + RTE_LOG(ERR, PMD, "bnxt_init_one_rx_ring failed!"); + bnxt_rx_queue_release_op(rxq); + return -ENOMEM; + } + B_RX_DB(rxr->rx_doorbell, rxr->rx_prod); + } + + for (i = 0; i < bp->tx_cp_nr_rings; i++) { + struct bnxt_tx_queue *txq = bp->tx_queues[i]; + struct bnxt_cp_ring_info *cpr = txq->cp_ring; + struct bnxt_ring_struct *cp_ring = cpr->cp_ring_struct; + struct bnxt_tx_ring_info *txr = txq->tx_ring; + struct bnxt_ring_struct *ring = txr->tx_ring_struct; + unsigned int idx = 1 + bp->rx_cp_nr_rings + i; + + /* Tx cmpl */ + rc = bnxt_hwrm_ring_alloc(bp, cp_ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_CMPL, + idx, HWRM_NA_SIGNATURE); + if (rc) + goto err_out; + + cpr->cp_doorbell = + (char *)bp->eth_dev->pci_dev->mem_resource[2].addr + + idx * 0x80; + bp->grp_info[idx].cp_fw_ring_id = cp_ring->fw_ring_id; + B_CP_DIS_DB(cpr, cpr->cp_raw_cons); + + /* Tx ring */ + rc = bnxt_hwrm_ring_alloc(bp, ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_TX, + idx, cpr->hw_stats_ctx_id); + if (rc) + goto err_out; + + txr->tx_doorbell = + (char *)bp->eth_dev->pci_dev->mem_resource[2].addr + + idx * 0x80; + } + +err_out: + return rc; +} diff --git a/drivers/net/bnxt/bnxt_ring.h b/drivers/net/bnxt/bnxt_ring.h index c7c3b33..e548586 100644 --- a/drivers/net/bnxt/bnxt_ring.h +++ b/drivers/net/bnxt/bnxt_ring.h @@ -92,10 +92,12 @@ struct bnxt_tx_ring_info; struct bnxt_rx_ring_info; struct bnxt_cp_ring_info; void bnxt_free_ring(struct bnxt_ring_struct *ring); +void bnxt_init_ring_grps(struct bnxt *bp); int bnxt_alloc_rings(struct bnxt *bp, uint16_t qidx, struct bnxt_tx_ring_info *tx_ring_info, struct bnxt_rx_ring_info *rx_ring_info, struct bnxt_cp_ring_info *cp_ring_info, const char *suffix); +int bnxt_alloc_hwrm_rings(struct bnxt *bp); #endif -- 1.9.1