xref: /freebsd/sys/dev/qat/qat_common/adf_cfg_bundle.c (revision ccb59683b98360afaf5b5bb641a68fea22c68d0b)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "adf_cfg_bundle.h"
5 #include "adf_cfg_strings.h"
6 #include "adf_cfg_instance.h"
7 #include <sys/cpuset.h>
8 
9 static bool
10 adf_cfg_is_interrupt_mode(struct adf_cfg_bundle *bundle)
11 {
12 	return (bundle->polling_mode == ADF_CFG_RESP_EPOLL) ||
13 	    (bundle->type == KERNEL &&
14 	     (bundle->polling_mode != ADF_CFG_RESP_POLL));
15 }
16 
17 static bool
18 adf_cfg_can_be_shared(struct adf_cfg_bundle *bundle,
19 		      const char *process_name,
20 		      int polling_mode)
21 {
22 	if (adf_cfg_is_free(bundle))
23 		return true;
24 
25 	if (bundle->polling_mode != polling_mode)
26 		return false;
27 
28 	return !adf_cfg_is_interrupt_mode(bundle) ||
29 	    !strncmp(process_name,
30 		     bundle->sections[0],
31 		     ADF_CFG_MAX_SECTION_LEN_IN_BYTES);
32 }
33 
34 bool
35 adf_cfg_is_free(struct adf_cfg_bundle *bundle)
36 {
37 	return bundle->type == FREE;
38 }
39 
40 struct adf_cfg_instance *
41 adf_cfg_get_free_instance(struct adf_cfg_device *device,
42 			  struct adf_cfg_bundle *bundle,
43 			  struct adf_cfg_instance *inst,
44 			  const char *process_name)
45 {
46 	int i = 0;
47 	struct adf_cfg_instance *ret_instance = NULL;
48 
49 	if (adf_cfg_can_be_shared(bundle, process_name, inst->polling_mode)) {
50 		for (i = 0; i < device->instance_index; i++) {
51 			/*
52 			 * the selected instance must match two criteria
53 			 * 1) instance is from the bundle
54 			 * 2) instance type is same
55 			 */
56 			if (bundle->number == device->instances[i]->bundle &&
57 			    inst->stype == device->instances[i]->stype) {
58 				ret_instance = device->instances[i];
59 				break;
60 			}
61 			/*
62 			 * no opportunity to match,
63 			 * quit the loop as early as possible
64 			 */
65 			if ((bundle->number + 1) ==
66 			    device->instances[i]->bundle)
67 				break;
68 		}
69 	}
70 
71 	return ret_instance;
72 }
73 
74 int
75 adf_cfg_get_ring_pairs_from_bundle(struct adf_cfg_bundle *bundle,
76 				   struct adf_cfg_instance *inst,
77 				   const char *process_name,
78 				   struct adf_cfg_instance *bundle_inst)
79 {
80 	if (inst->polling_mode == ADF_CFG_RESP_POLL &&
81 	    adf_cfg_is_interrupt_mode(bundle)) {
82 		pr_err("Trying to get ring pairs for a non-interrupt");
83 		pr_err(" bundle from an interrupt bundle\n");
84 		return EFAULT;
85 	}
86 
87 	if (inst->stype != bundle_inst->stype) {
88 		pr_err("Got an instance of different type (cy/dc) than the");
89 		pr_err(" one request\n");
90 		return EFAULT;
91 	}
92 
93 	if (strcmp(ADF_KERNEL_SEC, process_name) &&
94 	    strcmp(ADF_KERNEL_SAL_SEC, process_name) &&
95 	    inst->polling_mode != ADF_CFG_RESP_EPOLL &&
96 	    inst->polling_mode != ADF_CFG_RESP_POLL) {
97 		pr_err("User instance %s needs to be configured", inst->name);
98 		pr_err(" with IsPolled 1 or 2 for poll and epoll mode,");
99 		pr_err(" respectively\n");
100 		return EFAULT;
101 	}
102 
103 	strlcpy(bundle->sections[bundle->section_index],
104 		process_name,
105 		ADF_CFG_MAX_STR_LEN);
106 	bundle->section_index++;
107 
108 	if (adf_cfg_is_free(bundle)) {
109 		bundle->polling_mode = inst->polling_mode;
110 		bundle->type = (!strcmp(ADF_KERNEL_SEC, process_name) ||
111 				!strcmp(ADF_KERNEL_SAL_SEC, process_name)) ?
112 		    KERNEL :
113 		    USER;
114 		if (adf_cfg_is_interrupt_mode(bundle)) {
115 			CPU_ZERO(&bundle->affinity_mask);
116 			CPU_COPY(&inst->affinity_mask, &bundle->affinity_mask);
117 		}
118 	}
119 
120 	switch (inst->stype) {
121 	case CRYPTO:
122 		inst->asym_tx = bundle_inst->asym_tx;
123 		inst->asym_rx = bundle_inst->asym_rx;
124 		inst->sym_tx = bundle_inst->sym_tx;
125 		inst->sym_rx = bundle_inst->sym_rx;
126 		break;
127 	case COMP:
128 		inst->dc_tx = bundle_inst->dc_tx;
129 		inst->dc_rx = bundle_inst->dc_rx;
130 		break;
131 	case ASYM:
132 		inst->asym_tx = bundle_inst->asym_tx;
133 		inst->asym_rx = bundle_inst->asym_rx;
134 		break;
135 	case SYM:
136 		inst->sym_tx = bundle_inst->sym_tx;
137 		inst->sym_rx = bundle_inst->sym_rx;
138 		break;
139 	default:
140 		/* unknown service type of instance */
141 		pr_err("1 Unknown service type %d of instance\n", inst->stype);
142 	}
143 
144 	/* mark it as used */
145 	bundle_inst->stype = USED;
146 
147 	inst->bundle = bundle->number;
148 
149 	return 0;
150 }
151 
152 static void
153 adf_cfg_init_and_insert_inst(struct adf_cfg_bundle *bundle,
154 			     struct adf_cfg_device *device,
155 			     int bank_num,
156 			     struct adf_accel_dev *accel_dev)
157 {
158 	struct adf_cfg_instance *cfg_instance = NULL;
159 	int ring_pair_index = 0;
160 	int ring_index = 0;
161 	int i = 0;
162 	u8 serv_type;
163 	int num_rings_per_srv = 0;
164 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
165 	u16 ring_to_svc_map = GET_HW_DATA(accel_dev)->ring_to_svc_map;
166 
167 	/* init the bundle with instance information */
168 	for (ring_pair_index = 0; ring_pair_index < bundle->max_cfg_svc_num;
169 	     ring_pair_index++) {
170 		adf_get_ring_svc_map_data(hw_data,
171 					  bundle->number,
172 					  ring_pair_index,
173 					  &serv_type,
174 					  &ring_index,
175 					  &num_rings_per_srv);
176 
177 		for (i = 0; i < num_rings_per_srv; i++) {
178 			cfg_instance = malloc(sizeof(*cfg_instance),
179 					      M_QAT,
180 					      M_WAITOK | M_ZERO);
181 
182 			switch (serv_type) {
183 			case CRYPTO:
184 				crypto_instance_init(cfg_instance, bundle);
185 				break;
186 			case COMP:
187 				dc_instance_init(cfg_instance, bundle);
188 				break;
189 			case ASYM:
190 				asym_instance_init(cfg_instance, bundle);
191 				break;
192 			case SYM:
193 				sym_instance_init(cfg_instance, bundle);
194 				break;
195 			case NA:
196 				break;
197 
198 			default:
199 				/* Unknown service type */
200 				device_printf(
201 				    GET_DEV(accel_dev),
202 				    "Unknown service type %d of instance, mask is 0x%x\n",
203 				    serv_type,
204 				    ring_to_svc_map);
205 			}
206 			cfg_instance->bundle = bank_num;
207 			device->instances[device->instance_index++] =
208 			    cfg_instance;
209 			cfg_instance = NULL;
210 		}
211 		if (serv_type == CRYPTO) {
212 			ring_pair_index++;
213 			serv_type =
214 			    GET_SRV_TYPE(ring_to_svc_map, ring_pair_index);
215 		}
216 	}
217 
218 	return;
219 }
220 
221 int
222 adf_cfg_bundle_init(struct adf_cfg_bundle *bundle,
223 		    struct adf_cfg_device *device,
224 		    int bank_num,
225 		    struct adf_accel_dev *accel_dev)
226 {
227 	int i = 0;
228 
229 	bundle->number = bank_num;
230 	/* init ring to service mapping for this bundle */
231 	adf_cfg_init_ring2serv_mapping(accel_dev, bundle, device);
232 
233 	/* init the bundle with instance information */
234 	adf_cfg_init_and_insert_inst(bundle, device, bank_num, accel_dev);
235 
236 	CPU_FILL(&bundle->affinity_mask);
237 	bundle->type = FREE;
238 	bundle->polling_mode = -1;
239 	bundle->section_index = 0;
240 
241 	bundle->sections = malloc(sizeof(char *) * bundle->max_section,
242 				  M_QAT,
243 				  M_WAITOK | M_ZERO);
244 
245 	for (i = 0; i < bundle->max_section; i++) {
246 		bundle->sections[i] =
247 		    malloc(ADF_CFG_MAX_STR_LEN, M_QAT, M_WAITOK | M_ZERO);
248 	}
249 	return 0;
250 }
251 
252 void
253 adf_cfg_bundle_clear(struct adf_cfg_bundle *bundle,
254 		     struct adf_accel_dev *accel_dev)
255 {
256 	int i = 0;
257 
258 	for (i = 0; i < bundle->max_section; i++) {
259 		if (bundle->sections && bundle->sections[i]) {
260 			free(bundle->sections[i], M_QAT);
261 			bundle->sections[i] = NULL;
262 		}
263 	}
264 
265 	free(bundle->sections, M_QAT);
266 	bundle->sections = NULL;
267 
268 	adf_cfg_rel_ring2serv_mapping(bundle);
269 }
270 
271 static void
272 adf_cfg_assign_serv_to_rings(struct adf_hw_device_data *hw_data,
273 			     struct adf_cfg_bundle *bundle,
274 			     struct adf_cfg_device *device)
275 {
276 	int ring_pair_index = 0;
277 	int ring_index = 0;
278 	u8 serv_type = 0;
279 	int num_req_rings = bundle->num_of_rings / 2;
280 	int num_rings_per_srv = 0;
281 
282 	for (ring_pair_index = 0; ring_pair_index < bundle->max_cfg_svc_num;
283 	     ring_pair_index++) {
284 		adf_get_ring_svc_map_data(hw_data,
285 					  bundle->number,
286 					  ring_pair_index,
287 					  &serv_type,
288 					  &ring_index,
289 					  &num_rings_per_srv);
290 
291 		switch (serv_type) {
292 		case CRYPTO:
293 			ASSIGN_SERV_TO_RINGS(bundle,
294 					     ring_index,
295 					     num_req_rings,
296 					     ADF_ACCEL_SERV_ASYM,
297 					     num_rings_per_srv);
298 			ring_pair_index++;
299 			ring_index = num_rings_per_srv * ring_pair_index;
300 			if (ring_pair_index == bundle->max_cfg_svc_num)
301 				break;
302 			ASSIGN_SERV_TO_RINGS(bundle,
303 					     ring_index,
304 					     num_req_rings,
305 					     ADF_ACCEL_SERV_SYM,
306 					     num_rings_per_srv);
307 			break;
308 		case COMP:
309 			ASSIGN_SERV_TO_RINGS(bundle,
310 					     ring_index,
311 					     num_req_rings,
312 					     ADF_ACCEL_SERV_DC,
313 					     num_rings_per_srv);
314 			break;
315 		case SYM:
316 			ASSIGN_SERV_TO_RINGS(bundle,
317 					     ring_index,
318 					     num_req_rings,
319 					     ADF_ACCEL_SERV_SYM,
320 					     num_rings_per_srv);
321 			break;
322 		case ASYM:
323 			ASSIGN_SERV_TO_RINGS(bundle,
324 					     ring_index,
325 					     num_req_rings,
326 					     ADF_ACCEL_SERV_ASYM,
327 					     num_rings_per_srv);
328 			break;
329 		case NA:
330 			ASSIGN_SERV_TO_RINGS(bundle,
331 					     ring_index,
332 					     num_req_rings,
333 					     ADF_ACCEL_SERV_NA,
334 					     num_rings_per_srv);
335 			break;
336 
337 		default:
338 			/* unknown service type */
339 			pr_err("Unknown service type %d, mask 0x%x.\n",
340 			       serv_type,
341 			       hw_data->ring_to_svc_map);
342 		}
343 	}
344 
345 	return;
346 }
347 
348 void
349 adf_cfg_init_ring2serv_mapping(struct adf_accel_dev *accel_dev,
350 			       struct adf_cfg_bundle *bundle,
351 			       struct adf_cfg_device *device)
352 {
353 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
354 	struct adf_cfg_ring *ring_in_bundle;
355 	int ring_num = 0;
356 
357 	bundle->num_of_rings = hw_data->num_rings_per_bank;
358 	if (hw_data->num_rings_per_bank >= (2 * ADF_CFG_NUM_SERVICES))
359 		bundle->max_cfg_svc_num = ADF_CFG_NUM_SERVICES;
360 	else
361 		bundle->max_cfg_svc_num = 1;
362 
363 	bundle->rings =
364 	    malloc(bundle->num_of_rings * sizeof(struct adf_cfg_ring *),
365 		   M_QAT,
366 		   M_WAITOK | M_ZERO);
367 
368 	for (ring_num = 0; ring_num < bundle->num_of_rings; ring_num++) {
369 		ring_in_bundle = malloc(sizeof(struct adf_cfg_ring),
370 					M_QAT,
371 					M_WAITOK | M_ZERO);
372 		ring_in_bundle->mode =
373 		    (ring_num < bundle->num_of_rings / 2) ? TX : RX;
374 		ring_in_bundle->number = ring_num;
375 		bundle->rings[ring_num] = ring_in_bundle;
376 	}
377 
378 	adf_cfg_assign_serv_to_rings(hw_data, bundle, device);
379 
380 	return;
381 }
382 
383 int
384 adf_cfg_rel_ring2serv_mapping(struct adf_cfg_bundle *bundle)
385 {
386 	int i = 0;
387 
388 	if (bundle->rings) {
389 		for (i = 0; i < bundle->num_of_rings; i++)
390 			free(bundle->rings[i], M_QAT);
391 
392 		free(bundle->rings, M_QAT);
393 	}
394 
395 	return 0;
396 }
397