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