xref: /freebsd/sys/dev/qat/qat_common/adf_cfg_device.c (revision ded037e65e5239671b1292ec987a2e0894b217b5)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 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 void
adf_cfg_device_clear_all(struct adf_accel_dev * accel_dev)681 adf_cfg_device_clear_all(struct adf_accel_dev *accel_dev)
682 {
683 	sx_xlock(&accel_dev->cfg->lock);
684 	if (accel_dev->cfg->dev) {
685 		adf_cfg_device_clear(accel_dev->cfg->dev, accel_dev);
686                 free(accel_dev->cfg->dev, M_QAT);
687 		accel_dev->cfg->dev = NULL;
688 	}
689 	sx_xunlock(&accel_dev->cfg->lock);
690 }
691 
692 /*
693  * Static configuration for userspace
694  */
695 static int
adf_cfg_static_conf_user(struct adf_accel_dev * accel_dev,int cy_enabled,int dc_enabled)696 adf_cfg_static_conf_user(struct adf_accel_dev *accel_dev,
697 			 int cy_enabled,
698 			 int dc_enabled)
699 {
700 	int ret = 0;
701 	unsigned long val = 0;
702 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
703 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
704 	int cy_user_instances = 0;
705 	int dc_user_instances = 0;
706 	int i = 0;
707 	int cpus = num_online_cpus();
708 
709 	if (!(IS_QAT_GEN4(pci_get_device(GET_DEV(accel_dev))))) {
710 		device_printf(
711 		    GET_DEV(accel_dev),
712 		    "User space configuration supported only on QAT 4xxx devices\n");
713 		return ENXIO;
714 	}
715 
716 	ret |= adf_cfg_section_add(accel_dev, ADF_SAL_SEC);
717 
718 	if (accel_dev->is_vf) {
719 		if (cy_enabled)
720 			cy_user_instances =
721 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_CY_VF;
722 
723 		if (dc_enabled)
724 			dc_user_instances =
725 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_DC_VF;
726 	} else {
727 		if (cy_enabled)
728 			cy_user_instances =
729 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_CY;
730 
731 		if (dc_enabled)
732 			dc_user_instances =
733 			    ADF_CFG_STATIC_CONF_USER_INST_NUM_DC;
734 	}
735 
736 	val = cy_user_instances;
737 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY);
738 	ret |= adf_cfg_add_key_value_param(
739 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
740 
741 	val = dc_user_instances;
742 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC);
743 	ret |= adf_cfg_add_key_value_param(
744 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
745 
746 	val = accel_dev->cfg->num_user_processes;
747 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_PROCESSES);
748 	ret |= adf_cfg_add_key_value_param(
749 	    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
750 
751 	for (i = 0; i < cy_user_instances; i++) {
752 		val = (accel_dev->accel_id * cy_user_instances + i) % cpus;
753 		snprintf(key,
754 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
755 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
756 			 i);
757 		ret |= adf_cfg_add_key_value_param(
758 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
759 
760 		val = ADF_CFG_STATIC_CONF_POLL;
761 		snprintf(key,
762 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
763 			 ADF_CY "%d" ADF_POLL_MODE,
764 			 i);
765 		ret |= adf_cfg_add_key_value_param(
766 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
767 
768 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
769 		snprintf(key,
770 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
771 			 ADF_CY_NAME_FORMAT,
772 			 i);
773 		ret |= adf_cfg_add_key_value_param(
774 		    accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR);
775 	}
776 
777 	for (i = 0; i < dc_user_instances; i++) {
778 		val = (accel_dev->accel_id * dc_user_instances + i) % cpus;
779 		snprintf(key,
780 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
781 			 ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY,
782 			 i);
783 		ret |= adf_cfg_add_key_value_param(
784 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
785 
786 		val = ADF_CFG_STATIC_CONF_POLL;
787 		snprintf(key,
788 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
789 			 ADF_DC "%d" ADF_POLL_MODE,
790 			 i);
791 		ret |= adf_cfg_add_key_value_param(
792 		    accel_dev, ADF_SAL_SEC, key, (void *)&val, ADF_DEC);
793 
794 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i);
795 		snprintf(key,
796 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
797 			 ADF_DC_NAME_FORMAT,
798 			 i);
799 		ret |= adf_cfg_add_key_value_param(
800 		    accel_dev, ADF_SAL_SEC, key, (void *)value, ADF_STR);
801 	}
802 
803 	return ret;
804 }
805 
806 static int
adf_cfg_static_conf_kernel(struct adf_accel_dev * accel_dev,int asym_enabled,int sym_enabled,int dc_enabled)807 adf_cfg_static_conf_kernel(struct adf_accel_dev *accel_dev,
808 			   int asym_enabled,
809 			   int sym_enabled,
810 			   int dc_enabled)
811 {
812 	int ret = 0;
813 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
814 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
815 	unsigned long val = 0;
816 	int i = 0;
817 	int instances = 0;
818 	int cy_poll_instances = 0;
819 	int cy_irq_instances = 0;
820 	int dc_instances = 0;
821 	int def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL;
822 	int def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ;
823 	int def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC;
824 	int cpus = num_online_cpus();
825 
826 	instances = GET_MAX_BANKS(accel_dev);
827 	if (!instances)
828 		return EFAULT;
829 
830 	if (accel_dev->is_vf) {
831 		def_cy_poll_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_POLL_VF;
832 		def_cy_irq_inst = ADF_CFG_STATIC_CONF_INST_NUM_CY_IRQ_VF;
833 		def_dc_inst = ADF_CFG_STATIC_CONF_INST_NUM_DC_VF;
834 	}
835 
836 	/* Get the mode enabled by user */
837 	ret |= adf_cfg_section_add(accel_dev, ADF_KERNEL_SAL_SEC);
838 
839 	if (dc_enabled) {
840 		if (instances >= def_dc_inst) {
841 			dc_instances = def_dc_inst;
842 			instances -= dc_instances;
843 		} else {
844 			return EFAULT;
845 		}
846 	}
847 
848 	if (asym_enabled || sym_enabled) {
849 		if (instances >= def_cy_poll_inst) {
850 			cy_poll_instances = def_cy_poll_inst;
851 			instances -= cy_poll_instances;
852 		} else {
853 			return EFAULT;
854 		}
855 
856 		if (sym_enabled) {
857 			if (instances >= def_cy_irq_inst) {
858 				cy_irq_instances = def_cy_irq_inst;
859 				instances -= cy_irq_instances;
860 			} else {
861 				return EFAULT;
862 			}
863 		}
864 	}
865 
866 	val = (cy_poll_instances + cy_irq_instances);
867 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_CY);
868 	ret |= adf_cfg_add_key_value_param(
869 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
870 
871 	val = dc_instances;
872 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_NUM_DC);
873 	ret |= adf_cfg_add_key_value_param(
874 	    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
875 
876 	for (i = 0; i < (cy_irq_instances); i++) {
877 		val = (accel_dev->accel_id * cy_irq_instances + i) % cpus;
878 		snprintf(key,
879 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
880 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
881 			 i);
882 		ret |= adf_cfg_add_key_value_param(
883 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
884 
885 		val = ADF_CFG_STATIC_CONF_IRQ;
886 		snprintf(key,
887 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
888 			 ADF_CY "%d" ADF_POLL_MODE,
889 			 i);
890 		ret |= adf_cfg_add_key_value_param(
891 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
892 
893 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
894 		snprintf(key,
895 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
896 			 ADF_CY_NAME_FORMAT,
897 			 i);
898 		ret |= adf_cfg_add_key_value_param(
899 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
900 	}
901 
902 	for (i = cy_irq_instances; i < (cy_poll_instances + cy_irq_instances);
903 	     i++) {
904 		val = (accel_dev->accel_id * cy_poll_instances + i) % cpus;
905 		snprintf(key,
906 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
907 			 ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY,
908 			 i);
909 		ret |= adf_cfg_add_key_value_param(
910 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
911 
912 		val = ADF_CFG_STATIC_CONF_POLL;
913 		snprintf(key,
914 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
915 			 ADF_CY "%d" ADF_POLL_MODE,
916 			 i);
917 		ret |= adf_cfg_add_key_value_param(
918 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
919 
920 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_CY "%d", i);
921 		snprintf(key,
922 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
923 			 ADF_CY_NAME_FORMAT,
924 			 i);
925 		ret |= adf_cfg_add_key_value_param(
926 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
927 	}
928 
929 	for (i = 0; i < dc_instances; i++) {
930 		val = (accel_dev->accel_id * dc_instances + i) % cpus;
931 		snprintf(key,
932 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
933 			 ADF_DC "%d" ADF_ETRMGR_CORE_AFFINITY,
934 			 i);
935 		ret |= adf_cfg_add_key_value_param(
936 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
937 
938 		val = ADF_CFG_STATIC_CONF_POLL;
939 		snprintf(key,
940 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
941 			 ADF_DC "%d" ADF_POLL_MODE,
942 			 i);
943 		ret |= adf_cfg_add_key_value_param(
944 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)&val, ADF_DEC);
945 
946 		snprintf(value, ADF_CFG_MAX_VAL_LEN_IN_BYTES, ADF_DC "%d", i);
947 		snprintf(key,
948 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
949 			 ADF_DC_NAME_FORMAT,
950 			 i);
951 		ret |= adf_cfg_add_key_value_param(
952 		    accel_dev, ADF_KERNEL_SAL_SEC, key, (void *)value, ADF_STR);
953 	}
954 
955 	return ret;
956 }
957 
958 static int
adf_cfg_static_conf(struct adf_accel_dev * accel_dev)959 adf_cfg_static_conf(struct adf_accel_dev *accel_dev)
960 {
961 	int ret = 0;
962 	unsigned long val = 0;
963 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
964 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
965 	char *token, *cur_str;
966 	int ks_enabled = 0;
967 	int us_enabled = 0;
968 	int asym_enabled = 0;
969 	int sym_enabled = 0;
970 	int cy_enabled = 0;
971 	int dc_enabled = 0;
972 
973 	strncpy(value, accel_dev->cfg->cfg_mode, ADF_CFG_MAX_VAL);
974 	cur_str = value;
975 
976 	token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
977 	while (token) {
978 		if (!strncmp(token, ADF_CFG_KERNEL, strlen(ADF_CFG_KERNEL)))
979 			ks_enabled = 1;
980 		if (!strncmp(token, ADF_CFG_USER, strlen(ADF_CFG_USER)))
981 			us_enabled = 1;
982 		token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
983 	}
984 
985 	/* Get the services enabled by user */
986 	strncpy(value, accel_dev->cfg->cfg_services, ADF_CFG_MAX_VAL);
987 	cur_str = value;
988 
989 	token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
990 	while (token) {
991 		if (!strncmp(token, ADF_CFG_SYM, strlen(ADF_CFG_SYM))) {
992 			sym_enabled = 1;
993 		}
994 		if (!strncmp(token, ADF_CFG_ASYM, strlen(ADF_CFG_ASYM))) {
995 			asym_enabled = 1;
996 		}
997 		/* cy means both asym & crypto should be enabled
998 		 * Hardware resources allocation check will be done later
999 		 */
1000 		if (!strncmp(token, ADF_CFG_CY, strlen(ADF_CFG_CY))) {
1001 			asym_enabled = 1;
1002 			sym_enabled = 1;
1003 		}
1004 		if (!strncmp(token, ADF_SERVICE_DC, strlen(ADF_SERVICE_DC))) {
1005 			dc_enabled = 1;
1006 		}
1007 
1008 		token = strsep(&cur_str, ADF_SERVICES_SEPARATOR);
1009 	}
1010 
1011 	if (asym_enabled || sym_enabled) {
1012 		cy_enabled = 1;
1013 	}
1014 
1015 	ret |= adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC);
1016 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_SERVICES_ENABLED);
1017 
1018 	if (strcmp(ADF_CFG_SYM_ASYM, accel_dev->cfg->cfg_services) == 0) {
1019 		strncpy(value, ADF_CFG_CY, ADF_CFG_MAX_VAL_LEN_IN_BYTES);
1020 	} else {
1021 		strncpy(value,
1022 			accel_dev->cfg->cfg_services,
1023 			ADF_CFG_MAX_VAL_LEN_IN_BYTES);
1024 	}
1025 
1026 	ret |= adf_cfg_add_key_value_param(
1027 	    accel_dev, ADF_GENERAL_SEC, key, (void *)value, ADF_STR);
1028 
1029 	val = ADF_CFG_STATIC_CONF_VER;
1030 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CONFIG_VERSION);
1031 	ret |= adf_cfg_add_key_value_param(
1032 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1033 
1034 	val = ADF_CFG_STATIC_CONF_AUTO_RESET;
1035 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_AUTO_RESET_ON_ERROR);
1036 	ret |= adf_cfg_add_key_value_param(
1037 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1038 
1039 	if (accel_dev->hw_device->get_num_accel_units) {
1040 		int cy_au = 0;
1041 		int dc_au = 0;
1042 		int num_au = accel_dev->hw_device->get_num_accel_units(
1043 		    accel_dev->hw_device);
1044 
1045 		if (num_au > ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
1046 			cy_au = num_au - ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
1047 			dc_au = ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS;
1048 		} else if (num_au == ADF_CFG_STATIC_CONF_NUM_DC_ACCEL_UNITS) {
1049 			cy_au = 1;
1050 			dc_au = 1;
1051 		} else {
1052 			return EFAULT;
1053 		}
1054 
1055 		/* User defined adjustement basing on serives enabled */
1056 		if (cy_enabled && !dc_enabled) {
1057 			cy_au += dc_au;
1058 			dc_au = 0;
1059 		} else if (!cy_enabled && dc_enabled) {
1060 			dc_au += cy_au;
1061 			cy_au = 0;
1062 		}
1063 
1064 		val = cy_au;
1065 		snprintf(key,
1066 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1067 			 ADF_NUM_CY_ACCEL_UNITS);
1068 		ret |= adf_cfg_add_key_value_param(
1069 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1070 
1071 		val = dc_au;
1072 		snprintf(key,
1073 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1074 			 ADF_NUM_DC_ACCEL_UNITS);
1075 		ret |= adf_cfg_add_key_value_param(
1076 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1077 
1078 		val = ADF_CFG_STATIC_CONF_NUM_INLINE_ACCEL_UNITS;
1079 		snprintf(key,
1080 			 ADF_CFG_MAX_KEY_LEN_IN_BYTES,
1081 			 ADF_NUM_INLINE_ACCEL_UNITS);
1082 		ret |= adf_cfg_add_key_value_param(
1083 		    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1084 	}
1085 
1086 	val = ADF_CFG_STATIC_CONF_CY_ASYM_RING_SIZE;
1087 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_ASYM_SIZE);
1088 	ret |= adf_cfg_add_key_value_param(
1089 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1090 
1091 	val = ADF_CFG_STATIC_CONF_CY_SYM_RING_SIZE;
1092 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_CY ADF_RING_SYM_SIZE);
1093 	ret |= adf_cfg_add_key_value_param(
1094 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1095 
1096 	val = ADF_CFG_STATIC_CONF_DC_INTER_BUF_SIZE;
1097 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, ADF_INTER_BUF_SIZE);
1098 	ret |= adf_cfg_add_key_value_param(
1099 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1100 
1101 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DC;
1102 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DC);
1103 	ret |= adf_cfg_add_key_value_param(
1104 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1105 
1106 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DH;
1107 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DH);
1108 	ret |= adf_cfg_add_key_value_param(
1109 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1110 
1111 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DRBG;
1112 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DRBG);
1113 	ret |= adf_cfg_add_key_value_param(
1114 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1115 
1116 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_DSA;
1117 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_DSA);
1118 	ret |= adf_cfg_add_key_value_param(
1119 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1120 
1121 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ECC;
1122 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ECC);
1123 	ret |= adf_cfg_add_key_value_param(
1124 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1125 
1126 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_ENABLED;
1127 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_ENABLED);
1128 	ret |= adf_cfg_add_key_value_param(
1129 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1130 
1131 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_KEYGEN;
1132 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_KEYGEN);
1133 	ret |= adf_cfg_add_key_value_param(
1134 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1135 
1136 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_LN;
1137 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_LN);
1138 	ret |= adf_cfg_add_key_value_param(
1139 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1140 
1141 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_PRIME;
1142 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_PRIME);
1143 	ret |= adf_cfg_add_key_value_param(
1144 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1145 
1146 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_RSA;
1147 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_RSA);
1148 	ret |= adf_cfg_add_key_value_param(
1149 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1150 
1151 	val = ADF_CFG_STATIC_CONF_SAL_STATS_CFG_SYM;
1152 	snprintf(key, ADF_CFG_MAX_KEY_LEN_IN_BYTES, SAL_STATS_CFG_SYM);
1153 	ret |= adf_cfg_add_key_value_param(
1154 	    accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC);
1155 
1156 	if (ks_enabled) {
1157 		ret |= adf_cfg_static_conf_kernel(accel_dev,
1158 						  asym_enabled,
1159 						  sym_enabled,
1160 						  dc_enabled);
1161 	}
1162 
1163 	if (us_enabled) {
1164 		ret |=
1165 		    adf_cfg_static_conf_user(accel_dev, cy_enabled, dc_enabled);
1166 	}
1167 
1168 	if (ret)
1169 		ret = ENXIO;
1170 	return ret;
1171 }
1172 
1173 int
adf_config_device(struct adf_accel_dev * accel_dev)1174 adf_config_device(struct adf_accel_dev *accel_dev)
1175 {
1176 	struct adf_cfg_device_data *cfg = NULL;
1177 	struct adf_cfg_device *cfg_device = NULL;
1178 	struct adf_cfg_section *sec;
1179 	struct list_head *list;
1180 	int ret = ENOMEM;
1181 
1182 	if (!accel_dev)
1183 		return ret;
1184 
1185 	ret = adf_cfg_static_conf(accel_dev);
1186 	if (ret)
1187 		goto failed;
1188 
1189 	cfg = accel_dev->cfg;
1190 	cfg->dev = NULL;
1191 	cfg_device = (struct adf_cfg_device *)malloc(sizeof(*cfg_device),
1192 						     M_QAT,
1193 						     M_WAITOK | M_ZERO);
1194 
1195 	ret = EFAULT;
1196 
1197 	if (adf_cfg_device_init(cfg_device, accel_dev))
1198 		goto failed;
1199 
1200 	cfg->dev = cfg_device;
1201 
1202 	/* GENERAL and KERNEL section must be processed before others */
1203 	list_for_each(list, &cfg->sec_list)
1204 	{
1205 		sec = list_entry(list, struct adf_cfg_section, list);
1206 		if (!strcmp(sec->name, ADF_GENERAL_SEC)) {
1207 			ret = adf_cfg_process_section(accel_dev,
1208 						      sec->name,
1209 						      accel_dev->accel_id);
1210 			if (ret)
1211 				goto failed;
1212 			sec->processed = true;
1213 			break;
1214 		}
1215 	}
1216 
1217 	list_for_each(list, &cfg->sec_list)
1218 	{
1219 		sec = list_entry(list, struct adf_cfg_section, list);
1220 		if (!strcmp(sec->name, ADF_KERNEL_SEC)) {
1221 			ret = adf_cfg_process_section(accel_dev,
1222 						      sec->name,
1223 						      accel_dev->accel_id);
1224 			if (ret)
1225 				goto failed;
1226 			sec->processed = true;
1227 			break;
1228 		}
1229 	}
1230 
1231 	list_for_each(list, &cfg->sec_list)
1232 	{
1233 		sec = list_entry(list, struct adf_cfg_section, list);
1234 		if (!strcmp(sec->name, ADF_KERNEL_SAL_SEC)) {
1235 			ret = adf_cfg_process_section(accel_dev,
1236 						      sec->name,
1237 						      accel_dev->accel_id);
1238 			if (ret)
1239 				goto failed;
1240 			sec->processed = true;
1241 			break;
1242 		}
1243 	}
1244 
1245 	list_for_each(list, &cfg->sec_list)
1246 	{
1247 		sec = list_entry(list, struct adf_cfg_section, list);
1248 		/* avoid reprocessing one section */
1249 		if (!sec->processed && !sec->is_derived) {
1250 			ret = adf_cfg_process_section(accel_dev,
1251 						      sec->name,
1252 						      accel_dev->accel_id);
1253 			if (ret)
1254 				goto failed;
1255 			sec->processed = true;
1256 		}
1257 	}
1258 
1259 	/* newly added accel section */
1260 	ret = adf_cfg_process_section(accel_dev,
1261 				      ADF_ACCEL_SEC,
1262 				      accel_dev->accel_id);
1263 	if (ret)
1264 		goto failed;
1265 
1266 	/*
1267 	 * put item-remove task after item-process
1268 	 * because during process we may fetch values from those items
1269 	 */
1270 	list_for_each(list, &cfg->sec_list)
1271 	{
1272 		sec = list_entry(list, struct adf_cfg_section, list);
1273 		if (!sec->is_derived) {
1274 			ret = adf_cfg_cleanup_section(accel_dev,
1275 						      sec->name,
1276 						      accel_dev->accel_id);
1277 			if (ret)
1278 				goto failed;
1279 		}
1280 	}
1281 
1282 	ret = 0;
1283 	set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status);
1284 failed:
1285 	if (ret) {
1286 		if (cfg_device) {
1287 			adf_cfg_device_clear(cfg_device, accel_dev);
1288 			free(cfg_device, M_QAT);
1289 			cfg->dev = NULL;
1290 		}
1291 		adf_cfg_del_all(accel_dev);
1292 		device_printf(GET_DEV(accel_dev), "Failed to config device\n");
1293 	}
1294 
1295 	return ret;
1296 }
1297