[PATCH v2 4/7] net/bnxt: fix to use 1st cmpl ring for fwd and async event
From: Ajit Khaparde <ajit.khaparde@broadcom.com>
Date: 2018-05-22 18:13:55
Subsystem:
networking drivers, the rest · Maintainers:
Andrew Lunn, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
In order to save completion resource, use the first completion ring from
PF or VF as the default completion ring for async event & HWRM forward
response handling. Add bnxt_hwrm_set_async_event_cr() to set
async_event_cr for either PF or VF.
Fixes: 7bc8e9a227cc ("net/bnxt: support async link notification")
Signed-off-by: Qingmin Liu <redacted>
Signed-off-by: Somnath Kotur <redacted>
Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
--
v1->v2: shorten headline
---
drivers/net/bnxt/bnxt_cpr.c | 84 ++++++++++++------------------------------
drivers/net/bnxt/bnxt_cpr.h | 5 +--
drivers/net/bnxt/bnxt_ethdev.c | 20 +---------
drivers/net/bnxt/bnxt_hwrm.c | 19 ++++++++--
drivers/net/bnxt/bnxt_hwrm.h | 1 +
drivers/net/bnxt/bnxt_irq.c | 28 +++-----------
drivers/net/bnxt/bnxt_ring.c | 45 +++++++++++++++-------
drivers/net/bnxt/bnxt_rxr.c | 17 +++++++--
8 files changed, 91 insertions(+), 128 deletions(-)
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 7b4f9a14b..ff20b6fdf 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c@@ -132,69 +132,31 @@ void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmpl) return; } -/* For the default completion ring only */ -int bnxt_alloc_def_cp_ring(struct bnxt *bp) +int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp) { - struct bnxt_cp_ring_info *cpr = bp->def_cp_ring; - struct bnxt_ring *cp_ring = cpr->cp_ring_struct; - int rc; - - rc = bnxt_hwrm_ring_alloc(bp, cp_ring, - HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL, - 0, HWRM_NA_SIGNATURE, - HWRM_NA_SIGNATURE); - if (rc) - goto err_out; - cpr->cp_doorbell = (char *)bp->doorbell_base; - B_CP_DIS_DB(cpr, cpr->cp_raw_cons); - if (BNXT_PF(bp)) - rc = bnxt_hwrm_func_cfg_def_cp(bp); - else - rc = bnxt_hwrm_vf_func_cfg_def_cp(bp); - -err_out: - return rc; -} + bool evt = 0; -void bnxt_free_def_cp_ring(struct bnxt *bp) -{ - struct bnxt_cp_ring_info *cpr = bp->def_cp_ring; - - if (cpr == NULL) - return; + if (bp == NULL || cmp == NULL) { + PMD_DRV_LOG(ERR, "invalid NULL argument\n"); + return evt; + } - bnxt_free_ring(cpr->cp_ring_struct); - cpr->cp_ring_struct = NULL; - rte_free(cpr->cp_ring_struct); - rte_free(cpr); - bp->def_cp_ring = NULL; -} + switch (CMP_TYPE(cmp)) { + case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: + /* Handle any async event */ + bnxt_handle_async_event(bp, cmp); + evt = 1; + break; + case CMPL_BASE_TYPE_HWRM_FWD_RESP: + /* Handle HWRM forwarded responses */ + bnxt_handle_fwd_req(bp, cmp); + evt = 1; + break; + default: + /* Ignore any other events */ + PMD_DRV_LOG(INFO, "Ignoring %02x completion\n", CMP_TYPE(cmp)); + break; + } -/* For the default completion ring only */ -int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id) -{ - struct bnxt_cp_ring_info *cpr; - struct bnxt_ring *ring; - - cpr = rte_zmalloc_socket("cpr", - sizeof(struct bnxt_cp_ring_info), - RTE_CACHE_LINE_SIZE, socket_id); - if (cpr == NULL) - return -ENOMEM; - bp->def_cp_ring = cpr; - - ring = rte_zmalloc_socket("bnxt_cp_ring_struct", - sizeof(struct bnxt_ring), - RTE_CACHE_LINE_SIZE, socket_id); - if (ring == NULL) - return -ENOMEM; - cpr->cp_ring_struct = ring; - ring->bd = (void *)cpr->cp_desc_ring; - ring->bd_dma = cpr->cp_desc_mapping; - ring->ring_size = rte_align32pow2(DEFAULT_CP_RING_SIZE); - ring->ring_mask = ring->ring_size - 1; - ring->vmem_size = 0; - ring->vmem = NULL; - - return 0; + return evt; }
diff --git a/drivers/net/bnxt/bnxt_cpr.h b/drivers/net/bnxt/bnxt_cpr.h
index 6091404f1..6c1e6d2b0 100644
--- a/drivers/net/bnxt/bnxt_cpr.h
+++ b/drivers/net/bnxt/bnxt_cpr.h@@ -72,12 +72,9 @@ struct bnxt_cp_ring_info { #define RX_CMP_L2_ERRORS \ (RX_PKT_CMPL_ERRORS_BUFFER_ERROR_MASK | RX_PKT_CMPL_ERRORS_CRC_ERROR) - struct bnxt; -int bnxt_alloc_def_cp_ring(struct bnxt *bp); -void bnxt_free_def_cp_ring(struct bnxt *bp); -int bnxt_init_def_ring_struct(struct bnxt *bp, unsigned int socket_id); void bnxt_handle_async_event(struct bnxt *bp, struct cmpl_base *cmp); void bnxt_handle_fwd_req(struct bnxt *bp, struct cmpl_base *cmp); +int bnxt_event_hwrm_resp_handler(struct bnxt *bp, struct cmpl_base *cmp); #endif
diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c
index af141d453..0aba9a3fc 100644
--- a/drivers/net/bnxt/bnxt_ethdev.c
+++ b/drivers/net/bnxt/bnxt_ethdev.c@@ -168,23 +168,12 @@ static void bnxt_free_mem(struct bnxt *bp) bnxt_free_stats(bp); bnxt_free_tx_rings(bp); bnxt_free_rx_rings(bp); - bnxt_free_def_cp_ring(bp); } static int bnxt_alloc_mem(struct bnxt *bp) { int rc; - /* Default completion ring */ - rc = bnxt_init_def_ring_struct(bp, SOCKET_ID_ANY); - if (rc) - goto alloc_mem_err; - - rc = bnxt_alloc_rings(bp, 0, NULL, NULL, - bp->def_cp_ring, "def_cp"); - if (rc) - goto alloc_mem_err; - rc = bnxt_alloc_vnic_mem(bp); if (rc) goto alloc_mem_err;
@@ -509,11 +498,11 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) /* Inherit new configurations */ if (eth_dev->data->nb_rx_queues > bp->max_rx_rings || eth_dev->data->nb_tx_queues > bp->max_tx_rings || - eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues + 1 > + eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues > bp->max_cp_rings || eth_dev->data->nb_rx_queues + eth_dev->data->nb_tx_queues > bp->max_stat_ctx || - (uint32_t)(eth_dev->data->nb_rx_queues + 1) > bp->max_ring_grps) { + (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps) { PMD_DRV_LOG(ERR, "Insufficient resources to support requested config\n"); PMD_DRV_LOG(ERR,
@@ -3383,10 +3372,6 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) if (rc) goto error_free_int; - rc = bnxt_alloc_def_cp_ring(bp); - if (rc) - goto error_free_int; - bnxt_enable_int(bp); bnxt_init_nic(bp);
@@ -3394,7 +3379,6 @@ bnxt_dev_init(struct rte_eth_dev *eth_dev) error_free_int: bnxt_disable_int(bp); - bnxt_free_def_cp_ring(bp); bnxt_hwrm_func_buf_unrgtr(bp); bnxt_free_int(bp); bnxt_free_mem(bp);
diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c
index b285761eb..bf847a828 100644
--- a/drivers/net/bnxt/bnxt_hwrm.c
+++ b/drivers/net/bnxt/bnxt_hwrm.c@@ -1766,7 +1766,7 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp) struct bnxt_tx_ring_info *txr = txq->tx_ring; struct bnxt_ring *ring = txr->tx_ring_struct; struct bnxt_cp_ring_info *cpr = txq->cp_ring; - unsigned int idx = bp->rx_cp_nr_rings + i + 1; + unsigned int idx = bp->rx_cp_nr_rings + i; if (ring->fw_ring_id != INVALID_HW_RING_ID) { bnxt_hwrm_ring_free(bp, ring,
@@ -1792,13 +1792,12 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp) struct bnxt_rx_ring_info *rxr = rxq->rx_ring; struct bnxt_ring *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; + bp->grp_info[i].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));
@@ -1819,7 +1818,7 @@ int bnxt_free_all_hwrm_rings(struct bnxt *bp) bp->grp_info[i].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, idx); + bnxt_free_cp_ring(bp, cpr, i); bp->grp_info[i].cp_fw_ring_id = INVALID_HW_RING_ID; cpr->cp_ring_struct->fw_ring_id = INVALID_HW_RING_ID; }
@@ -2933,6 +2932,18 @@ int bnxt_hwrm_set_vf_vlan(struct bnxt *bp, int vf) return rc; } +int bnxt_hwrm_set_async_event_cr(struct bnxt *bp) +{ + int rc; + + if (BNXT_PF(bp)) + rc = bnxt_hwrm_func_cfg_def_cp(bp); + else + rc = bnxt_hwrm_vf_func_cfg_def_cp(bp); + + return rc; +} + int bnxt_hwrm_reject_fwd_resp(struct bnxt *bp, uint16_t target_id, void *encaped, size_t ec_size) {
diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h
index 7c161eea0..4813c7fb6 100644
--- a/drivers/net/bnxt/bnxt_hwrm.h
+++ b/drivers/net/bnxt/bnxt_hwrm.h@@ -63,6 +63,7 @@ int bnxt_hwrm_vf_func_cfg_def_cp(struct bnxt *bp); int bnxt_hwrm_queue_qportcfg(struct bnxt *bp); +int bnxt_hwrm_set_async_event_cr(struct bnxt *bp); int bnxt_hwrm_ring_alloc(struct bnxt *bp, struct bnxt_ring *ring, uint32_t ring_type, uint32_t map_index,
diff --git a/drivers/net/bnxt/bnxt_irq.c b/drivers/net/bnxt/bnxt_irq.c
index fd05f66af..7ef7023eb 100644
--- a/drivers/net/bnxt/bnxt_irq.c
+++ b/drivers/net/bnxt/bnxt_irq.c@@ -40,30 +40,10 @@ static void bnxt_int_handler(void *param) if (!CMP_VALID(cmp, raw_cons, cpr->cp_ring_struct)) break; - switch (CMP_TYPE(cmp)) { - case CMPL_BASE_TYPE_HWRM_ASYNC_EVENT: - /* Handle any async event */ - bnxt_handle_async_event(bp, cmp); - break; - case CMPL_BASE_TYPE_HWRM_FWD_REQ: - /* Handle HWRM forwarded responses */ - bnxt_handle_fwd_req(bp, cmp); - break; - default: - /* Ignore any other events */ - if (cmp->type & rte_cpu_to_le_16(0x01)) { - if (!CMP_VALID(cmp, raw_cons, - cpr->cp_ring_struct)) - goto no_more; - } - PMD_DRV_LOG(INFO, - "Ignoring %02x completion\n", CMP_TYPE(cmp)); - break; - } + bnxt_event_hwrm_resp_handler(bp, cmp); raw_cons = NEXT_RAW_CMP(raw_cons); - }; -no_more: + cpr->cp_raw_cons = raw_cons; B_CP_DB_REARM(cpr, cpr->cp_raw_cons); }
@@ -99,7 +79,9 @@ void bnxt_enable_int(struct bnxt *bp) { struct bnxt_cp_ring_info *cpr = bp->def_cp_ring; - B_CP_DB_ARM(cpr); + /* Only the default completion ring */ + if (cpr != NULL && cpr->cp_doorbell != NULL) + B_CP_DB_ARM(cpr); } int bnxt_setup_int(struct bnxt *bp)
diff --git a/drivers/net/bnxt/bnxt_ring.c b/drivers/net/bnxt/bnxt_ring.c
index 1e748b949..bb9f6d1c0 100644
--- a/drivers/net/bnxt/bnxt_ring.c
+++ b/drivers/net/bnxt/bnxt_ring.c@@ -274,31 +274,48 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp) struct bnxt_ring *cp_ring = cpr->cp_ring_struct; struct bnxt_rx_ring_info *rxr = rxq->rx_ring; struct bnxt_ring *ring = rxr->rx_ring_struct; - unsigned int idx = i + 1; - unsigned int map_idx = idx + bp->rx_cp_nr_rings; + unsigned int map_idx = i + bp->rx_cp_nr_rings; bp->grp_info[i].fw_stats_ctx = cpr->hw_stats_ctx_id; /* Rx cmpl */ - rc = bnxt_hwrm_ring_alloc(bp, cp_ring, - HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL, - idx, HWRM_NA_SIGNATURE, - HWRM_NA_SIGNATURE); + rc = bnxt_hwrm_ring_alloc + (bp, + cp_ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_L2_CMPL, + i, + HWRM_NA_SIGNATURE, + HWRM_NA_SIGNATURE); if (rc) goto err_out; - cpr->cp_doorbell = (char *)bp->doorbell_base + idx * 0x80; + cpr->cp_doorbell = (char *)bp->doorbell_base + i * 0x80; bp->grp_info[i].cp_fw_ring_id = cp_ring->fw_ring_id; B_CP_DIS_DB(cpr, cpr->cp_raw_cons); + if (!i) { + /* + * In order to save completion resource, use the first + * completion ring from PF or VF as the default + * completion ring for async event & HWRM + * forward response handling. + */ + bp->def_cp_ring = cpr; + rc = bnxt_hwrm_set_async_event_cr(bp); + if (rc) + goto err_out; + } + /* Rx ring */ - rc = bnxt_hwrm_ring_alloc(bp, ring, - HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, - idx, cpr->hw_stats_ctx_id, - cp_ring->fw_ring_id); + rc = bnxt_hwrm_ring_alloc(bp, + ring, + HWRM_RING_ALLOC_INPUT_RING_TYPE_RX, + i, + cpr->hw_stats_ctx_id, + cp_ring->fw_ring_id); if (rc) goto err_out; rxr->rx_prod = 0; - rxr->rx_doorbell = (char *)bp->doorbell_base + idx * 0x80; + rxr->rx_doorbell = (char *)bp->doorbell_base + i * 0x80; bp->grp_info[i].rx_fw_ring_id = ring->fw_ring_id; B_RX_DB(rxr->rx_doorbell, rxr->rx_prod);
@@ -330,7 +347,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp) } B_RX_DB(rxr->rx_doorbell, rxr->rx_prod); B_RX_DB(rxr->ag_doorbell, rxr->ag_prod); - rxq->index = idx; + rxq->index = i; } for (i = 0; i < bp->tx_cp_nr_rings; i++) {
@@ -339,7 +356,7 @@ int bnxt_alloc_hwrm_rings(struct bnxt *bp) struct bnxt_ring *cp_ring = cpr->cp_ring_struct; struct bnxt_tx_ring_info *txr = txq->tx_ring; struct bnxt_ring *ring = txr->tx_ring_struct; - unsigned int idx = i + 1 + bp->rx_cp_nr_rings; + unsigned int idx = i + bp->rx_cp_nr_rings; /* Tx cmpl */ rc = bnxt_hwrm_ring_alloc(bp, cp_ring,
diff --git a/drivers/net/bnxt/bnxt_rxr.c b/drivers/net/bnxt/bnxt_rxr.c
index 6eeb93b7b..a8b5d6683 100644
--- a/drivers/net/bnxt/bnxt_rxr.c
+++ b/drivers/net/bnxt/bnxt_rxr.c@@ -534,6 +534,7 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, uint16_t prod = rxr->rx_prod; uint16_t ag_prod = rxr->ag_prod; int rc = 0; + bool evt = false; /* If Rx Q was stopped return */ if (rxq->rx_deferred_start)
@@ -558,14 +559,19 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, nb_rx_pkts++; if (rc == -EBUSY) /* partial completion */ break; + } else { + evt = + bnxt_event_hwrm_resp_handler(rxq->bp, + (struct cmpl_base *)rxcmp); } + raw_cons = NEXT_RAW_CMP(raw_cons); - if (nb_rx_pkts == nb_pkts) + if (nb_rx_pkts == nb_pkts || evt) break; } cpr->cp_raw_cons = raw_cons; - if (prod == rxr->rx_prod && ag_prod == rxr->ag_prod) { + if ((prod == rxr->rx_prod && ag_prod == rxr->ag_prod) && !evt) { /* * For PMD, there is no need to keep on pushing to REARM * the doorbell if there are no new completions
@@ -574,9 +580,12 @@ uint16_t bnxt_recv_pkts(void *rx_queue, struct rte_mbuf **rx_pkts, } B_CP_DIS_DB(cpr, cpr->cp_raw_cons); - B_RX_DB(rxr->rx_doorbell, rxr->rx_prod); + if (prod != rxr->rx_prod) + B_RX_DB(rxr->rx_doorbell, rxr->rx_prod); + /* Ring the AGG ring DB */ - B_RX_DB(rxr->ag_doorbell, rxr->ag_prod); + if (ag_prod != rxr->ag_prod) + B_RX_DB(rxr->ag_doorbell, rxr->ag_prod); /* Attempt to alloc Rx buf in case of a previous allocation failure. */ if (rc == -ENOMEM) {
--
2.15.1 (Apple Git-101)