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