1*5f41b66dSYuval Avnery /* SPDX-License-Identifier: BSD-3-Clause 2*5f41b66dSYuval Avnery * Copyright 2020 Mellanox Technologies, Ltd 3*5f41b66dSYuval Avnery */ 4*5f41b66dSYuval Avnery 5*5f41b66dSYuval Avnery #include <unistd.h> 6*5f41b66dSYuval Avnery #include <sys/mman.h> 7*5f41b66dSYuval Avnery 8*5f41b66dSYuval Avnery #include <rte_malloc.h> 9*5f41b66dSYuval Avnery #include <rte_log.h> 10*5f41b66dSYuval Avnery #include <rte_errno.h> 11*5f41b66dSYuval Avnery #include <rte_bus_pci.h> 12*5f41b66dSYuval Avnery #include <rte_pci.h> 13*5f41b66dSYuval Avnery #include <rte_regexdev_driver.h> 14*5f41b66dSYuval Avnery #include <rte_mbuf.h> 15*5f41b66dSYuval Avnery 16*5f41b66dSYuval Avnery #include <infiniband/mlx5dv.h> 17*5f41b66dSYuval Avnery #include <mlx5_glue.h> 18*5f41b66dSYuval Avnery #include <mlx5_common.h> 19*5f41b66dSYuval Avnery #include <mlx5_prm.h> 20*5f41b66dSYuval Avnery #include <strings.h> 21*5f41b66dSYuval Avnery 22*5f41b66dSYuval Avnery #include "mlx5_regex_utils.h" 23*5f41b66dSYuval Avnery #include "mlx5_rxp.h" 24*5f41b66dSYuval Avnery #include "mlx5_regex.h" 25*5f41b66dSYuval Avnery 26*5f41b66dSYuval Avnery #define MLX5_REGEX_METADATA_SIZE 64 27*5f41b66dSYuval Avnery #define MLX5_REGEX_MAX_INPUT (1 << 14) 28*5f41b66dSYuval Avnery #define MLX5_REGEX_MAX_OUTPUT (1 << 11) 29*5f41b66dSYuval Avnery 30*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_METADATA_OFFSET 16 31*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_GATHER_OFFSET 32 32*5f41b66dSYuval Avnery #define MLX5_REGEX_WQE_SCATTER_OFFSET 48 33*5f41b66dSYuval Avnery 34*5f41b66dSYuval Avnery static inline uint32_t 35*5f41b66dSYuval Avnery sq_size_get(struct mlx5_regex_sq *sq) 36*5f41b66dSYuval Avnery { 37*5f41b66dSYuval Avnery return (1U << sq->log_nb_desc); 38*5f41b66dSYuval Avnery } 39*5f41b66dSYuval Avnery 40*5f41b66dSYuval Avnery struct mlx5_regex_job { 41*5f41b66dSYuval Avnery uint64_t user_id; 42*5f41b66dSYuval Avnery uint8_t *input; 43*5f41b66dSYuval Avnery volatile uint8_t *output; 44*5f41b66dSYuval Avnery volatile uint8_t *metadata; 45*5f41b66dSYuval Avnery } __rte_cached_aligned; 46*5f41b66dSYuval Avnery 47*5f41b66dSYuval Avnery static inline void 48*5f41b66dSYuval Avnery set_data_seg(struct mlx5_wqe_data_seg *seg, 49*5f41b66dSYuval Avnery uint32_t length, uint32_t lkey, 50*5f41b66dSYuval Avnery uintptr_t address) 51*5f41b66dSYuval Avnery { 52*5f41b66dSYuval Avnery seg->byte_count = rte_cpu_to_be_32(length); 53*5f41b66dSYuval Avnery seg->lkey = rte_cpu_to_be_32(lkey); 54*5f41b66dSYuval Avnery seg->addr = rte_cpu_to_be_64(address); 55*5f41b66dSYuval Avnery } 56*5f41b66dSYuval Avnery 57*5f41b66dSYuval Avnery static inline void 58*5f41b66dSYuval Avnery set_metadata_seg(struct mlx5_wqe_metadata_seg *seg, 59*5f41b66dSYuval Avnery uint32_t mmo_control_31_0, uint32_t lkey, 60*5f41b66dSYuval Avnery uintptr_t address) 61*5f41b66dSYuval Avnery { 62*5f41b66dSYuval Avnery seg->mmo_control_31_0 = htobe32(mmo_control_31_0); 63*5f41b66dSYuval Avnery seg->lkey = rte_cpu_to_be_32(lkey); 64*5f41b66dSYuval Avnery seg->addr = rte_cpu_to_be_64(address); 65*5f41b66dSYuval Avnery } 66*5f41b66dSYuval Avnery 67*5f41b66dSYuval Avnery static void 68*5f41b66dSYuval Avnery setup_sqs(struct mlx5_regex_qp *queue) 69*5f41b66dSYuval Avnery { 70*5f41b66dSYuval Avnery size_t sqid, entry; 71*5f41b66dSYuval Avnery uint32_t job_id; 72*5f41b66dSYuval Avnery for (sqid = 0; sqid < queue->nb_obj; sqid++) { 73*5f41b66dSYuval Avnery struct mlx5_regex_sq *sq = &queue->sqs[sqid]; 74*5f41b66dSYuval Avnery uint8_t *wqe = (uint8_t *)sq->wqe; 75*5f41b66dSYuval Avnery for (entry = 0 ; entry < sq_size_get(sq); entry++) { 76*5f41b66dSYuval Avnery job_id = sqid * sq_size_get(sq) + entry; 77*5f41b66dSYuval Avnery struct mlx5_regex_job *job = &queue->jobs[job_id]; 78*5f41b66dSYuval Avnery 79*5f41b66dSYuval Avnery set_metadata_seg((struct mlx5_wqe_metadata_seg *) 80*5f41b66dSYuval Avnery (wqe + MLX5_REGEX_WQE_METADATA_OFFSET), 81*5f41b66dSYuval Avnery 0, queue->metadata->lkey, 82*5f41b66dSYuval Avnery (uintptr_t)job->metadata); 83*5f41b66dSYuval Avnery set_data_seg((struct mlx5_wqe_data_seg *) 84*5f41b66dSYuval Avnery (wqe + MLX5_REGEX_WQE_GATHER_OFFSET), 85*5f41b66dSYuval Avnery 0, queue->inputs->lkey, 86*5f41b66dSYuval Avnery (uintptr_t)job->input); 87*5f41b66dSYuval Avnery set_data_seg((struct mlx5_wqe_data_seg *) 88*5f41b66dSYuval Avnery (wqe + MLX5_REGEX_WQE_SCATTER_OFFSET), 89*5f41b66dSYuval Avnery MLX5_REGEX_MAX_OUTPUT, 90*5f41b66dSYuval Avnery queue->outputs->lkey, 91*5f41b66dSYuval Avnery (uintptr_t)job->output); 92*5f41b66dSYuval Avnery wqe += 64; 93*5f41b66dSYuval Avnery } 94*5f41b66dSYuval Avnery queue->free_sqs |= 1 << sqid; 95*5f41b66dSYuval Avnery } 96*5f41b66dSYuval Avnery } 97*5f41b66dSYuval Avnery 98*5f41b66dSYuval Avnery static int 99*5f41b66dSYuval Avnery setup_buffers(struct mlx5_regex_qp *qp, struct ibv_pd *pd) 100*5f41b66dSYuval Avnery { 101*5f41b66dSYuval Avnery uint32_t i; 102*5f41b66dSYuval Avnery int err; 103*5f41b66dSYuval Avnery 104*5f41b66dSYuval Avnery void *ptr = rte_calloc(__func__, qp->nb_desc, 105*5f41b66dSYuval Avnery MLX5_REGEX_METADATA_SIZE, 106*5f41b66dSYuval Avnery MLX5_REGEX_METADATA_SIZE); 107*5f41b66dSYuval Avnery if (!ptr) 108*5f41b66dSYuval Avnery return -ENOMEM; 109*5f41b66dSYuval Avnery 110*5f41b66dSYuval Avnery qp->metadata = mlx5_glue->reg_mr(pd, ptr, 111*5f41b66dSYuval Avnery MLX5_REGEX_METADATA_SIZE*qp->nb_desc, 112*5f41b66dSYuval Avnery IBV_ACCESS_LOCAL_WRITE); 113*5f41b66dSYuval Avnery if (!qp->metadata) { 114*5f41b66dSYuval Avnery rte_free(ptr); 115*5f41b66dSYuval Avnery return -EINVAL; 116*5f41b66dSYuval Avnery } 117*5f41b66dSYuval Avnery ptr = rte_calloc(__func__, qp->nb_desc, 118*5f41b66dSYuval Avnery MLX5_REGEX_MAX_INPUT, 119*5f41b66dSYuval Avnery MLX5_REGEX_MAX_INPUT); 120*5f41b66dSYuval Avnery 121*5f41b66dSYuval Avnery if (!ptr) { 122*5f41b66dSYuval Avnery err = -ENOMEM; 123*5f41b66dSYuval Avnery goto err_input; 124*5f41b66dSYuval Avnery } 125*5f41b66dSYuval Avnery qp->inputs = mlx5_glue->reg_mr(pd, ptr, 126*5f41b66dSYuval Avnery MLX5_REGEX_MAX_INPUT*qp->nb_desc, 127*5f41b66dSYuval Avnery IBV_ACCESS_LOCAL_WRITE); 128*5f41b66dSYuval Avnery if (!qp->inputs) { 129*5f41b66dSYuval Avnery rte_free(ptr); 130*5f41b66dSYuval Avnery err = -EINVAL; 131*5f41b66dSYuval Avnery goto err_input; 132*5f41b66dSYuval Avnery } 133*5f41b66dSYuval Avnery 134*5f41b66dSYuval Avnery ptr = rte_calloc(__func__, qp->nb_desc, 135*5f41b66dSYuval Avnery MLX5_REGEX_MAX_OUTPUT, 136*5f41b66dSYuval Avnery MLX5_REGEX_MAX_OUTPUT); 137*5f41b66dSYuval Avnery if (!ptr) { 138*5f41b66dSYuval Avnery err = -ENOMEM; 139*5f41b66dSYuval Avnery goto err_output; 140*5f41b66dSYuval Avnery } 141*5f41b66dSYuval Avnery qp->outputs = mlx5_glue->reg_mr(pd, ptr, 142*5f41b66dSYuval Avnery MLX5_REGEX_MAX_OUTPUT * qp->nb_desc, 143*5f41b66dSYuval Avnery IBV_ACCESS_LOCAL_WRITE); 144*5f41b66dSYuval Avnery if (!qp->outputs) { 145*5f41b66dSYuval Avnery rte_free(ptr); 146*5f41b66dSYuval Avnery err = -EINVAL; 147*5f41b66dSYuval Avnery goto err_output; 148*5f41b66dSYuval Avnery } 149*5f41b66dSYuval Avnery 150*5f41b66dSYuval Avnery /* distribute buffers to jobs */ 151*5f41b66dSYuval Avnery for (i = 0; i < qp->nb_desc; i++) { 152*5f41b66dSYuval Avnery qp->jobs[i].input = 153*5f41b66dSYuval Avnery (uint8_t *)qp->inputs->addr + 154*5f41b66dSYuval Avnery (i % qp->nb_desc) * MLX5_REGEX_MAX_INPUT; 155*5f41b66dSYuval Avnery qp->jobs[i].output = 156*5f41b66dSYuval Avnery (uint8_t *)qp->outputs->addr + 157*5f41b66dSYuval Avnery (i % qp->nb_desc) * MLX5_REGEX_MAX_OUTPUT; 158*5f41b66dSYuval Avnery qp->jobs[i].metadata = 159*5f41b66dSYuval Avnery (uint8_t *)qp->metadata->addr + 160*5f41b66dSYuval Avnery (i % qp->nb_desc) * MLX5_REGEX_METADATA_SIZE; 161*5f41b66dSYuval Avnery } 162*5f41b66dSYuval Avnery return 0; 163*5f41b66dSYuval Avnery 164*5f41b66dSYuval Avnery err_output: 165*5f41b66dSYuval Avnery ptr = qp->inputs->addr; 166*5f41b66dSYuval Avnery rte_free(ptr); 167*5f41b66dSYuval Avnery mlx5_glue->dereg_mr(qp->inputs); 168*5f41b66dSYuval Avnery err_input: 169*5f41b66dSYuval Avnery ptr = qp->metadata->addr; 170*5f41b66dSYuval Avnery rte_free(ptr); 171*5f41b66dSYuval Avnery mlx5_glue->dereg_mr(qp->metadata); 172*5f41b66dSYuval Avnery return err; 173*5f41b66dSYuval Avnery } 174*5f41b66dSYuval Avnery 175*5f41b66dSYuval Avnery int 176*5f41b66dSYuval Avnery mlx5_regexdev_setup_fastpath(struct mlx5_regex_priv *priv, uint32_t qp_id) 177*5f41b66dSYuval Avnery { 178*5f41b66dSYuval Avnery struct mlx5_regex_qp *qp = &priv->qps[qp_id]; 179*5f41b66dSYuval Avnery int err; 180*5f41b66dSYuval Avnery 181*5f41b66dSYuval Avnery qp->jobs = rte_calloc(__func__, qp->nb_desc, sizeof(*qp->jobs), 182*5f41b66dSYuval Avnery sizeof(*qp->jobs)); 183*5f41b66dSYuval Avnery if (!qp->jobs) 184*5f41b66dSYuval Avnery return -ENOMEM; 185*5f41b66dSYuval Avnery err = setup_buffers(qp, priv->pd); 186*5f41b66dSYuval Avnery if (err) 187*5f41b66dSYuval Avnery return err; 188*5f41b66dSYuval Avnery setup_sqs(qp); 189*5f41b66dSYuval Avnery return 0; 190*5f41b66dSYuval Avnery } 191