xref: /freebsd/sys/dev/qat/qat_common/adf_cfg.c (revision c38bafee7e182fbcdc3c346b2785ed258230cb06)
178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
2*c38bafeeSHareshx Sankar Raj /* Copyright(c) 2007-2025 Intel Corporation */
378ee8d1cSJulian Grajkowski #include "adf_accel_devices.h"
478ee8d1cSJulian Grajkowski #include "adf_cfg.h"
578ee8d1cSJulian Grajkowski #include "adf_common_drv.h"
6266b0663SKrzysztof Zdziarski #include "adf_cfg_device.h"
7266b0663SKrzysztof Zdziarski #include "adf_cfg_sysctl.h"
878ee8d1cSJulian Grajkowski 
978ee8d1cSJulian Grajkowski /**
1078ee8d1cSJulian Grajkowski  * adf_cfg_dev_add() - Create an acceleration device configuration table.
1178ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
1278ee8d1cSJulian Grajkowski  *
1378ee8d1cSJulian Grajkowski  * Function creates a configuration table for the given acceleration device.
1478ee8d1cSJulian Grajkowski  * The table stores device specific config values.
1578ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
1678ee8d1cSJulian Grajkowski  *
1778ee8d1cSJulian Grajkowski  * Return: 0 on success, error code otherwise.
1878ee8d1cSJulian Grajkowski  */
1978ee8d1cSJulian Grajkowski int
adf_cfg_dev_add(struct adf_accel_dev * accel_dev)2078ee8d1cSJulian Grajkowski adf_cfg_dev_add(struct adf_accel_dev *accel_dev)
2178ee8d1cSJulian Grajkowski {
2278ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *dev_cfg_data;
2378ee8d1cSJulian Grajkowski 
2478ee8d1cSJulian Grajkowski 	dev_cfg_data = malloc(sizeof(*dev_cfg_data), M_QAT, M_WAITOK | M_ZERO);
2578ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(&dev_cfg_data->sec_list);
2678ee8d1cSJulian Grajkowski 	sx_init(&dev_cfg_data->lock, "qat cfg data");
2778ee8d1cSJulian Grajkowski 	accel_dev->cfg = dev_cfg_data;
2878ee8d1cSJulian Grajkowski 
29266b0663SKrzysztof Zdziarski 	/* Default device configuration initialization */
30266b0663SKrzysztof Zdziarski 	if (!accel_dev->is_vf) {
31266b0663SKrzysztof Zdziarski 
32266b0663SKrzysztof Zdziarski 		if (IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev)))) {
33266b0663SKrzysztof Zdziarski 			dev_cfg_data->num_user_processes =
34266b0663SKrzysztof Zdziarski 			    ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM;
35266b0663SKrzysztof Zdziarski 
36266b0663SKrzysztof Zdziarski 			strncpy(dev_cfg_data->cfg_mode,
37266b0663SKrzysztof Zdziarski 				ADF_CFG_KERNEL_USER,
38266b0663SKrzysztof Zdziarski 				ADF_CFG_MAX_VAL);
39266b0663SKrzysztof Zdziarski 
40266b0663SKrzysztof Zdziarski 			if (accel_dev->accel_id % 2 == 0) {
41266b0663SKrzysztof Zdziarski 				strncpy(dev_cfg_data->cfg_services,
42266b0663SKrzysztof Zdziarski 					ADF_CFG_SYM_ASYM,
43266b0663SKrzysztof Zdziarski 					ADF_CFG_MAX_VAL);
44266b0663SKrzysztof Zdziarski 			} else {
45266b0663SKrzysztof Zdziarski 				strncpy(dev_cfg_data->cfg_services,
46266b0663SKrzysztof Zdziarski 					ADF_CFG_DC,
47266b0663SKrzysztof Zdziarski 					ADF_CFG_MAX_VAL);
48266b0663SKrzysztof Zdziarski 			}
49266b0663SKrzysztof Zdziarski 		} else {
50266b0663SKrzysztof Zdziarski 			strncpy(dev_cfg_data->cfg_mode,
51266b0663SKrzysztof Zdziarski 				ADF_CFG_KERNEL,
52266b0663SKrzysztof Zdziarski 				ADF_CFG_MAX_VAL);
53266b0663SKrzysztof Zdziarski 			dev_cfg_data->num_user_processes = 0;
54266b0663SKrzysztof Zdziarski 			strncpy(dev_cfg_data->cfg_services,
55266b0663SKrzysztof Zdziarski 				ADF_CFG_SYM_DC,
56266b0663SKrzysztof Zdziarski 				ADF_CFG_MAX_VAL);
57266b0663SKrzysztof Zdziarski 		}
58266b0663SKrzysztof Zdziarski 	} else {
59266b0663SKrzysztof Zdziarski 		dev_cfg_data->num_user_processes =
60266b0663SKrzysztof Zdziarski 		    ADF_CFG_STATIC_CONF_USER_PROCESSES_NUM;
61266b0663SKrzysztof Zdziarski 
62266b0663SKrzysztof Zdziarski 		strncpy(dev_cfg_data->cfg_mode,
63266b0663SKrzysztof Zdziarski 			ADF_CFG_KERNEL,
64266b0663SKrzysztof Zdziarski 			ADF_CFG_MAX_VAL);
65266b0663SKrzysztof Zdziarski 
66266b0663SKrzysztof Zdziarski 		strncpy(dev_cfg_data->cfg_services,
67266b0663SKrzysztof Zdziarski 			"sym;asym",
68266b0663SKrzysztof Zdziarski 			ADF_CFG_MAX_VAL);
69266b0663SKrzysztof Zdziarski 	}
70266b0663SKrzysztof Zdziarski 
71*c38bafeeSHareshx Sankar Raj 	if (adf_cfg_sysctl_add(accel_dev)) {
7278ee8d1cSJulian Grajkowski 		free(dev_cfg_data, M_QAT);
7378ee8d1cSJulian Grajkowski 		accel_dev->cfg = NULL;
7478ee8d1cSJulian Grajkowski 		return EFAULT;
7578ee8d1cSJulian Grajkowski 	}
7678ee8d1cSJulian Grajkowski 
77*c38bafeeSHareshx Sankar Raj 	return 0;
78*c38bafeeSHareshx Sankar Raj }
79*c38bafeeSHareshx Sankar Raj 
8078ee8d1cSJulian Grajkowski static void adf_cfg_section_del_all(struct list_head *head);
8178ee8d1cSJulian Grajkowski 
8278ee8d1cSJulian Grajkowski void
adf_cfg_del_all(struct adf_accel_dev * accel_dev)8378ee8d1cSJulian Grajkowski adf_cfg_del_all(struct adf_accel_dev *accel_dev)
8478ee8d1cSJulian Grajkowski {
8578ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
8678ee8d1cSJulian Grajkowski 
8778ee8d1cSJulian Grajkowski 	sx_xlock(&dev_cfg_data->lock);
8878ee8d1cSJulian Grajkowski 	adf_cfg_section_del_all(&dev_cfg_data->sec_list);
8978ee8d1cSJulian Grajkowski 	sx_xunlock(&dev_cfg_data->lock);
9078ee8d1cSJulian Grajkowski 	clear_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
9178ee8d1cSJulian Grajkowski }
9278ee8d1cSJulian Grajkowski 
9378ee8d1cSJulian Grajkowski void
adf_cfg_depot_del_all(struct list_head * head)9478ee8d1cSJulian Grajkowski adf_cfg_depot_del_all(struct list_head *head)
9578ee8d1cSJulian Grajkowski {
9678ee8d1cSJulian Grajkowski 	adf_cfg_section_del_all(head);
9778ee8d1cSJulian Grajkowski }
9878ee8d1cSJulian Grajkowski 
9978ee8d1cSJulian Grajkowski /**
10078ee8d1cSJulian Grajkowski  * adf_cfg_dev_remove() - Clears acceleration device configuration table.
10178ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
10278ee8d1cSJulian Grajkowski  *
10378ee8d1cSJulian Grajkowski  * Function removes configuration table from the given acceleration device
10478ee8d1cSJulian Grajkowski  * and frees all allocated memory.
10578ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
10678ee8d1cSJulian Grajkowski  *
10778ee8d1cSJulian Grajkowski  * Return: void
10878ee8d1cSJulian Grajkowski  */
10978ee8d1cSJulian Grajkowski void
adf_cfg_dev_remove(struct adf_accel_dev * accel_dev)11078ee8d1cSJulian Grajkowski adf_cfg_dev_remove(struct adf_accel_dev *accel_dev)
11178ee8d1cSJulian Grajkowski {
11278ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
11378ee8d1cSJulian Grajkowski 
11478ee8d1cSJulian Grajkowski 	if (!dev_cfg_data)
11578ee8d1cSJulian Grajkowski 		return;
11678ee8d1cSJulian Grajkowski 
11778ee8d1cSJulian Grajkowski 	sx_xlock(&dev_cfg_data->lock);
11878ee8d1cSJulian Grajkowski 	adf_cfg_section_del_all(&dev_cfg_data->sec_list);
11978ee8d1cSJulian Grajkowski 	sx_xunlock(&dev_cfg_data->lock);
12078ee8d1cSJulian Grajkowski 
121266b0663SKrzysztof Zdziarski 	adf_cfg_sysctl_remove(accel_dev);
12278ee8d1cSJulian Grajkowski 
12378ee8d1cSJulian Grajkowski 	free(dev_cfg_data, M_QAT);
12478ee8d1cSJulian Grajkowski 	accel_dev->cfg = NULL;
12578ee8d1cSJulian Grajkowski }
12678ee8d1cSJulian Grajkowski 
12778ee8d1cSJulian Grajkowski static void
adf_cfg_keyval_add(struct adf_cfg_key_val * new,struct adf_cfg_section * sec)12878ee8d1cSJulian Grajkowski adf_cfg_keyval_add(struct adf_cfg_key_val *new, struct adf_cfg_section *sec)
12978ee8d1cSJulian Grajkowski {
13078ee8d1cSJulian Grajkowski 	list_add_tail(&new->list, &sec->param_head);
13178ee8d1cSJulian Grajkowski }
13278ee8d1cSJulian Grajkowski 
13378ee8d1cSJulian Grajkowski static void
adf_cfg_keyval_remove(const char * key,struct adf_cfg_section * sec)13478ee8d1cSJulian Grajkowski adf_cfg_keyval_remove(const char *key, struct adf_cfg_section *sec)
13578ee8d1cSJulian Grajkowski {
13678ee8d1cSJulian Grajkowski 	struct list_head *list_ptr, *tmp;
13778ee8d1cSJulian Grajkowski 	struct list_head *head = &sec->param_head;
13878ee8d1cSJulian Grajkowski 
13978ee8d1cSJulian Grajkowski 	list_for_each_prev_safe(list_ptr, tmp, head)
14078ee8d1cSJulian Grajkowski 	{
14178ee8d1cSJulian Grajkowski 		struct adf_cfg_key_val *ptr =
14278ee8d1cSJulian Grajkowski 		    list_entry(list_ptr, struct adf_cfg_key_val, list);
14378ee8d1cSJulian Grajkowski 
14478ee8d1cSJulian Grajkowski 		if (strncmp(ptr->key, key, sizeof(ptr->key)) != 0)
14578ee8d1cSJulian Grajkowski 			continue;
14678ee8d1cSJulian Grajkowski 
14778ee8d1cSJulian Grajkowski 		list_del(list_ptr);
14878ee8d1cSJulian Grajkowski 		free(ptr, M_QAT);
14978ee8d1cSJulian Grajkowski 		break;
15078ee8d1cSJulian Grajkowski 	}
15178ee8d1cSJulian Grajkowski }
15278ee8d1cSJulian Grajkowski 
15378ee8d1cSJulian Grajkowski static int
adf_cfg_section_restore_all(struct adf_accel_dev * accel_dev,struct adf_cfg_depot_list * cfg_depot_list)15478ee8d1cSJulian Grajkowski adf_cfg_section_restore_all(struct adf_accel_dev *accel_dev,
15578ee8d1cSJulian Grajkowski 			    struct adf_cfg_depot_list *cfg_depot_list)
15678ee8d1cSJulian Grajkowski {
15778ee8d1cSJulian Grajkowski 	struct adf_cfg_section *ptr_sec, *iter_sec;
15878ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *ptr_key;
15978ee8d1cSJulian Grajkowski 	struct list_head *list, *tmp;
16078ee8d1cSJulian Grajkowski 	struct list_head *restore_list = &accel_dev->cfg->sec_list;
16178ee8d1cSJulian Grajkowski 	struct list_head *head = &cfg_depot_list[accel_dev->accel_id].sec_list;
16278ee8d1cSJulian Grajkowski 
16378ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(restore_list);
16478ee8d1cSJulian Grajkowski 
16578ee8d1cSJulian Grajkowski 	list_for_each_prev_safe(list, tmp, head)
16678ee8d1cSJulian Grajkowski 	{
16778ee8d1cSJulian Grajkowski 		ptr_sec = list_entry(list, struct adf_cfg_section, list);
16878ee8d1cSJulian Grajkowski 		iter_sec = malloc(sizeof(*iter_sec), M_QAT, M_WAITOK | M_ZERO);
16978ee8d1cSJulian Grajkowski 
17078ee8d1cSJulian Grajkowski 		strlcpy(iter_sec->name, ptr_sec->name, sizeof(iter_sec->name));
17178ee8d1cSJulian Grajkowski 
17278ee8d1cSJulian Grajkowski 		INIT_LIST_HEAD(&iter_sec->param_head);
17378ee8d1cSJulian Grajkowski 
17478ee8d1cSJulian Grajkowski 		/* now we restore all the parameters */
17578ee8d1cSJulian Grajkowski 		list_for_each_entry(ptr_key, &ptr_sec->param_head, list)
17678ee8d1cSJulian Grajkowski 		{
17778ee8d1cSJulian Grajkowski 			struct adf_cfg_key_val *key_val;
17878ee8d1cSJulian Grajkowski 
17978ee8d1cSJulian Grajkowski 			key_val =
18078ee8d1cSJulian Grajkowski 			    malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
18178ee8d1cSJulian Grajkowski 
18278ee8d1cSJulian Grajkowski 			memcpy(key_val, ptr_key, sizeof(*key_val));
18378ee8d1cSJulian Grajkowski 			list_add_tail(&key_val->list, &iter_sec->param_head);
18478ee8d1cSJulian Grajkowski 		}
18578ee8d1cSJulian Grajkowski 		list_add_tail(&iter_sec->list, restore_list);
18678ee8d1cSJulian Grajkowski 	}
18778ee8d1cSJulian Grajkowski 	adf_cfg_section_del_all(head);
18878ee8d1cSJulian Grajkowski 	return 0;
18978ee8d1cSJulian Grajkowski }
19078ee8d1cSJulian Grajkowski 
19178ee8d1cSJulian Grajkowski int
adf_cfg_depot_restore_all(struct adf_accel_dev * accel_dev,struct adf_cfg_depot_list * cfg_depot_list)19278ee8d1cSJulian Grajkowski adf_cfg_depot_restore_all(struct adf_accel_dev *accel_dev,
19378ee8d1cSJulian Grajkowski 			  struct adf_cfg_depot_list *cfg_depot_list)
19478ee8d1cSJulian Grajkowski {
19578ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
19678ee8d1cSJulian Grajkowski 	int ret = 0;
19778ee8d1cSJulian Grajkowski 
19878ee8d1cSJulian Grajkowski 	sx_xlock(&dev_cfg_data->lock);
19978ee8d1cSJulian Grajkowski 	ret = adf_cfg_section_restore_all(accel_dev, cfg_depot_list);
20078ee8d1cSJulian Grajkowski 	sx_xunlock(&dev_cfg_data->lock);
20178ee8d1cSJulian Grajkowski 
20278ee8d1cSJulian Grajkowski 	return ret;
20378ee8d1cSJulian Grajkowski }
20478ee8d1cSJulian Grajkowski 
20578ee8d1cSJulian Grajkowski /**
20678ee8d1cSJulian Grajkowski  * adf_cfg_section_del() - Delete config section entry to config table.
20778ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
20878ee8d1cSJulian Grajkowski  * @name: Name of the section
20978ee8d1cSJulian Grajkowski  *
21078ee8d1cSJulian Grajkowski  * Function deletes configuration section where key - value entries
21178ee8d1cSJulian Grajkowski  * will be stored.
21278ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
21378ee8d1cSJulian Grajkowski  */
21478ee8d1cSJulian Grajkowski static void
adf_cfg_section_del(struct adf_accel_dev * accel_dev,const char * name)21578ee8d1cSJulian Grajkowski adf_cfg_section_del(struct adf_accel_dev *accel_dev, const char *name)
21678ee8d1cSJulian Grajkowski {
21778ee8d1cSJulian Grajkowski 	struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
21878ee8d1cSJulian Grajkowski 
21978ee8d1cSJulian Grajkowski 	if (!sec)
22078ee8d1cSJulian Grajkowski 		return;
22178ee8d1cSJulian Grajkowski 	adf_cfg_keyval_del_all(&sec->param_head);
22278ee8d1cSJulian Grajkowski 	list_del(&sec->list);
22378ee8d1cSJulian Grajkowski 	free(sec, M_QAT);
22478ee8d1cSJulian Grajkowski }
22578ee8d1cSJulian Grajkowski 
22678ee8d1cSJulian Grajkowski void
adf_cfg_keyval_del_all(struct list_head * head)22778ee8d1cSJulian Grajkowski adf_cfg_keyval_del_all(struct list_head *head)
22878ee8d1cSJulian Grajkowski {
22978ee8d1cSJulian Grajkowski 	struct list_head *list_ptr, *tmp;
23078ee8d1cSJulian Grajkowski 
23178ee8d1cSJulian Grajkowski 	list_for_each_prev_safe(list_ptr, tmp, head)
23278ee8d1cSJulian Grajkowski 	{
23378ee8d1cSJulian Grajkowski 		struct adf_cfg_key_val *ptr =
23478ee8d1cSJulian Grajkowski 		    list_entry(list_ptr, struct adf_cfg_key_val, list);
23578ee8d1cSJulian Grajkowski 		list_del(list_ptr);
23678ee8d1cSJulian Grajkowski 		free(ptr, M_QAT);
23778ee8d1cSJulian Grajkowski 	}
23878ee8d1cSJulian Grajkowski }
23978ee8d1cSJulian Grajkowski 
24078ee8d1cSJulian Grajkowski static void
adf_cfg_section_del_all(struct list_head * head)24178ee8d1cSJulian Grajkowski adf_cfg_section_del_all(struct list_head *head)
24278ee8d1cSJulian Grajkowski {
24378ee8d1cSJulian Grajkowski 	struct adf_cfg_section *ptr;
24478ee8d1cSJulian Grajkowski 	struct list_head *list, *tmp;
24578ee8d1cSJulian Grajkowski 
24678ee8d1cSJulian Grajkowski 	list_for_each_prev_safe(list, tmp, head)
24778ee8d1cSJulian Grajkowski 	{
24878ee8d1cSJulian Grajkowski 		ptr = list_entry(list, struct adf_cfg_section, list);
24978ee8d1cSJulian Grajkowski 		adf_cfg_keyval_del_all(&ptr->param_head);
25078ee8d1cSJulian Grajkowski 		list_del(list);
25178ee8d1cSJulian Grajkowski 		free(ptr, M_QAT);
25278ee8d1cSJulian Grajkowski 	}
25378ee8d1cSJulian Grajkowski }
25478ee8d1cSJulian Grajkowski 
25578ee8d1cSJulian Grajkowski static struct adf_cfg_key_val *
adf_cfg_key_value_find(struct adf_cfg_section * s,const char * key)25678ee8d1cSJulian Grajkowski adf_cfg_key_value_find(struct adf_cfg_section *s, const char *key)
25778ee8d1cSJulian Grajkowski {
25878ee8d1cSJulian Grajkowski 	struct list_head *list;
25978ee8d1cSJulian Grajkowski 
26078ee8d1cSJulian Grajkowski 	list_for_each(list, &s->param_head)
26178ee8d1cSJulian Grajkowski 	{
26278ee8d1cSJulian Grajkowski 		struct adf_cfg_key_val *ptr =
26378ee8d1cSJulian Grajkowski 		    list_entry(list, struct adf_cfg_key_val, list);
26478ee8d1cSJulian Grajkowski 		if (!strncmp(ptr->key, key, sizeof(ptr->key)))
26578ee8d1cSJulian Grajkowski 			return ptr;
26678ee8d1cSJulian Grajkowski 	}
26778ee8d1cSJulian Grajkowski 	return NULL;
26878ee8d1cSJulian Grajkowski }
26978ee8d1cSJulian Grajkowski 
27078ee8d1cSJulian Grajkowski struct adf_cfg_section *
adf_cfg_sec_find(struct adf_accel_dev * accel_dev,const char * sec_name)27178ee8d1cSJulian Grajkowski adf_cfg_sec_find(struct adf_accel_dev *accel_dev, const char *sec_name)
27278ee8d1cSJulian Grajkowski {
27378ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
27478ee8d1cSJulian Grajkowski 	struct list_head *list;
27578ee8d1cSJulian Grajkowski 
27678ee8d1cSJulian Grajkowski 	list_for_each(list, &cfg->sec_list)
27778ee8d1cSJulian Grajkowski 	{
27878ee8d1cSJulian Grajkowski 		struct adf_cfg_section *ptr =
27978ee8d1cSJulian Grajkowski 		    list_entry(list, struct adf_cfg_section, list);
28078ee8d1cSJulian Grajkowski 		if (!strncmp(ptr->name, sec_name, sizeof(ptr->name)))
28178ee8d1cSJulian Grajkowski 			return ptr;
28278ee8d1cSJulian Grajkowski 	}
28378ee8d1cSJulian Grajkowski 	return NULL;
28478ee8d1cSJulian Grajkowski }
28578ee8d1cSJulian Grajkowski 
28678ee8d1cSJulian Grajkowski static int
adf_cfg_key_val_get(struct adf_accel_dev * accel_dev,const char * sec_name,const char * key_name,char * val)28778ee8d1cSJulian Grajkowski adf_cfg_key_val_get(struct adf_accel_dev *accel_dev,
28878ee8d1cSJulian Grajkowski 		    const char *sec_name,
28978ee8d1cSJulian Grajkowski 		    const char *key_name,
29078ee8d1cSJulian Grajkowski 		    char *val)
29178ee8d1cSJulian Grajkowski {
29278ee8d1cSJulian Grajkowski 	struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, sec_name);
29378ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *keyval = NULL;
29478ee8d1cSJulian Grajkowski 
29578ee8d1cSJulian Grajkowski 	if (sec)
29678ee8d1cSJulian Grajkowski 		keyval = adf_cfg_key_value_find(sec, key_name);
29778ee8d1cSJulian Grajkowski 	if (keyval) {
29878ee8d1cSJulian Grajkowski 		memcpy(val, keyval->val, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
29978ee8d1cSJulian Grajkowski 		return 0;
30078ee8d1cSJulian Grajkowski 	}
30178ee8d1cSJulian Grajkowski 	return -1;
30278ee8d1cSJulian Grajkowski }
30378ee8d1cSJulian Grajkowski 
30478ee8d1cSJulian Grajkowski /**
30578ee8d1cSJulian Grajkowski  * adf_cfg_add_key_value_param() - Add key-value config entry to config table.
30678ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
30778ee8d1cSJulian Grajkowski  * @section_name: Name of the section where the param will be added
30878ee8d1cSJulian Grajkowski  * @key: The key string
30978ee8d1cSJulian Grajkowski  * @val: Value pain for the given @key
31078ee8d1cSJulian Grajkowski  * @type: Type - string, int or address
31178ee8d1cSJulian Grajkowski  *
31278ee8d1cSJulian Grajkowski  * Function adds configuration key - value entry in the appropriate section
31378ee8d1cSJulian Grajkowski  * in the given acceleration device
31478ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
31578ee8d1cSJulian Grajkowski  *
31678ee8d1cSJulian Grajkowski  * Return: 0 on success, error code otherwise.
31778ee8d1cSJulian Grajkowski  */
31878ee8d1cSJulian Grajkowski int
adf_cfg_add_key_value_param(struct adf_accel_dev * accel_dev,const char * section_name,const char * key,const void * val,enum adf_cfg_val_type type)31978ee8d1cSJulian Grajkowski adf_cfg_add_key_value_param(struct adf_accel_dev *accel_dev,
32078ee8d1cSJulian Grajkowski 			    const char *section_name,
32178ee8d1cSJulian Grajkowski 			    const char *key,
32278ee8d1cSJulian Grajkowski 			    const void *val,
32378ee8d1cSJulian Grajkowski 			    enum adf_cfg_val_type type)
32478ee8d1cSJulian Grajkowski {
32578ee8d1cSJulian Grajkowski 	char temp_val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
32678ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
32778ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *key_val;
32878ee8d1cSJulian Grajkowski 	struct adf_cfg_section *section =
32978ee8d1cSJulian Grajkowski 	    adf_cfg_sec_find(accel_dev, section_name);
33078ee8d1cSJulian Grajkowski 	if (!section)
33178ee8d1cSJulian Grajkowski 		return EFAULT;
33278ee8d1cSJulian Grajkowski 
33378ee8d1cSJulian Grajkowski 	key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
33478ee8d1cSJulian Grajkowski 
33578ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(&key_val->list);
33678ee8d1cSJulian Grajkowski 	strlcpy(key_val->key, key, sizeof(key_val->key));
33778ee8d1cSJulian Grajkowski 
33878ee8d1cSJulian Grajkowski 	if (type == ADF_DEC) {
33978ee8d1cSJulian Grajkowski 		snprintf(key_val->val,
34078ee8d1cSJulian Grajkowski 			 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
34178ee8d1cSJulian Grajkowski 			 "%ld",
34278ee8d1cSJulian Grajkowski 			 (*((const long *)val)));
34378ee8d1cSJulian Grajkowski 	} else if (type == ADF_STR) {
34478ee8d1cSJulian Grajkowski 		strlcpy(key_val->val, (const char *)val, sizeof(key_val->val));
34578ee8d1cSJulian Grajkowski 	} else if (type == ADF_HEX) {
34678ee8d1cSJulian Grajkowski 		snprintf(key_val->val,
34778ee8d1cSJulian Grajkowski 			 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
34878ee8d1cSJulian Grajkowski 			 "0x%lx",
34978ee8d1cSJulian Grajkowski 			 (unsigned long)val);
35078ee8d1cSJulian Grajkowski 	} else {
35178ee8d1cSJulian Grajkowski 		device_printf(GET_DEV(accel_dev), "Unknown type given.\n");
35278ee8d1cSJulian Grajkowski 		free(key_val, M_QAT);
35378ee8d1cSJulian Grajkowski 		return -1;
35478ee8d1cSJulian Grajkowski 	}
35578ee8d1cSJulian Grajkowski 	key_val->type = type;
35678ee8d1cSJulian Grajkowski 
35778ee8d1cSJulian Grajkowski 	/* Add the key-value pair as below policy:
35878ee8d1cSJulian Grajkowski 	 *     1. If the key doesn't exist, add it,
35978ee8d1cSJulian Grajkowski 	 *     2. If the key already exists with a different value
36078ee8d1cSJulian Grajkowski 	 *        then delete it,
36178ee8d1cSJulian Grajkowski 	 *     3. If the key exists with the same value, then return
36278ee8d1cSJulian Grajkowski 	 *        without doing anything.
36378ee8d1cSJulian Grajkowski 	 */
36478ee8d1cSJulian Grajkowski 	if (adf_cfg_key_val_get(accel_dev, section_name, key, temp_val) == 0) {
36578ee8d1cSJulian Grajkowski 		if (strncmp(temp_val, key_val->val, sizeof(temp_val)) != 0) {
36678ee8d1cSJulian Grajkowski 			adf_cfg_keyval_remove(key, section);
36778ee8d1cSJulian Grajkowski 		} else {
36878ee8d1cSJulian Grajkowski 			free(key_val, M_QAT);
36978ee8d1cSJulian Grajkowski 			return 0;
37078ee8d1cSJulian Grajkowski 		}
37178ee8d1cSJulian Grajkowski 	}
37278ee8d1cSJulian Grajkowski 
37378ee8d1cSJulian Grajkowski 	sx_xlock(&cfg->lock);
37478ee8d1cSJulian Grajkowski 	adf_cfg_keyval_add(key_val, section);
37578ee8d1cSJulian Grajkowski 	sx_xunlock(&cfg->lock);
37678ee8d1cSJulian Grajkowski 	return 0;
37778ee8d1cSJulian Grajkowski }
37878ee8d1cSJulian Grajkowski 
37978ee8d1cSJulian Grajkowski int
adf_cfg_save_section(struct adf_accel_dev * accel_dev,const char * name,struct adf_cfg_section * section)38078ee8d1cSJulian Grajkowski adf_cfg_save_section(struct adf_accel_dev *accel_dev,
38178ee8d1cSJulian Grajkowski 		     const char *name,
38278ee8d1cSJulian Grajkowski 		     struct adf_cfg_section *section)
38378ee8d1cSJulian Grajkowski {
38478ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *ptr;
38578ee8d1cSJulian Grajkowski 	struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
38678ee8d1cSJulian Grajkowski 
38778ee8d1cSJulian Grajkowski 	if (!sec) {
38878ee8d1cSJulian Grajkowski 		device_printf(GET_DEV(accel_dev),
38978ee8d1cSJulian Grajkowski 			      "Couldn't find section %s\n",
39078ee8d1cSJulian Grajkowski 			      name);
39178ee8d1cSJulian Grajkowski 		return EFAULT;
39278ee8d1cSJulian Grajkowski 	}
39378ee8d1cSJulian Grajkowski 
39478ee8d1cSJulian Grajkowski 	strlcpy(section->name, name, sizeof(section->name));
39578ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(&section->param_head);
39678ee8d1cSJulian Grajkowski 
39778ee8d1cSJulian Grajkowski 	/* now we save all the parameters */
39878ee8d1cSJulian Grajkowski 	list_for_each_entry(ptr, &sec->param_head, list)
39978ee8d1cSJulian Grajkowski 	{
40078ee8d1cSJulian Grajkowski 		struct adf_cfg_key_val *key_val;
40178ee8d1cSJulian Grajkowski 
40278ee8d1cSJulian Grajkowski 		key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
40378ee8d1cSJulian Grajkowski 
40478ee8d1cSJulian Grajkowski 		memcpy(key_val, ptr, sizeof(*key_val));
40578ee8d1cSJulian Grajkowski 		list_add_tail(&key_val->list, &section->param_head);
40678ee8d1cSJulian Grajkowski 	}
40778ee8d1cSJulian Grajkowski 	return 0;
40878ee8d1cSJulian Grajkowski }
40978ee8d1cSJulian Grajkowski 
41078ee8d1cSJulian Grajkowski static int
adf_cfg_section_save_all(struct adf_accel_dev * accel_dev,struct adf_cfg_depot_list * cfg_depot_list)41178ee8d1cSJulian Grajkowski adf_cfg_section_save_all(struct adf_accel_dev *accel_dev,
41278ee8d1cSJulian Grajkowski 			 struct adf_cfg_depot_list *cfg_depot_list)
41378ee8d1cSJulian Grajkowski {
41478ee8d1cSJulian Grajkowski 	struct adf_cfg_section *ptr_sec, *iter_sec;
41578ee8d1cSJulian Grajkowski 	struct list_head *list, *tmp, *save_list;
41678ee8d1cSJulian Grajkowski 	struct list_head *head = &accel_dev->cfg->sec_list;
41778ee8d1cSJulian Grajkowski 
41878ee8d1cSJulian Grajkowski 	save_list = &cfg_depot_list[accel_dev->accel_id].sec_list;
41978ee8d1cSJulian Grajkowski 
42078ee8d1cSJulian Grajkowski 	list_for_each_prev_safe(list, tmp, head)
42178ee8d1cSJulian Grajkowski 	{
42278ee8d1cSJulian Grajkowski 		ptr_sec = list_entry(list, struct adf_cfg_section, list);
42378ee8d1cSJulian Grajkowski 		iter_sec = malloc(sizeof(*iter_sec), M_QAT, M_WAITOK | M_ZERO);
42478ee8d1cSJulian Grajkowski 
42578ee8d1cSJulian Grajkowski 		adf_cfg_save_section(accel_dev, ptr_sec->name, iter_sec);
42678ee8d1cSJulian Grajkowski 		list_add_tail(&iter_sec->list, save_list);
42778ee8d1cSJulian Grajkowski 	}
42878ee8d1cSJulian Grajkowski 	return 0;
42978ee8d1cSJulian Grajkowski }
43078ee8d1cSJulian Grajkowski 
43178ee8d1cSJulian Grajkowski int
adf_cfg_depot_save_all(struct adf_accel_dev * accel_dev,struct adf_cfg_depot_list * cfg_depot_list)43278ee8d1cSJulian Grajkowski adf_cfg_depot_save_all(struct adf_accel_dev *accel_dev,
43378ee8d1cSJulian Grajkowski 		       struct adf_cfg_depot_list *cfg_depot_list)
43478ee8d1cSJulian Grajkowski {
43578ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *dev_cfg_data = accel_dev->cfg;
43678ee8d1cSJulian Grajkowski 	int ret = 0;
43778ee8d1cSJulian Grajkowski 
43878ee8d1cSJulian Grajkowski 	sx_xlock(&dev_cfg_data->lock);
43978ee8d1cSJulian Grajkowski 	ret = adf_cfg_section_save_all(accel_dev, cfg_depot_list);
44078ee8d1cSJulian Grajkowski 	sx_xunlock(&dev_cfg_data->lock);
44178ee8d1cSJulian Grajkowski 
44278ee8d1cSJulian Grajkowski 	return ret;
44378ee8d1cSJulian Grajkowski }
44478ee8d1cSJulian Grajkowski 
44578ee8d1cSJulian Grajkowski /**
44678ee8d1cSJulian Grajkowski  * adf_cfg_remove_key_param() - remove config entry in config table.
44778ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
44878ee8d1cSJulian Grajkowski  * @section_name: Name of the section where the param will be added
44978ee8d1cSJulian Grajkowski  * @key: The key string
45078ee8d1cSJulian Grajkowski  *
45178ee8d1cSJulian Grajkowski  * Function remove configuration key
45278ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
45378ee8d1cSJulian Grajkowski  *
45478ee8d1cSJulian Grajkowski  * Return: 0 on success, error code otherwise.
45578ee8d1cSJulian Grajkowski  */
45678ee8d1cSJulian Grajkowski int
adf_cfg_remove_key_param(struct adf_accel_dev * accel_dev,const char * section_name,const char * key)45778ee8d1cSJulian Grajkowski adf_cfg_remove_key_param(struct adf_accel_dev *accel_dev,
45878ee8d1cSJulian Grajkowski 			 const char *section_name,
45978ee8d1cSJulian Grajkowski 			 const char *key)
46078ee8d1cSJulian Grajkowski {
46178ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
46278ee8d1cSJulian Grajkowski 	struct adf_cfg_section *section =
46378ee8d1cSJulian Grajkowski 	    adf_cfg_sec_find(accel_dev, section_name);
46478ee8d1cSJulian Grajkowski 	if (!section)
46578ee8d1cSJulian Grajkowski 		return EFAULT;
46678ee8d1cSJulian Grajkowski 
46778ee8d1cSJulian Grajkowski 	sx_xlock(&cfg->lock);
46878ee8d1cSJulian Grajkowski 	adf_cfg_keyval_remove(key, section);
46978ee8d1cSJulian Grajkowski 	sx_xunlock(&cfg->lock);
47078ee8d1cSJulian Grajkowski 	return 0;
47178ee8d1cSJulian Grajkowski }
47278ee8d1cSJulian Grajkowski 
47378ee8d1cSJulian Grajkowski /**
47478ee8d1cSJulian Grajkowski  * adf_cfg_section_add() - Add config section entry to config table.
47578ee8d1cSJulian Grajkowski  * @accel_dev:  Pointer to acceleration device.
47678ee8d1cSJulian Grajkowski  * @name: Name of the section
47778ee8d1cSJulian Grajkowski  *
47878ee8d1cSJulian Grajkowski  * Function adds configuration section where key - value entries
47978ee8d1cSJulian Grajkowski  * will be stored.
48078ee8d1cSJulian Grajkowski  * To be used by QAT device specific drivers.
48178ee8d1cSJulian Grajkowski  *
48278ee8d1cSJulian Grajkowski  * Return: 0 on success, error code otherwise.
48378ee8d1cSJulian Grajkowski  */
48478ee8d1cSJulian Grajkowski int
adf_cfg_section_add(struct adf_accel_dev * accel_dev,const char * name)48578ee8d1cSJulian Grajkowski adf_cfg_section_add(struct adf_accel_dev *accel_dev, const char *name)
48678ee8d1cSJulian Grajkowski {
48778ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
48878ee8d1cSJulian Grajkowski 	struct adf_cfg_section *sec = adf_cfg_sec_find(accel_dev, name);
48978ee8d1cSJulian Grajkowski 
49078ee8d1cSJulian Grajkowski 	if (sec)
49178ee8d1cSJulian Grajkowski 		return 0;
49278ee8d1cSJulian Grajkowski 
49378ee8d1cSJulian Grajkowski 	sec = malloc(sizeof(*sec), M_QAT, M_WAITOK | M_ZERO);
49478ee8d1cSJulian Grajkowski 
49578ee8d1cSJulian Grajkowski 	strlcpy(sec->name, name, sizeof(sec->name));
49678ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(&sec->param_head);
49778ee8d1cSJulian Grajkowski 	sx_xlock(&cfg->lock);
49878ee8d1cSJulian Grajkowski 	list_add_tail(&sec->list, &cfg->sec_list);
49978ee8d1cSJulian Grajkowski 	sx_xunlock(&cfg->lock);
50078ee8d1cSJulian Grajkowski 	return 0;
50178ee8d1cSJulian Grajkowski }
50278ee8d1cSJulian Grajkowski 
50378ee8d1cSJulian Grajkowski /* need to differentiate derived section with the original section */
50478ee8d1cSJulian Grajkowski int
adf_cfg_derived_section_add(struct adf_accel_dev * accel_dev,const char * name)50578ee8d1cSJulian Grajkowski adf_cfg_derived_section_add(struct adf_accel_dev *accel_dev, const char *name)
50678ee8d1cSJulian Grajkowski {
50778ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
50878ee8d1cSJulian Grajkowski 	struct adf_cfg_section *sec = NULL;
50978ee8d1cSJulian Grajkowski 
51078ee8d1cSJulian Grajkowski 	if (adf_cfg_section_add(accel_dev, name))
51178ee8d1cSJulian Grajkowski 		return EFAULT;
51278ee8d1cSJulian Grajkowski 
51378ee8d1cSJulian Grajkowski 	sec = adf_cfg_sec_find(accel_dev, name);
51478ee8d1cSJulian Grajkowski 	if (!sec)
51578ee8d1cSJulian Grajkowski 		return EFAULT;
51678ee8d1cSJulian Grajkowski 
51778ee8d1cSJulian Grajkowski 	sx_xlock(&cfg->lock);
51878ee8d1cSJulian Grajkowski 	sec->is_derived = true;
51978ee8d1cSJulian Grajkowski 	sx_xunlock(&cfg->lock);
52078ee8d1cSJulian Grajkowski 	return 0;
52178ee8d1cSJulian Grajkowski }
52278ee8d1cSJulian Grajkowski 
52378ee8d1cSJulian Grajkowski static int
adf_cfg_restore_key_value_param(struct adf_accel_dev * accel_dev,const char * section_name,const char * key,const char * val,enum adf_cfg_val_type type)52478ee8d1cSJulian Grajkowski adf_cfg_restore_key_value_param(struct adf_accel_dev *accel_dev,
52578ee8d1cSJulian Grajkowski 				const char *section_name,
52678ee8d1cSJulian Grajkowski 				const char *key,
52778ee8d1cSJulian Grajkowski 				const char *val,
52878ee8d1cSJulian Grajkowski 				enum adf_cfg_val_type type)
52978ee8d1cSJulian Grajkowski {
53078ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
53178ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *key_val;
53278ee8d1cSJulian Grajkowski 	struct adf_cfg_section *section =
53378ee8d1cSJulian Grajkowski 	    adf_cfg_sec_find(accel_dev, section_name);
53478ee8d1cSJulian Grajkowski 	if (!section)
53578ee8d1cSJulian Grajkowski 		return EFAULT;
53678ee8d1cSJulian Grajkowski 
53778ee8d1cSJulian Grajkowski 	key_val = malloc(sizeof(*key_val), M_QAT, M_WAITOK | M_ZERO);
53878ee8d1cSJulian Grajkowski 
53978ee8d1cSJulian Grajkowski 	INIT_LIST_HEAD(&key_val->list);
54078ee8d1cSJulian Grajkowski 
54178ee8d1cSJulian Grajkowski 	strlcpy(key_val->key, key, sizeof(key_val->key));
54278ee8d1cSJulian Grajkowski 	strlcpy(key_val->val, val, sizeof(key_val->val));
54378ee8d1cSJulian Grajkowski 	key_val->type = type;
54478ee8d1cSJulian Grajkowski 	sx_xlock(&cfg->lock);
54578ee8d1cSJulian Grajkowski 	adf_cfg_keyval_add(key_val, section);
54678ee8d1cSJulian Grajkowski 	sx_xunlock(&cfg->lock);
54778ee8d1cSJulian Grajkowski 	return 0;
54878ee8d1cSJulian Grajkowski }
54978ee8d1cSJulian Grajkowski 
55078ee8d1cSJulian Grajkowski int
adf_cfg_restore_section(struct adf_accel_dev * accel_dev,struct adf_cfg_section * section)55178ee8d1cSJulian Grajkowski adf_cfg_restore_section(struct adf_accel_dev *accel_dev,
55278ee8d1cSJulian Grajkowski 			struct adf_cfg_section *section)
55378ee8d1cSJulian Grajkowski {
55478ee8d1cSJulian Grajkowski 	struct adf_cfg_key_val *ptr;
55578ee8d1cSJulian Grajkowski 	int ret = 0;
55678ee8d1cSJulian Grajkowski 
55778ee8d1cSJulian Grajkowski 	ret = adf_cfg_section_add(accel_dev, section->name);
55878ee8d1cSJulian Grajkowski 	if (ret)
55978ee8d1cSJulian Grajkowski 		goto err;
56078ee8d1cSJulian Grajkowski 
56178ee8d1cSJulian Grajkowski 	list_for_each_entry(ptr, &section->param_head, list)
56278ee8d1cSJulian Grajkowski 	{
56378ee8d1cSJulian Grajkowski 		ret = adf_cfg_restore_key_value_param(
56478ee8d1cSJulian Grajkowski 		    accel_dev, section->name, ptr->key, ptr->val, ptr->type);
56578ee8d1cSJulian Grajkowski 		if (ret)
56678ee8d1cSJulian Grajkowski 			goto err_remove_sec;
56778ee8d1cSJulian Grajkowski 	}
56878ee8d1cSJulian Grajkowski 	return 0;
56978ee8d1cSJulian Grajkowski 
57078ee8d1cSJulian Grajkowski err_remove_sec:
57178ee8d1cSJulian Grajkowski 	adf_cfg_section_del(accel_dev, section->name);
57278ee8d1cSJulian Grajkowski err:
57378ee8d1cSJulian Grajkowski 	device_printf(GET_DEV(accel_dev),
57478ee8d1cSJulian Grajkowski 		      "Failed to restore section %s\n",
57578ee8d1cSJulian Grajkowski 		      section->name);
57678ee8d1cSJulian Grajkowski 	return ret;
57778ee8d1cSJulian Grajkowski }
57878ee8d1cSJulian Grajkowski 
57978ee8d1cSJulian Grajkowski int
adf_cfg_get_param_value(struct adf_accel_dev * accel_dev,const char * section,const char * name,char * value)58078ee8d1cSJulian Grajkowski adf_cfg_get_param_value(struct adf_accel_dev *accel_dev,
58178ee8d1cSJulian Grajkowski 			const char *section,
58278ee8d1cSJulian Grajkowski 			const char *name,
58378ee8d1cSJulian Grajkowski 			char *value)
58478ee8d1cSJulian Grajkowski {
58578ee8d1cSJulian Grajkowski 	struct adf_cfg_device_data *cfg = accel_dev->cfg;
58678ee8d1cSJulian Grajkowski 	int ret;
58778ee8d1cSJulian Grajkowski 
58878ee8d1cSJulian Grajkowski 	sx_slock(&cfg->lock);
58978ee8d1cSJulian Grajkowski 	ret = adf_cfg_key_val_get(accel_dev, section, name, value);
59078ee8d1cSJulian Grajkowski 	sx_sunlock(&cfg->lock);
59178ee8d1cSJulian Grajkowski 	return ret;
59278ee8d1cSJulian Grajkowski }
593