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 30*330a70b7SSuanming Mou #define MLX5_REGEX_WQE_LOG_NUM(has_umr, log_desc) \ 31*330a70b7SSuanming Mou ((has_umr) ? ((log_desc) + 2) : (log_desc)) 32*330a70b7SSuanming 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 1099de7b160SMichael Baum regex_ctrl_destroy_sq(struct mlx5_regex_qp *qp, uint16_t q_ind) 1109de7b160SMichael Baum { 1119de7b160SMichael Baum struct mlx5_regex_sq *sq = &qp->sqs[q_ind]; 1129de7b160SMichael Baum 1139de7b160SMichael Baum mlx5_devx_sq_destroy(&sq->sq_obj); 1149de7b160SMichael Baum memset(sq, 0, sizeof(*sq)); 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 13492f2c6a3SOri Kam regex_ctrl_create_sq(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 1389de7b160SMichael Baum struct mlx5_devx_create_sq_attr attr = { 1399de7b160SMichael Baum .user_index = q_ind, 1409de7b160SMichael Baum .cqn = qp->cq.cq_obj.cq->id, 1419de7b160SMichael Baum .wq_attr = (struct mlx5_devx_wq_attr){ 1429de7b160SMichael Baum .uar_page = priv->uar->page_id, 1439de7b160SMichael Baum }, 144dd25bd20SViacheslav Ovsiienko .ts_format = mlx5_ts_format_conv(priv->sq_ts_format), 1459de7b160SMichael Baum }; 1469de7b160SMichael Baum struct mlx5_devx_modify_sq_attr modify_attr = { 1479de7b160SMichael Baum .state = MLX5_SQC_STATE_RDY, 1489de7b160SMichael Baum }; 14992f2c6a3SOri Kam struct mlx5_regex_sq *sq = &qp->sqs[q_ind]; 15092f2c6a3SOri Kam uint32_t pd_num = 0; 15192f2c6a3SOri Kam int ret; 15292f2c6a3SOri Kam 15392f2c6a3SOri Kam sq->log_nb_desc = log_nb_desc; 154*330a70b7SSuanming Mou sq->sqn = q_ind; 1554d4e245aSYuval Avnery sq->ci = 0; 1564d4e245aSYuval Avnery sq->pi = 0; 1579de7b160SMichael Baum ret = regex_get_pdn(priv->pd, &pd_num); 1589de7b160SMichael Baum if (ret) 1599de7b160SMichael Baum return ret; 1609de7b160SMichael Baum attr.wq_attr.pd = pd_num; 161*330a70b7SSuanming Mou ret = mlx5_devx_sq_create(priv->ctx, &sq->sq_obj, 162*330a70b7SSuanming Mou MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_nb_desc), 163*330a70b7SSuanming Mou &attr, SOCKET_ID_ANY); 16492f2c6a3SOri Kam if (ret) { 1659de7b160SMichael Baum DRV_LOG(ERR, "Can't create SQ object."); 16692f2c6a3SOri Kam rte_errno = ENOMEM; 16792f2c6a3SOri Kam return -rte_errno; 1689de7b160SMichael Baum } 1699de7b160SMichael Baum ret = mlx5_devx_cmd_modify_sq(sq->sq_obj.sq, &modify_attr); 1709de7b160SMichael Baum if (ret) { 1719de7b160SMichael Baum DRV_LOG(ERR, "Can't change SQ state to ready."); 1729de7b160SMichael Baum regex_ctrl_destroy_sq(qp, q_ind); 1739de7b160SMichael Baum rte_errno = ENOMEM; 1749de7b160SMichael Baum return -rte_errno; 1759de7b160SMichael Baum } 1769de7b160SMichael Baum return 0; 17792f2c6a3SOri Kam #else 17892f2c6a3SOri Kam (void)priv; 17992f2c6a3SOri Kam (void)qp; 18092f2c6a3SOri Kam (void)q_ind; 18192f2c6a3SOri Kam (void)log_nb_desc; 18292f2c6a3SOri Kam DRV_LOG(ERR, "Cannot get pdn - no DV support."); 18392f2c6a3SOri Kam return -ENOTSUP; 18492f2c6a3SOri Kam #endif 18592f2c6a3SOri Kam } 18692f2c6a3SOri Kam 18792f2c6a3SOri Kam /** 188fbc8c700SOri Kam * Setup the qp. 189fbc8c700SOri Kam * 190fbc8c700SOri Kam * @param dev 191fbc8c700SOri Kam * Pointer to RegEx dev structure. 192fbc8c700SOri Kam * @param qp_ind 193fbc8c700SOri Kam * The queue index to setup. 194fbc8c700SOri Kam * @param cfg 195fbc8c700SOri Kam * The queue requested configuration. 196fbc8c700SOri Kam * 197fbc8c700SOri Kam * @return 198fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 199fbc8c700SOri Kam */ 200fbc8c700SOri Kam int 201fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind, 202fbc8c700SOri Kam const struct rte_regexdev_qp_conf *cfg) 203fbc8c700SOri Kam { 204fbc8c700SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 205fbc8c700SOri Kam struct mlx5_regex_qp *qp; 20692f2c6a3SOri Kam int i; 207a165ee1eSMichael Baum int nb_sq_config = 0; 208fbc8c700SOri Kam int ret; 20992f2c6a3SOri Kam uint16_t log_desc; 210fbc8c700SOri Kam 211fbc8c700SOri Kam qp = &priv->qps[qp_ind]; 212fbc8c700SOri Kam qp->flags = cfg->qp_conf_flags; 213*330a70b7SSuanming Mou log_desc = rte_log2_u32(cfg->nb_desc); 214*330a70b7SSuanming Mou /* 215*330a70b7SSuanming Mou * UMR mode requires two WQEs(UMR and RegEx WQE) for one descriptor. 216*330a70b7SSuanming Mou * For CQ, expand the CQE number multiple with 2. 217*330a70b7SSuanming Mou * For SQ, the UMR and RegEx WQE for one descriptor consumes 4 WQEBBS, 218*330a70b7SSuanming Mou * expand the WQE number multiple with 4. 219*330a70b7SSuanming Mou */ 220*330a70b7SSuanming Mou qp->cq.log_nb_desc = log_desc + (!!priv->has_umr); 221*330a70b7SSuanming Mou qp->nb_desc = 1 << log_desc; 222fbc8c700SOri Kam if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F) 223*330a70b7SSuanming Mou qp->nb_obj = regex_ctrl_get_nb_obj 224*330a70b7SSuanming Mou (1 << MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_desc)); 225fbc8c700SOri Kam else 226fbc8c700SOri Kam qp->nb_obj = 1; 227fbc8c700SOri Kam qp->sqs = rte_malloc(NULL, 228fbc8c700SOri Kam qp->nb_obj * sizeof(struct mlx5_regex_sq), 64); 229fbc8c700SOri Kam if (!qp->sqs) { 230fbc8c700SOri Kam DRV_LOG(ERR, "Can't allocate sq array memory."); 231fbc8c700SOri Kam rte_errno = ENOMEM; 232fbc8c700SOri Kam return -rte_errno; 233fbc8c700SOri Kam } 23492f2c6a3SOri Kam log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj); 235fbc8c700SOri Kam ret = regex_ctrl_create_cq(priv, &qp->cq); 236fbc8c700SOri Kam if (ret) { 237fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq."); 23854fa1f6aSYuval Avnery goto err_cq; 239fbc8c700SOri Kam } 24092f2c6a3SOri Kam for (i = 0; i < qp->nb_obj; i++) { 24192f2c6a3SOri Kam ret = regex_ctrl_create_sq(priv, qp, i, log_desc); 24292f2c6a3SOri Kam if (ret) { 24392f2c6a3SOri Kam DRV_LOG(ERR, "Can't create sq."); 244a165ee1eSMichael Baum goto err_btree; 24592f2c6a3SOri Kam } 246a165ee1eSMichael Baum nb_sq_config++; 24792f2c6a3SOri Kam } 2485f41b66dSYuval Avnery 249cda883bbSYuval Avnery ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N, 250cda883bbSYuval Avnery rte_socket_id()); 251cda883bbSYuval Avnery if (ret) { 252cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up mr btree"); 253cda883bbSYuval Avnery goto err_btree; 254cda883bbSYuval Avnery } 255cda883bbSYuval Avnery 25654fa1f6aSYuval Avnery ret = mlx5_regexdev_setup_fastpath(priv, qp_ind); 25754fa1f6aSYuval Avnery if (ret) { 258cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up fastpath"); 25954fa1f6aSYuval Avnery goto err_fp; 26054fa1f6aSYuval Avnery } 261fbc8c700SOri Kam return 0; 262fbc8c700SOri Kam 26354fa1f6aSYuval Avnery err_fp: 264cda883bbSYuval Avnery mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh); 265cda883bbSYuval Avnery err_btree: 266a165ee1eSMichael Baum for (i = 0; i < nb_sq_config; i++) 2679de7b160SMichael Baum regex_ctrl_destroy_sq(qp, i); 2683ddf5706SMichael Baum regex_ctrl_destroy_cq(&qp->cq); 26954fa1f6aSYuval Avnery err_cq: 27054fa1f6aSYuval Avnery rte_free(qp->sqs); 27154fa1f6aSYuval Avnery return ret; 272fbc8c700SOri Kam } 273