linux/drivers/crypto/qat/qat_common/adf_cfg.c
<<
>>
Prefs
   1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
   2/* Copyright(c) 2014 - 2020 Intel Corporation */
   3#include <linux/mutex.h>
   4#include <linux/slab.h>
   5#include <linux/list.h>
   6#include <linux/seq_file.h>
   7#include "adf_accel_devices.h"
   8#include "adf_cfg.h"
   9#include "adf_common_drv.h"
  10
  11static DEFINE_MUTEX(qat_cfg_read_lock);
  12
  13static void *qat_dev_cfg_start(struct seq_file *sfile, loff_t *pos)
  14{
  15        struct adf_cfg_device_data *dev_cfg = sfile->private;
  16
  17        mutex_lock(&qat_cfg_read_lock);
  18        return seq_list_start(&dev_cfg->sec_list, *pos);
  19}
  20
  21static int qat_dev_cfg_show(struct seq_file *sfile, void *v)
  22{
  23        struct list_head *list;
  24        struct adf_cfg_section *sec =
  25                                list_entry(v, struct adf_cfg_section, list);
  26
  27        seq_printf(sfile, "[%s]\n", sec->name);
  28        list_for_each(list, &sec->param_head) {
  29                struct adf_cfg_key_val *ptr =
  30                        list_entry(list, struct adf_cfg_key_val, list);
  31                seq_printf(sfile, "%s = %s\n", ptr->key, ptr->val);
  32        }
  33        return 0;
  34}
  35
  36static void *qat_dev_cfg_next(struct seq_file *sfile, void *v, loff_t *pos)
  37{
  38        struct adf_cfg_device_data *dev_cfg = sfile->private;
  39
  40        return seq_list_next(v, &dev_cfg->sec_list, pos);
  41}
  42
  43static void qat_dev_cfg_stop(struct seq_file *sfile, void *v)
  44{
  45        mutex_unlock(&qat_cfg_read_lock);
  46}
  47
  48static const struct seq_operations qat_dev_cfg_sops = {
  49        .start = qat_dev_cfg_start,
  50        .next = qat_dev_cfg_next,
  51        .stop = qat_dev_cfg_stop,
  52        .show = qat_dev_cfg_show
  53};
  54
  55static int qat_dev_cfg_open(struct inode *inode, struct file *file)
  56{
  57        int ret = seq_open(file, &qat_dev_cfg_sops);
  58
  59        if (!ret) {
  60                struct seq_file *seq_f = file->private_data;
  61
  62                seq_f->private = inode->i_private;
  63        }
  64        return ret;
  65}
  66
  67static const struct file_operations qat_dev_cfg_fops = {
  68        .open = qat_dev_cfg_open,
  69        .read = seq_read,
  70        .llseek = seq_lseek,
  71        .release = seq_release
  72};
  73
  74/**
  75 * adf_cfg_dev_add() - Create an acceleration device configuration table.
  76 * @accel_dev:  Pointer to acceleration device.
  77 *
  78 * Function creates a configuration table for the given acceleration device.
  79 * The table stores device specific config values.
  80 * To be used by QAT device specific drivers.
  81 *
  82 * Return: 0 on success, error code otherwise.
  83 */
  84int adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
  85{
  86        struct adf_cfg_device_data *dev_cfg_data;
  87
  88        dev_cfg_data = kzalloc(sizeof(*dev_cfg_data), GFP_KERNEL);
  89        if (!dev_cfg_data)
  90                return -ENOMEM;
  91        INIT_LIST_HEAD(&dev_cfg_data->sec_list);
  92        init_rwsem(&dev_cfg_data->lock);
  93        accel_dev->cfg = dev_cfg_data;
  94
  95        /* accel_dev->debugfs_dir should always be non-NULL here */
  96        dev_cfg_data->debug = debugfs_create_file("dev_cfg", S_IRUSR,
  97                                                  accel_dev->debugfs_dir,
  98                                                  dev_cfg_data,
  99                                                  &qat_dev_cfg_fops);
 100        return 0;
 101}
 102EXPORT_SYMBOL_GPL(adf_cfg_dev_add);
 103
 104static void adf_cfg_section_del_all(struct list_head *head);
 105
 106void adf_cfg_del_all(struct adf_accel_dev *accel_dev)
 107{
 108        struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
 109
 110        down_write(&dev_cfg_data->lock);
 111        adf_cfg_section_del_all(&dev_cfg_data->sec_list);
 112        up_write(&dev_cfg_data->lock);
 113        clear_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
 114}
 115
 116/**
 117 * adf_cfg_dev_remove() - Clears acceleration device configuration table.
 118 * @accel_dev:  Pointer to acceleration device.
 119 *
 120 * Function removes configuration table from the given acceleration device
 121 * and frees all allocated memory.
 122 * To be used by QAT device specific drivers.
 123 *
 124 * Return: void
 125 */
 126void adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
 127{
 128        struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
 129
 130        if (!dev_cfg_data)
 131                return;
 132
 133        down_write(&dev_cfg_data->lock);
 134        adf_cfg_section_del_all(&dev_cfg_data->sec_list);
 135        up_write(&dev_cfg_data->lock);
 136        debugfs_remove(dev_cfg_data->debug);
 137        kfree(dev_cfg_data);
 138        accel_dev->cfg = NULL;
 139}
 140EXPORT_SYMBOL_GPL(adf_cfg_dev_remove);
 141
 142static void adf_cfg_keyval_add(struct adf_cfg_key_val *new,
 143                               struct adf_cfg_section *sec)
 144{
 145        list_add_tail(&new->list, &sec->param_head);
 146}
 147
 148static void adf_cfg_keyval_del_all(struct list_head *head)
 149{
 150        struct list_head *list_ptr, *tmp;
 151
 152        list_for_each_prev_safe(list_ptr, tmp, head) {
 153                struct adf_cfg_key_val *ptr =
 154                        list_entry(list_ptr, struct adf_cfg_key_val, list);
 155                list_del(list_ptr);
 156                kfree(ptr);
 157        }
 158}
 159
 160static void adf_cfg_section_del_all(struct list_head *head)
 161{
 162        struct adf_cfg_section *ptr;
 163        struct list_head *list, *tmp;
 164
 165        list_for_each_prev_safe(list, tmp, head) {
 166                ptr = list_entry(list, struct adf_cfg_section, list);
 167                adf_cfg_keyval_del_all(&ptr->param_head);
 168                list_del(list);
 169                kfree(ptr);
 170        }
 171}
 172
 173static struct adf_cfg_key_val *adf_cfg_key_value_find(struct adf_cfg_section *s,
 174                                                      const char *key)
 175{
 176        struct list_head *list;
 177
 178        list_for_each(list, &s->param_head) {
 179                struct adf_cfg_key_val *ptr =
 180                        list_entry(list, struct adf_cfg_key_val, list);
 181                if (!strcmp(ptr->key, key))
 182                        return ptr;
 183        }
 184        return NULL;
 185}
 186
 187static struct adf_cfg_section *adf_cfg_sec_find(struct adf_accel_dev *accel_dev,
 188                                                const char *sec_name)
 189{
 190        struct adf_cfg_device_data *cfg = accel_dev->cfg;
 191        struct list_head *list;
 192
 193        list_for_each(list, &cfg->sec_list) {
 194                struct adf_cfg_section *ptr =
 195                        list_entry(list, struct adf_cfg_section, list);
 196                if (!strcmp(ptr->name, sec_name))
 197                        return ptr;
 198        }
 199        return NULL;
 200}
 201
 202static int adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
 203                               const char *sec_name,
 204                               const char *key_name,
 205                               char *val)
 206{
 207        struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
 208        struct adf_cfg_key_val *keyval = NULL;
 209
 210        if (sec)
 211                keyval = adf_cfg_key_value_find(sec, key_name);
 212        if (keyval) {
 213                memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
 214                return 0;
 215        }
 216        return -1;
 217}
 218
 219/**
 220 * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
 221 * @accel_dev:  Pointer to acceleration device.
 222 * @section_name: Name of the section where the param will be added
 223 * @key: The key string
 224 * @val: Value pain for the given @key
 225 * @type: Type - string, int or address
 226 *
 227 * Function adds configuration key - value entry in the appropriate section
 228 * in the given acceleration device
 229 * To be used by QAT device specific drivers.
 230 *
 231 * Return: 0 on success, error code otherwise.
 232 */
 233int adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
 234                                const char *section_name,
 235                                const char *key, const void *val,
 236                                enum adf_cfg_val_type type)
 237{
 238        struct adf_cfg_device_data *cfg = accel_dev->cfg;
 239        struct adf_cfg_key_val *key_val;
 240        struct adf_cfg_section *section = adf_cfg_sec_find(accel_dev,
 241                                                           section_name);
 242        if (!section)
 243                return -EFAULT;
 244
 245        key_val = kzalloc(sizeof(*key_val), GFP_KERNEL);
 246        if (!key_val)
 247                return -ENOMEM;
 248
 249        INIT_LIST_HEAD(&key_val->list);
 250        strlcpy(key_val->key, key, sizeof(key_val->key));
 251
 252        if (type == ADF_DEC) {
 253                snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
 254                         "%ld", (*((long *)val)));
 255        } else if (type == ADF_STR) {
 256                strlcpy(key_val->val, (char *)val, sizeof(key_val->val));
 257        } else if (type == ADF_HEX) {
 258                snprintf(key_val->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES,
 259                         "0x%lx", (unsigned long)val);
 260        } else {
 261                dev_err(&GET_DEV(accel_dev), "Unknown type given.\n");
 262                kfree(key_val);
 263                return -1;
 264        }
 265        key_val->type = type;
 266        down_write(&cfg->lock);
 267        adf_cfg_keyval_add(key_val, section);
 268        up_write(&cfg->lock);
 269        return 0;
 270}
 271EXPORT_SYMBOL_GPL(adf_cfg_add_key_value_param);
 272
 273/**
 274 * adf_cfg_section_add() - Add config section entry to config table.
 275 * @accel_dev:  Pointer to acceleration device.
 276 * @name: Name of the section
 277 *
 278 * Function adds configuration section where key - value entries
 279 * will be stored.
 280 * To be used by QAT device specific drivers.
 281 *
 282 * Return: 0 on success, error code otherwise.
 283 */
 284int adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
 285{
 286        struct adf_cfg_device_data *cfg = accel_dev->cfg;
 287        struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
 288
 289        if (sec)
 290                return 0;
 291
 292        sec = kzalloc(sizeof(*sec), GFP_KERNEL);
 293        if (!sec)
 294                return -ENOMEM;
 295
 296        strlcpy(sec->name, name, sizeof(sec->name));
 297        INIT_LIST_HEAD(&sec->param_head);
 298        down_write(&cfg->lock);
 299        list_add_tail(&sec->list, &cfg->sec_list);
 300        up_write(&cfg->lock);
 301        return 0;
 302}
 303EXPORT_SYMBOL_GPL(adf_cfg_section_add);
 304
 305int adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
 306                            const char *section, const char *name,
 307                            char *value)
 308{
 309        struct adf_cfg_device_data *cfg = accel_dev->cfg;
 310        int ret;
 311
 312        down_read(&cfg->lock);
 313        ret = adf_cfg_key_val_get(accel_dev, section, name, value);
 314        up_read(&cfg->lock);
 315        return ret;
 316}
 317