net/bnxt: use first completion ring for fwd and async event
authorAjit Khaparde <ajit.khaparde@broadcom.com>
Tue, 22 May 2018 18:13:44 +0000 (11:13 -0700)
committerFerruh Yigit <ferruh.yigit@intel.com>
Tue, 22 May 2018 22:35:01 +0000 (00:35 +0200)
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>
drivers/net/bnxt/bnxt_cpr.c
drivers/net/bnxt/bnxt_cpr.h
drivers/net/bnxt/bnxt_ethdev.c
drivers/net/bnxt/bnxt_hwrm.c
drivers/net/bnxt/bnxt_hwrm.h
drivers/net/bnxt/bnxt_irq.c
drivers/net/bnxt/bnxt_ring.c
drivers/net/bnxt/bnxt_rxr.c

index 7b4f9a1..ff20b6f 100644 (file)
@@ -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;
 }
index 6091404..6c1e6d2 100644 (file)
@@ -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
index af141d4..0aba9a3 100644 (file)
@@ -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);
index b285761..bf847a8 100644 (file)
@@ -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)
 {
index 7c161ee..4813c7f 100644 (file)
@@ -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,
index fd05f66..7ef7023 100644 (file)
@@ -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)
index 1e748b9..bb9f6d1 100644 (file)
@@ -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,
index 6eeb93b..a8b5d66 100644 (file)
@@ -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) {