1fbc8c700SOri Kam /* SPDX-License-Identifier: BSD-3-Clause 2fbc8c700SOri Kam * Copyright 2020 Mellanox Technologies, Ltd 3fbc8c700SOri Kam */ 4fbc8c700SOri Kam 5fbc8c700SOri Kam #include <errno.h> 6fbc8c700SOri Kam 7fbc8c700SOri Kam #include <rte_log.h> 8fbc8c700SOri Kam #include <rte_errno.h> 93ddf5706SMichael Baum #include <rte_memory.h> 10fbc8c700SOri Kam #include <rte_malloc.h> 11fbc8c700SOri Kam #include <rte_regexdev.h> 12fbc8c700SOri Kam #include <rte_regexdev_core.h> 13fbc8c700SOri Kam #include <rte_regexdev_driver.h> 14cda883bbSYuval Avnery #include <rte_dev.h> 15fbc8c700SOri Kam 16fbc8c700SOri Kam #include <mlx5_common.h> 17fbc8c700SOri Kam #include <mlx5_glue.h> 18fbc8c700SOri Kam #include <mlx5_devx_cmds.h> 19fbc8c700SOri Kam #include <mlx5_prm.h> 20fbc8c700SOri Kam #include <mlx5_common_os.h> 213ddf5706SMichael Baum #include <mlx5_common_devx.h> 22fbc8c700SOri Kam 23fbc8c700SOri Kam #include "mlx5_regex.h" 24fbc8c700SOri Kam #include "mlx5_regex_utils.h" 25fbc8c700SOri Kam #include "mlx5_rxp_csrs.h" 26fbc8c700SOri Kam #include "mlx5_rxp.h" 27fbc8c700SOri Kam 28fbc8c700SOri Kam #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64) 29fbc8c700SOri Kam 30330a70b7SSuanming Mou #define MLX5_REGEX_WQE_LOG_NUM(has_umr, log_desc) \ 31330a70b7SSuanming Mou ((has_umr) ? ((log_desc) + 2) : (log_desc)) 32330a70b7SSuanming Mou 33fbc8c700SOri Kam /** 34fbc8c700SOri Kam * Returns the number of qp obj to be created. 35fbc8c700SOri Kam * 36fbc8c700SOri Kam * @param nb_desc 37fbc8c700SOri Kam * The number of descriptors for the queue. 38fbc8c700SOri Kam * 39fbc8c700SOri Kam * @return 40fbc8c700SOri Kam * The number of obj to be created. 41fbc8c700SOri Kam */ 42fbc8c700SOri Kam static uint16_t 43fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc) 44fbc8c700SOri Kam { 45fbc8c700SOri Kam return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) + 46fbc8c700SOri Kam !!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE)); 47fbc8c700SOri Kam } 48fbc8c700SOri Kam 49fbc8c700SOri Kam /** 50fbc8c700SOri Kam * destroy CQ. 51fbc8c700SOri Kam * 52fbc8c700SOri Kam * @param cp 53fbc8c700SOri Kam * Pointer to the CQ to be destroyed. 54fbc8c700SOri Kam * 55fbc8c700SOri Kam * @return 56fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 57fbc8c700SOri Kam */ 58fbc8c700SOri Kam static int 593ddf5706SMichael Baum regex_ctrl_destroy_cq(struct mlx5_regex_cq *cq) 60fbc8c700SOri Kam { 613ddf5706SMichael Baum mlx5_devx_cq_destroy(&cq->cq_obj); 623ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 63fbc8c700SOri Kam return 0; 64fbc8c700SOri Kam } 65fbc8c700SOri Kam 66fbc8c700SOri Kam /** 67fbc8c700SOri Kam * create the CQ object. 68fbc8c700SOri Kam * 69fbc8c700SOri Kam * @param priv 70fbc8c700SOri Kam * Pointer to the priv object. 71fbc8c700SOri Kam * @param cp 72fbc8c700SOri Kam * Pointer to the CQ to be created. 73fbc8c700SOri Kam * 74fbc8c700SOri Kam * @return 75fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 76fbc8c700SOri Kam */ 77fbc8c700SOri Kam static int 78fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq) 79fbc8c700SOri Kam { 80fbc8c700SOri Kam struct mlx5_devx_cq_attr attr = { 813ddf5706SMichael Baum .uar_page_id = priv->uar->page_id, 82fbc8c700SOri Kam }; 833ddf5706SMichael Baum int ret; 84fbc8c700SOri Kam 850db041e7SYuval Avnery cq->ci = 0; 863ddf5706SMichael Baum ret = mlx5_devx_cq_create(priv->ctx, &cq->cq_obj, cq->log_nb_desc, 873ddf5706SMichael Baum &attr, SOCKET_ID_ANY); 883ddf5706SMichael Baum if (ret) { 893ddf5706SMichael Baum DRV_LOG(ERR, "Can't create CQ object."); 903ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 91fbc8c700SOri Kam rte_errno = ENOMEM; 923ddf5706SMichael Baum return -rte_errno; 93fbc8c700SOri Kam } 94fbc8c700SOri Kam return 0; 95fbc8c700SOri Kam } 96fbc8c700SOri Kam 9792f2c6a3SOri Kam /** 989de7b160SMichael Baum * Destroy the SQ object. 999de7b160SMichael Baum * 1009de7b160SMichael Baum * @param qp 1019de7b160SMichael Baum * Pointer to the QP element 1029de7b160SMichael Baum * @param q_ind 1039de7b160SMichael Baum * The index of the queue. 1049de7b160SMichael Baum * 1059de7b160SMichael Baum * @return 1069de7b160SMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set. 1079de7b160SMichael Baum */ 1089de7b160SMichael Baum static int 109*27003260SRaja Zidane regex_ctrl_destroy_hw_qp(struct mlx5_regex_qp *qp, uint16_t q_ind) 1109de7b160SMichael Baum { 111*27003260SRaja Zidane struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind]; 1129de7b160SMichael Baum 113*27003260SRaja Zidane mlx5_devx_qp_destroy(&qp_obj->qp_obj); 114*27003260SRaja Zidane memset(qp, 0, sizeof(*qp)); 1159de7b160SMichael Baum return 0; 1169de7b160SMichael Baum } 1179de7b160SMichael Baum 1189de7b160SMichael Baum /** 11992f2c6a3SOri Kam * create the SQ object. 12092f2c6a3SOri Kam * 12192f2c6a3SOri Kam * @param priv 12292f2c6a3SOri Kam * Pointer to the priv object. 12392f2c6a3SOri Kam * @param qp 12492f2c6a3SOri Kam * Pointer to the QP element 12592f2c6a3SOri Kam * @param q_ind 12692f2c6a3SOri Kam * The index of the queue. 12792f2c6a3SOri Kam * @param log_nb_desc 12892f2c6a3SOri Kam * Log 2 of the number of descriptors to be used. 12992f2c6a3SOri Kam * 13092f2c6a3SOri Kam * @return 13192f2c6a3SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 13292f2c6a3SOri Kam */ 13392f2c6a3SOri Kam static int 134*27003260SRaja Zidane regex_ctrl_create_hw_qp(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp, 13592f2c6a3SOri Kam uint16_t q_ind, uint16_t log_nb_desc) 13692f2c6a3SOri Kam { 13792f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT 138*27003260SRaja Zidane struct mlx5_devx_qp_attr attr = { 1399de7b160SMichael Baum .cqn = qp->cq.cq_obj.cq->id, 140*27003260SRaja Zidane .uar_index = priv->uar->page_id, 141*27003260SRaja Zidane .ts_format = mlx5_ts_format_conv(priv->qp_ts_format), 142*27003260SRaja Zidane .user_index = q_ind, 1439de7b160SMichael Baum }; 144*27003260SRaja Zidane struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind]; 14592f2c6a3SOri Kam uint32_t pd_num = 0; 14692f2c6a3SOri Kam int ret; 14792f2c6a3SOri Kam 148*27003260SRaja Zidane qp_obj->log_nb_desc = log_nb_desc; 149*27003260SRaja Zidane qp_obj->qpn = q_ind; 150*27003260SRaja Zidane qp_obj->ci = 0; 151*27003260SRaja Zidane qp_obj->pi = 0; 1529de7b160SMichael Baum ret = regex_get_pdn(priv->pd, &pd_num); 1539de7b160SMichael Baum if (ret) 1549de7b160SMichael Baum return ret; 155*27003260SRaja Zidane attr.pd = pd_num; 156*27003260SRaja Zidane attr.rq_size = 0; 157*27003260SRaja Zidane attr.sq_size = RTE_BIT32(MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, 158*27003260SRaja Zidane log_nb_desc)); 159*27003260SRaja Zidane attr.mmo = priv->mmo_regex_qp_cap; 160*27003260SRaja Zidane ret = mlx5_devx_qp_create(priv->ctx, &qp_obj->qp_obj, 161330a70b7SSuanming Mou MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_nb_desc), 162330a70b7SSuanming Mou &attr, SOCKET_ID_ANY); 16392f2c6a3SOri Kam if (ret) { 164*27003260SRaja Zidane DRV_LOG(ERR, "Can't create QP object."); 16592f2c6a3SOri Kam rte_errno = ENOMEM; 16692f2c6a3SOri Kam return -rte_errno; 1679de7b160SMichael Baum } 168*27003260SRaja Zidane ret = mlx5_devx_qp2rts(&qp_obj->qp_obj, 0); 1699de7b160SMichael Baum if (ret) { 170*27003260SRaja Zidane DRV_LOG(ERR, "Can't change QP state to RTS."); 171*27003260SRaja Zidane regex_ctrl_destroy_hw_qp(qp, q_ind); 1729de7b160SMichael Baum rte_errno = ENOMEM; 1739de7b160SMichael Baum return -rte_errno; 1749de7b160SMichael Baum } 1759de7b160SMichael Baum return 0; 17692f2c6a3SOri Kam #else 17792f2c6a3SOri Kam (void)priv; 17892f2c6a3SOri Kam (void)qp; 17992f2c6a3SOri Kam (void)q_ind; 18092f2c6a3SOri Kam (void)log_nb_desc; 18192f2c6a3SOri Kam DRV_LOG(ERR, "Cannot get pdn - no DV support."); 18292f2c6a3SOri Kam return -ENOTSUP; 18392f2c6a3SOri Kam #endif 18492f2c6a3SOri Kam } 18592f2c6a3SOri Kam 18692f2c6a3SOri Kam /** 187fbc8c700SOri Kam * Setup the qp. 188fbc8c700SOri Kam * 189fbc8c700SOri Kam * @param dev 190fbc8c700SOri Kam * Pointer to RegEx dev structure. 191fbc8c700SOri Kam * @param qp_ind 192fbc8c700SOri Kam * The queue index to setup. 193fbc8c700SOri Kam * @param cfg 194fbc8c700SOri Kam * The queue requested configuration. 195fbc8c700SOri Kam * 196fbc8c700SOri Kam * @return 197fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 198fbc8c700SOri Kam */ 199fbc8c700SOri Kam int 200fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind, 201fbc8c700SOri Kam const struct rte_regexdev_qp_conf *cfg) 202fbc8c700SOri Kam { 203fbc8c700SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 204fbc8c700SOri Kam struct mlx5_regex_qp *qp; 20592f2c6a3SOri Kam int i; 206a165ee1eSMichael Baum int nb_sq_config = 0; 207fbc8c700SOri Kam int ret; 20892f2c6a3SOri Kam uint16_t log_desc; 209fbc8c700SOri Kam 210fbc8c700SOri Kam qp = &priv->qps[qp_ind]; 211fbc8c700SOri Kam qp->flags = cfg->qp_conf_flags; 212330a70b7SSuanming Mou log_desc = rte_log2_u32(cfg->nb_desc); 213330a70b7SSuanming Mou /* 214330a70b7SSuanming Mou * UMR mode requires two WQEs(UMR and RegEx WQE) for one descriptor. 215330a70b7SSuanming Mou * For CQ, expand the CQE number multiple with 2. 216330a70b7SSuanming Mou * For SQ, the UMR and RegEx WQE for one descriptor consumes 4 WQEBBS, 217330a70b7SSuanming Mou * expand the WQE number multiple with 4. 218330a70b7SSuanming Mou */ 219330a70b7SSuanming Mou qp->cq.log_nb_desc = log_desc + (!!priv->has_umr); 220330a70b7SSuanming Mou qp->nb_desc = 1 << log_desc; 221fbc8c700SOri Kam if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F) 222330a70b7SSuanming Mou qp->nb_obj = regex_ctrl_get_nb_obj 223330a70b7SSuanming Mou (1 << MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_desc)); 224fbc8c700SOri Kam else 225fbc8c700SOri Kam qp->nb_obj = 1; 226*27003260SRaja Zidane qp->qps = rte_malloc(NULL, 227*27003260SRaja Zidane qp->nb_obj * sizeof(struct mlx5_regex_hw_qp), 64); 228*27003260SRaja Zidane if (!qp->qps) { 229*27003260SRaja Zidane DRV_LOG(ERR, "Can't allocate qp array memory."); 230fbc8c700SOri Kam rte_errno = ENOMEM; 231fbc8c700SOri Kam return -rte_errno; 232fbc8c700SOri Kam } 23392f2c6a3SOri Kam log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj); 234fbc8c700SOri Kam ret = regex_ctrl_create_cq(priv, &qp->cq); 235fbc8c700SOri Kam if (ret) { 236fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq."); 23754fa1f6aSYuval Avnery goto err_cq; 238fbc8c700SOri Kam } 23992f2c6a3SOri Kam for (i = 0; i < qp->nb_obj; i++) { 240*27003260SRaja Zidane ret = regex_ctrl_create_hw_qp(priv, qp, i, log_desc); 24192f2c6a3SOri Kam if (ret) { 242*27003260SRaja Zidane DRV_LOG(ERR, "Can't create qp object."); 243a165ee1eSMichael Baum goto err_btree; 24492f2c6a3SOri Kam } 245a165ee1eSMichael Baum nb_sq_config++; 24692f2c6a3SOri Kam } 2475f41b66dSYuval Avnery 24829ca3215SMichael Baum /* Save pointer of global generation number to check memory event. */ 24929ca3215SMichael Baum qp->mr_ctrl.dev_gen_ptr = &priv->mr_scache.dev_gen; 250cda883bbSYuval Avnery ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N, 251cda883bbSYuval Avnery rte_socket_id()); 252cda883bbSYuval Avnery if (ret) { 253cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up mr btree"); 254cda883bbSYuval Avnery goto err_btree; 255cda883bbSYuval Avnery } 256cda883bbSYuval Avnery 25754fa1f6aSYuval Avnery ret = mlx5_regexdev_setup_fastpath(priv, qp_ind); 25854fa1f6aSYuval Avnery if (ret) { 259cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up fastpath"); 26054fa1f6aSYuval Avnery goto err_fp; 26154fa1f6aSYuval Avnery } 262fbc8c700SOri Kam return 0; 263fbc8c700SOri Kam 26454fa1f6aSYuval Avnery err_fp: 265cda883bbSYuval Avnery mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh); 266cda883bbSYuval Avnery err_btree: 267a165ee1eSMichael Baum for (i = 0; i < nb_sq_config; i++) 268*27003260SRaja Zidane regex_ctrl_destroy_hw_qp(qp, i); 2693ddf5706SMichael Baum regex_ctrl_destroy_cq(&qp->cq); 27054fa1f6aSYuval Avnery err_cq: 271*27003260SRaja Zidane rte_free(qp->qps); 27254fa1f6aSYuval Avnery return ret; 273fbc8c700SOri Kam } 274