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
adf_cfg_is_interrupt_mode(struct adf_cfg_bundle * bundle)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
adf_cfg_can_be_shared(struct adf_cfg_bundle * bundle,const char * process_name,int polling_mode)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
adf_cfg_is_free(struct adf_cfg_bundle * bundle)34 adf_cfg_is_free(struct adf_cfg_bundle *bundle)
35 {
36 return bundle->type == FREE;
37 }
38
39 struct adf_cfg_instance *
adf_cfg_get_free_instance(struct adf_cfg_device * device,struct adf_cfg_bundle * bundle,struct adf_cfg_instance * inst,const char * process_name)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
adf_cfg_get_ring_pairs_from_bundle(struct adf_cfg_bundle * bundle,struct adf_cfg_instance * inst,const char * process_name,struct adf_cfg_instance * bundle_inst)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
adf_cfg_init_and_insert_inst(struct adf_cfg_bundle * bundle,struct adf_cfg_device * device,int bank_num,struct adf_accel_dev * accel_dev)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
adf_cfg_bundle_init(struct adf_cfg_bundle * bundle,struct adf_cfg_device * device,int bank_num,struct adf_accel_dev * accel_dev)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
adf_cfg_bundle_clear(struct adf_cfg_bundle * bundle,struct adf_accel_dev * accel_dev)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
adf_cfg_assign_serv_to_rings(struct adf_hw_device_data * hw_data,struct adf_cfg_bundle * bundle,struct adf_cfg_device * device)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
adf_cfg_init_ring2serv_mapping(struct adf_accel_dev * accel_dev,struct adf_cfg_bundle * bundle,struct adf_cfg_device * device)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
adf_cfg_rel_ring2serv_mapping(struct adf_cfg_bundle * bundle)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