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 30fbc8c700SOri Kam /** 31fbc8c700SOri Kam * Returns the number of qp obj to be created. 32fbc8c700SOri Kam * 33fbc8c700SOri Kam * @param nb_desc 34fbc8c700SOri Kam * The number of descriptors for the queue. 35fbc8c700SOri Kam * 36fbc8c700SOri Kam * @return 37fbc8c700SOri Kam * The number of obj to be created. 38fbc8c700SOri Kam */ 39fbc8c700SOri Kam static uint16_t 40fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc) 41fbc8c700SOri Kam { 42fbc8c700SOri Kam return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) + 43fbc8c700SOri Kam !!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE)); 44fbc8c700SOri Kam } 45fbc8c700SOri Kam 46fbc8c700SOri Kam /** 47fbc8c700SOri Kam * destroy CQ. 48fbc8c700SOri Kam * 49fbc8c700SOri Kam * @param cp 50fbc8c700SOri Kam * Pointer to the CQ to be destroyed. 51fbc8c700SOri Kam * 52fbc8c700SOri Kam * @return 53fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 54fbc8c700SOri Kam */ 55fbc8c700SOri Kam static int 563ddf5706SMichael Baum regex_ctrl_destroy_cq(struct mlx5_regex_cq *cq) 57fbc8c700SOri Kam { 583ddf5706SMichael Baum mlx5_devx_cq_destroy(&cq->cq_obj); 593ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 60fbc8c700SOri Kam return 0; 61fbc8c700SOri Kam } 62fbc8c700SOri Kam 63fbc8c700SOri Kam /** 64fbc8c700SOri Kam * create the CQ object. 65fbc8c700SOri Kam * 66fbc8c700SOri Kam * @param priv 67fbc8c700SOri Kam * Pointer to the priv object. 68fbc8c700SOri Kam * @param cp 69fbc8c700SOri Kam * Pointer to the CQ to be created. 70fbc8c700SOri Kam * 71fbc8c700SOri Kam * @return 72fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 73fbc8c700SOri Kam */ 74fbc8c700SOri Kam static int 75fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq) 76fbc8c700SOri Kam { 77fbc8c700SOri Kam struct mlx5_devx_cq_attr attr = { 783ddf5706SMichael Baum .uar_page_id = priv->uar->page_id, 79fbc8c700SOri Kam }; 803ddf5706SMichael Baum int ret; 81fbc8c700SOri Kam 820db041e7SYuval Avnery cq->ci = 0; 833ddf5706SMichael Baum ret = mlx5_devx_cq_create(priv->ctx, &cq->cq_obj, cq->log_nb_desc, 843ddf5706SMichael Baum &attr, SOCKET_ID_ANY); 853ddf5706SMichael Baum if (ret) { 863ddf5706SMichael Baum DRV_LOG(ERR, "Can't create CQ object."); 873ddf5706SMichael Baum memset(cq, 0, sizeof(*cq)); 88fbc8c700SOri Kam rte_errno = ENOMEM; 893ddf5706SMichael Baum return -rte_errno; 90fbc8c700SOri Kam } 91fbc8c700SOri Kam return 0; 92fbc8c700SOri Kam } 93fbc8c700SOri Kam 9492f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT 9592f2c6a3SOri Kam static int 9692f2c6a3SOri Kam regex_get_pdn(void *pd, uint32_t *pdn) 9792f2c6a3SOri Kam { 9892f2c6a3SOri Kam struct mlx5dv_obj obj; 9992f2c6a3SOri Kam struct mlx5dv_pd pd_info; 10092f2c6a3SOri Kam int ret = 0; 10192f2c6a3SOri Kam 10292f2c6a3SOri Kam obj.pd.in = pd; 10392f2c6a3SOri Kam obj.pd.out = &pd_info; 10492f2c6a3SOri Kam ret = mlx5_glue->dv_init_obj(&obj, MLX5DV_OBJ_PD); 10592f2c6a3SOri Kam if (ret) { 10692f2c6a3SOri Kam DRV_LOG(DEBUG, "Fail to get PD object info"); 10792f2c6a3SOri Kam return ret; 10892f2c6a3SOri Kam } 10992f2c6a3SOri Kam *pdn = pd_info.pdn; 11092f2c6a3SOri Kam return 0; 11192f2c6a3SOri Kam } 11292f2c6a3SOri Kam #endif 11392f2c6a3SOri Kam 11492f2c6a3SOri Kam /** 115*9de7b160SMichael Baum * Destroy the SQ object. 116*9de7b160SMichael Baum * 117*9de7b160SMichael Baum * @param qp 118*9de7b160SMichael Baum * Pointer to the QP element 119*9de7b160SMichael Baum * @param q_ind 120*9de7b160SMichael Baum * The index of the queue. 121*9de7b160SMichael Baum * 122*9de7b160SMichael Baum * @return 123*9de7b160SMichael Baum * 0 on success, a negative errno value otherwise and rte_errno is set. 124*9de7b160SMichael Baum */ 125*9de7b160SMichael Baum static int 126*9de7b160SMichael Baum regex_ctrl_destroy_sq(struct mlx5_regex_qp *qp, uint16_t q_ind) 127*9de7b160SMichael Baum { 128*9de7b160SMichael Baum struct mlx5_regex_sq *sq = &qp->sqs[q_ind]; 129*9de7b160SMichael Baum 130*9de7b160SMichael Baum mlx5_devx_sq_destroy(&sq->sq_obj); 131*9de7b160SMichael Baum memset(sq, 0, sizeof(*sq)); 132*9de7b160SMichael Baum return 0; 133*9de7b160SMichael Baum } 134*9de7b160SMichael Baum 135*9de7b160SMichael Baum /** 13692f2c6a3SOri Kam * create the SQ object. 13792f2c6a3SOri Kam * 13892f2c6a3SOri Kam * @param priv 13992f2c6a3SOri Kam * Pointer to the priv object. 14092f2c6a3SOri Kam * @param qp 14192f2c6a3SOri Kam * Pointer to the QP element 14292f2c6a3SOri Kam * @param q_ind 14392f2c6a3SOri Kam * The index of the queue. 14492f2c6a3SOri Kam * @param log_nb_desc 14592f2c6a3SOri Kam * Log 2 of the number of descriptors to be used. 14692f2c6a3SOri Kam * 14792f2c6a3SOri Kam * @return 14892f2c6a3SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 14992f2c6a3SOri Kam */ 15092f2c6a3SOri Kam static int 15192f2c6a3SOri Kam regex_ctrl_create_sq(struct mlx5_regex_priv *priv, struct mlx5_regex_qp *qp, 15292f2c6a3SOri Kam uint16_t q_ind, uint16_t log_nb_desc) 15392f2c6a3SOri Kam { 15492f2c6a3SOri Kam #ifdef HAVE_IBV_FLOW_DV_SUPPORT 155*9de7b160SMichael Baum struct mlx5_devx_create_sq_attr attr = { 156*9de7b160SMichael Baum .user_index = q_ind, 157*9de7b160SMichael Baum .cqn = qp->cq.cq_obj.cq->id, 158*9de7b160SMichael Baum .wq_attr = (struct mlx5_devx_wq_attr){ 159*9de7b160SMichael Baum .uar_page = priv->uar->page_id, 160*9de7b160SMichael Baum }, 161*9de7b160SMichael Baum }; 162*9de7b160SMichael Baum struct mlx5_devx_modify_sq_attr modify_attr = { 163*9de7b160SMichael Baum .state = MLX5_SQC_STATE_RDY, 164*9de7b160SMichael Baum }; 16592f2c6a3SOri Kam struct mlx5_regex_sq *sq = &qp->sqs[q_ind]; 16692f2c6a3SOri Kam uint32_t pd_num = 0; 16792f2c6a3SOri Kam int ret; 16892f2c6a3SOri Kam 16992f2c6a3SOri Kam sq->log_nb_desc = log_nb_desc; 1704d4e245aSYuval Avnery sq->ci = 0; 1714d4e245aSYuval Avnery sq->pi = 0; 172*9de7b160SMichael Baum ret = regex_get_pdn(priv->pd, &pd_num); 173*9de7b160SMichael Baum if (ret) 174*9de7b160SMichael Baum return ret; 175*9de7b160SMichael Baum attr.wq_attr.pd = pd_num; 176*9de7b160SMichael Baum ret = mlx5_devx_sq_create(priv->ctx, &sq->sq_obj, log_nb_desc, &attr, 177*9de7b160SMichael Baum SOCKET_ID_ANY); 17892f2c6a3SOri Kam if (ret) { 179*9de7b160SMichael Baum DRV_LOG(ERR, "Can't create SQ object."); 18092f2c6a3SOri Kam rte_errno = ENOMEM; 18192f2c6a3SOri Kam return -rte_errno; 182*9de7b160SMichael Baum } 183*9de7b160SMichael Baum ret = mlx5_devx_cmd_modify_sq(sq->sq_obj.sq, &modify_attr); 184*9de7b160SMichael Baum if (ret) { 185*9de7b160SMichael Baum DRV_LOG(ERR, "Can't change SQ state to ready."); 186*9de7b160SMichael Baum regex_ctrl_destroy_sq(qp, q_ind); 187*9de7b160SMichael Baum rte_errno = ENOMEM; 188*9de7b160SMichael Baum return -rte_errno; 189*9de7b160SMichael Baum } 190*9de7b160SMichael Baum return 0; 19192f2c6a3SOri Kam #else 19292f2c6a3SOri Kam (void)priv; 19392f2c6a3SOri Kam (void)qp; 19492f2c6a3SOri Kam (void)q_ind; 19592f2c6a3SOri Kam (void)log_nb_desc; 19692f2c6a3SOri Kam DRV_LOG(ERR, "Cannot get pdn - no DV support."); 19792f2c6a3SOri Kam return -ENOTSUP; 19892f2c6a3SOri Kam #endif 19992f2c6a3SOri Kam } 20092f2c6a3SOri Kam 20192f2c6a3SOri Kam /** 202fbc8c700SOri Kam * Setup the qp. 203fbc8c700SOri Kam * 204fbc8c700SOri Kam * @param dev 205fbc8c700SOri Kam * Pointer to RegEx dev structure. 206fbc8c700SOri Kam * @param qp_ind 207fbc8c700SOri Kam * The queue index to setup. 208fbc8c700SOri Kam * @param cfg 209fbc8c700SOri Kam * The queue requested configuration. 210fbc8c700SOri Kam * 211fbc8c700SOri Kam * @return 212fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 213fbc8c700SOri Kam */ 214fbc8c700SOri Kam int 215fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind, 216fbc8c700SOri Kam const struct rte_regexdev_qp_conf *cfg) 217fbc8c700SOri Kam { 218fbc8c700SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 219fbc8c700SOri Kam struct mlx5_regex_qp *qp; 22092f2c6a3SOri Kam int i; 221a165ee1eSMichael Baum int nb_sq_config = 0; 222fbc8c700SOri Kam int ret; 22392f2c6a3SOri Kam uint16_t log_desc; 224fbc8c700SOri Kam 225fbc8c700SOri Kam qp = &priv->qps[qp_ind]; 226fbc8c700SOri Kam qp->flags = cfg->qp_conf_flags; 227fbc8c700SOri Kam qp->cq.log_nb_desc = rte_log2_u32(cfg->nb_desc); 228fbc8c700SOri Kam qp->nb_desc = 1 << qp->cq.log_nb_desc; 229fbc8c700SOri Kam if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F) 230fbc8c700SOri Kam qp->nb_obj = regex_ctrl_get_nb_obj(qp->nb_desc); 231fbc8c700SOri Kam else 232fbc8c700SOri Kam qp->nb_obj = 1; 233fbc8c700SOri Kam qp->sqs = rte_malloc(NULL, 234fbc8c700SOri Kam qp->nb_obj * sizeof(struct mlx5_regex_sq), 64); 235fbc8c700SOri Kam if (!qp->sqs) { 236fbc8c700SOri Kam DRV_LOG(ERR, "Can't allocate sq array memory."); 237fbc8c700SOri Kam rte_errno = ENOMEM; 238fbc8c700SOri Kam return -rte_errno; 239fbc8c700SOri Kam } 24092f2c6a3SOri Kam log_desc = rte_log2_u32(qp->nb_desc / qp->nb_obj); 241fbc8c700SOri Kam ret = regex_ctrl_create_cq(priv, &qp->cq); 242fbc8c700SOri Kam if (ret) { 243fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq."); 24454fa1f6aSYuval Avnery goto err_cq; 245fbc8c700SOri Kam } 24692f2c6a3SOri Kam for (i = 0; i < qp->nb_obj; i++) { 24792f2c6a3SOri Kam ret = regex_ctrl_create_sq(priv, qp, i, log_desc); 24892f2c6a3SOri Kam if (ret) { 24992f2c6a3SOri Kam DRV_LOG(ERR, "Can't create sq."); 250a165ee1eSMichael Baum goto err_btree; 25192f2c6a3SOri Kam } 252a165ee1eSMichael Baum nb_sq_config++; 25392f2c6a3SOri Kam } 2545f41b66dSYuval Avnery 255cda883bbSYuval Avnery ret = mlx5_mr_btree_init(&qp->mr_ctrl.cache_bh, MLX5_MR_BTREE_CACHE_N, 256cda883bbSYuval Avnery rte_socket_id()); 257cda883bbSYuval Avnery if (ret) { 258cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up mr btree"); 259cda883bbSYuval Avnery goto err_btree; 260cda883bbSYuval Avnery } 261cda883bbSYuval Avnery 26254fa1f6aSYuval Avnery ret = mlx5_regexdev_setup_fastpath(priv, qp_ind); 26354fa1f6aSYuval Avnery if (ret) { 264cda883bbSYuval Avnery DRV_LOG(ERR, "Error setting up fastpath"); 26554fa1f6aSYuval Avnery goto err_fp; 26654fa1f6aSYuval Avnery } 267fbc8c700SOri Kam return 0; 268fbc8c700SOri Kam 26954fa1f6aSYuval Avnery err_fp: 270cda883bbSYuval Avnery mlx5_mr_btree_free(&qp->mr_ctrl.cache_bh); 271cda883bbSYuval Avnery err_btree: 272a165ee1eSMichael Baum for (i = 0; i < nb_sq_config; i++) 273*9de7b160SMichael Baum regex_ctrl_destroy_sq(qp, i); 2743ddf5706SMichael Baum regex_ctrl_destroy_cq(&qp->cq); 27554fa1f6aSYuval Avnery err_cq: 27654fa1f6aSYuval Avnery rte_free(qp->sqs); 27754fa1f6aSYuval Avnery return ret; 278fbc8c700SOri Kam } 279