1// SPDX-License-Identifier: GPL-2.0-only
2/* Copyright(c) 2023 Intel Corporation */
3
4#define dev_fmt(fmt) "RateLimiting: " fmt
5
6#include <linux/dev_printk.h>
7#include <linux/pci.h>
8#include <linux/sysfs.h>
9#include <linux/types.h>
10
11#include "adf_common_drv.h"
12#include "adf_rl.h"
13#include "adf_sysfs_rl.h"
14
15#define GET_RL_STRUCT(accel_dev) ((accel_dev)->rate_limiting->user_input)
16
17enum rl_ops {
18 ADD,
19 UPDATE,
20 RM,
21 RM_ALL,
22 GET,
23};
24
25enum rl_params {
26 RP_MASK,
27 ID,
28 CIR,
29 PIR,
30 SRV,
31 CAP_REM_SRV,
32};
33
34static const char *const rl_services[] = {
35 [SVC_ASYM] = "asym",
36 [SVC_SYM] = "sym",
37 [SVC_DC] = "dc",
38 [SVC_DECOMP] = "decomp",
39};
40
41static const char *const rl_operations[] = {
42 [ADD] = "add",
43 [UPDATE] = "update",
44 [RM] = "rm",
45 [RM_ALL] = "rm_all",
46 [GET] = "get",
47};
48
49static int set_param_u(struct device *dev, enum rl_params param, u64 set)
50{
51 struct adf_rl_interface_data *data;
52 struct adf_accel_dev *accel_dev;
53 int ret = 0;
54
55 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
56 if (!accel_dev)
57 return -EINVAL;
58
59 data = &GET_RL_STRUCT(accel_dev);
60
61 down_write(sem: &data->lock);
62 switch (param) {
63 case RP_MASK:
64 data->input.rp_mask = set;
65 break;
66 case CIR:
67 data->input.cir = set;
68 break;
69 case PIR:
70 data->input.pir = set;
71 break;
72 case SRV:
73 data->input.srv = set;
74 break;
75 case CAP_REM_SRV:
76 data->cap_rem_srv = set;
77 break;
78 default:
79 ret = -EINVAL;
80 break;
81 }
82 up_write(sem: &data->lock);
83
84 return ret;
85}
86
87static int set_param_s(struct device *dev, enum rl_params param, int set)
88{
89 struct adf_rl_interface_data *data;
90 struct adf_accel_dev *accel_dev;
91
92 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
93 if (!accel_dev || param != ID)
94 return -EINVAL;
95
96 data = &GET_RL_STRUCT(accel_dev);
97
98 down_write(sem: &data->lock);
99 data->input.sla_id = set;
100 up_write(sem: &data->lock);
101
102 return 0;
103}
104
105static int get_param_u(struct device *dev, enum rl_params param, u64 *get)
106{
107 struct adf_rl_interface_data *data;
108 struct adf_accel_dev *accel_dev;
109 int ret = 0;
110
111 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
112 if (!accel_dev)
113 return -EINVAL;
114
115 data = &GET_RL_STRUCT(accel_dev);
116
117 down_read(sem: &data->lock);
118 switch (param) {
119 case RP_MASK:
120 *get = data->input.rp_mask;
121 break;
122 case CIR:
123 *get = data->input.cir;
124 break;
125 case PIR:
126 *get = data->input.pir;
127 break;
128 case SRV:
129 *get = data->input.srv;
130 break;
131 default:
132 ret = -EINVAL;
133 }
134 up_read(sem: &data->lock);
135
136 return ret;
137}
138
139static int get_param_s(struct device *dev, enum rl_params param)
140{
141 struct adf_rl_interface_data *data;
142 struct adf_accel_dev *accel_dev;
143 int ret = 0;
144
145 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
146 if (!accel_dev)
147 return -EINVAL;
148
149 data = &GET_RL_STRUCT(accel_dev);
150
151 down_read(sem: &data->lock);
152 if (param == ID)
153 ret = data->input.sla_id;
154 up_read(sem: &data->lock);
155
156 return ret;
157}
158
159static ssize_t rp_show(struct device *dev, struct device_attribute *attr,
160 char *buf)
161{
162 int ret;
163 u64 get;
164
165 ret = get_param_u(dev, param: RP_MASK, get: &get);
166 if (ret)
167 return ret;
168
169 return sysfs_emit(buf, fmt: "%#llx\n", get);
170}
171
172static ssize_t rp_store(struct device *dev, struct device_attribute *attr,
173 const char *buf, size_t count)
174{
175 int err;
176 u64 val;
177
178 err = kstrtou64(s: buf, base: 16, res: &val);
179 if (err)
180 return err;
181
182 err = set_param_u(dev, param: RP_MASK, set: val);
183 if (err)
184 return err;
185
186 return count;
187}
188static DEVICE_ATTR_RW(rp);
189
190static ssize_t id_show(struct device *dev, struct device_attribute *attr,
191 char *buf)
192{
193 return sysfs_emit(buf, fmt: "%d\n", get_param_s(dev, param: ID));
194}
195
196static ssize_t id_store(struct device *dev, struct device_attribute *attr,
197 const char *buf, size_t count)
198{
199 int err;
200 int val;
201
202 err = kstrtoint(s: buf, base: 10, res: &val);
203 if (err)
204 return err;
205
206 err = set_param_s(dev, param: ID, set: val);
207 if (err)
208 return err;
209
210 return count;
211}
212static DEVICE_ATTR_RW(id);
213
214static ssize_t cir_show(struct device *dev, struct device_attribute *attr,
215 char *buf)
216{
217 int ret;
218 u64 get;
219
220 ret = get_param_u(dev, param: CIR, get: &get);
221 if (ret)
222 return ret;
223
224 return sysfs_emit(buf, fmt: "%llu\n", get);
225}
226
227static ssize_t cir_store(struct device *dev, struct device_attribute *attr,
228 const char *buf, size_t count)
229{
230 unsigned int val;
231 int err;
232
233 err = kstrtouint(s: buf, base: 10, res: &val);
234 if (err)
235 return err;
236
237 err = set_param_u(dev, param: CIR, set: val);
238 if (err)
239 return err;
240
241 return count;
242}
243static DEVICE_ATTR_RW(cir);
244
245static ssize_t pir_show(struct device *dev, struct device_attribute *attr,
246 char *buf)
247{
248 int ret;
249 u64 get;
250
251 ret = get_param_u(dev, param: PIR, get: &get);
252 if (ret)
253 return ret;
254
255 return sysfs_emit(buf, fmt: "%llu\n", get);
256}
257
258static ssize_t pir_store(struct device *dev, struct device_attribute *attr,
259 const char *buf, size_t count)
260{
261 unsigned int val;
262 int err;
263
264 err = kstrtouint(s: buf, base: 10, res: &val);
265 if (err)
266 return err;
267
268 err = set_param_u(dev, param: PIR, set: val);
269 if (err)
270 return err;
271
272 return count;
273}
274static DEVICE_ATTR_RW(pir);
275
276static ssize_t srv_show(struct device *dev, struct device_attribute *attr,
277 char *buf)
278{
279 int ret;
280 u64 get;
281
282 ret = get_param_u(dev, param: SRV, get: &get);
283 if (ret)
284 return ret;
285
286 if (get == SVC_BASE_COUNT)
287 return -EINVAL;
288
289 return sysfs_emit(buf, fmt: "%s\n", rl_services[get]);
290}
291
292static ssize_t srv_store(struct device *dev, struct device_attribute *attr,
293 const char *buf, size_t count)
294{
295 struct adf_accel_dev *accel_dev;
296 unsigned int val;
297 int ret;
298
299 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
300 if (!accel_dev)
301 return -EINVAL;
302
303 ret = sysfs_match_string(rl_services, buf);
304 if (ret < 0)
305 return ret;
306
307 val = ret;
308 if (!adf_is_service_enabled(accel_dev, svc: val))
309 return -EINVAL;
310
311 ret = set_param_u(dev, param: SRV, set: val);
312 if (ret)
313 return ret;
314
315 return count;
316}
317static DEVICE_ATTR_RW(srv);
318
319static ssize_t cap_rem_show(struct device *dev, struct device_attribute *attr,
320 char *buf)
321{
322 struct adf_rl_interface_data *data;
323 struct adf_accel_dev *accel_dev;
324 int ret, rem_cap;
325
326 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
327 if (!accel_dev)
328 return -EINVAL;
329
330 data = &GET_RL_STRUCT(accel_dev);
331
332 down_read(sem: &data->lock);
333 rem_cap = adf_rl_get_capability_remaining(accel_dev, srv: data->cap_rem_srv,
334 RL_SLA_EMPTY_ID);
335 up_read(sem: &data->lock);
336 if (rem_cap < 0)
337 return rem_cap;
338
339 ret = sysfs_emit(buf, fmt: "%u\n", rem_cap);
340
341 return ret;
342}
343
344static ssize_t cap_rem_store(struct device *dev, struct device_attribute *attr,
345 const char *buf, size_t count)
346{
347 unsigned int val;
348 int ret;
349
350 ret = sysfs_match_string(rl_services, buf);
351 if (ret < 0)
352 return ret;
353
354 val = ret;
355 ret = set_param_u(dev, param: CAP_REM_SRV, set: val);
356 if (ret)
357 return ret;
358
359 return count;
360}
361static DEVICE_ATTR_RW(cap_rem);
362
363static ssize_t sla_op_store(struct device *dev, struct device_attribute *attr,
364 const char *buf, size_t count)
365{
366 struct adf_rl_interface_data *data;
367 struct adf_accel_dev *accel_dev;
368 int ret;
369
370 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
371 if (!accel_dev)
372 return -EINVAL;
373
374 data = &GET_RL_STRUCT(accel_dev);
375
376 ret = sysfs_match_string(rl_operations, buf);
377 if (ret < 0)
378 return ret;
379
380 down_write(sem: &data->lock);
381 switch (ret) {
382 case ADD:
383 data->input.parent_id = RL_PARENT_DEFAULT_ID;
384 data->input.type = RL_LEAF;
385 data->input.sla_id = 0;
386 ret = adf_rl_add_sla(accel_dev, sla_in: &data->input);
387 if (ret)
388 goto err_free_lock;
389 break;
390 case UPDATE:
391 ret = adf_rl_update_sla(accel_dev, sla_in: &data->input);
392 if (ret)
393 goto err_free_lock;
394 break;
395 case RM:
396 ret = adf_rl_remove_sla(accel_dev, sla_id: data->input.sla_id);
397 if (ret)
398 goto err_free_lock;
399 break;
400 case RM_ALL:
401 adf_rl_remove_sla_all(accel_dev, incl_default: false);
402 break;
403 case GET:
404 ret = adf_rl_get_sla(accel_dev, sla_in: &data->input);
405 if (ret)
406 goto err_free_lock;
407 break;
408 default:
409 ret = -EINVAL;
410 goto err_free_lock;
411 }
412 up_write(sem: &data->lock);
413
414 return count;
415
416err_free_lock:
417 up_write(sem: &data->lock);
418
419 return ret;
420}
421static DEVICE_ATTR_WO(sla_op);
422
423static struct attribute *qat_rl_attrs[] = {
424 &dev_attr_rp.attr,
425 &dev_attr_id.attr,
426 &dev_attr_cir.attr,
427 &dev_attr_pir.attr,
428 &dev_attr_srv.attr,
429 &dev_attr_cap_rem.attr,
430 &dev_attr_sla_op.attr,
431 NULL,
432};
433
434static struct attribute_group qat_rl_group = {
435 .attrs = qat_rl_attrs,
436 .name = "qat_rl",
437};
438
439int adf_sysfs_rl_add(struct adf_accel_dev *accel_dev)
440{
441 struct adf_rl_interface_data *data;
442 int ret;
443
444 data = &GET_RL_STRUCT(accel_dev);
445
446 ret = device_add_group(dev: &GET_DEV(accel_dev), grp: &qat_rl_group);
447 if (ret)
448 dev_err(&GET_DEV(accel_dev),
449 "Failed to create qat_rl attribute group\n");
450
451 data->cap_rem_srv = SVC_BASE_COUNT;
452 data->input.srv = SVC_BASE_COUNT;
453 data->sysfs_added = true;
454
455 return ret;
456}
457
458void adf_sysfs_rl_rm(struct adf_accel_dev *accel_dev)
459{
460 struct adf_rl_interface_data *data;
461
462 data = &GET_RL_STRUCT(accel_dev);
463 if (!data->sysfs_added)
464 return;
465
466 device_remove_group(dev: &GET_DEV(accel_dev), grp: &qat_rl_group);
467 data->sysfs_added = false;
468}
469

source code of linux/drivers/crypto/intel/qat/qat_common/adf_sysfs_rl.c