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.h" 26fbc8c700SOri Kam 27fbc8c700SOri Kam #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64) 28fbc8c700SOri Kam 29330a70b7SSuanming Mou #define MLX5_REGEX_WQE_LOG_NUM(has_umr, log_desc) \ 30330a70b7SSuanming Mou ((has_umr) ? ((log_desc) + 2) : (log_desc)) 31330a70b7SSuanming Mou 32fbc8c700SOri Kam /** 33fbc8c700SOri Kam * Returns the number of qp obj to be created. 34fbc8c700SOri Kam * 35fbc8c700SOri Kam * @param nb_desc 36fbc8c700SOri Kam * The number of descriptors for the queue. 37fbc8c700SOri Kam * 38fbc8c700SOri Kam * @return 39fbc8c700SOri Kam * The number of obj to be created. 40fbc8c700SOri Kam */ 41fbc8c700SOri Kam static uint16_t 42fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc) 43fbc8c700SOri Kam { 44fbc8c700SOri Kam return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) + 45fbc8c700SOri Kam !!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE)); 46fbc8c700SOri Kam } 47fbc8c700SOri Kam 48fbc8c700SOri Kam /** 49fbc8c700SOri Kam * destroy CQ. 50fbc8c700SOri Kam * 51fbc8c700SOri Kam * @param cp 52fbc8c700SOri Kam * Pointer to the CQ to be destroyed. 53fbc8c700SOri Kam * 54fbc8c700SOri Kam * @return 55fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 56fbc8c700SOri Kam */ 57fbc8c700SOri Kam static int 583ddf5706SMichael Baum regex_ctrl_destroy_cq(struct mlx5_regex_cq *cq) 59fbc8c700SOri Kam { 603ddf5706SMichael Baum mlx5_devx_cq_destroy(&cq->cq_obj); 613ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 62fbc8c700SOri Kam return 0; 63fbc8c700SOri Kam } 64fbc8c700SOri Kam 65fbc8c700SOri Kam /** 66fbc8c700SOri Kam * create the CQ object. 67fbc8c700SOri Kam * 68fbc8c700SOri Kam * @param priv 69fbc8c700SOri Kam * Pointer to the priv object. 70fbc8c700SOri Kam * @param cp 71fbc8c700SOri Kam * Pointer to the CQ to be created. 72fbc8c700SOri Kam * 73fbc8c700SOri Kam * @return 74fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 75fbc8c700SOri Kam */ 76fbc8c700SOri Kam static int 77fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq) 78fbc8c700SOri Kam { 79fbc8c700SOri Kam struct mlx5_devx_cq_attr attr = { 80*5dfa003dSMichael Baum .uar_page_id = mlx5_os_get_devx_uar_page_id(priv->uar.obj), 81fbc8c700SOri Kam }; 823ddf5706SMichael Baum int ret; 83fbc8c700SOri Kam 840db041e7SYuval Avnery cq->ci = 0; 85ca1418ceSMichael Baum ret = mlx5_devx_cq_create(priv->cdev->ctx, &cq->cq_obj, cq->log_nb_desc, 863ddf5706SMichael Baum &attr, SOCKET_ID_ANY); 873ddf5706SMichael Baum if (ret) { 883ddf5706SMichael Baum DRV_LOG(ERR, "Can't create CQ object."); 893ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 90fbc8c700SOri Kam rte_errno = ENOMEM; 913ddf5706SMichael Baum return -rte_errno; 92fbc8c700SOri Kam } 93fbc8c700SOri Kam return 0; 94fbc8c700SOri Kam } 95fbc8c700SOri Kam 9692f2c6a3SOri Kam /** 979de7b160SMichael Baum * Destroy the SQ object. 989de7b160SMichael Baum * 999de7b160SMichael Baum * @param qp 1009de7b160SMichael Baum * Pointer to the QP element 1019de7b160SMichael Baum * @param q_ind 1029de7b160SMichael Baum * The index of the queue. 1039de7b160SMichael Baum * 1049de7b160SMichael Baum * @return 1059de7b160SMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set. 1069de7b160SMichael Baum */ 1079de7b160SMichael Baum static int 10827003260SRaja Zidane regex_ctrl_destroy_hw_qp(struct mlx5_regex_qp *qp, uint16_t q_ind) 1099de7b160SMichael Baum { 11027003260SRaja Zidane struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind]; 1119de7b160SMichael Baum 11227003260SRaja Zidane mlx5_devx_qp_destroy(&qp_obj->qp_obj); 11327003260SRaja Zidane memset(qp, 0, sizeof(*qp)); 1149de7b160SMichael Baum return 0; 1159de7b160SMichael Baum } 1169de7b160SMichael Baum 1179de7b160SMichael Baum /** 11892f2c6a3SOri Kam * create the SQ object. 11992f2c6a3SOri Kam * 12092f2c6a3SOri Kam * @param priv 12192f2c6a3SOri Kam * Pointer to the priv object. 12292f2c6a3SOri Kam * @param qp 12392f2c6a3SOri Kam * Pointer to the QP element 12492f2c6a3SOri Kam * @param q_ind 12592f2c6a3SOri Kam * The index of the queue. 12692f2c6a3SOri Kam * @param log_nb_desc 12792f2c6a3SOri Kam * Log 2 of the number of descriptors to be used. 12892f2c6a3SOri Kam * 12992f2c6a3SOri Kam * @return 13092f2c6a3SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 13192f2c6a3SOri Kam */ 13292f2c6a3SOri Kam static int 13327003260SRaja Zidane regex_ctrl_create_hw_qp(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp, 13492f2c6a3SOri Kam uint16_t q_ind, uint16_t log_nb_desc) 13592f2c6a3SOri Kam { 13692f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT 13727003260SRaja Zidane struct mlx5_devx_qp_attr attr = { 1389de7b160SMichael Baum .cqn = qp->cq.cq_obj.cq->id, 139*5dfa003dSMichael Baum .uar_index = mlx5_os_get_devx_uar_page_id(priv->uar.obj), 140e35ccf24SMichael Baum .pd = priv->cdev->pdn, 141fe46b20cSMichael Baum .ts_format = mlx5_ts_format_conv 142fe46b20cSMichael Baum (priv->cdev->config.hca_attr.qp_ts_format), 14327003260SRaja Zidane .user_index = q_ind, 1449de7b160SMichael Baum }; 14527003260SRaja Zidane struct mlx5_regex_hw_qp *qp_obj = &qp->qps[q_ind]; 14692f2c6a3SOri Kam int ret; 14792f2c6a3SOri Kam 14827003260SRaja Zidane qp_obj->log_nb_desc = log_nb_desc; 14927003260SRaja Zidane qp_obj->qpn = q_ind; 15027003260SRaja Zidane qp_obj->ci = 0; 15127003260SRaja Zidane qp_obj->pi = 0; 15227003260SRaja Zidane attr.rq_size = 0; 15327003260SRaja Zidane attr.sq_size = RTE_BIT32(MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, 15427003260SRaja Zidane log_nb_desc)); 15527003260SRaja Zidane attr.mmo = priv->mmo_regex_qp_cap; 156ca1418ceSMichael Baum ret = mlx5_devx_qp_create(priv->cdev->ctx, &qp_obj->qp_obj, 157330a70b7SSuanming Mou MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_nb_desc), 158330a70b7SSuanming Mou &attr, SOCKET_ID_ANY); 15992f2c6a3SOri Kam if (ret) { 16027003260SRaja Zidane DRV_LOG(ERR, "Can't create QP object."); 16192f2c6a3SOri Kam rte_errno = ENOMEM; 16292f2c6a3SOri Kam return -rte_errno; 1639de7b160SMichael Baum } 16427003260SRaja Zidane ret = mlx5_devx_qp2rts(&qp_obj->qp_obj, 0); 1659de7b160SMichael Baum if (ret) { 16627003260SRaja Zidane DRV_LOG(ERR, "Can't change QP state to RTS."); 16727003260SRaja Zidane regex_ctrl_destroy_hw_qp(qp, q_ind); 1689de7b160SMichael Baum rte_errno = ENOMEM; 1699de7b160SMichael Baum return -rte_errno; 1709de7b160SMichael Baum } 1719de7b160SMichael Baum return 0; 17292f2c6a3SOri Kam #else 17392f2c6a3SOri Kam (void)priv; 17492f2c6a3SOri Kam (void)qp; 17592f2c6a3SOri Kam (void)q_ind; 17692f2c6a3SOri Kam (void)log_nb_desc; 17792f2c6a3SOri Kam DRV_LOG(ERR, "Cannot get pdn - no DV support."); 17892f2c6a3SOri Kam return -ENOTSUP; 17992f2c6a3SOri Kam #endif 18092f2c6a3SOri Kam } 18192f2c6a3SOri Kam 18292f2c6a3SOri Kam /** 183fbc8c700SOri Kam * Setup the qp. 184fbc8c700SOri Kam * 185fbc8c700SOri Kam * @param dev 186fbc8c700SOri Kam * Pointer to RegEx dev structure. 187fbc8c700SOri Kam * @param qp_ind 188fbc8c700SOri Kam * The queue index to setup. 189fbc8c700SOri Kam * @param cfg 190fbc8c700SOri Kam * The queue requested configuration. 191fbc8c700SOri Kam * 192fbc8c700SOri Kam * @return 193fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 194fbc8c700SOri Kam */ 195fbc8c700SOri Kam int 196fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind, 197fbc8c700SOri Kam const struct rte_regexdev_qp_conf *cfg) 198fbc8c700SOri Kam { 199fbc8c700SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 200fbc8c700SOri Kam struct mlx5_regex_qp *qp; 20192f2c6a3SOri Kam int i; 202a165ee1eSMichael Baum int nb_sq_config = 0; 203fbc8c700SOri Kam int ret; 20492f2c6a3SOri Kam uint16_t log_desc; 205fbc8c700SOri Kam 206fbc8c700SOri Kam qp = &priv->qps[qp_ind]; 207b5832a0dSAdy Agbarih if (qp->jobs) { 208b5832a0dSAdy Agbarih DRV_LOG(ERR, "Attempting to setup QP a second time."); 209b5832a0dSAdy Agbarih rte_errno = EINVAL; 210b5832a0dSAdy Agbarih return -rte_errno; 211b5832a0dSAdy Agbarih } 212b5832a0dSAdy Agbarih 213fbc8c700SOri Kam qp->flags = cfg->qp_conf_flags; 214330a70b7SSuanming Mou log_desc = rte_log2_u32(cfg->nb_desc); 215330a70b7SSuanming Mou /* 216330a70b7SSuanming Mou * UMR mode requires two WQEs(UMR and RegEx WQE) for one descriptor. 217330a70b7SSuanming Mou * For CQ, expand the CQE number multiple with 2. 218330a70b7SSuanming Mou * For SQ, the UMR and RegEx WQE for one descriptor consumes 4 WQEBBS, 219330a70b7SSuanming Mou * expand the WQE number multiple with 4. 220330a70b7SSuanming Mou */ 221330a70b7SSuanming Mou qp->cq.log_nb_desc = log_desc + (!!priv->has_umr); 222330a70b7SSuanming Mou qp->nb_desc = 1 << log_desc; 223fbc8c700SOri Kam if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F) 224330a70b7SSuanming Mou qp->nb_obj = regex_ctrl_get_nb_obj 225330a70b7SSuanming Mou (1 << MLX5_REGEX_WQE_LOG_NUM(priv->has_umr, log_desc)); 226fbc8c700SOri Kam else 227fbc8c700SOri Kam qp->nb_obj = 1; 22827003260SRaja Zidane qp->qps = rte_malloc(NULL, 22927003260SRaja Zidane qp->nb_obj * sizeof(struct mlx5_regex_hw_qp), 64); 23027003260SRaja Zidane if (!qp->qps) { 23127003260SRaja Zidane DRV_LOG(ERR, "Can't allocate qp array memory."); 232fbc8c700SOri Kam rte_errno = ENOMEM; 233fbc8c700SOri Kam return -rte_errno; 234fbc8c700SOri Kam } 23592f2c6a3SOri Kam log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj); 236fbc8c700SOri Kam ret = regex_ctrl_create_cq(priv, &qp->cq); 237fbc8c700SOri Kam if (ret) { 238fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq."); 23954fa1f6aSYuval Avnery goto err_cq; 240fbc8c700SOri Kam } 24192f2c6a3SOri Kam for (i = 0; i < qp->nb_obj; i++) { 24227003260SRaja Zidane ret = regex_ctrl_create_hw_qp(priv, qp, i, log_desc); 24392f2c6a3SOri Kam if (ret) { 24427003260SRaja Zidane DRV_LOG(ERR, "Can't create qp object."); 245a165ee1eSMichael Baum goto err_btree; 24692f2c6a3SOri Kam } 247a165ee1eSMichael Baum nb_sq_config++; 24892f2c6a3SOri Kam } 2495f41b66dSYuval Avnery 250334ed198SMichael Baum ret = mlx5_mr_ctrl_init(&qp->mr_ctrl, priv->cdev, 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++) 26727003260SRaja Zidane regex_ctrl_destroy_hw_qp(qp, i); 2683ddf5706SMichael Baum regex_ctrl_destroy_cq(&qp->cq); 26954fa1f6aSYuval Avnery err_cq: 27027003260SRaja Zidane rte_free(qp->qps); 27154fa1f6aSYuval Avnery return ret; 272fbc8c700SOri Kam } 273fe375336SOri Kam 274fe375336SOri Kam void 275fe375336SOri Kam mlx5_regex_clean_ctrl(struct rte_regexdev *dev) 276fe375336SOri Kam { 277fe375336SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 278fe375336SOri Kam struct mlx5_regex_qp *qp; 279fe375336SOri Kam int qp_ind; 280fe375336SOri Kam int i; 281fe375336SOri Kam 282fe375336SOri Kam if (!priv->qps) 283fe375336SOri Kam return; 284fe375336SOri Kam for (qp_ind = 0; qp_ind < priv->nb_queues; qp_ind++) { 285fe375336SOri Kam qp = &priv->qps[qp_ind]; 286fe375336SOri Kam /* Check if mlx5_regex_qp_setup() was called for this QP */ 287fe375336SOri Kam if (!qp->jobs) 288fe375336SOri Kam continue; 289fe375336SOri Kam mlx5_regexdev_teardown_fastpath(priv, qp_ind); 290fe375336SOri Kam mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh); 291fe375336SOri Kam for (i = 0; i < qp->nb_obj; i++) 292fe375336SOri Kam regex_ctrl_destroy_hw_qp(qp, i); 293fe375336SOri Kam regex_ctrl_destroy_cq(&qp->cq); 294fe375336SOri Kam } 295fe375336SOri Kam } 296