File Index
Files and directories
Sign in
FILE

adf_sysfs_rl.c

File preview with syntax highlighting.

linux-6.19.14/drivers/crypto/intel/qat/qat_common/adf_sysfs_rl.c C
  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(&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(&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(&data->lock);
 99	data->input.sla_id = set;
100	up_write(&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(&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(&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(&data->lock);
152	if (param == ID)
153		ret = data->input.sla_id;
154	up_read(&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, RP_MASK, &get);
166	if (ret)
167		return ret;
168
169	return sysfs_emit(buf, "%#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(buf, 16, &val);
179	if (err)
180		return err;
181
182	err = set_param_u(dev, RP_MASK, 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, "%d\n", get_param_s(dev, 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(buf, 10, &val);
203	if (err)
204		return err;
205
206	err = set_param_s(dev, ID, 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, CIR, &get);
221	if (ret)
222		return ret;
223
224	return sysfs_emit(buf, "%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(buf, 10, &val);
234	if (err)
235		return err;
236
237	err = set_param_u(dev, CIR, 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, PIR, &get);
252	if (ret)
253		return ret;
254
255	return sysfs_emit(buf, "%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(buf, 10, &val);
265	if (err)
266		return err;
267
268	err = set_param_u(dev, PIR, 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, SRV, &get);
283	if (ret)
284		return ret;
285
286	if (get == SVC_BASE_COUNT)
287		return -EINVAL;
288
289	return sysfs_emit(buf, "%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, val))
309		return -EINVAL;
310
311	ret = set_param_u(dev, SRV, 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(&data->lock);
333	rem_cap = adf_rl_get_capability_remaining(accel_dev, data->cap_rem_srv,
334						  RL_SLA_EMPTY_ID);
335	up_read(&data->lock);
336	if (rem_cap < 0)
337		return rem_cap;
338
339	ret = sysfs_emit(buf, "%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, CAP_REM_SRV, 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(&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, &data->input);
387		if (ret)
388			goto err_free_lock;
389		break;
390	case UPDATE:
391		ret = adf_rl_update_sla(accel_dev, &data->input);
392		if (ret)
393			goto err_free_lock;
394		break;
395	case RM:
396		ret = adf_rl_remove_sla(accel_dev, 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, false);
402		break;
403	case GET:
404		ret = adf_rl_get_sla(accel_dev, &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(&data->lock);
413
414	return count;
415
416err_free_lock:
417	up_write(&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(&GET_DEV(accel_dev), &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(&GET_DEV(accel_dev), &qat_rl_group);
467	data->sysfs_added = false;
468}
~/ Read-only file preview.