1*fbc8c700SOri Kam /* SPDX-License-Identifier: BSD-3-Clause 2*fbc8c700SOri Kam * Copyright 2020 Mellanox Technologies, Ltd 3*fbc8c700SOri Kam */ 4*fbc8c700SOri Kam 5*fbc8c700SOri Kam #include <errno.h> 6*fbc8c700SOri Kam 7*fbc8c700SOri Kam #include <rte_log.h> 8*fbc8c700SOri Kam #include <rte_errno.h> 9*fbc8c700SOri Kam #include <rte_malloc.h> 10*fbc8c700SOri Kam #include <rte_regexdev.h> 11*fbc8c700SOri Kam #include <rte_regexdev_core.h> 12*fbc8c700SOri Kam #include <rte_regexdev_driver.h> 13*fbc8c700SOri Kam 14*fbc8c700SOri Kam #include <mlx5_common.h> 15*fbc8c700SOri Kam #include <mlx5_glue.h> 16*fbc8c700SOri Kam #include <mlx5_devx_cmds.h> 17*fbc8c700SOri Kam #include <mlx5_prm.h> 18*fbc8c700SOri Kam #include <mlx5_common_os.h> 19*fbc8c700SOri Kam 20*fbc8c700SOri Kam #include "mlx5_regex.h" 21*fbc8c700SOri Kam #include "mlx5_regex_utils.h" 22*fbc8c700SOri Kam #include "mlx5_rxp_csrs.h" 23*fbc8c700SOri Kam #include "mlx5_rxp.h" 24*fbc8c700SOri Kam 25*fbc8c700SOri Kam #define MLX5_REGEX_NUM_WQE_PER_PAGE (4096/64) 26*fbc8c700SOri Kam 27*fbc8c700SOri Kam /** 28*fbc8c700SOri Kam * Returns the number of qp obj to be created. 29*fbc8c700SOri Kam * 30*fbc8c700SOri Kam * @param nb_desc 31*fbc8c700SOri Kam * The number of descriptors for the queue. 32*fbc8c700SOri Kam * 33*fbc8c700SOri Kam * @return 34*fbc8c700SOri Kam * The number of obj to be created. 35*fbc8c700SOri Kam */ 36*fbc8c700SOri Kam static uint16_t 37*fbc8c700SOri Kam regex_ctrl_get_nb_obj(uint16_t nb_desc) 38*fbc8c700SOri Kam { 39*fbc8c700SOri Kam return ((nb_desc / MLX5_REGEX_NUM_WQE_PER_PAGE) + 40*fbc8c700SOri Kam !!(nb_desc % MLX5_REGEX_NUM_WQE_PER_PAGE)); 41*fbc8c700SOri Kam } 42*fbc8c700SOri Kam 43*fbc8c700SOri Kam /** 44*fbc8c700SOri Kam * destroy CQ. 45*fbc8c700SOri Kam * 46*fbc8c700SOri Kam * @param priv 47*fbc8c700SOri Kam * Pointer to the priv object. 48*fbc8c700SOri Kam * @param cp 49*fbc8c700SOri Kam * Pointer to the CQ to be destroyed. 50*fbc8c700SOri Kam * 51*fbc8c700SOri Kam * @return 52*fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 53*fbc8c700SOri Kam */ 54*fbc8c700SOri Kam static int 55*fbc8c700SOri Kam regex_ctrl_destroy_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq) 56*fbc8c700SOri Kam { 57*fbc8c700SOri Kam if (cq->cqe_umem) { 58*fbc8c700SOri Kam mlx5_glue->devx_umem_dereg(cq->cqe_umem); 59*fbc8c700SOri Kam cq->cqe_umem = NULL; 60*fbc8c700SOri Kam } 61*fbc8c700SOri Kam if (cq->cqe) { 62*fbc8c700SOri Kam rte_free((void *)(uintptr_t)cq->cqe); 63*fbc8c700SOri Kam cq->cqe = NULL; 64*fbc8c700SOri Kam } 65*fbc8c700SOri Kam if (cq->dbr_offset) { 66*fbc8c700SOri Kam mlx5_release_dbr(&priv->dbrpgs, cq->dbr_umem, cq->dbr_offset); 67*fbc8c700SOri Kam cq->dbr_offset = -1; 68*fbc8c700SOri Kam } 69*fbc8c700SOri Kam if (cq->obj) { 70*fbc8c700SOri Kam mlx5_devx_cmd_destroy(cq->obj); 71*fbc8c700SOri Kam cq->obj = NULL; 72*fbc8c700SOri Kam } 73*fbc8c700SOri Kam return 0; 74*fbc8c700SOri Kam } 75*fbc8c700SOri Kam 76*fbc8c700SOri Kam /** 77*fbc8c700SOri Kam * create the CQ object. 78*fbc8c700SOri Kam * 79*fbc8c700SOri Kam * @param priv 80*fbc8c700SOri Kam * Pointer to the priv object. 81*fbc8c700SOri Kam * @param cp 82*fbc8c700SOri Kam * Pointer to the CQ to be created. 83*fbc8c700SOri Kam * 84*fbc8c700SOri Kam * @return 85*fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 86*fbc8c700SOri Kam */ 87*fbc8c700SOri Kam static int 88*fbc8c700SOri Kam regex_ctrl_create_cq(struct mlx5_regex_priv *priv, struct mlx5_regex_cq *cq) 89*fbc8c700SOri Kam { 90*fbc8c700SOri Kam struct mlx5_devx_cq_attr attr = { 91*fbc8c700SOri Kam .q_umem_valid = 1, 92*fbc8c700SOri Kam .db_umem_valid = 1, 93*fbc8c700SOri Kam .eqn = priv->eqn, 94*fbc8c700SOri Kam }; 95*fbc8c700SOri Kam struct mlx5_devx_dbr_page *dbr_page = NULL; 96*fbc8c700SOri Kam void *buf = NULL; 97*fbc8c700SOri Kam size_t pgsize = sysconf(_SC_PAGESIZE); 98*fbc8c700SOri Kam uint32_t cq_size = 1 << cq->log_nb_desc; 99*fbc8c700SOri Kam uint32_t i; 100*fbc8c700SOri Kam 101*fbc8c700SOri Kam cq->dbr_offset = mlx5_get_dbr(priv->ctx, &priv->dbrpgs, &dbr_page); 102*fbc8c700SOri Kam if (cq->dbr_offset < 0) { 103*fbc8c700SOri Kam DRV_LOG(ERR, "Can't allocate cq door bell record."); 104*fbc8c700SOri Kam rte_errno = ENOMEM; 105*fbc8c700SOri Kam goto error; 106*fbc8c700SOri Kam } 107*fbc8c700SOri Kam cq->dbr_umem = mlx5_os_get_umem_id(dbr_page->umem); 108*fbc8c700SOri Kam buf = rte_calloc(NULL, 1, sizeof(struct mlx5_cqe) * cq_size, 4096); 109*fbc8c700SOri Kam if (!buf) { 110*fbc8c700SOri Kam DRV_LOG(ERR, "Can't allocate cqe buffer."); 111*fbc8c700SOri Kam rte_errno = ENOMEM; 112*fbc8c700SOri Kam goto error; 113*fbc8c700SOri Kam } 114*fbc8c700SOri Kam cq->cqe = buf; 115*fbc8c700SOri Kam for (i = 0; i < cq_size; i++) 116*fbc8c700SOri Kam cq->cqe[i].op_own = 0xff; 117*fbc8c700SOri Kam cq->cqe_umem = mlx5_glue->devx_umem_reg(priv->ctx, buf, 118*fbc8c700SOri Kam sizeof(struct mlx5_cqe) * 119*fbc8c700SOri Kam cq_size, 7); 120*fbc8c700SOri Kam if (!cq->cqe_umem) { 121*fbc8c700SOri Kam DRV_LOG(ERR, "Can't register cqe mem."); 122*fbc8c700SOri Kam rte_errno = ENOMEM; 123*fbc8c700SOri Kam goto error; 124*fbc8c700SOri Kam } 125*fbc8c700SOri Kam attr.db_umem_offset = cq->dbr_offset; 126*fbc8c700SOri Kam attr.db_umem_id = cq->dbr_umem; 127*fbc8c700SOri Kam attr.q_umem_id = mlx5_os_get_umem_id(cq->cqe_umem); 128*fbc8c700SOri Kam attr.log_cq_size = cq->log_nb_desc; 129*fbc8c700SOri Kam attr.uar_page_id = priv->uar->page_id; 130*fbc8c700SOri Kam attr.log_page_size = rte_log2_u32(pgsize); 131*fbc8c700SOri Kam cq->obj = mlx5_devx_cmd_create_cq(priv->ctx, &attr); 132*fbc8c700SOri Kam if (!cq->obj) { 133*fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq object."); 134*fbc8c700SOri Kam rte_errno = ENOMEM; 135*fbc8c700SOri Kam goto error; 136*fbc8c700SOri Kam } 137*fbc8c700SOri Kam return 0; 138*fbc8c700SOri Kam error: 139*fbc8c700SOri Kam if (cq->cqe_umem) 140*fbc8c700SOri Kam mlx5_glue->devx_umem_dereg(cq->cqe_umem); 141*fbc8c700SOri Kam if (buf) 142*fbc8c700SOri Kam rte_free(buf); 143*fbc8c700SOri Kam if (cq->dbr_offset) 144*fbc8c700SOri Kam mlx5_release_dbr(&priv->dbrpgs, cq->dbr_umem, cq->dbr_offset); 145*fbc8c700SOri Kam return -rte_errno; 146*fbc8c700SOri Kam } 147*fbc8c700SOri Kam 148*fbc8c700SOri Kam /** 149*fbc8c700SOri Kam * Setup the qp. 150*fbc8c700SOri Kam * 151*fbc8c700SOri Kam * @param dev 152*fbc8c700SOri Kam * Pointer to RegEx dev structure. 153*fbc8c700SOri Kam * @param qp_ind 154*fbc8c700SOri Kam * The queue index to setup. 155*fbc8c700SOri Kam * @param cfg 156*fbc8c700SOri Kam * The queue requested configuration. 157*fbc8c700SOri Kam * 158*fbc8c700SOri Kam * @return 159*fbc8c700SOri Kam * 0 on success, a negative errno value otherwise and rte_errno is set. 160*fbc8c700SOri Kam */ 161*fbc8c700SOri Kam int 162*fbc8c700SOri Kam mlx5_regex_qp_setup(struct rte_regexdev *dev, uint16_t qp_ind, 163*fbc8c700SOri Kam const struct rte_regexdev_qp_conf *cfg) 164*fbc8c700SOri Kam { 165*fbc8c700SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 166*fbc8c700SOri Kam struct mlx5_regex_qp *qp; 167*fbc8c700SOri Kam int ret; 168*fbc8c700SOri Kam 169*fbc8c700SOri Kam qp = &priv->qps[qp_ind]; 170*fbc8c700SOri Kam qp->flags = cfg->qp_conf_flags; 171*fbc8c700SOri Kam qp->cq.log_nb_desc = rte_log2_u32(cfg->nb_desc); 172*fbc8c700SOri Kam qp->nb_desc = 1 << qp->cq.log_nb_desc; 173*fbc8c700SOri Kam if (qp->flags & RTE_REGEX_QUEUE_PAIR_CFG_OOS_F) 174*fbc8c700SOri Kam qp->nb_obj = regex_ctrl_get_nb_obj(qp->nb_desc); 175*fbc8c700SOri Kam else 176*fbc8c700SOri Kam qp->nb_obj = 1; 177*fbc8c700SOri Kam qp->sqs = rte_malloc(NULL, 178*fbc8c700SOri Kam qp->nb_obj * sizeof(struct mlx5_regex_sq), 64); 179*fbc8c700SOri Kam if (!qp->sqs) { 180*fbc8c700SOri Kam DRV_LOG(ERR, "Can't allocate sq array memory."); 181*fbc8c700SOri Kam rte_errno = ENOMEM; 182*fbc8c700SOri Kam return -rte_errno; 183*fbc8c700SOri Kam } 184*fbc8c700SOri Kam ret = regex_ctrl_create_cq(priv, &qp->cq); 185*fbc8c700SOri Kam if (ret) { 186*fbc8c700SOri Kam DRV_LOG(ERR, "Can't create cq."); 187*fbc8c700SOri Kam goto error; 188*fbc8c700SOri Kam } 189*fbc8c700SOri Kam return 0; 190*fbc8c700SOri Kam 191*fbc8c700SOri Kam error: 192*fbc8c700SOri Kam regex_ctrl_destroy_cq(priv, &qp->cq); 193*fbc8c700SOri Kam return -rte_errno; 194*fbc8c700SOri Kam 195*fbc8c700SOri Kam } 196