summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAjit Khaparde <ajit.khaparde@broadcom.com>2018-05-22 11:13:44 -0700
committerFerruh Yigit <ferruh.yigit@intel.com>2018-05-23 00:35:01 +0200
commit2b947bd294ffce2d980d092683de82269abe3676 (patch)
tree971405a3a2eec94d8764f1c95c6951d7815541e0
parent44cbeffe77651239cb4d425c61b9ee1cfde27152 (diff)
downloaddpdk-2b947bd294ffce2d980d092683de82269abe3676.zip
dpdk-2b947bd294ffce2d980d092683de82269abe3676.tar.gz
dpdk-2b947bd294ffce2d980d092683de82269abe3676.tar.xz
net/bnxt: use first completion ring for fwd and async event
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 <qingmin.liu@broadcom.com> Signed-off-by: Somnath Kotur <somnath.kotur@broadcom.com> Signed-off-by: Ajit Khaparde <ajit.khaparde@broadcom.com>
-rw-r--r--drivers/net/bnxt/bnxt_cpr.c84
-rw-r--r--drivers/net/bnxt/bnxt_cpr.h5
-rw-r--r--drivers/net/bnxt/bnxt_ethdev.c20
-rw-r--r--drivers/net/bnxt/bnxt_hwrm.c19
-rw-r--r--drivers/net/bnxt/bnxt_hwrm.h1
-rw-r--r--drivers/net/bnxt/bnxt_irq.c28
-rw-r--r--drivers/net/bnxt/bnxt_ring.c45
-rw-r--r--drivers/net/bnxt/bnxt_rxr.c17
8 files changed, 91 insertions, 128 deletions
diff --git a/drivers/net/bnxt/bnxt_cpr.c b/drivers/net/bnxt/bnxt_cpr.c
index 7b4f9a1..ff20b6f 100644
--- a/drivers/net/bnxt/bnxt_cpr.c
+++ b/drivers/net/bnxt/bnxt_cpr.c
@@ -132,69 +132,31 @@ reject:
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 6091404..6c1e6d2 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 af141d4..0aba9a3 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 @@ skip_init:
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 @@ skip_init:
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 b285761..bf847a8 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 7c161ee..4813c7f 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 fd05f66..7ef7023 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 1e748b9..bb9f6d1 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 6eeb93b..a8b5d66 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) {