The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/dev/qat/qat_common/adf_cfg.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /* SPDX-License-Identifier: BSD-3-Clause */
    2 /* Copyright(c) 2007-2022 Intel Corporation */
    3 /* $FreeBSD$ */
    4 #include "adf_accel_devices.h"
    5 #include "adf_cfg.h"
    6 #include "adf_common_drv.h"
    7 #include "adf_cfg_dev_dbg.h"
    8 #include "adf_heartbeat_dbg.h"
    9 #include "adf_ver_dbg.h"
   10 #include "adf_fw_counters.h"
   11 #include "adf_cnvnr_freq_counters.h"
   12 
   13 /**
   14  * adf_cfg_dev_add() - Create an acceleration device configuration table.
   15  * @accel_dev:  Pointer to acceleration device.
   16  *
   17  * Function creates a configuration table for the given acceleration device.
   18  * The table stores device specific config values.
   19  * To be used by QAT device specific drivers.
   20  *
   21  * Return: 0 on success, error code otherwise.
   22  */
   23 int
   24 adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
   25 {
   26         struct adf_cfg_device_data *dev_cfg_data;
   27 
   28         dev_cfg_data = malloc(sizeof(*dev_cfg_data), M_QAT, M_WAITOK | M_ZERO);
   29         INIT_LIST_HEAD(&dev_cfg_data->sec_list);
   30         sx_init(&dev_cfg_data->lock, "qat cfg data");
   31         accel_dev->cfg = dev_cfg_data;
   32 
   33         if (adf_cfg_dev_dbg_add(accel_dev))
   34                 goto err;
   35         if (!accel_dev->is_vf) {
   36                 if (adf_heartbeat_dbg_add(accel_dev))
   37                         goto err;
   38 
   39                 if (adf_ver_dbg_add(accel_dev))
   40                         goto err;
   41 
   42                 if (adf_fw_counters_add(accel_dev))
   43                         goto err;
   44 
   45                 if (adf_cnvnr_freq_counters_add(accel_dev))
   46                         goto err;
   47         }
   48         return 0;
   49 
   50 err:
   51         free(dev_cfg_data, M_QAT);
   52         accel_dev->cfg = NULL;
   53         return EFAULT;
   54 }
   55 
   56 static void adf_cfg_section_del_all(struct list_head *head);
   57 
   58 void
   59 adf_cfg_del_all(struct adf_accel_dev *accel_dev)
   60 {
   61         struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
   62 
   63         sx_xlock(&dev_cfg_data->lock);
   64         adf_cfg_section_del_all(&dev_cfg_data->sec_list);
   65         sx_xunlock(&dev_cfg_data->lock);
   66         clear_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
   67 }
   68 
   69 void
   70 adf_cfg_depot_del_all(struct list_head *head)
   71 {
   72         adf_cfg_section_del_all(head);
   73 }
   74 
   75 /**
   76  * adf_cfg_dev_remove() - Clears acceleration device configuration table.
   77  * @accel_dev:  Pointer to acceleration device.
   78  *
   79  * Function removes configuration table from the given acceleration device
   80  * and frees all allocated memory.
   81  * To be used by QAT device specific drivers.
   82  *
   83  * Return: void
   84  */
   85 void
   86 adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
   87 {
   88         struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
   89 
   90         if (!dev_cfg_data)
   91                 return;
   92 
   93         sx_xlock(&dev_cfg_data->lock);
   94         adf_cfg_section_del_all(&dev_cfg_data->sec_list);
   95         sx_xunlock(&dev_cfg_data->lock);
   96 
   97         adf_cfg_dev_dbg_remove(accel_dev);
   98         if (!accel_dev->is_vf) {
   99                 adf_ver_dbg_del(accel_dev);
  100                 adf_heartbeat_dbg_del(accel_dev);
  101                 adf_fw_counters_remove(accel_dev);
  102                 adf_cnvnr_freq_counters_remove(accel_dev);
  103         }
  104 
  105         free(dev_cfg_data, M_QAT);
  106         accel_dev->cfg = NULL;
  107 }
  108 
  109 static void
  110 adf_cfg_keyval_add(struct adf_cfg_key_val *new, struct adf_cfg_section *sec)
  111 {
  112         list_add_tail(&new->list, &sec->param_head);
  113 }
  114 
  115 static void
  116 adf_cfg_keyval_remove(const char *key, struct adf_cfg_section *sec)
  117 {
  118         struct list_head *list_ptr, *tmp;
  119         struct list_head *head = &sec->param_head;
  120 
  121         list_for_each_prev_safe(list_ptr, tmp, head)
  122         {
  123                 struct adf_cfg_key_val *ptr =
  124                     list_entry(list_ptr, struct adf_cfg_key_val, list);
  125 
  126                 if (strncmp(ptr->key, key, sizeof(ptr->key)) != 0)
  127                         continue;
  128 
  129                 list_del(list_ptr);
  130                 free(ptr, M_QAT);
  131                 break;
  132         }
  133 }
  134 
  135 static int
  136 adf_cfg_section_restore_all(struct adf_accel_dev *accel_dev,
  137                             struct adf_cfg_depot_list *cfg_depot_list)
  138 {
  139         struct adf_cfg_section *ptr_sec, *iter_sec;
  140         struct adf_cfg_key_val *ptr_key;
  141         struct list_head *list, *tmp;
  142         struct list_head *restore_list = &accel_dev->cfg->sec_list;
  143         struct list_head *head = &cfg_depot_list[accel_dev->accel_id].sec_list;
  144 
  145         INIT_LIST_HEAD(restore_list);
  146 
  147         list_for_each_prev_safe(list, tmp, head)
  148         {
  149                 ptr_sec = list_entry(list, struct adf_cfg_section, list);
  150                 iter_sec = malloc(sizeof(*iter_sec), M_QAT, M_WAITOK | M_ZERO);
  151 
  152                 strlcpy(iter_sec->name, ptr_sec->name, sizeof(iter_sec->name));
  153 
  154                 INIT_LIST_HEAD(&iter_sec->param_head);
  155 
  156                 /* now we restore all the parameters */
  157                 list_for_each_entry(ptr_key, &ptr_sec->param_head, list)
  158                 {
  159                         struct adf_cfg_key_val *key_val;
  160 
  161                         key_val =
  162                             malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
  163 
  164                         memcpy(key_val, ptr_key, sizeof(*key_val));
  165                         list_add_tail(&key_val->list, &iter_sec->param_head);
  166                 }
  167                 list_add_tail(&iter_sec->list, restore_list);
  168         }
  169         adf_cfg_section_del_all(head);
  170         return 0;
  171 }
  172 
  173 int
  174 adf_cfg_depot_restore_all(struct adf_accel_dev *accel_dev,
  175                           struct adf_cfg_depot_list *cfg_depot_list)
  176 {
  177         struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
  178         int ret = 0;
  179 
  180         sx_xlock(&dev_cfg_data->lock);
  181         ret = adf_cfg_section_restore_all(accel_dev, cfg_depot_list);
  182         sx_xunlock(&dev_cfg_data->lock);
  183 
  184         return ret;
  185 }
  186 
  187 /**
  188  * adf_cfg_section_del() - Delete config section entry to config table.
  189  * @accel_dev:  Pointer to acceleration device.
  190  * @name: Name of the section
  191  *
  192  * Function deletes configuration section where key - value entries
  193  * will be stored.
  194  * To be used by QAT device specific drivers.
  195  */
  196 static void
  197 adf_cfg_section_del(struct adf_accel_dev *accel_dev, const char *name)
  198 {
  199         struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
  200 
  201         if (!sec)
  202                 return;
  203         adf_cfg_keyval_del_all(&sec->param_head);
  204         list_del(&sec->list);
  205         free(sec, M_QAT);
  206 }
  207 
  208 void
  209 adf_cfg_keyval_del_all(struct list_head *head)
  210 {
  211         struct list_head *list_ptr, *tmp;
  212 
  213         list_for_each_prev_safe(list_ptr, tmp, head)
  214         {
  215                 struct adf_cfg_key_val *ptr =
  216                     list_entry(list_ptr, struct adf_cfg_key_val, list);
  217                 list_del(list_ptr);
  218                 free(ptr, M_QAT);
  219         }
  220 }
  221 
  222 static void
  223 adf_cfg_section_del_all(struct list_head *head)
  224 {
  225         struct adf_cfg_section *ptr;
  226         struct list_head *list, *tmp;
  227 
  228         list_for_each_prev_safe(list, tmp, head)
  229         {
  230                 ptr = list_entry(list, struct adf_cfg_section, list);
  231                 adf_cfg_keyval_del_all(&ptr->param_head);
  232                 list_del(list);
  233                 free(ptr, M_QAT);
  234         }
  235 }
  236 
  237 static struct adf_cfg_key_val *
  238 adf_cfg_key_value_find(struct adf_cfg_section *s, const char *key)
  239 {
  240         struct list_head *list;
  241 
  242         list_for_each(list, &s->param_head)
  243         {
  244                 struct adf_cfg_key_val *ptr =
  245                     list_entry(list, struct adf_cfg_key_val, list);
  246                 if (!strncmp(ptr->key, key, sizeof(ptr->key)))
  247                         return ptr;
  248         }
  249         return NULL;
  250 }
  251 
  252 struct adf_cfg_section *
  253 adf_cfg_sec_find(struct adf_accel_dev *accel_dev, const char *sec_name)
  254 {
  255         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  256         struct list_head *list;
  257 
  258         list_for_each(list, &cfg->sec_list)
  259         {
  260                 struct adf_cfg_section *ptr =
  261                     list_entry(list, struct adf_cfg_section, list);
  262                 if (!strncmp(ptr->name, sec_name, sizeof(ptr->name)))
  263                         return ptr;
  264         }
  265         return NULL;
  266 }
  267 
  268 static int
  269 adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
  270                     const char *sec_name,
  271                     const char *key_name,
  272                     char *val)
  273 {
  274         struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
  275         struct adf_cfg_key_val *keyval = NULL;
  276 
  277         if (sec)
  278                 keyval = adf_cfg_key_value_find(sec, key_name);
  279         if (keyval) {
  280                 memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
  281                 return 0;
  282         }
  283         return -1;
  284 }
  285 
  286 /**
  287  * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
  288  * @accel_dev:  Pointer to acceleration device.
  289  * @section_name: Name of the section where the param will be added
  290  * @key: The key string
  291  * @val: Value pain for the given @key
  292  * @type: Type - string, int or address
  293  *
  294  * Function adds configuration key - value entry in the appropriate section
  295  * in the given acceleration device
  296  * To be used by QAT device specific drivers.
  297  *
  298  * Return: 0 on success, error code otherwise.
  299  */
  300 int
  301 adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
  302                             const char *section_name,
  303                             const char *key,
  304                             const void *val,
  305                             enum adf_cfg_val_type type)
  306 {
  307         char temp_val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
  308         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  309         struct adf_cfg_key_val *key_val;
  310         struct adf_cfg_section *section =
  311             adf_cfg_sec_find(accel_dev, section_name);
  312         if (!section)
  313                 return EFAULT;
  314 
  315         key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
  316 
  317         INIT_LIST_HEAD(&key_val->list);
  318         strlcpy(key_val->key, key, sizeof(key_val->key));
  319 
  320         if (type == ADF_DEC) {
  321                 snprintf(key_val->val,
  322                          ADF_CFG_MAX_VAL_LEN_IN_BYTES,
  323                          "%ld",
  324                          (*((const long *)val)));
  325         } else if (type == ADF_STR) {
  326                 strlcpy(key_val->val, (const char *)val, sizeof(key_val->val));
  327         } else if (type == ADF_HEX) {
  328                 snprintf(key_val->val,
  329                          ADF_CFG_MAX_VAL_LEN_IN_BYTES,
  330                          "0x%lx",
  331                          (unsigned long)val);
  332         } else {
  333                 device_printf(GET_DEV(accel_dev), "Unknown type given.\n");
  334                 free(key_val, M_QAT);
  335                 return -1;
  336         }
  337         key_val->type = type;
  338 
  339         /* Add the key-value pair as below policy:
  340          *     1. If the key doesn't exist, add it,
  341          *     2. If the key already exists with a different value
  342          *        then delete it,
  343          *     3. If the key exists with the same value, then return
  344          *        without doing anything.
  345          */
  346         if (adf_cfg_key_val_get(accel_dev, section_name, key, temp_val) == 0) {
  347                 if (strncmp(temp_val, key_val->val, sizeof(temp_val)) != 0) {
  348                         adf_cfg_keyval_remove(key, section);
  349                 } else {
  350                         free(key_val, M_QAT);
  351                         return 0;
  352                 }
  353         }
  354 
  355         sx_xlock(&cfg->lock);
  356         adf_cfg_keyval_add(key_val, section);
  357         sx_xunlock(&cfg->lock);
  358         return 0;
  359 }
  360 
  361 int
  362 adf_cfg_save_section(struct adf_accel_dev *accel_dev,
  363                      const char *name,
  364                      struct adf_cfg_section *section)
  365 {
  366         struct adf_cfg_key_val *ptr;
  367         struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
  368 
  369         if (!sec) {
  370                 device_printf(GET_DEV(accel_dev),
  371                               "Couldn't find section %s\n",
  372                               name);
  373                 return EFAULT;
  374         }
  375 
  376         strlcpy(section->name, name, sizeof(section->name));
  377         INIT_LIST_HEAD(&section->param_head);
  378 
  379         /* now we save all the parameters */
  380         list_for_each_entry(ptr, &sec->param_head, list)
  381         {
  382                 struct adf_cfg_key_val *key_val;
  383 
  384                 key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
  385 
  386                 memcpy(key_val, ptr, sizeof(*key_val));
  387                 list_add_tail(&key_val->list, &section->param_head);
  388         }
  389         return 0;
  390 }
  391 
  392 static int
  393 adf_cfg_section_save_all(struct adf_accel_dev *accel_dev,
  394                          struct adf_cfg_depot_list *cfg_depot_list)
  395 {
  396         struct adf_cfg_section *ptr_sec, *iter_sec;
  397         struct list_head *list, *tmp, *save_list;
  398         struct list_head *head = &accel_dev->cfg->sec_list;
  399 
  400         save_list = &cfg_depot_list[accel_dev->accel_id].sec_list;
  401 
  402         list_for_each_prev_safe(list, tmp, head)
  403         {
  404                 ptr_sec = list_entry(list, struct adf_cfg_section, list);
  405                 iter_sec = malloc(sizeof(*iter_sec), M_QAT, M_WAITOK | M_ZERO);
  406 
  407                 adf_cfg_save_section(accel_dev, ptr_sec->name, iter_sec);
  408                 list_add_tail(&iter_sec->list, save_list);
  409         }
  410         return 0;
  411 }
  412 
  413 int
  414 adf_cfg_depot_save_all(struct adf_accel_dev *accel_dev,
  415                        struct adf_cfg_depot_list *cfg_depot_list)
  416 {
  417         struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
  418         int ret = 0;
  419 
  420         sx_xlock(&dev_cfg_data->lock);
  421         ret = adf_cfg_section_save_all(accel_dev, cfg_depot_list);
  422         sx_xunlock(&dev_cfg_data->lock);
  423 
  424         return ret;
  425 }
  426 
  427 /**
  428  * adf_cfg_remove_key_param() - remove config entry in config table.
  429  * @accel_dev:  Pointer to acceleration device.
  430  * @section_name: Name of the section where the param will be added
  431  * @key: The key string
  432  *
  433  * Function remove configuration key
  434  * To be used by QAT device specific drivers.
  435  *
  436  * Return: 0 on success, error code otherwise.
  437  */
  438 int
  439 adf_cfg_remove_key_param(struct adf_accel_dev *accel_dev,
  440                          const char *section_name,
  441                          const char *key)
  442 {
  443         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  444         struct adf_cfg_section *section =
  445             adf_cfg_sec_find(accel_dev, section_name);
  446         if (!section)
  447                 return EFAULT;
  448 
  449         sx_xlock(&cfg->lock);
  450         adf_cfg_keyval_remove(key, section);
  451         sx_xunlock(&cfg->lock);
  452         return 0;
  453 }
  454 
  455 /**
  456  * adf_cfg_section_add() - Add config section entry to config table.
  457  * @accel_dev:  Pointer to acceleration device.
  458  * @name: Name of the section
  459  *
  460  * Function adds configuration section where key - value entries
  461  * will be stored.
  462  * To be used by QAT device specific drivers.
  463  *
  464  * Return: 0 on success, error code otherwise.
  465  */
  466 int
  467 adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
  468 {
  469         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  470         struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
  471 
  472         if (sec)
  473                 return 0;
  474 
  475         sec = malloc(sizeof(*sec), M_QAT, M_WAITOK | M_ZERO);
  476 
  477         strlcpy(sec->name, name, sizeof(sec->name));
  478         INIT_LIST_HEAD(&sec->param_head);
  479         sx_xlock(&cfg->lock);
  480         list_add_tail(&sec->list, &cfg->sec_list);
  481         sx_xunlock(&cfg->lock);
  482         return 0;
  483 }
  484 
  485 /* need to differentiate derived section with the original section */
  486 int
  487 adf_cfg_derived_section_add(struct adf_accel_dev *accel_dev, const char *name)
  488 {
  489         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  490         struct adf_cfg_section *sec = NULL;
  491 
  492         if (adf_cfg_section_add(accel_dev, name))
  493                 return EFAULT;
  494 
  495         sec = adf_cfg_sec_find(accel_dev, name);
  496         if (!sec)
  497                 return EFAULT;
  498 
  499         sx_xlock(&cfg->lock);
  500         sec->is_derived = true;
  501         sx_xunlock(&cfg->lock);
  502         return 0;
  503 }
  504 
  505 static int
  506 adf_cfg_restore_key_value_param(struct adf_accel_dev *accel_dev,
  507                                 const char *section_name,
  508                                 const char *key,
  509                                 const char *val,
  510                                 enum adf_cfg_val_type type)
  511 {
  512         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  513         struct adf_cfg_key_val *key_val;
  514         struct adf_cfg_section *section =
  515             adf_cfg_sec_find(accel_dev, section_name);
  516         if (!section)
  517                 return EFAULT;
  518 
  519         key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
  520 
  521         INIT_LIST_HEAD(&key_val->list);
  522 
  523         strlcpy(key_val->key, key, sizeof(key_val->key));
  524         strlcpy(key_val->val, val, sizeof(key_val->val));
  525         key_val->type = type;
  526         sx_xlock(&cfg->lock);
  527         adf_cfg_keyval_add(key_val, section);
  528         sx_xunlock(&cfg->lock);
  529         return 0;
  530 }
  531 
  532 int
  533 adf_cfg_restore_section(struct adf_accel_dev *accel_dev,
  534                         struct adf_cfg_section *section)
  535 {
  536         struct adf_cfg_key_val *ptr;
  537         int ret = 0;
  538 
  539         ret = adf_cfg_section_add(accel_dev, section->name);
  540         if (ret)
  541                 goto err;
  542 
  543         list_for_each_entry(ptr, &section->param_head, list)
  544         {
  545                 ret = adf_cfg_restore_key_value_param(
  546                     accel_dev, section->name, ptr->key, ptr->val, ptr->type);
  547                 if (ret)
  548                         goto err_remove_sec;
  549         }
  550         return 0;
  551 
  552 err_remove_sec:
  553         adf_cfg_section_del(accel_dev, section->name);
  554 err:
  555         device_printf(GET_DEV(accel_dev),
  556                       "Failed to restore section %s\n",
  557                       section->name);
  558         return ret;
  559 }
  560 
  561 int
  562 adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
  563                         const char *section,
  564                         const char *name,
  565                         char *value)
  566 {
  567         struct adf_cfg_device_data *cfg = accel_dev->cfg;
  568         int ret;
  569 
  570         sx_slock(&cfg->lock);
  571         ret = adf_cfg_key_val_get(accel_dev, section, name, value);
  572         sx_sunlock(&cfg->lock);
  573         return ret;
  574 }

Cache object: 50f7dcc47c49f5c891220d1fb1d76a61


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.