1c126512bSOri Kam /* SPDX-License-Identifier: BSD-3-Clause 2c126512bSOri Kam * Copyright 2020 Mellanox Technologies, Ltd 3c126512bSOri Kam */ 4c126512bSOri Kam 5c126512bSOri Kam #include <rte_log.h> 6c126512bSOri Kam #include <rte_errno.h> 7e3dbbf71SOri Kam #include <rte_malloc.h> 8c126512bSOri Kam #include <rte_regexdev.h> 9c126512bSOri Kam #include <rte_regexdev_core.h> 10c126512bSOri Kam #include <rte_regexdev_driver.h> 11f324162eSOri Kam #include <sys/mman.h> 12c126512bSOri Kam 13e3dbbf71SOri Kam #include <mlx5_glue.h> 14e3dbbf71SOri Kam #include <mlx5_devx_cmds.h> 15e3dbbf71SOri Kam #include <mlx5_prm.h> 16b34d8163SFrancis Kelly #include <mlx5_common_os.h> 17e3dbbf71SOri Kam 18c126512bSOri Kam #include "mlx5_regex.h" 19e3dbbf71SOri Kam #include "mlx5_regex_utils.h" 20e3dbbf71SOri Kam #include "mlx5_rxp_csrs.h" 21b34d8163SFrancis Kelly #include "mlx5_rxp.h" 22c126512bSOri Kam 23b34d8163SFrancis Kelly #define MLX5_REGEX_MAX_MATCHES MLX5_RXP_MAX_MATCHES 24b34d8163SFrancis Kelly #define MLX5_REGEX_MAX_PAYLOAD_SIZE MLX5_RXP_MAX_JOB_LENGTH 25b34d8163SFrancis Kelly #define MLX5_REGEX_MAX_RULES_PER_GROUP UINT32_MAX 26b34d8163SFrancis Kelly #define MLX5_REGEX_MAX_GROUPS MLX5_RXP_MAX_SUBSETS 27b34d8163SFrancis Kelly 28f324162eSOri Kam #define MLX5_REGEX_RXP_ROF2_LINE_LEN 34 29f324162eSOri Kam 30b34d8163SFrancis Kelly /* Private Declarations */ 31*9fa82d28SAdy Agbarih static int 32*9fa82d28SAdy Agbarih rxp_create_mkey(struct mlx5_regex_priv *priv, void *ptr, size_t size, 33*9fa82d28SAdy Agbarih uint32_t access, struct mlx5_regex_mkey *mkey); 34*9fa82d28SAdy Agbarih static inline void 35*9fa82d28SAdy Agbarih rxp_destroy_mkey(struct mlx5_regex_mkey *mkey); 36*9fa82d28SAdy Agbarih 37c126512bSOri Kam int 38c126512bSOri Kam mlx5_regex_info_get(struct rte_regexdev *dev __rte_unused, 39c126512bSOri Kam struct rte_regexdev_info *info) 40c126512bSOri Kam { 41c126512bSOri Kam info->max_matches = MLX5_REGEX_MAX_MATCHES; 42c126512bSOri Kam info->max_payload_size = MLX5_REGEX_MAX_PAYLOAD_SIZE; 43c126512bSOri Kam info->max_rules_per_group = MLX5_REGEX_MAX_RULES_PER_GROUP; 44c126512bSOri Kam info->max_groups = MLX5_REGEX_MAX_GROUPS; 45c8452005SOphir Munk info->regexdev_capa = RTE_REGEXDEV_SUPP_PCRE_GREEDY_F | 46c8452005SOphir Munk RTE_REGEXDEV_CAPA_QUEUE_PAIR_OOS_F; 47c126512bSOri Kam info->rule_flags = 0; 487a7a9907SOri Kam info->max_queue_pairs = UINT16_MAX; 49c126512bSOri Kam return 0; 50c126512bSOri Kam } 51e3dbbf71SOri Kam 52e3dbbf71SOri Kam static int 53*9fa82d28SAdy Agbarih rxp_create_mkey(struct mlx5_regex_priv *priv, void *ptr, size_t size, 54*9fa82d28SAdy Agbarih uint32_t access, struct mlx5_regex_mkey *mkey) 55b34d8163SFrancis Kelly { 56*9fa82d28SAdy Agbarih struct mlx5_devx_mkey_attr mkey_attr; 57b34d8163SFrancis Kelly 58b34d8163SFrancis Kelly /* Register the memory. */ 59*9fa82d28SAdy Agbarih mkey->umem = mlx5_glue->devx_umem_reg(priv->cdev->ctx, ptr, size, access); 60*9fa82d28SAdy Agbarih if (!mkey->umem) { 61b34d8163SFrancis Kelly DRV_LOG(ERR, "Failed to register memory!"); 62*9fa82d28SAdy Agbarih return -ENODEV; 63b34d8163SFrancis Kelly } 64*9fa82d28SAdy Agbarih /* Create mkey */ 65*9fa82d28SAdy Agbarih mkey_attr = (struct mlx5_devx_mkey_attr) { 66*9fa82d28SAdy Agbarih .addr = (uintptr_t)ptr, 67*9fa82d28SAdy Agbarih .size = (uint32_t)size, 68*9fa82d28SAdy Agbarih .umem_id = mlx5_os_get_umem_id(mkey->umem), 69*9fa82d28SAdy Agbarih .pg_access = 1, 70*9fa82d28SAdy Agbarih .umr_en = 0, 71*9fa82d28SAdy Agbarih }; 72*9fa82d28SAdy Agbarih #ifdef HAVE_IBV_FLOW_DV_SUPPORT 73*9fa82d28SAdy Agbarih mkey_attr.pd = priv->cdev->pdn; 74*9fa82d28SAdy Agbarih #endif 75*9fa82d28SAdy Agbarih mkey->mkey = mlx5_devx_cmd_mkey_create(priv->cdev->ctx, &mkey_attr); 76*9fa82d28SAdy Agbarih if (!mkey->mkey) { 77*9fa82d28SAdy Agbarih DRV_LOG(ERR, "Failed to create direct mkey!"); 78*9fa82d28SAdy Agbarih return -ENODEV; 79b34d8163SFrancis Kelly } 80b34d8163SFrancis Kelly return 0; 81b34d8163SFrancis Kelly } 82*9fa82d28SAdy Agbarih 83*9fa82d28SAdy Agbarih static inline void 84*9fa82d28SAdy Agbarih rxp_destroy_mkey(struct mlx5_regex_mkey *mkey) 85*9fa82d28SAdy Agbarih { 86*9fa82d28SAdy Agbarih if (mkey->mkey) 87*9fa82d28SAdy Agbarih claim_zero(mlx5_devx_cmd_destroy(mkey->mkey)); 88*9fa82d28SAdy Agbarih if (mkey->umem) 89*9fa82d28SAdy Agbarih claim_zero(mlx5_glue->devx_umem_dereg(mkey->umem)); 90b34d8163SFrancis Kelly } 91b34d8163SFrancis Kelly 92b34d8163SFrancis Kelly int 93b34d8163SFrancis Kelly mlx5_regex_rules_db_import(struct rte_regexdev *dev, 94b34d8163SFrancis Kelly const char *rule_db, uint32_t rule_db_len) 95b34d8163SFrancis Kelly { 96b34d8163SFrancis Kelly struct mlx5_regex_priv *priv = dev->data->dev_private; 97*9fa82d28SAdy Agbarih struct mlx5_regex_mkey mkey; 98*9fa82d28SAdy Agbarih uint32_t id; 99*9fa82d28SAdy Agbarih int ret; 100*9fa82d28SAdy Agbarih void *ptr; 101b34d8163SFrancis Kelly 102b34d8163SFrancis Kelly if (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED) { 103b34d8163SFrancis Kelly DRV_LOG(ERR, "RXP programming mode not set!"); 104b34d8163SFrancis Kelly return -1; 105b34d8163SFrancis Kelly } 106b34d8163SFrancis Kelly if (rule_db == NULL) { 107b34d8163SFrancis Kelly DRV_LOG(ERR, "Database empty!"); 108b34d8163SFrancis Kelly return -ENODEV; 109b34d8163SFrancis Kelly } 110b34d8163SFrancis Kelly if (rule_db_len == 0) 111b34d8163SFrancis Kelly return -EINVAL; 112*9fa82d28SAdy Agbarih /* copy rules - rules have to be 4KB aligned. */ 113*9fa82d28SAdy Agbarih ptr = rte_malloc("", rule_db_len, 1 << 12); 114*9fa82d28SAdy Agbarih if (!ptr) { 115*9fa82d28SAdy Agbarih DRV_LOG(ERR, "Failed to allocate rules file memory."); 116*9fa82d28SAdy Agbarih return -ENOMEM; 117*9fa82d28SAdy Agbarih } 118*9fa82d28SAdy Agbarih rte_memcpy(ptr, rule_db, rule_db_len); 119*9fa82d28SAdy Agbarih /* Register umem and create rof mkey. */ 120*9fa82d28SAdy Agbarih ret = rxp_create_mkey(priv, ptr, rule_db_len, /*access=*/7, &mkey); 121*9fa82d28SAdy Agbarih if (ret < 0) 122*9fa82d28SAdy Agbarih return ret; 123ab2e0b0dSAdy Agbarih 124*9fa82d28SAdy Agbarih for (id = 0; id < priv->nb_engines; id++) { 125*9fa82d28SAdy Agbarih ret = mlx5_devx_regex_rules_program(priv->cdev->ctx, id, 126*9fa82d28SAdy Agbarih mkey.mkey->id, rule_db_len, (uintptr_t)ptr); 127*9fa82d28SAdy Agbarih if (ret < 0) { 128*9fa82d28SAdy Agbarih DRV_LOG(ERR, "Failed to program rxp rules."); 129*9fa82d28SAdy Agbarih ret = -ENODEV; 130*9fa82d28SAdy Agbarih break; 131*9fa82d28SAdy Agbarih } 132*9fa82d28SAdy Agbarih ret = 0; 133*9fa82d28SAdy Agbarih } 134*9fa82d28SAdy Agbarih rxp_destroy_mkey(&mkey); 135*9fa82d28SAdy Agbarih rte_free(ptr); 136*9fa82d28SAdy Agbarih return ret; 137b34d8163SFrancis Kelly } 138b34d8163SFrancis Kelly 139e3dbbf71SOri Kam int 140e3dbbf71SOri Kam mlx5_regex_configure(struct rte_regexdev *dev, 141e3dbbf71SOri Kam const struct rte_regexdev_config *cfg) 142e3dbbf71SOri Kam { 143e3dbbf71SOri Kam struct mlx5_regex_priv *priv = dev->data->dev_private; 144e3dbbf71SOri Kam int ret; 145e3dbbf71SOri Kam 146b34d8163SFrancis Kelly if (priv->prog_mode == MLX5_RXP_MODE_NOT_DEFINED) 147b34d8163SFrancis Kelly return -1; 148e3dbbf71SOri Kam priv->nb_queues = cfg->nb_queue_pairs; 149b34d8163SFrancis Kelly dev->data->dev_conf.nb_queue_pairs = priv->nb_queues; 150e3dbbf71SOri Kam priv->qps = rte_zmalloc(NULL, sizeof(struct mlx5_regex_qp) * 151e3dbbf71SOri Kam priv->nb_queues, 0); 152e3dbbf71SOri Kam if (!priv->nb_queues) { 153e3dbbf71SOri Kam DRV_LOG(ERR, "can't allocate qps memory"); 154e3dbbf71SOri Kam rte_errno = ENOMEM; 155e3dbbf71SOri Kam return -rte_errno; 156e3dbbf71SOri Kam } 157e3dbbf71SOri Kam priv->nb_max_matches = cfg->nb_max_matches; 158b34d8163SFrancis Kelly if (cfg->rule_db != NULL) { 159b34d8163SFrancis Kelly ret = mlx5_regex_rules_db_import(dev, cfg->rule_db, 160b34d8163SFrancis Kelly cfg->rule_db_len); 161b34d8163SFrancis Kelly if (ret < 0) { 162b34d8163SFrancis Kelly DRV_LOG(ERR, "Failed to program rxp rules."); 163e3dbbf71SOri Kam rte_errno = ENODEV; 164e3dbbf71SOri Kam goto configure_error; 165e3dbbf71SOri Kam } 166b34d8163SFrancis Kelly } else 167b34d8163SFrancis Kelly DRV_LOG(DEBUG, "Regex config without rules programming!"); 168e3dbbf71SOri Kam return 0; 169e3dbbf71SOri Kam configure_error: 170e3dbbf71SOri Kam if (priv->qps) 171e3dbbf71SOri Kam rte_free(priv->qps); 172e3dbbf71SOri Kam return -rte_errno; 173e3dbbf71SOri Kam } 174