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;
}
#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
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;
/* 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,
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);
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);
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,
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));
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;
}
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)
{
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,
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);
}
{
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)
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);
}
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++) {
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,
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)
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
}
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) {