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 (12)
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 	    { "asym;sym",
87 	      ADF_CFG_CY_RINGS,
88 	      ADF_CFG_CAP_CY,
89 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
90 	    { "sym;asym",
91 	      ADF_CFG_CY_RINGS,
92 	      ADF_CFG_CAP_CY,
93 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
94 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
95 	    { "sym",
96 	      ADF_CFG_SYM_RINGS,
97 	      ADF_CFG_CAP_SYM,
98 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
99 	    { "asym",
100 	      ADF_CFG_ASYM_RINGS,
101 	      ADF_CFG_CAP_ASYM,
102 	      ADF_CFG_FW_CAP_ECEDMONT },
103 	    { "cy;dc",
104 	      ADF_CFG_CY_DC_RINGS,
105 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
106 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
107 	    { "dc;cy",
108 	      ADF_CFG_CY_DC_RINGS,
109 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
110 	      ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
111 	    { "asym;dc",
112 	      ADF_CFG_ASYM_DC_RINGS,
113 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
114 	      ADF_CFG_FW_CAP_ECEDMONT },
115 	    { "dc;asym",
116 	      ADF_CFG_ASYM_DC_RINGS,
117 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
118 	      ADF_CFG_FW_CAP_ECEDMONT },
119 	    { "sym;dc",
120 	      ADF_CFG_SYM_DC_RINGS,
121 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
122 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
123 	    { "dc;sym",
124 	      ADF_CFG_SYM_DC_RINGS,
125 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
126 	      ADF_CFG_FW_CAP_EXT_ALGCHAIN },
127 	} },
128       { ADF_FW_IMAGE_CRYPTO,
129 	{
130 	    { "cy",
131 	      ADF_CFG_CY_RINGS,
132 	      ADF_CFG_CAP_CY,
133 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
134 		  ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
135 	    { "sym",
136 	      ADF_CFG_SYM_RINGS,
137 	      ADF_CFG_CAP_SYM,
138 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
139 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
140 	    { "asym",
141 	      ADF_CFG_ASYM_RINGS,
142 	      ADF_CFG_CAP_ASYM,
143 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
144 	} },
145       { ADF_FW_IMAGE_COMPRESSION,
146 	{
147 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
148 	} },
149       { ADF_FW_IMAGE_CUSTOM1,
150 	{
151 	    { "cy",
152 	      ADF_CFG_CY_RINGS,
153 	      ADF_CFG_CAP_CY,
154 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
155 		  ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
156 	    { "dc", ADF_CFG_DC_RINGS, ADF_CFG_CAP_DC, 0 },
157 	    { "sym",
158 	      ADF_CFG_SYM_RINGS,
159 	      ADF_CFG_CAP_SYM,
160 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
161 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
162 	    { "asym",
163 	      ADF_CFG_ASYM_RINGS,
164 	      ADF_CFG_CAP_ASYM,
165 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
166 	    { "cy;dc",
167 	      ADF_CFG_CY_DC_RINGS,
168 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
169 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
170 		  ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
171 	    { "dc;cy",
172 	      ADF_CFG_CY_DC_RINGS,
173 	      ADF_CFG_CAP_CY | ADF_CFG_CAP_DC,
174 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
175 		  ADF_CFG_FW_CAP_ECEDMONT | ADF_CFG_FW_CAP_EXT_ALGCHAIN },
176 	    { "asym;dc",
177 	      ADF_CFG_ASYM_DC_RINGS,
178 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
179 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
180 	    { "dc;asym",
181 	      ADF_CFG_ASYM_DC_RINGS,
182 	      ADF_CFG_CAP_ASYM | ADF_CFG_CAP_DC,
183 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_ECEDMONT },
184 	    { "sym;dc",
185 	      ADF_CFG_SYM_DC_RINGS,
186 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
187 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
188 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
189 	    { "dc;sym",
190 	      ADF_CFG_SYM_DC_RINGS,
191 	      ADF_CFG_CAP_SYM | ADF_CFG_CAP_DC,
192 	      ADF_CFG_FW_CAP_RL | ADF_CFG_FW_CAP_HKDF |
193 		  ADF_CFG_FW_CAP_EXT_ALGCHAIN },
194 	} } };
195 
196 int
197 adf_cfg_get_ring_pairs(struct adf_cfg_device *device,
198 		       struct adf_cfg_instance *inst,
199 		       const char *process_name,
200 		       struct adf_accel_dev *accel_dev)
201 {
202 	int i = 0;
203 	int ret = EFAULT;
204 	struct adf_cfg_instance *free_inst = NULL;
205 	enum adf_cfg_bundle_type free_bundle_type;
206 	int first_user_bundle = 0;
207 
208 	/* Section of user process with poll mode */
209 	if (strcmp(ADF_KERNEL_SEC, process_name) &&
210 	    strcmp(ADF_KERNEL_SAL_SEC, process_name) &&
211 	    inst->polling_mode == ADF_CFG_RESP_POLL) {
212 		first_user_bundle = device->max_kernel_bundle_nr + 1;
213 		for (i = first_user_bundle; i < device->bundle_num; i++) {
214 			free_inst = adf_cfg_get_free_instance(
215 			    device, device->bundles[i], inst, process_name);
216 
217 			if (!free_inst)
218 				continue;
219 
220 			ret = adf_cfg_get_ring_pairs_from_bundle(
221 			    device->bundles[i], inst, process_name, free_inst);
222 			return ret;
223 		}
224 	} else {
225 		/* Section of in-tree, or kernel API or user process
226 		 * with epoll mode
227 		 */
228 		if (!strcmp(ADF_KERNEL_SEC, process_name) ||
229 		    !strcmp(ADF_KERNEL_SAL_SEC, process_name))
230 			free_bundle_type = KERNEL;
231 		else
232 			free_bundle_type = USER;
233 
234 		for (i = 0; i < device->bundle_num; i++) {
235 			/* Since both in-tree and kernel API's bundle type
236 			 * are kernel, use cpumask_subset to check if the
237 			 * ring's affinity mask is a subset of a bundle's
238 			 * one.
239 			 */
240 			if (free_bundle_type == device->bundles[i]->type &&
241 			    CPU_SUBSET(&device->bundles[i]->affinity_mask,
242 				       &inst->affinity_mask)) {
243 				free_inst = adf_cfg_get_free_instance(
244 				    device,
245 				    device->bundles[i],
246 				    inst,
247 				    process_name);
248 
249 				if (!free_inst)
250 					continue;
251 				ret = adf_cfg_get_ring_pairs_from_bundle(
252 				    device->bundles[i],
253 				    inst,
254 				    process_name,
255 				    free_inst);
256 
257 				return ret;
258 
259 			}
260 		}
261 		for (i = 0; i < device->bundle_num; i++) {
262 			if (adf_cfg_is_free(device->bundles[i])) {
263 				free_inst = adf_cfg_get_free_instance(
264 				    device,
265 				    device->bundles[i],
266 				    inst,
267 				    process_name);
268 				if (!free_inst)
269 					continue;
270 
271 				ret = adf_cfg_get_ring_pairs_from_bundle(
272 				    device->bundles[i],
273 				    inst,
274 				    process_name,
275 				    free_inst);
276 				return ret;
277 			}
278 		}
279 	}
280 	pr_err("Don't have enough rings for instance %s in process %s\n",
281 	       inst->name,
282 	       process_name);
283 
284 	return ret;
285 }
286 
287 int
288 adf_cfg_get_services_enabled(struct adf_accel_dev *accel_dev,
289 			     u16 *ring_to_svc_map)
290 {
291 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
292 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
293 	u32 i = 0;
294 	struct adf_cfg_enabled_services *svcs = NULL;
295 	enum adf_cfg_fw_image_type fw_image_type = ADF_FW_IMAGE_DEFAULT;
296 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
297 	*ring_to_svc_map = 0;
298 
299 	/* Get the services enabled by user */
300 	snprintf(key, sizeof(key), ADF_SERVICES_ENABLED);
301 	if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
302 		return EFAULT;
303 
304 	if (hw_data->get_fw_image_type) {
305 		if (hw_data->get_fw_image_type(accel_dev, &fw_image_type))
306 			return EFAULT;
307 	}
308 
309 	for (i = 0; i < ADF_CFG_SVCS_MAX; i++) {
310 		svcs = &adf_profiles[fw_image_type].supported_svcs[i];
311 
312 		if (!strncmp(svcs->svcs_enabled,
313 			     "",
314 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES))
315 			break;
316 
317 		if (!strncmp(val,
318 			     svcs->svcs_enabled,
319 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES)) {
320 			*ring_to_svc_map = svcs->rng_to_svc_msk;
321 			return 0;
322 		}
323 	}
324 
325 	device_printf(GET_DEV(accel_dev),
326 		      "Invalid ServicesEnabled %s for ServicesProfile: %d\n",
327 		      val,
328 		      fw_image_type);
329 
330 	return EFAULT;
331 }
332 
333 void
334 adf_cfg_set_asym_rings_mask(struct adf_accel_dev *accel_dev)
335 {
336 	int service;
337 	u16 ena_srv_mask;
338 	u16 service_type;
339 	u16 asym_mask = 0;
340 	struct adf_cfg_device *cfg_dev = accel_dev->cfg->dev;
341 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
342 
343 	if (!cfg_dev) {
344 		hw_data->asym_rings_mask = ADF_CFG_DEF_ASYM_MASK;
345 		return;
346 	}
347 
348 	ena_srv_mask = accel_dev->hw_device->ring_to_svc_map;
349 
350 	/* parse each service */
351 	for (service = 0; service < ADF_CFG_MAX_SERVICES; service++) {
352 		service_type = GET_SRV_TYPE(ena_srv_mask, service);
353 		switch (service_type) {
354 		case CRYPTO:
355 		case ASYM:
356 			SET_ASYM_MASK(asym_mask, service);
357 			if (service_type == CRYPTO)
358 				service++;
359 			break;
360 		}
361 	}
362 
363 	hw_data->asym_rings_mask = asym_mask;
364 }
365 
366 void
367 adf_cfg_gen_dispatch_arbiter(struct adf_accel_dev *accel_dev,
368 			     const u32 *thrd_to_arb_map,
369 			     u32 *thrd_to_arb_map_gen,
370 			     u32 total_engines)
371 {
372 	int engine, thread, service, bits;
373 	u32 thread_ability, ability_map, service_mask, service_type;
374 	u16 ena_srv_mask = GET_HW_DATA(accel_dev)->ring_to_svc_map;
375 
376 	for (engine = 0; engine < total_engines; engine++) {
377 		if (!(GET_HW_DATA(accel_dev)->ae_mask & (1 << engine)))
378 			continue;
379 		bits = 0;
380 		/* ability_map is used to indicate the threads ability */
381 		ability_map = thrd_to_arb_map[engine];
382 		thrd_to_arb_map_gen[engine] = 0;
383 		/* parse each thread on the engine */
384 		for (thread = 0; thread < ADF_NUM_THREADS_PER_AE; thread++) {
385 			/* get the ability of this thread */
386 			thread_ability = ability_map & ADF_THRD_ABILITY_MASK;
387 			ability_map >>= ADF_THRD_ABILITY_BIT_LEN;
388 			/* parse each service */
389 			for (service = 0; service < ADF_CFG_MAX_SERVICES;
390 			     service++) {
391 				service_type =
392 				    GET_SRV_TYPE(ena_srv_mask, service);
393 				switch (service_type) {
394 				case CRYPTO:
395 					service_mask = ADF_CFG_ASYM_SRV_MASK;
396 					if (thread_ability & service_mask)
397 						thrd_to_arb_map_gen[engine] |=
398 						    (1 << bits);
399 					bits++;
400 					service++;
401 					service_mask = ADF_CFG_SYM_SRV_MASK;
402 					break;
403 				case COMP:
404 					service_mask = ADF_CFG_DC_SRV_MASK;
405 					break;
406 				case SYM:
407 					service_mask = ADF_CFG_SYM_SRV_MASK;
408 					break;
409 				case ASYM:
410 					service_mask = ADF_CFG_ASYM_SRV_MASK;
411 					break;
412 				default:
413 					service_mask = ADF_CFG_UNKNOWN_SRV_MASK;
414 				}
415 				if (thread_ability & service_mask)
416 					thrd_to_arb_map_gen[engine] |=
417 					    (1 << bits);
418 				bits++;
419 			}
420 		}
421 	}
422 }
423 
424 int
425 adf_cfg_get_fw_image_type(struct adf_accel_dev *accel_dev,
426 			  enum adf_cfg_fw_image_type *fw_image_type)
427 {
428 	*fw_image_type = ADF_FW_IMAGE_CUSTOM1;
429 
430 	return 0;
431 }
432 
433 static int
434 adf_cfg_get_caps_enabled(struct adf_accel_dev *accel_dev,
435 			 u32 *enabled_svc_caps,
436 			 u32 *enabled_fw_caps)
437 {
438 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
439 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
440 	u8 i = 0;
441 	struct adf_cfg_enabled_services *svcs = NULL;
442 	enum adf_cfg_fw_image_type fw_image_type = ADF_FW_IMAGE_DEFAULT;
443 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
444 
445 	*enabled_svc_caps = 0;
446 	*enabled_fw_caps = 0;
447 
448 	/* Get the services enabled by user */
449 	snprintf(key, sizeof(key), ADF_SERVICES_ENABLED);
450 	if (adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC, key, val))
451 		return EFAULT;
452 
453 	/*
454 	 * Only the PF driver has the hook for get_fw_image_type as the VF's
455 	 * enabled service is from PFVF communication. The fw_image_type for
456 	 * the VF is set to DEFAULT since this type contains all kinds of
457 	 * enabled service.
458 	 */
459 	if (hw_data->get_fw_image_type) {
460 		if (hw_data->get_fw_image_type(accel_dev, &fw_image_type))
461 			return EFAULT;
462 	}
463 
464 	for (i = 0; i < ADF_CFG_SVCS_MAX; i++) {
465 		svcs = &adf_profiles[fw_image_type].supported_svcs[i];
466 
467 		if (!strncmp(svcs->svcs_enabled,
468 			     "",
469 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES))
470 			break;
471 
472 		if (!strncmp(val,
473 			     svcs->svcs_enabled,
474 			     ADF_CFG_MAX_VAL_LEN_IN_BYTES)) {
475 			*enabled_svc_caps = svcs->enabled_svc_cap;
476 			*enabled_fw_caps = svcs->enabled_fw_cap;
477 			return 0;
478 		}
479 	}
480 	device_printf(GET_DEV(accel_dev),
481 		      "Invalid ServicesEnabled %s for ServicesProfile: %d\n",
482 		      val,
483 		      fw_image_type);
484 
485 	return EFAULT;
486 }
487 
488 static void
489 adf_cfg_check_deprecated_params(struct adf_accel_dev *accel_dev)
490 {
491 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
492 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
493 	u8 i = 0;
494 
495 	for (i = 0; i < ADF_CFG_DEPRE_PARAMS_NUM; i++) {
496 		/* give a warning if the deprecated params are set by user */
497 		snprintf(key, sizeof(key), "%s", adf_cfg_deprecated_params[i]);
498 		if (!adf_cfg_get_param_value(
499 			accel_dev, ADF_GENERAL_SEC, key, val)) {
500 			device_printf(GET_DEV(accel_dev),
501 				      "Parameter '%s' has been deprecated\n",
502 				      key);
503 		}
504 	}
505 }
506 
507 static int
508 adf_cfg_check_enabled_services(struct adf_accel_dev *accel_dev,
509 			       u32 enabled_svc_caps)
510 {
511 	u32 hw_caps = GET_HW_DATA(accel_dev)->accel_capabilities_mask;
512 
513 	if ((enabled_svc_caps & hw_caps) == enabled_svc_caps)
514 		return 0;
515 
516 	device_printf(GET_DEV(accel_dev), "Unsupported device configuration\n");
517 
518 	return EFAULT;
519 }
520 
521 static int
522 adf_cfg_update_pf_accel_cap_mask(struct adf_accel_dev *accel_dev)
523 {
524 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
525 	u32 enabled_svc_caps = 0;
526 	u32 enabled_fw_caps = 0;
527 
528 	if (hw_data->get_accel_cap) {
529 		hw_data->accel_capabilities_mask =
530 		    hw_data->get_accel_cap(accel_dev);
531 	}
532 
533 	if (adf_cfg_get_caps_enabled(accel_dev,
534 				     &enabled_svc_caps,
535 				     &enabled_fw_caps))
536 		return EFAULT;
537 
538 	if (adf_cfg_check_enabled_services(accel_dev, enabled_svc_caps))
539 		return EFAULT;
540 
541 	if (!(enabled_svc_caps & ADF_CFG_CAP_ASYM))
542 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_ASYM;
543 	if (!(enabled_svc_caps & ADF_CFG_CAP_SYM))
544 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_SYM;
545 	if (!(enabled_svc_caps & ADF_CFG_CAP_DC))
546 		hw_data->accel_capabilities_mask &= ~ADF_CFG_CAP_DC;
547 
548 	/* Enable FW defined capabilities*/
549 	if (enabled_fw_caps)
550 		hw_data->accel_capabilities_mask |= enabled_fw_caps;
551 
552 	return 0;
553 }
554 
555 static int
556 adf_cfg_update_vf_accel_cap_mask(struct adf_accel_dev *accel_dev)
557 {
558 	u32 enabled_svc_caps = 0;
559 	u32 enabled_fw_caps = 0;
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 	return 0;
569 }
570 
571 int
572 adf_cfg_device_init(struct adf_cfg_device *device,
573 		    struct adf_accel_dev *accel_dev)
574 {
575 	int i = 0;
576 	/* max_inst indicates the max instance number one bank can hold */
577 	int max_inst = accel_dev->hw_device->tx_rx_gap;
578 	int ret = ENOMEM;
579 	struct adf_hw_device_data *hw_data = GET_HW_DATA(accel_dev);
580 
581 	adf_cfg_check_deprecated_params(accel_dev);
582 
583 	device->bundle_num = 0;
584 	device->bundles = (struct adf_cfg_bundle **)malloc(
585 	    sizeof(struct adf_cfg_bundle *) * accel_dev->hw_device->num_banks,
586 	    M_QAT,
587 	    M_WAITOK | M_ZERO);
588 
589 	device->bundle_num = accel_dev->hw_device->num_banks;
590 
591 	device->instances = (struct adf_cfg_instance **)malloc(
592 	    sizeof(struct adf_cfg_instance *) * device->bundle_num * max_inst,
593 	    M_QAT,
594 	    M_WAITOK | M_ZERO);
595 
596 	device->instance_index = 0;
597 
598 	device->max_kernel_bundle_nr = -1;
599 
600 	ret = EFAULT;
601 
602 	/* Update the acceleration capability mask based on User capability */
603 	if (!accel_dev->is_vf) {
604 		if (adf_cfg_update_pf_accel_cap_mask(accel_dev))
605 			goto failed;
606 	} else {
607 		if (adf_cfg_update_vf_accel_cap_mask(accel_dev))
608 			goto failed;
609 	}
610 
611 	/* Based on the svc configured, get ring_to_svc_map */
612 	if (hw_data->get_ring_to_svc_map) {
613 		if (hw_data->get_ring_to_svc_map(accel_dev,
614 						 &hw_data->ring_to_svc_map))
615 			goto failed;
616 	}
617 
618 	ret = ENOMEM;
619 	/*
620 	 * 1) get the config information to generate the ring to service
621 	 *    mapping table
622 	 * 2) init each bundle of this device
623 	 */
624 	for (i = 0; i < device->bundle_num; i++) {
625 		device->bundles[i] = malloc(sizeof(struct adf_cfg_bundle),
626 					    M_QAT,
627 					    M_WAITOK | M_ZERO);
628 
629 		device->bundles[i]->max_section = max_inst;
630 		adf_cfg_bundle_init(device->bundles[i], device, i, accel_dev);
631 	}
632 
633 	return 0;
634 
635 failed:
636 	for (i = 0; i < device->bundle_num; i++) {
637 		if (device->bundles[i])
638 			adf_cfg_bundle_clear(device->bundles[i], accel_dev);
639 	}
640 
641 	for (i = 0; i < (device->bundle_num * max_inst); i++) {
642 		if (device->instances && device->instances[i])
643 			free(device->instances[i], M_QAT);
644 	}
645 
646 	free(device->instances, M_QAT);
647 	device->instances = NULL;
648 
649 	device_printf(GET_DEV(accel_dev), "Failed to do device init\n");
650 	return ret;
651 }
652 
653 void
654 adf_cfg_device_clear(struct adf_cfg_device *device,
655 		     struct adf_accel_dev *accel_dev)
656 {
657 	int i = 0;
658 
659 	for (i = 0; i < device->bundle_num; i++) {
660 		if (device->bundles && device->bundles[i]) {
661 			adf_cfg_bundle_clear(device->bundles[i], accel_dev);
662 			free(device->bundles[i], M_QAT);
663 			device->bundles[i] = NULL;
664 		}
665 	}
666 
667 	free(device->bundles, M_QAT);
668 	device->bundles = NULL;
669 
670 	for (i = 0; i < device->instance_index; i++) {
671 		if (device->instances && device->instances[i]) {
672 			free(device->instances[i], M_QAT);
673 			device->instances[i] = NULL;
674 		}
675 	}
676 
677 	free(device->instances, M_QAT);
678 	device->instances = NULL;
679 }
680 
681 /*
682  * Static configuration for userspace
683  */
684 static int
685 adf_cfg_static_conf_user(struct adf_accel_dev *accel_dev,
686 			 int cy_enabled,
687 			 int dc_enabled)
688 {
689 	int ret = 0;
690 	unsigned long val = 0;
691 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
692 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
693 	int cy_user_instances = 0;
694 	int dc_user_instances = 0;
695 	int i = 0;
696 	int cpus = num_online_cpus();
697 
698 	if (!(IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev))))) {
699 		device_printf(
700 		    GET_DEV(accel_dev),
701 		    "User space configuration supported only on QAT 4xxx devices\n");
702 		return ENXIO;
703 	}
704 
705 	ret |= adf_cfg_section_add(accel_dev, ADF_SAL_SEC);
706 
707 	if (accel_dev->is_vf) {
708 		if (cy_enabled)
709 			cy_user_instances =
710 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_CY_VF;
711 
712 		if (dc_enabled)
713 			dc_user_instances =
714 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_DC_VF;
715 	} else {
716 		if (cy_enabled)
717 			cy_user_instances =
718 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_CY;
719 
720 		if (dc_enabled)
721 			dc_user_instances =
722 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_DC;
723 	}
724 
725 	val = cy_user_instances;
726 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY);
727 	ret |= adf_cfg_add_key_value_param(
728 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
729 
730 	val = dc_user_instances;
731 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC);
732 	ret |= adf_cfg_add_key_value_param(
733 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
734 
735 	val = accel_dev->cfg->num_user_processes;
736 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_PROCESSES);
737 	ret |= adf_cfg_add_key_value_param(
738 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
739 
740 	for (i = 0; i < cy_user_instances; i++) {
741 		val = (accel_dev->accel_id * cy_user_instances + i) % cpus;
742 		snprintf(key,
743 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
744 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
745 			 i);
746 		ret |= adf_cfg_add_key_value_param(
747 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
748 
749 		val = ADF_CFG_STATIC_CONF_POLL;
750 		snprintf(key,
751 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
752 			 ADF_CY "%d" ADF_POLL_MODE,
753 			 i);
754 		ret |= adf_cfg_add_key_value_param(
755 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
756 
757 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
758 		snprintf(key,
759 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
760 			 ADF_CY_NAME_FORMAT,
761 			 i);
762 		ret |= adf_cfg_add_key_value_param(
763 		    accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR);
764 	}
765 
766 	for (i = 0; i < dc_user_instances; i++) {
767 		val = (accel_dev->accel_id * dc_user_instances + i) % cpus;
768 		snprintf(key,
769 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
770 			 ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY,
771 			 i);
772 		ret |= adf_cfg_add_key_value_param(
773 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
774 
775 		val = ADF_CFG_STATIC_CONF_POLL;
776 		snprintf(key,
777 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
778 			 ADF_DC "%d" ADF_POLL_MODE,
779 			 i);
780 		ret |= adf_cfg_add_key_value_param(
781 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
782 
783 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i);
784 		snprintf(key,
785 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
786 			 ADF_DC_NAME_FORMAT,
787 			 i);
788 		ret |= adf_cfg_add_key_value_param(
789 		    accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR);
790 	}
791 
792 	return ret;
793 }
794 
795 static int
796 adf_cfg_static_conf_kernel(struct adf_accel_dev *accel_dev,
797 			   int asym_enabled,
798 			   int sym_enabled,
799 			   int dc_enabled)
800 {
801 	int ret = 0;
802 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
803 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
804 	unsigned long val = 0;
805 	int i = 0;
806 	int instances = 0;
807 	int cy_poll_instances = 0;
808 	int cy_irq_instances = 0;
809 	int dc_instances = 0;
810 	int def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL;
811 	int def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ;
812 	int def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC;
813 	int cpus = num_online_cpus();
814 
815 	instances = GET_MAX_BANKS(accel_dev);
816 	if (!instances)
817 		return EFAULT;
818 
819 	if (accel_dev->is_vf) {
820 		def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL_VF;
821 		def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ_VF;
822 		def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC_VF;
823 	}
824 
825 	/* Get the mode enabled by user */
826 	ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC);
827 
828 	if (dc_enabled) {
829 		if (instances >= def_dc_inst) {
830 			dc_instances = def_dc_inst;
831 			instances -= dc_instances;
832 		} else {
833 			return EFAULT;
834 		}
835 	}
836 
837 	if (asym_enabled || sym_enabled) {
838 		if (instances >= def_cy_poll_inst) {
839 			cy_poll_instances = def_cy_poll_inst;
840 			instances -= cy_poll_instances;
841 		} else {
842 			return EFAULT;
843 		}
844 
845 		if (sym_enabled) {
846 			if (instances >= def_cy_irq_inst) {
847 				cy_irq_instances = def_cy_irq_inst;
848 				instances -= cy_irq_instances;
849 			} else {
850 				return EFAULT;
851 			}
852 		}
853 	}
854 
855 	val = (cy_poll_instances + cy_irq_instances);
856 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY);
857 	ret |= adf_cfg_add_key_value_param(
858 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
859 
860 	val = dc_instances;
861 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC);
862 	ret |= adf_cfg_add_key_value_param(
863 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
864 
865 	for (i = 0; i < (cy_irq_instances); i++) {
866 		val = (accel_dev->accel_id * cy_irq_instances + i) % cpus;
867 		snprintf(key,
868 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
869 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
870 			 i);
871 		ret |= adf_cfg_add_key_value_param(
872 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
873 
874 		val = ADF_CFG_STATIC_CONF_IRQ;
875 		snprintf(key,
876 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
877 			 ADF_CY "%d" ADF_POLL_MODE,
878 			 i);
879 		ret |= adf_cfg_add_key_value_param(
880 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
881 
882 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
883 		snprintf(key,
884 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
885 			 ADF_CY_NAME_FORMAT,
886 			 i);
887 		ret |= adf_cfg_add_key_value_param(
888 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
889 	}
890 
891 	for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances);
892 	     i++) {
893 		val = (accel_dev->accel_id * cy_poll_instances + i) % cpus;
894 		snprintf(key,
895 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
896 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
897 			 i);
898 		ret |= adf_cfg_add_key_value_param(
899 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
900 
901 		val = ADF_CFG_STATIC_CONF_POLL;
902 		snprintf(key,
903 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
904 			 ADF_CY "%d" ADF_POLL_MODE,
905 			 i);
906 		ret |= adf_cfg_add_key_value_param(
907 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
908 
909 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
910 		snprintf(key,
911 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
912 			 ADF_CY_NAME_FORMAT,
913 			 i);
914 		ret |= adf_cfg_add_key_value_param(
915 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
916 	}
917 
918 	for (i = 0; i < dc_instances; i++) {
919 		val = (accel_dev->accel_id * dc_instances + i) % cpus;
920 		snprintf(key,
921 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
922 			 ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY,
923 			 i);
924 		ret |= adf_cfg_add_key_value_param(
925 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
926 
927 		val = ADF_CFG_STATIC_CONF_POLL;
928 		snprintf(key,
929 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
930 			 ADF_DC "%d" ADF_POLL_MODE,
931 			 i);
932 		ret |= adf_cfg_add_key_value_param(
933 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
934 
935 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i);
936 		snprintf(key,
937 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
938 			 ADF_DC_NAME_FORMAT,
939 			 i);
940 		ret |= adf_cfg_add_key_value_param(
941 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
942 	}
943 
944 	return ret;
945 }
946 
947 static int
948 adf_cfg_static_conf(struct adf_accel_dev *accel_dev)
949 {
950 	int ret = 0;
951 	unsigned long val = 0;
952 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
953 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
954 	char *token, *cur_str;
955 	int ks_enabled = 0;
956 	int us_enabled = 0;
957 	int asym_enabled = 0;
958 	int sym_enabled = 0;
959 	int cy_enabled = 0;
960 	int dc_enabled = 0;
961 
962 	strncpy(value, accel_dev->cfg->cfg_mode, ADF_CFG_MAX_VAL);
963 	cur_str = value;
964 
965 	token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
966 	while (token) {
967 		if (!strncmp(token, ADF_CFG_KERNEL, strlen(ADF_CFG_KERNEL)))
968 			ks_enabled = 1;
969 		if (!strncmp(token, ADF_CFG_USER, strlen(ADF_CFG_USER)))
970 			us_enabled = 1;
971 		token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
972 	}
973 
974 	/* Get the services enabled by user */
975 	strncpy(value, accel_dev->cfg->cfg_services, ADF_CFG_MAX_VAL);
976 	cur_str = value;
977 
978 	token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
979 	while (token) {
980 		if (!strncmp(token, ADF_CFG_SYM, strlen(ADF_CFG_SYM))) {
981 			sym_enabled = 1;
982 		}
983 		if (!strncmp(token, ADF_CFG_ASYM, strlen(ADF_CFG_ASYM))) {
984 			asym_enabled = 1;
985 		}
986 		/* cy means both asym & crypto should be enabled
987 		 * Hardware resources allocation check will be done later
988 		 */
989 		if (!strncmp(token, ADF_CFG_CY, strlen(ADF_CFG_CY))) {
990 			asym_enabled = 1;
991 			sym_enabled = 1;
992 		}
993 		if (!strncmp(token, ADF_SERVICE_DC, strlen(ADF_SERVICE_DC))) {
994 			dc_enabled = 1;
995 		}
996 
997 		token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
998 	}
999 
1000 	if (asym_enabled || sym_enabled) {
1001 		cy_enabled = 1;
1002 	}
1003 
1004 	ret |= adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
1005 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED);
1006 
1007 	if (strcmp(ADF_CFG_SYM_ASYM, accel_dev->cfg->cfg_services) == 0) {
1008 		strncpy(value, ADF_CFG_CY, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
1009 	} else {
1010 		strncpy(value,
1011 			accel_dev->cfg->cfg_services,
1012 			ADF_CFG_MAX_VAL_LEN_IN_BYTES);
1013 	}
1014 
1015 	ret |= adf_cfg_add_key_value_param(
1016 	    accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR);
1017 
1018 	val = ADF_CFG_STATIC_CONF_VER;
1019 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CONFIG_VERSION);
1020 	ret |= adf_cfg_add_key_value_param(
1021 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1022 
1023 	val = ADF_CFG_STATIC_CONF_AUTO_RESET;
1024 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_AUTO_RESET_ON_ERROR);
1025 	ret |= adf_cfg_add_key_value_param(
1026 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1027 
1028 	if (accel_dev->hw_device->get_num_accel_units) {
1029 		int cy_au = 0;
1030 		int dc_au = 0;
1031 		int num_au = accel_dev->hw_device->get_num_accel_units(
1032 		    accel_dev->hw_device);
1033 
1034 		if (num_au > ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
1035 			cy_au = num_au - ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
1036 			dc_au = ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
1037 		} else if (num_au == ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
1038 			cy_au = 1;
1039 			dc_au = 1;
1040 		} else {
1041 			return EFAULT;
1042 		}
1043 
1044 		/* User defined adjustement basing on serives enabled */
1045 		if (cy_enabled && !dc_enabled) {
1046 			cy_au += dc_au;
1047 			dc_au = 0;
1048 		} else if (!cy_enabled && dc_enabled) {
1049 			dc_au += cy_au;
1050 			cy_au = 0;
1051 		}
1052 
1053 		val = cy_au;
1054 		snprintf(key,
1055 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1056 			 ADF_NUM_CY_ACCEL_UNITS);
1057 		ret |= adf_cfg_add_key_value_param(
1058 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1059 
1060 		val = dc_au;
1061 		snprintf(key,
1062 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1063 			 ADF_NUM_DC_ACCEL_UNITS);
1064 		ret |= adf_cfg_add_key_value_param(
1065 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1066 
1067 		val = ADF_CFG_STATIC_CONF_NUM_INLINE_ACCEL_UNITS;
1068 		snprintf(key,
1069 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1070 			 ADF_NUM_INLINE_ACCEL_UNITS);
1071 		ret |= adf_cfg_add_key_value_param(
1072 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1073 	}
1074 
1075 	val = ADF_CFG_STATIC_CONF_CY_ASYM_RING_SIZE;
1076 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_ASYM_SIZE);
1077 	ret |= adf_cfg_add_key_value_param(
1078 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1079 
1080 	val = ADF_CFG_STATIC_CONF_CY_SYM_RING_SIZE;
1081 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_SYM_SIZE);
1082 	ret |= adf_cfg_add_key_value_param(
1083 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1084 
1085 	val = ADF_CFG_STATIC_CONF_DC_INTER_BUF_SIZE;
1086 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_INTER_BUF_SIZE);
1087 	ret |= adf_cfg_add_key_value_param(
1088 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1089 
1090 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC;
1091 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DC);
1092 	ret |= adf_cfg_add_key_value_param(
1093 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1094 
1095 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DH;
1096 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DH);
1097 	ret |= adf_cfg_add_key_value_param(
1098 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1099 
1100 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DRBG;
1101 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DRBG);
1102 	ret |= adf_cfg_add_key_value_param(
1103 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1104 
1105 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DSA;
1106 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DSA);
1107 	ret |= adf_cfg_add_key_value_param(
1108 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1109 
1110 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ECC;
1111 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ECC);
1112 	ret |= adf_cfg_add_key_value_param(
1113 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1114 
1115 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ENABLED;
1116 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ENABLED);
1117 	ret |= adf_cfg_add_key_value_param(
1118 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1119 
1120 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_KEYGEN;
1121 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_KEYGEN);
1122 	ret |= adf_cfg_add_key_value_param(
1123 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1124 
1125 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_LN;
1126 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_LN);
1127 	ret |= adf_cfg_add_key_value_param(
1128 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1129 
1130 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_PRIME;
1131 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_PRIME);
1132 	ret |= adf_cfg_add_key_value_param(
1133 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1134 
1135 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_RSA;
1136 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_RSA);
1137 	ret |= adf_cfg_add_key_value_param(
1138 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1139 
1140 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_SYM;
1141 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_SYM);
1142 	ret |= adf_cfg_add_key_value_param(
1143 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1144 
1145 	if (ks_enabled) {
1146 		ret |= adf_cfg_static_conf_kernel(accel_dev,
1147 						  asym_enabled,
1148 						  sym_enabled,
1149 						  dc_enabled);
1150 	}
1151 
1152 	if (us_enabled) {
1153 		ret |=
1154 		    adf_cfg_static_conf_user(accel_dev, cy_enabled, dc_enabled);
1155 	}
1156 
1157 	if (ret)
1158 		ret = ENXIO;
1159 	return ret;
1160 }
1161 
1162 int
1163 adf_config_device(struct adf_accel_dev *accel_dev)
1164 {
1165 	struct adf_cfg_device_data *cfg = NULL;
1166 	struct adf_cfg_device *cfg_device = NULL;
1167 	struct adf_cfg_section *sec;
1168 	struct list_head *list;
1169 	int ret = ENOMEM;
1170 
1171 	if (!accel_dev)
1172 		return ret;
1173 
1174 	ret = adf_cfg_static_conf(accel_dev);
1175 	if (ret)
1176 		goto failed;
1177 
1178 	cfg = accel_dev->cfg;
1179 	cfg->dev = NULL;
1180 	cfg_device = (struct adf_cfg_device *)malloc(sizeof(*cfg_device),
1181 						     M_QAT,
1182 						     M_WAITOK | M_ZERO);
1183 
1184 	ret = EFAULT;
1185 
1186 	if (adf_cfg_device_init(cfg_device, accel_dev))
1187 		goto failed;
1188 
1189 	cfg->dev = cfg_device;
1190 
1191 	/* GENERAL and KERNEL section must be processed before others */
1192 	list_for_each(list, &cfg->sec_list)
1193 	{
1194 		sec = list_entry(list, struct adf_cfg_section, list);
1195 		if (!strcmp(sec->name, ADF_GENERAL_SEC)) {
1196 			ret = adf_cfg_process_section(accel_dev,
1197 						      sec->name,
1198 						      accel_dev->accel_id);
1199 			if (ret)
1200 				goto failed;
1201 			sec->processed = true;
1202 			break;
1203 		}
1204 	}
1205 
1206 	list_for_each(list, &cfg->sec_list)
1207 	{
1208 		sec = list_entry(list, struct adf_cfg_section, list);
1209 		if (!strcmp(sec->name, ADF_KERNEL_SEC)) {
1210 			ret = adf_cfg_process_section(accel_dev,
1211 						      sec->name,
1212 						      accel_dev->accel_id);
1213 			if (ret)
1214 				goto failed;
1215 			sec->processed = true;
1216 			break;
1217 		}
1218 	}
1219 
1220 	list_for_each(list, &cfg->sec_list)
1221 	{
1222 		sec = list_entry(list, struct adf_cfg_section, list);
1223 		if (!strcmp(sec->name, ADF_KERNEL_SAL_SEC)) {
1224 			ret = adf_cfg_process_section(accel_dev,
1225 						      sec->name,
1226 						      accel_dev->accel_id);
1227 			if (ret)
1228 				goto failed;
1229 			sec->processed = true;
1230 			break;
1231 		}
1232 	}
1233 
1234 	list_for_each(list, &cfg->sec_list)
1235 	{
1236 		sec = list_entry(list, struct adf_cfg_section, list);
1237 		/* avoid reprocessing one section */
1238 		if (!sec->processed && !sec->is_derived) {
1239 			ret = adf_cfg_process_section(accel_dev,
1240 						      sec->name,
1241 						      accel_dev->accel_id);
1242 			if (ret)
1243 				goto failed;
1244 			sec->processed = true;
1245 		}
1246 	}
1247 
1248 	/* newly added accel section */
1249 	ret = adf_cfg_process_section(accel_dev,
1250 				      ADF_ACCEL_SEC,
1251 				      accel_dev->accel_id);
1252 	if (ret)
1253 		goto failed;
1254 
1255 	/*
1256 	 * put item-remove task after item-process
1257 	 * because during process we may fetch values from those items
1258 	 */
1259 	list_for_each(list, &cfg->sec_list)
1260 	{
1261 		sec = list_entry(list, struct adf_cfg_section, list);
1262 		if (!sec->is_derived) {
1263 			ret = adf_cfg_cleanup_section(accel_dev,
1264 						      sec->name,
1265 						      accel_dev->accel_id);
1266 			if (ret)
1267 				goto failed;
1268 		}
1269 	}
1270 
1271 	ret = 0;
1272 	set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
1273 failed:
1274 	if (ret) {
1275 		if (cfg_device) {
1276 			adf_cfg_device_clear(cfg_device, accel_dev);
1277 			free(cfg_device, M_QAT);
1278 			cfg->dev = NULL;
1279 		}
1280 		adf_cfg_del_all(accel_dev);
1281 		device_printf(GET_DEV(accel_dev), "Failed to config device\n");
1282 	}
1283 
1284 	return ret;
1285 }
1286