xref: /freebsd/sys/dev/qat/qat_common/adf_cfg_bundle.c (revision 38a52bd3b5cac3da6f7f6eef3dd050e6aa08ebb3)
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 i = 0;
161 	u8 serv_type;
162 	int num_req_rings = bundle->num_of_rings / 2;
163 	int num_rings_per_srv = num_req_rings / ADF_CFG_NUM_SERVICES;
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 < ADF_CFG_NUM_SERVICES;
168 	     ring_pair_index++) {
169 		serv_type = GET_SRV_TYPE(ring_to_svc_map, ring_pair_index);
170 		for (i = 0; i < num_rings_per_srv; i++) {
171 			cfg_instance = malloc(sizeof(*cfg_instance),
172 					      M_QAT,
173 					      M_WAITOK | M_ZERO);
174 
175 			switch (serv_type) {
176 			case CRYPTO:
177 				crypto_instance_init(cfg_instance, bundle);
178 				break;
179 			case COMP:
180 				dc_instance_init(cfg_instance, bundle);
181 				break;
182 			case ASYM:
183 				asym_instance_init(cfg_instance, bundle);
184 				break;
185 			case SYM:
186 				sym_instance_init(cfg_instance, bundle);
187 				break;
188 			case NA:
189 				break;
190 
191 			default:
192 				/* Unknown service type */
193 				device_printf(
194 				    GET_DEV(accel_dev),
195 				    "Unknown service type %d of instance, mask is 0x%x\n",
196 				    serv_type,
197 				    ring_to_svc_map);
198 			}
199 			cfg_instance->bundle = bank_num;
200 			device->instances[device->instance_index++] =
201 			    cfg_instance;
202 			cfg_instance = NULL;
203 		}
204 		if (serv_type == CRYPTO) {
205 			ring_pair_index++;
206 			serv_type =
207 			    GET_SRV_TYPE(ring_to_svc_map, ring_pair_index);
208 		}
209 	}
210 
211 	return;
212 }
213 
214 int
215 adf_cfg_bundle_init(struct adf_cfg_bundle *bundle,
216 		    struct adf_cfg_device *device,
217 		    int bank_num,
218 		    struct adf_accel_dev *accel_dev)
219 {
220 	int i = 0;
221 
222 	/* init ring to service mapping for this bundle */
223 	adf_cfg_init_ring2serv_mapping(accel_dev, bundle);
224 
225 	/* init the bundle with instance information */
226 	adf_cfg_init_and_insert_inst(bundle, device, bank_num, accel_dev);
227 
228 	CPU_FILL(&bundle->affinity_mask);
229 	bundle->type = FREE;
230 	bundle->polling_mode = -1;
231 	bundle->section_index = 0;
232 	bundle->number = bank_num;
233 
234 	bundle->sections = malloc(sizeof(char *) * bundle->max_section,
235 				  M_QAT,
236 				  M_WAITOK | M_ZERO);
237 
238 	for (i = 0; i < bundle->max_section; i++) {
239 		bundle->sections[i] =
240 		    malloc(ADF_CFG_MAX_STR_LEN, M_QAT, M_WAITOK | M_ZERO);
241 	}
242 	return 0;
243 }
244 
245 void
246 adf_cfg_bundle_clear(struct adf_cfg_bundle *bundle,
247 		     struct adf_accel_dev *accel_dev)
248 {
249 	int i = 0;
250 
251 	for (i = 0; i < bundle->max_section; i++) {
252 		if (bundle->sections && bundle->sections[i]) {
253 			free(bundle->sections[i], M_QAT);
254 			bundle->sections[i] = NULL;
255 		}
256 	}
257 
258 	free(bundle->sections, M_QAT);
259 	bundle->sections = NULL;
260 
261 	adf_cfg_rel_ring2serv_mapping(bundle);
262 }
263 
264 static void
265 adf_cfg_assign_serv_to_rings(struct adf_cfg_bundle *bundle, u16 ring_to_svc_map)
266 {
267 	int ring_pair_index = 0;
268 	int ring_index = 0;
269 	u8 serv_type = 0;
270 	int num_req_rings = bundle->num_of_rings / 2;
271 	int num_rings_per_srv = num_req_rings / ADF_CFG_NUM_SERVICES;
272 
273 	for (ring_pair_index = 0; ring_pair_index < ADF_CFG_NUM_SERVICES;
274 	     ring_pair_index++) {
275 		serv_type = GET_SRV_TYPE(ring_to_svc_map, ring_pair_index);
276 		ring_index = num_rings_per_srv * ring_pair_index;
277 		switch (serv_type) {
278 		case CRYPTO:
279 			ASSIGN_SERV_TO_RINGS(bundle,
280 					     ring_index,
281 					     num_req_rings,
282 					     ADF_ACCEL_SERV_ASYM,
283 					     num_rings_per_srv);
284 			ring_pair_index++;
285 			ring_index = num_rings_per_srv * ring_pair_index;
286 			if (ring_pair_index == ADF_CFG_NUM_SERVICES)
287 				break;
288 			ASSIGN_SERV_TO_RINGS(bundle,
289 					     ring_index,
290 					     num_req_rings,
291 					     ADF_ACCEL_SERV_SYM,
292 					     num_rings_per_srv);
293 			break;
294 		case COMP:
295 			ASSIGN_SERV_TO_RINGS(bundle,
296 					     ring_index,
297 					     num_req_rings,
298 					     ADF_ACCEL_SERV_DC,
299 					     num_rings_per_srv);
300 			break;
301 		case SYM:
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 ASYM:
309 			ASSIGN_SERV_TO_RINGS(bundle,
310 					     ring_index,
311 					     num_req_rings,
312 					     ADF_ACCEL_SERV_ASYM,
313 					     num_rings_per_srv);
314 			break;
315 		case NA:
316 			ASSIGN_SERV_TO_RINGS(bundle,
317 					     ring_index,
318 					     num_req_rings,
319 					     ADF_ACCEL_SERV_NA,
320 					     num_rings_per_srv);
321 			break;
322 
323 		default:
324 			/* unknown service type */
325 			pr_err("Unknown service type %d, mask 0x%x.\n",
326 			       serv_type,
327 			       ring_to_svc_map);
328 		}
329 	}
330 
331 	return;
332 }
333 
334 void
335 adf_cfg_init_ring2serv_mapping(struct adf_accel_dev *accel_dev,
336 			       struct adf_cfg_bundle *bundle)
337 {
338 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
339 	struct adf_cfg_ring *ring_in_bundle;
340 	int ring_num = 0;
341 
342 	bundle->num_of_rings = hw_data->num_rings_per_bank;
343 
344 	bundle->rings =
345 	    malloc(bundle->num_of_rings * sizeof(struct adf_cfg_ring *),
346 		   M_QAT,
347 		   M_WAITOK | M_ZERO);
348 
349 	for (ring_num = 0; ring_num < bundle->num_of_rings; ring_num++) {
350 		ring_in_bundle = malloc(sizeof(struct adf_cfg_ring),
351 					M_QAT,
352 					M_WAITOK | M_ZERO);
353 		ring_in_bundle->mode =
354 		    (ring_num < bundle->num_of_rings / 2) ? TX : RX;
355 		ring_in_bundle->number = ring_num;
356 		bundle->rings[ring_num] = ring_in_bundle;
357 	}
358 
359 	adf_cfg_assign_serv_to_rings(bundle, hw_data->ring_to_svc_map);
360 
361 	return;
362 }
363 
364 int
365 adf_cfg_rel_ring2serv_mapping(struct adf_cfg_bundle *bundle)
366 {
367 	int i = 0;
368 
369 	if (bundle->rings) {
370 		for (i = 0; i < bundle->num_of_rings; i++)
371 			free(bundle->rings[i], M_QAT);
372 
373 		free(bundle->rings, M_QAT);
374 	}
375 
376 	return 0;
377 }
378