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 }
Cache object: 1d8c868a894ff83377d73683c45f784d
|