1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "adf_cfg_instance.h"
5 #include "adf_cfg_section.h"
6 #include "adf_cfg_device.h"
7 #include "icp_qat_hw.h"
8 #include "adf_common_drv.h"
9 
10 #define ADF_CFG_SVCS_MAX (25)
11 #define ADF_CFG_DEPRE_PARAMS_NUM (4)
12 
13 #define ADF_CFG_CAP_DC ADF_ACCEL_CAPABILITIES_COMPRESSION
14 #define ADF_CFG_CAP_ASYM ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC
15 #define ADF_CFG_CAP_SYM                                                        \
16 	(ADF_ACCEL_CAPABILITIES_CRYPTO_SYMMETRIC |                             \
17 	 ADF_ACCEL_CAPABILITIES_CIPHER |                                       \
18 	 ADF_ACCEL_CAPABILITIES_AUTHENTICATION)
19 #define ADF_CFG_CAP_CY (ADF_CFG_CAP_ASYM | ADF_CFG_CAP_SYM)
20 
21 #define ADF_CFG_FW_CAP_RL ICP_ACCEL_CAPABILITIES_RL
22 #define ADF_CFG_FW_CAP_HKDF ICP_ACCEL_CAPABILITIES_HKDF
23 #define ADF_CFG_FW_CAP_ECEDMONT ICP_ACCEL_CAPABILITIES_ECEDMONT
24 #define ADF_CFG_FW_CAP_EXT_ALGCHAIN ICP_ACCEL_CAPABILITIES_EXT_ALGCHAIN
25 
26 #define ADF_CFG_CY_RINGS                                                       \
27 	(CRYPTO | CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                   \
28 	 CRYPTO << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                            \
29 	 CRYPTO << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
30 
31 #define ADF_CFG_SYM_RINGS                                                      \
32 	(SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                         \
33 	 SYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                               \
34 	 SYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
35 
36 #define ADF_CFG_ASYM_RINGS                                                     \
37 	(ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                       \
38 	 ASYM << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                              \
39 	 ASYM << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
40 
41 #define ADF_CFG_CY_DC_RINGS                                                    \
42 	(CRYPTO | CRYPTO << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                   \
43 	 NA << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                                \
44 	 COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
45 
46 #define ADF_CFG_ASYM_DC_RINGS                                                  \
47 	(ASYM | ASYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                       \
48 	 COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                              \
49 	 COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
50 
51 #define ADF_CFG_SYM_DC_RINGS                                                   \
52 	(SYM | SYM << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                         \
53 	 COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                              \
54 	 COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
55 
56 #define ADF_CFG_DC_RINGS                                                       \
57 	(COMP | COMP << ADF_CFG_SERV_RING_PAIR_1_SHIFT |                       \
58 	 COMP << ADF_CFG_SERV_RING_PAIR_2_SHIFT |                              \
59 	 COMP << ADF_CFG_SERV_RING_PAIR_3_SHIFT)
60 
61 static char adf_cfg_deprecated_params[][ADF_CFG_MAX_KEY_LEN_IN_BYTES] =
62     { ADF_DEV_KPT_ENABLE,
63       ADF_STORAGE_FIRMWARE_ENABLED,
64       ADF_RL_FIRMWARE_ENABLED,
65       ADF_PKE_DISABLED };
66 
67 struct adf_cfg_enabled_services {
68 	const char svcs_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
69 	u16 rng_to_svc_msk;
70 	u32 enabled_svc_cap;
71 	u32 enabled_fw_cap;
72 };
73 
74 struct adf_cfg_profile {
75 	enum adf_cfg_fw_image_type fw_image_type;
76 	struct adf_cfg_enabled_services supported_svcs[ADF_CFG_SVCS_MAX];
77 };
78 
79 static struct adf_cfg_profile adf_profiles[] =
80     { { ADF_FW_IMAGE_DEFAULT,
81 	{
82 	    { "cy",
83 	      ADF_CFG_CY_RINGS,
84 	      ADF_CFG_CAP_CY,
85 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
86 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
87 	    { "sym",
88 	      ADF_CFG_SYM_RINGS,
89 	      ADF_CFG_CAP_SYM,
90 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
91 	    { "asym",
92 	      ADF_CFG_ASYM_RINGS,
93 	      ADF_CFG_CAP_ASYM,
94 	      ADF_CFG_FW_CAP_ECEDMONT },
95 	    { "cy;dc",
96 	      ADF_CFG_CY_DC_RINGS,
97 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
98 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
99 	    { "dc;cy",
100 	      ADF_CFG_CY_DC_RINGS,
101 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
102 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
103 	    { "asym;dc",
104 	      ADF_CFG_ASYM_DC_RINGS,
105 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
106 	      ADF_CFG_FW_CAP_ECEDMONT },
107 	    { "dc;asym",
108 	      ADF_CFG_ASYM_DC_RINGS,
109 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
110 	      ADF_CFG_FW_CAP_ECEDMONT },
111 	    { "sym;dc",
112 	      ADF_CFG_SYM_DC_RINGS,
113 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
114 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
115 	    { "dc;sym",
116 	      ADF_CFG_SYM_DC_RINGS,
117 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
118 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
119 	    { "inline;sym",
120 	      ADF_CFG_SYM_RINGS,
121 	      ADF_CFG_CAP_SYM,
122 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
123 	    { "sym;inline",
124 	      ADF_CFG_SYM_RINGS,
125 	      ADF_CFG_CAP_SYM,
126 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
127 	    { "inline;asym",
128 	      ADF_CFG_SYM_RINGS,
129 	      ADF_CFG_CAP_SYM,
130 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
131 	    { "asym;inline",
132 	      ADF_CFG_ASYM_RINGS,
133 	      ADF_CFG_CAP_ASYM,
134 	      ADF_CFG_FW_CAP_ECEDMONT },
135 	    { "inline", 0, 0, 0 },
136 	    { "inline;cy",
137 	      ADF_CFG_CY_RINGS,
138 	      ADF_CFG_CAP_CY,
139 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
140 	    { "cy;inline",
141 	      ADF_CFG_CY_RINGS,
142 	      ADF_CFG_CAP_CY,
143 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
144 	    { "dc;inline", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
145 	    { "inline;dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
146 	    { "cy;dc;inline",
147 	      ADF_CFG_CY_DC_RINGS,
148 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
149 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
150 	    { "cy;inline;dc",
151 	      ADF_CFG_CY_DC_RINGS,
152 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
153 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
154 	    { "dc;inline;cy",
155 	      ADF_CFG_CY_DC_RINGS,
156 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
157 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
158 	    { "dc;cy;inline",
159 	      ADF_CFG_CY_DC_RINGS,
160 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
161 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
162 	    { "inline;cy;dc",
163 	      ADF_CFG_CY_DC_RINGS,
164 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
165 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
166 	    { "inline;dc;cy",
167 	      ADF_CFG_CY_DC_RINGS,
168 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
169 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
170 	} },
171       { ADF_FW_IMAGE_CRYPTO,
172 	{
173 	    { "cy",
174 	      ADF_CFG_CY_RINGS,
175 	      ADF_CFG_CAP_CY,
176 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
177 		  ADF_CFG_FW_CAP_ECEDMONT |
178 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
179 	    { "sym",
180 	      ADF_CFG_SYM_RINGS,
181 	      ADF_CFG_CAP_SYM,
182 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
183 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
184 	    { "asym",
185 	      ADF_CFG_ASYM_RINGS,
186 	      ADF_CFG_CAP_ASYM,
187 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
188 	} },
189       { ADF_FW_IMAGE_COMPRESSION,
190 	{
191 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
192 	} },
193       { ADF_FW_IMAGE_CUSTOM1,
194 	{
195 	    { "cy",
196 	      ADF_CFG_CY_RINGS,
197 	      ADF_CFG_CAP_CY,
198 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
199 		  ADF_CFG_FW_CAP_ECEDMONT |
200 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
201 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
202 	    { "sym",
203 	      ADF_CFG_SYM_RINGS,
204 	      ADF_CFG_CAP_SYM,
205 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
206 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
207 	    { "asym",
208 	      ADF_CFG_ASYM_RINGS,
209 	      ADF_CFG_CAP_ASYM,
210 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
211 	    { "cy;dc",
212 	      ADF_CFG_CY_DC_RINGS,
213 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
214 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
215 		  ADF_CFG_FW_CAP_ECEDMONT |
216 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
217 	    { "dc;cy",
218 	      ADF_CFG_CY_DC_RINGS,
219 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
220 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
221 		  ADF_CFG_FW_CAP_ECEDMONT |
222 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
223 	    { "asym;dc",
224 	      ADF_CFG_ASYM_DC_RINGS,
225 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
226 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
227 	    { "dc;asym",
228 	      ADF_CFG_ASYM_DC_RINGS,
229 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
230 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
231 	    { "sym;dc",
232 	      ADF_CFG_SYM_DC_RINGS,
233 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
234 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
235 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
236 	    { "dc;sym",
237 	      ADF_CFG_SYM_DC_RINGS,
238 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
239 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
240 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
241 	} } };
242 
243 int
244 adf_cfg_get_ring_pairs(struct adf_cfg_device *device,
245 		       struct adf_cfg_instance *inst,
246 		       const char *process_name,
247 		       struct adf_accel_dev *accel_dev)
248 {
249 	int i = 0;
250 	int ret = EFAULT;
251 	struct adf_cfg_instance *free_inst = NULL;
252 	struct adf_cfg_bundle *first_free_bundle = NULL;
253 	enum adf_cfg_bundle_type free_bundle_type;
254 	int first_user_bundle = 0;
255 
256 	/* Section of user process with poll mode */
257 	if (strcmp(ADF_KERNEL_SEC, process_name) &&
258 	    strcmp(ADF_KERNEL_SAL_SEC, process_name) &&
259 	    inst->polling_mode == ADF_CFG_RESP_POLL) {
260 		first_user_bundle = device->max_kernel_bundle_nr + 1;
261 		for (i = first_user_bundle; i < device->bundle_num; i++) {
262 			free_inst = adf_cfg_get_free_instance(
263 			    device, device->bundles[i], inst, process_name);
264 
265 			if (!free_inst)
266 				continue;
267 
268 			ret = adf_cfg_get_ring_pairs_from_bundle(
269 			    device->bundles[i], inst, process_name, free_inst);
270 			return ret;
271 		}
272 	} else {
273 		/* Section of in-tree, or kernel API or user process
274 		 * with epoll mode
275 		 */
276 		if (!strcmp(ADF_KERNEL_SEC, process_name) ||
277 		    !strcmp(ADF_KERNEL_SAL_SEC, process_name))
278 			free_bundle_type = KERNEL;
279 		else
280 			free_bundle_type = USER;
281 
282 		for (i = 0; i < device->bundle_num; i++) {
283 			/* Since both in-tree and kernel API's bundle type
284 			 * are kernel, use cpumask_subset to check if the
285 			 * ring's affinity mask is a subset of a bundle's
286 			 * one.
287 			 */
288 			if (free_bundle_type == device->bundles[i]->type &&
289 			    CPU_SUBSET(&device->bundles[i]->affinity_mask,
290 				       &inst->affinity_mask)) {
291 				free_inst = adf_cfg_get_free_instance(
292 				    device,
293 				    device->bundles[i],
294 				    inst,
295 				    process_name);
296 
297 				if (!free_inst)
298 					continue;
299 				ret = adf_cfg_get_ring_pairs_from_bundle(
300 				    device->bundles[i],
301 				    inst,
302 				    process_name,
303 				    free_inst);
304 
305 				return ret;
306 
307 			} else if (!first_free_bundle &&
308 				   adf_cfg_is_free(device->bundles[i])) {
309 				first_free_bundle = device->bundles[i];
310 			}
311 		}
312 
313 		if (first_free_bundle) {
314 			free_inst = adf_cfg_get_free_instance(device,
315 							      first_free_bundle,
316 							      inst,
317 							      process_name);
318 
319 			if (!free_inst)
320 				return ret;
321 
322 			ret = adf_cfg_get_ring_pairs_from_bundle(
323 			    first_free_bundle, inst, process_name, free_inst);
324 
325 			if (free_bundle_type == KERNEL) {
326 				device->max_kernel_bundle_nr =
327 				    first_free_bundle->number;
328 			}
329 			return ret;
330 		}
331 	}
332 	pr_err("Don't have enough rings for instance %s in process %s\n",
333 	       inst->name,
334 	       process_name);
335 
336 	return ret;
337 }
338 
339 int
340 adf_cfg_get_services_enabled(struct adf_accel_dev *accel_dev,
341 			     u16 *ring_to_svc_map)
342 {
343 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
344 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
345 	u32 i = 0;
346 	struct adf_cfg_enabled_services *svcs = NULL;
347 	enum adf_cfg_fw_image_type fw_image_type = ADF_FW_IMAGE_DEFAULT;
348 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
349 	*ring_to_svc_map = 0;
350 
351 	/* Get the services enabled by user */
352 	snprintf(key, sizeof(key), ADF_SERVICES_ENABLED);
353 	if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
354 		return EFAULT;
355 
356 	if (hw_data->get_fw_image_type) {
357 		if (hw_data->get_fw_image_type(accel_dev, &fw_image_type))
358 			return EFAULT;
359 	}
360 
361 	for (i = 0; i < ADF_CFG_SVCS_MAX; i++) {
362 		svcs = &adf_profiles[fw_image_type].supported_svcs[i];
363 
364 		if (!strncmp(svcs->svcs_enabled,
365 			     "",
366 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES))
367 			break;
368 
369 		if (!strncmp(val,
370 			     svcs->svcs_enabled,
371 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES)) {
372 			*ring_to_svc_map = svcs->rng_to_svc_msk;
373 			return 0;
374 		}
375 	}
376 
377 	device_printf(GET_DEV(accel_dev),
378 		      "Invalid ServicesEnabled %s for ServicesProfile: %d\n",
379 		      val,
380 		      fw_image_type);
381 
382 	return EFAULT;
383 }
384 
385 void
386 adf_cfg_set_asym_rings_mask(struct adf_accel_dev *accel_dev)
387 {
388 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
389 
390 	hw_data->asym_rings_mask = 0;
391 }
392 
393 void
394 adf_cfg_gen_dispatch_arbiter(struct adf_accel_dev *accel_dev,
395 			     const u32 *thrd_to_arb_map,
396 			     u32 *thrd_to_arb_map_gen,
397 			     u32 total_engines)
398 {
399 	int engine, thread, service, bits;
400 	u32 thread_ability, ability_map, service_mask, service_type;
401 	u16 ena_srv_mask = GET_HW_DATA(accel_dev)->ring_to_svc_map;
402 
403 	for (engine = 0; engine < total_engines; engine++) {
404 		if (!(GET_HW_DATA(accel_dev)->ae_mask & (1 << engine)))
405 			continue;
406 		bits = 0;
407 		/* ability_map is used to indicate the threads ability */
408 		ability_map = thrd_to_arb_map[engine];
409 		thrd_to_arb_map_gen[engine] = 0;
410 		/* parse each thread on the engine */
411 		for (thread = 0; thread < ADF_NUM_THREADS_PER_AE; thread++) {
412 			/* get the ability of this thread */
413 			thread_ability = ability_map & ADF_THRD_ABILITY_MASK;
414 			ability_map >>= ADF_THRD_ABILITY_BIT_LEN;
415 			/* parse each service */
416 			for (service = 0; service < ADF_CFG_MAX_SERVICES;
417 			     service++) {
418 				service_type =
419 				    GET_SRV_TYPE(ena_srv_mask, service);
420 				switch (service_type) {
421 				case CRYPTO:
422 					service_mask = ADF_CFG_ASYM_SRV_MASK;
423 					if (thread_ability & service_mask)
424 						thrd_to_arb_map_gen[engine] |=
425 						    (1 << bits);
426 					bits++;
427 					service++;
428 					service_mask = ADF_CFG_SYM_SRV_MASK;
429 					break;
430 				case COMP:
431 					service_mask = ADF_CFG_DC_SRV_MASK;
432 					break;
433 				case SYM:
434 					service_mask = ADF_CFG_SYM_SRV_MASK;
435 					break;
436 				case ASYM:
437 					service_mask = ADF_CFG_ASYM_SRV_MASK;
438 					break;
439 				default:
440 					service_mask = ADF_CFG_UNKNOWN_SRV_MASK;
441 				}
442 				if (thread_ability & service_mask)
443 					thrd_to_arb_map_gen[engine] |=
444 					    (1 << bits);
445 				bits++;
446 			}
447 		}
448 	}
449 }
450 
451 int
452 adf_cfg_get_fw_image_type(struct adf_accel_dev *accel_dev,
453 			  enum adf_cfg_fw_image_type *fw_image_type)
454 {
455 	*fw_image_type = ADF_FW_IMAGE_CUSTOM1;
456 
457 	return 0;
458 }
459 
460 static int
461 adf_cfg_get_caps_enabled(struct adf_accel_dev *accel_dev,
462 			 u32 *enabled_svc_caps,
463 			 u32 *enabled_fw_caps)
464 {
465 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
466 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
467 	u8 i = 0;
468 	struct adf_cfg_enabled_services *svcs = NULL;
469 	enum adf_cfg_fw_image_type fw_image_type = ADF_FW_IMAGE_DEFAULT;
470 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
471 
472 	*enabled_svc_caps = 0;
473 	*enabled_fw_caps = 0;
474 
475 	/* Get the services enabled by user */
476 	snprintf(key, sizeof(key), ADF_SERVICES_ENABLED);
477 	if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
478 		return EFAULT;
479 
480 	/*
481 	 * Only the PF driver has the hook for get_fw_image_type as the VF's
482 	 * enabled service is from PFVF communication. The fw_image_type for
483 	 * the VF is set to DEFAULT since this type contains all kinds of
484 	 * enabled service.
485 	 */
486 	if (hw_data->get_fw_image_type) {
487 		if (hw_data->get_fw_image_type(accel_dev, &fw_image_type))
488 			return EFAULT;
489 	}
490 
491 	for (i = 0; i < ADF_CFG_SVCS_MAX; i++) {
492 		svcs = &adf_profiles[fw_image_type].supported_svcs[i];
493 
494 		if (!strncmp(svcs->svcs_enabled,
495 			     "",
496 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES))
497 			break;
498 
499 		if (!strncmp(val,
500 			     svcs->svcs_enabled,
501 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES)) {
502 			*enabled_svc_caps = svcs->enabled_svc_cap;
503 			*enabled_fw_caps = svcs->enabled_fw_cap;
504 			return 0;
505 		}
506 	}
507 	device_printf(GET_DEV(accel_dev),
508 		      "Invalid ServicesEnabled %s for ServicesProfile: %d\n",
509 		      val,
510 		      fw_image_type);
511 
512 	return EFAULT;
513 }
514 
515 static void
516 adf_cfg_check_deprecated_params(struct adf_accel_dev *accel_dev)
517 {
518 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
519 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
520 	u8 i = 0;
521 
522 	for (i = 0; i < ADF_CFG_DEPRE_PARAMS_NUM; i++) {
523 		/* give a warning if the deprecated params are set by user */
524 		snprintf(key, sizeof(key), "%s", adf_cfg_deprecated_params[i]);
525 		if (!adf_cfg_get_param_value(
526 			accel_dev, ADF_GENERAL_SEC, key, val)) {
527 			device_printf(GET_DEV(accel_dev),
528 				      "Parameter '%s' has been deprecated\n",
529 				      key);
530 		}
531 	}
532 }
533 
534 static int
535 adf_cfg_check_enabled_services(struct adf_accel_dev *accel_dev,
536 			       u32 enabled_svc_caps)
537 {
538 	u32 hw_caps = GET_HW_DATA(accel_dev)->accel_capabilities_mask;
539 
540 	if ((enabled_svc_caps & hw_caps) == enabled_svc_caps)
541 		return 0;
542 
543 	device_printf(GET_DEV(accel_dev), "Unsupported device configuration\n");
544 
545 	return EFAULT;
546 }
547 
548 static int
549 adf_cfg_update_pf_accel_cap_mask(struct adf_accel_dev *accel_dev)
550 {
551 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
552 	u32 enabled_svc_caps = 0;
553 	u32 enabled_fw_caps = 0;
554 
555 	if (hw_data->get_accel_cap) {
556 		hw_data->accel_capabilities_mask =
557 		    hw_data->get_accel_cap(accel_dev);
558 	}
559 
560 	if (adf_cfg_get_caps_enabled(accel_dev,
561 				     &enabled_svc_caps,
562 				     &enabled_fw_caps))
563 		return EFAULT;
564 
565 	if (adf_cfg_check_enabled_services(accel_dev, enabled_svc_caps))
566 		return EFAULT;
567 
568 	if (!(enabled_svc_caps & ADF_CFG_CAP_ASYM))
569 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_ASYM;
570 	if (!(enabled_svc_caps & ADF_CFG_CAP_SYM))
571 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_SYM;
572 	if (!(enabled_svc_caps & ADF_CFG_CAP_DC))
573 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_DC;
574 
575 	/* Enable FW defined capabilities*/
576 	if (enabled_fw_caps)
577 		hw_data->accel_capabilities_mask |= enabled_fw_caps;
578 
579 	return 0;
580 }
581 
582 static int
583 adf_cfg_update_vf_accel_cap_mask(struct adf_accel_dev *accel_dev)
584 {
585 	u32 enabled_svc_caps = 0;
586 	u32 enabled_fw_caps = 0;
587 
588 	if (adf_cfg_get_caps_enabled(accel_dev,
589 				     &enabled_svc_caps,
590 				     &enabled_fw_caps))
591 		return EFAULT;
592 
593 	if (adf_cfg_check_enabled_services(accel_dev, enabled_svc_caps))
594 		return EFAULT;
595 
596 	return 0;
597 }
598 
599 int
600 adf_cfg_device_init(struct adf_cfg_device *device,
601 		    struct adf_accel_dev *accel_dev)
602 {
603 	int i = 0;
604 	/* max_inst indicates the max instance number one bank can hold */
605 	int max_inst = accel_dev->hw_device->tx_rx_gap;
606 	int ret = ENOMEM;
607 	struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
608 
609 	adf_cfg_check_deprecated_params(accel_dev);
610 
611 	device->bundle_num = 0;
612 	device->bundles = (struct adf_cfg_bundle **)malloc(
613 	    sizeof(struct adf_cfg_bundle *) * accel_dev->hw_device->num_banks,
614 	    M_QAT,
615 	    M_WAITOK | M_ZERO);
616 
617 	device->bundle_num = accel_dev->hw_device->num_banks;
618 
619 	device->instances = (struct adf_cfg_instance **)malloc(
620 	    sizeof(struct adf_cfg_instance *) * device->bundle_num * max_inst,
621 	    M_QAT,
622 	    M_WAITOK | M_ZERO);
623 
624 	device->instance_index = 0;
625 
626 	device->max_kernel_bundle_nr = -1;
627 
628 	ret = EFAULT;
629 
630 	/* Update the acceleration capability mask based on User capability */
631 	if (!accel_dev->is_vf) {
632 		if (adf_cfg_update_pf_accel_cap_mask(accel_dev))
633 			goto failed;
634 	} else {
635 		if (adf_cfg_update_vf_accel_cap_mask(accel_dev))
636 			goto failed;
637 	}
638 
639 	/* Based on the svc configured, get ring_to_svc_map */
640 	if (hw_data->get_ring_to_svc_map) {
641 		if (hw_data->get_ring_to_svc_map(accel_dev,
642 						 &hw_data->ring_to_svc_map))
643 			goto failed;
644 	}
645 
646 	ret = ENOMEM;
647 	/*
648 	 * 1) get the config information to generate the ring to service
649 	 *    mapping table
650 	 * 2) init each bundle of this device
651 	 */
652 	for (i = 0; i < device->bundle_num; i++) {
653 		device->bundles[i] = malloc(sizeof(struct adf_cfg_bundle),
654 					    M_QAT,
655 					    M_WAITOK | M_ZERO);
656 
657 		device->bundles[i]->max_section = max_inst;
658 		adf_cfg_bundle_init(device->bundles[i], device, i, accel_dev);
659 	}
660 
661 	return 0;
662 
663 failed:
664 	for (i = 0; i < device->bundle_num; i++) {
665 		if (device->bundles[i])
666 			adf_cfg_bundle_clear(device->bundles[i], accel_dev);
667 	}
668 
669 	for (i = 0; i < (device->bundle_num * max_inst); i++) {
670 		if (device->instances && device->instances[i])
671 			free(device->instances[i], M_QAT);
672 	}
673 
674 	free(device->instances, M_QAT);
675 	device->instances = NULL;
676 
677 	device_printf(GET_DEV(accel_dev), "Failed to do device init\n");
678 	return ret;
679 }
680 
681 void
682 adf_cfg_device_clear(struct adf_cfg_device *device,
683 		     struct adf_accel_dev *accel_dev)
684 {
685 	int i = 0;
686 
687 	for (i = 0; i < device->bundle_num; i++) {
688 		if (device->bundles && device->bundles[i]) {
689 			adf_cfg_bundle_clear(device->bundles[i], accel_dev);
690 			free(device->bundles[i], M_QAT);
691 			device->bundles[i] = NULL;
692 		}
693 	}
694 
695 	free(device->bundles, M_QAT);
696 	device->bundles = NULL;
697 
698 	for (i = 0; i < device->instance_index; i++) {
699 		if (device->instances && device->instances[i]) {
700 			free(device->instances[i], M_QAT);
701 			device->instances[i] = NULL;
702 		}
703 	}
704 
705 	free(device->instances, M_QAT);
706 	device->instances = NULL;
707 }
708 
709 static int
710 adf_cfg_static_conf(struct adf_accel_dev *accel_dev)
711 {
712 	int ret = 0;
713 	unsigned long val = 0;
714 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
715 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
716 	int cpus;
717 	int instances = 0;
718 	int cy_poll_instances;
719 	int cy_irq_instances;
720 	int dc_instances;
721 	int i = 0;
722 
723 	cpus = num_online_cpus();
724 	instances =
725 	    GET_MAX_BANKS(accel_dev) > cpus ? GET_MAX_BANKS(accel_dev) : cpus;
726 	if (!instances)
727 		return EFAULT;
728 
729 	if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_DC)
730 		dc_instances = ADF_CFG_STATIC_CONF_INST_NUM_DC;
731 	else
732 		return EFAULT;
733 	instances -= dc_instances;
734 
735 	if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL)
736 		cy_poll_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL;
737 	else
738 		return EFAULT;
739 	instances -= cy_poll_instances;
740 
741 	if (instances >= ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ)
742 		cy_irq_instances = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ;
743 	else
744 		return EFAULT;
745 	instances -= cy_irq_instances;
746 
747 	ret |= adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
748 
749 	ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC);
750 
751 	val = ADF_CFG_STATIC_CONF_VER;
752 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CONFIG_VERSION);
753 	ret |= adf_cfg_add_key_value_param(
754 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
755 
756 	val = ADF_CFG_STATIC_CONF_AUTO_RESET;
757 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_AUTO_RESET_ON_ERROR);
758 	ret |= adf_cfg_add_key_value_param(
759 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
760 
761 	if (accel_dev->hw_device->get_num_accel_units) {
762 		int cy_au = 0;
763 		int dc_au = 0;
764 		int num_au = accel_dev->hw_device->get_num_accel_units(
765 		    accel_dev->hw_device);
766 
767 		if (num_au > ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
768 			cy_au = num_au - ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
769 			dc_au = ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
770 		} else if (num_au == ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
771 			cy_au = 1;
772 			dc_au = 1;
773 		} else {
774 			return EFAULT;
775 		}
776 
777 		val = cy_au;
778 		snprintf(key,
779 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
780 			 ADF_NUM_CY_ACCEL_UNITS);
781 		ret |= adf_cfg_add_key_value_param(
782 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
783 
784 		val = dc_au;
785 		snprintf(key,
786 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
787 			 ADF_NUM_DC_ACCEL_UNITS);
788 		ret |= adf_cfg_add_key_value_param(
789 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
790 
791 		val = ADF_CFG_STATIC_CONF_NUM_INLINE_ACCEL_UNITS;
792 		snprintf(key,
793 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
794 			 ADF_NUM_INLINE_ACCEL_UNITS);
795 		ret |= adf_cfg_add_key_value_param(
796 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
797 	}
798 
799 	val = ADF_CFG_STATIC_CONF_CY_ASYM_RING_SIZE;
800 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_ASYM_SIZE);
801 	ret |= adf_cfg_add_key_value_param(
802 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
803 
804 	val = ADF_CFG_STATIC_CONF_CY_SYM_RING_SIZE;
805 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_SYM_SIZE);
806 	ret |= adf_cfg_add_key_value_param(
807 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
808 
809 	val = ADF_CFG_STATIC_CONF_DC_INTER_BUF_SIZE;
810 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_INTER_BUF_SIZE);
811 	ret |= adf_cfg_add_key_value_param(
812 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
813 
814 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED);
815 	if ((cy_poll_instances + cy_irq_instances) == 0 && dc_instances > 0) {
816 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_DC);
817 	} else if (((cy_poll_instances + cy_irq_instances)) > 0 &&
818 		   dc_instances == 0) {
819 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CFG_SYM);
820 	} else {
821 		snprintf(value,
822 			 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
823 			 "%s;%s",
824 			 ADF_CFG_SYM,
825 			 ADF_CFG_DC);
826 	}
827 	ret |= adf_cfg_add_key_value_param(
828 	    accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR);
829 
830 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC;
831 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DC);
832 	ret |= adf_cfg_add_key_value_param(
833 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
834 
835 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DH;
836 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DH);
837 	ret |= adf_cfg_add_key_value_param(
838 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
839 
840 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DRBG;
841 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DRBG);
842 	ret |= adf_cfg_add_key_value_param(
843 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
844 
845 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DSA;
846 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DSA);
847 	ret |= adf_cfg_add_key_value_param(
848 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
849 
850 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ECC;
851 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ECC);
852 	ret |= adf_cfg_add_key_value_param(
853 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
854 
855 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ENABLED;
856 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ENABLED);
857 	ret |= adf_cfg_add_key_value_param(
858 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
859 
860 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_KEYGEN;
861 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_KEYGEN);
862 	ret |= adf_cfg_add_key_value_param(
863 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
864 
865 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_LN;
866 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_LN);
867 	ret |= adf_cfg_add_key_value_param(
868 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
869 
870 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_PRIME;
871 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_PRIME);
872 	ret |= adf_cfg_add_key_value_param(
873 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
874 
875 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_RSA;
876 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_RSA);
877 	ret |= adf_cfg_add_key_value_param(
878 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
879 
880 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_SYM;
881 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_SYM);
882 	ret |= adf_cfg_add_key_value_param(
883 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
884 
885 	val = (cy_poll_instances + cy_irq_instances);
886 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY);
887 	ret |= adf_cfg_add_key_value_param(
888 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
889 
890 	val = dc_instances;
891 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC);
892 	ret |= adf_cfg_add_key_value_param(
893 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
894 
895 	for (i = 0; i < (cy_irq_instances); i++) {
896 		val = i;
897 		snprintf(key,
898 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
899 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
900 			 i);
901 		ret |= adf_cfg_add_key_value_param(
902 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
903 
904 		val = ADF_CFG_STATIC_CONF_IRQ;
905 		snprintf(key,
906 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
907 			 ADF_CY "%d" ADF_POLL_MODE,
908 			 i);
909 		ret |= adf_cfg_add_key_value_param(
910 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
911 
912 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
913 		snprintf(key,
914 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
915 			 ADF_CY_NAME_FORMAT,
916 			 i);
917 		ret |= adf_cfg_add_key_value_param(
918 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
919 	}
920 
921 	for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances);
922 	     i++) {
923 		val = i;
924 		snprintf(key,
925 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
926 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
927 			 i);
928 		ret |= adf_cfg_add_key_value_param(
929 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
930 
931 		val = ADF_CFG_STATIC_CONF_POLL;
932 		snprintf(key,
933 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
934 			 ADF_CY "%d" ADF_POLL_MODE,
935 			 i);
936 		ret |= adf_cfg_add_key_value_param(
937 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
938 
939 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
940 		snprintf(key,
941 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
942 			 ADF_CY_NAME_FORMAT,
943 			 i);
944 		ret |= adf_cfg_add_key_value_param(
945 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
946 	}
947 
948 	for (i = 0; i < dc_instances; i++) {
949 		val = i;
950 		snprintf(key,
951 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
952 			 ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY,
953 			 i);
954 		ret |= adf_cfg_add_key_value_param(
955 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
956 
957 		val = ADF_CFG_STATIC_CONF_POLL;
958 		snprintf(key,
959 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
960 			 ADF_DC "%d" ADF_POLL_MODE,
961 			 i);
962 		ret |= adf_cfg_add_key_value_param(
963 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
964 
965 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i);
966 		snprintf(key,
967 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
968 			 ADF_DC_NAME_FORMAT,
969 			 i);
970 		ret |= adf_cfg_add_key_value_param(
971 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
972 	}
973 
974 	if (ret)
975 		ret = EFAULT;
976 	return ret;
977 }
978 
979 int
980 adf_config_device(struct adf_accel_dev *accel_dev)
981 {
982 	struct adf_cfg_device_data *cfg = NULL;
983 	struct adf_cfg_device *cfg_device = NULL;
984 	struct adf_cfg_section *sec;
985 	struct list_head *list;
986 	int ret = ENOMEM;
987 
988 	if (!accel_dev)
989 		return ret;
990 
991 	ret = adf_cfg_static_conf(accel_dev);
992 	if (ret)
993 		goto failed;
994 
995 	cfg = accel_dev->cfg;
996 	cfg->dev = NULL;
997 	cfg_device = (struct adf_cfg_device *)malloc(sizeof(*cfg_device),
998 						     M_QAT,
999 						     M_WAITOK | M_ZERO);
1000 
1001 	ret = EFAULT;
1002 
1003 	if (adf_cfg_device_init(cfg_device, accel_dev))
1004 		goto failed;
1005 
1006 	cfg->dev = cfg_device;
1007 
1008 	/* GENERAL and KERNEL section must be processed before others */
1009 	list_for_each(list, &cfg->sec_list)
1010 	{
1011 		sec = list_entry(list, struct adf_cfg_section, list);
1012 		if (!strcmp(sec->name, ADF_GENERAL_SEC)) {
1013 			ret = adf_cfg_process_section(accel_dev,
1014 						      sec->name,
1015 						      accel_dev->accel_id);
1016 			if (ret)
1017 				goto failed;
1018 			sec->processed = true;
1019 			break;
1020 		}
1021 	}
1022 
1023 	list_for_each(list, &cfg->sec_list)
1024 	{
1025 		sec = list_entry(list, struct adf_cfg_section, list);
1026 		if (!strcmp(sec->name, ADF_KERNEL_SEC)) {
1027 			ret = adf_cfg_process_section(accel_dev,
1028 						      sec->name,
1029 						      accel_dev->accel_id);
1030 			if (ret)
1031 				goto failed;
1032 			sec->processed = true;
1033 			break;
1034 		}
1035 	}
1036 
1037 	list_for_each(list, &cfg->sec_list)
1038 	{
1039 		sec = list_entry(list, struct adf_cfg_section, list);
1040 		if (!strcmp(sec->name, ADF_KERNEL_SAL_SEC)) {
1041 			ret = adf_cfg_process_section(accel_dev,
1042 						      sec->name,
1043 						      accel_dev->accel_id);
1044 			if (ret)
1045 				goto failed;
1046 			sec->processed = true;
1047 			break;
1048 		}
1049 	}
1050 
1051 	list_for_each(list, &cfg->sec_list)
1052 	{
1053 		sec = list_entry(list, struct adf_cfg_section, list);
1054 		/* avoid reprocessing one section */
1055 		if (!sec->processed && !sec->is_derived) {
1056 			ret = adf_cfg_process_section(accel_dev,
1057 						      sec->name,
1058 						      accel_dev->accel_id);
1059 			if (ret)
1060 				goto failed;
1061 			sec->processed = true;
1062 		}
1063 	}
1064 
1065 	/* newly added accel section */
1066 	ret = adf_cfg_process_section(accel_dev,
1067 				      ADF_ACCEL_SEC,
1068 				      accel_dev->accel_id);
1069 	if (ret)
1070 		goto failed;
1071 
1072 	/*
1073 	 * put item-remove task after item-process
1074 	 * because during process we may fetch values from those items
1075 	 */
1076 	list_for_each(list, &cfg->sec_list)
1077 	{
1078 		sec = list_entry(list, struct adf_cfg_section, list);
1079 		if (!sec->is_derived) {
1080 			ret = adf_cfg_cleanup_section(accel_dev,
1081 						      sec->name,
1082 						      accel_dev->accel_id);
1083 			if (ret)
1084 				goto failed;
1085 		}
1086 	}
1087 
1088 	ret = 0;
1089 	set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
1090 failed:
1091 	if (ret) {
1092 		if (cfg_device) {
1093 			adf_cfg_device_clear(cfg_device, accel_dev);
1094 			free(cfg_device, M_QAT);
1095 			cfg->dev = NULL;
1096 		}
1097 		adf_cfg_del_all(accel_dev);
1098 		device_printf(GET_DEV(accel_dev), "Failed to config device\n");
1099 	}
1100 
1101 	return ret;
1102 }
1103