From: Ajit Khaparde Date: Thu, 28 Jun 2018 20:15:47 +0000 (-0700) Subject: net/bnxt: check VF resources if resource manager is enabled X-Git-Url: http://git.droids-corp.org/?a=commitdiff_plain;h=6d8109bcb3981f63f6caec1532c7f0c7bbde5bb3;p=dpdk.git net/bnxt: check VF resources if resource manager is enabled If HWRM resource manager is enabled, check VF resources before proceeding. Make sure there are enough resources allocated and return an error in case of insufficient error. Signed-off-by: Ajit Khaparde --- diff --git a/drivers/net/bnxt/bnxt.h b/drivers/net/bnxt/bnxt.h index 246b8d4d8d..db5c4eb0db 100644 --- a/drivers/net/bnxt/bnxt.h +++ b/drivers/net/bnxt/bnxt.h @@ -22,6 +22,10 @@ #define BNXT_MAX_MTU 9500 #define VLAN_TAG_SIZE 4 +#define BNXT_VF_RSV_NUM_RSS_CTX 1 +#define BNXT_VF_RSV_NUM_L2_CTX 4 +/* TODO: For now, do not support VMDq/RFS on VFs. */ +#define BNXT_VF_RSV_NUM_VNIC 1 #define BNXT_MAX_LED 4 #define BNXT_NUM_VLANS 2 #define BNXT_MIN_RING_DESC 16 @@ -328,6 +332,7 @@ struct bnxt { struct bnxt_led_info leds[BNXT_MAX_LED]; uint8_t num_leds; struct bnxt_ptp_cfg *ptp_cfg; + uint16_t vf_resv_strategy; }; int bnxt_link_update_op(struct rte_eth_dev *eth_dev, int wait_to_complete); diff --git a/drivers/net/bnxt/bnxt_ethdev.c b/drivers/net/bnxt/bnxt_ethdev.c index e93a3762f0..5701290e1e 100644 --- a/drivers/net/bnxt/bnxt_ethdev.c +++ b/drivers/net/bnxt/bnxt_ethdev.c @@ -510,6 +510,7 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) { struct bnxt *bp = (struct bnxt *)eth_dev->data->dev_private; uint64_t rx_offloads = eth_dev->data->dev_conf.rxmode.offloads; + int rc; bp->rx_queues = (void *)eth_dev->data->rx_queues; bp->tx_queues = (void *)eth_dev->data->tx_queues; @@ -517,19 +518,23 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) bp->rx_nr_rings = eth_dev->data->nb_rx_queues; if (BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM)) { - int rc; + rc = bnxt_hwrm_check_vf_rings(bp); + if (rc) { + PMD_DRV_LOG(ERR, "HWRM insufficient resources\n"); + return -ENOSPC; + } - rc = bnxt_hwrm_func_reserve_vf_resc(bp); + rc = bnxt_hwrm_func_reserve_vf_resc(bp, false); if (rc) { PMD_DRV_LOG(ERR, "HWRM resource alloc fail:%x\n", rc); return -ENOSPC; } - + } else { /* legacy driver needs to get updated values */ rc = bnxt_hwrm_func_qcaps(bp); if (rc) { PMD_DRV_LOG(ERR, "hwrm func qcaps fail:%d\n", rc); - return -ENOSPC; + return rc; } } @@ -540,7 +545,9 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) 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) > bp->max_ring_grps) { + (uint32_t)(eth_dev->data->nb_rx_queues) > bp->max_ring_grps || + (!(eth_dev->data->dev_conf.rxmode.mq_mode & ETH_MQ_RX_RSS) && + bp->max_vnics < eth_dev->data->nb_rx_queues)) { PMD_DRV_LOG(ERR, "Insufficient resources to support requested config\n"); PMD_DRV_LOG(ERR, @@ -548,9 +555,9 @@ static int bnxt_dev_configure_op(struct rte_eth_dev *eth_dev) eth_dev->data->nb_tx_queues, eth_dev->data->nb_rx_queues); PMD_DRV_LOG(ERR, - "Res available: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d\n", + "MAX: TxQ %d, RxQ %d, CQ %d Stat %d, Grp %d, Vnic %d\n", bp->max_tx_rings, bp->max_rx_rings, bp->max_cp_rings, - bp->max_stat_ctx, bp->max_ring_grps); + bp->max_stat_ctx, bp->max_ring_grps, bp->max_vnics); return -ENOSPC; } diff --git a/drivers/net/bnxt/bnxt_hwrm.c b/drivers/net/bnxt/bnxt_hwrm.c index ba8e44a9be..de04fe863d 100644 --- a/drivers/net/bnxt/bnxt_hwrm.c +++ b/drivers/net/bnxt/bnxt_hwrm.c @@ -166,6 +166,18 @@ err_ret: req.resp_addr = rte_cpu_to_le_64(bp->hwrm_cmd_resp_dma_addr); \ } while (0) +#define HWRM_CHECK_RESULT_SILENT() do {\ + if (rc) { \ + rte_spinlock_unlock(&bp->hwrm_lock); \ + return rc; \ + } \ + if (resp->error_code) { \ + rc = rte_le_to_cpu_16(resp->error_code); \ + rte_spinlock_unlock(&bp->hwrm_lock); \ + return rc; \ + } \ +} while (0) + #define HWRM_CHECK_RESULT() do {\ if (rc) { \ PMD_DRV_LOG(ERR, "failed rc:%d\n", rc); \ @@ -658,9 +670,19 @@ int bnxt_hwrm_func_driver_register(struct bnxt *bp) return rc; } -int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp) +int bnxt_hwrm_check_vf_rings(struct bnxt *bp) +{ + if (!(BNXT_VF(bp) && (bp->flags & BNXT_FLAG_NEW_RM))) + return 0; + + return bnxt_hwrm_func_reserve_vf_resc(bp, true); +} + +int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test) { int rc; + uint32_t flags = 0; + uint32_t enables; struct hwrm_func_vf_cfg_output *resp = bp->hwrm_cmd_resp_addr; struct hwrm_func_vf_cfg_input req = {0}; @@ -671,7 +693,8 @@ int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp) HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_TX_RINGS | HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_STAT_CTXS | HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_CMPL_RINGS | - HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS); + HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_HW_RING_GRPS | + HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS); req.num_tx_rings = rte_cpu_to_le_16(bp->tx_nr_rings); req.num_rx_rings = rte_cpu_to_le_16(bp->rx_nr_rings * @@ -680,10 +703,35 @@ int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp) req.num_cmpl_rings = rte_cpu_to_le_16(bp->rx_nr_rings + bp->tx_nr_rings); req.num_hw_ring_grps = rte_cpu_to_le_16(bp->rx_nr_rings); + req.num_vnics = rte_cpu_to_le_16(bp->rx_nr_rings); + if (bp->vf_resv_strategy == + HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC) { + enables = HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_VNICS | + HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_L2_CTXS | + HWRM_FUNC_VF_CFG_INPUT_ENABLES_NUM_RSSCOS_CTXS; + req.enables |= rte_cpu_to_le_32(enables); + req.num_rsscos_ctxs = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_RSS_CTX); + req.num_l2_ctxs = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_L2_CTX); + req.num_vnics = rte_cpu_to_le_16(BNXT_VF_RSV_NUM_VNIC); + } + + if (test) + flags = HWRM_FUNC_VF_CFG_INPUT_FLAGS_TX_ASSETS_TEST | + HWRM_FUNC_VF_CFG_INPUT_FLAGS_RX_ASSETS_TEST | + HWRM_FUNC_VF_CFG_INPUT_FLAGS_CMPL_ASSETS_TEST | + HWRM_FUNC_VF_CFG_INPUT_FLAGS_RING_GRP_ASSETS_TEST | + HWRM_FUNC_VF_CFG_INPUT_FLAGS_STAT_CTX_ASSETS_TEST | + HWRM_FUNC_VF_CFG_INPUT_FLAGS_VNIC_ASSETS_TEST; + + req.flags = rte_cpu_to_le_32(flags); rc = bnxt_hwrm_send_message(bp, &req, sizeof(req)); - HWRM_CHECK_RESULT(); + if (test) + HWRM_CHECK_RESULT_SILENT(); + else + HWRM_CHECK_RESULT(); + HWRM_UNLOCK(); return rc; } @@ -711,6 +759,11 @@ int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp) bp->max_vnics = rte_le_to_cpu_16(resp->max_vnics); bp->max_stat_ctx = rte_le_to_cpu_16(resp->max_stat_ctx); } + bp->vf_resv_strategy = rte_le_to_cpu_16(resp->vf_reservation_strategy); + if (bp->vf_resv_strategy > + HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC) + bp->vf_resv_strategy = + HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MAXIMAL; HWRM_UNLOCK(); return rc; diff --git a/drivers/net/bnxt/bnxt_hwrm.h b/drivers/net/bnxt/bnxt_hwrm.h index 4a237c4b45..379aac6e1e 100644 --- a/drivers/net/bnxt/bnxt_hwrm.h +++ b/drivers/net/bnxt/bnxt_hwrm.h @@ -29,6 +29,9 @@ struct bnxt_cp_ring_info; #define HWRM_QUEUE_SERVICE_PROFILE_LOSSY \ HWRM_QUEUE_QPORTCFG_OUTPUT_QUEUE_ID0_SERVICE_PROFILE_LOSSY +#define HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESV_STRATEGY_MINIMAL_STATIC \ + HWRM_FUNC_RESOURCE_QCAPS_OUTPUT_VF_RESERVATION_STRATEGY_MINIMAL_STATIC + int bnxt_hwrm_cfa_l2_clear_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic); int bnxt_hwrm_cfa_l2_set_rx_mask(struct bnxt *bp, struct bnxt_vnic_info *vnic, @@ -113,7 +116,7 @@ int bnxt_get_hwrm_link_config(struct bnxt *bp, struct rte_eth_link *link); int bnxt_set_hwrm_link_config(struct bnxt *bp, bool link_up); int bnxt_hwrm_func_qcfg(struct bnxt *bp); int bnxt_hwrm_func_resc_qcaps(struct bnxt *bp); -int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp); +int bnxt_hwrm_func_reserve_vf_resc(struct bnxt *bp, bool test); int bnxt_hwrm_allocate_pf_only(struct bnxt *bp); int bnxt_hwrm_allocate_vfs(struct bnxt *bp, int num_vfs); int bnxt_hwrm_func_vf_mac(struct bnxt *bp, uint16_t vf, @@ -170,4 +173,5 @@ int bnxt_vnic_rss_configure(struct bnxt *bp, struct bnxt_vnic_info *vnic); int bnxt_hwrm_set_ring_coal(struct bnxt *bp, struct bnxt_coal *coal, uint16_t ring_id); +int bnxt_hwrm_check_vf_rings(struct bnxt *bp); #endif