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