1// SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2/* Copyright(c) 2022 Intel Corporation */
3#include <linux/device.h>
4#include <linux/errno.h>
5#include <linux/pci.h>
6#include <linux/string_choices.h>
7#include "adf_accel_devices.h"
8#include "adf_cfg.h"
9#include "adf_cfg_services.h"
10#include "adf_common_drv.h"
11
12#define UNSET_RING_NUM -1
13
14static const char * const state_operations[] = {
15 [DEV_DOWN] = "down",
16 [DEV_UP] = "up",
17};
18
19static ssize_t state_show(struct device *dev, struct device_attribute *attr,
20 char *buf)
21{
22 struct adf_accel_dev *accel_dev;
23
24 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
25 if (!accel_dev)
26 return -EINVAL;
27
28 return sysfs_emit(buf, fmt: "%s\n", str_up_down(v: adf_dev_started(accel_dev)));
29}
30
31static ssize_t state_store(struct device *dev, struct device_attribute *attr,
32 const char *buf, size_t count)
33{
34 struct adf_accel_dev *accel_dev;
35 u32 accel_id;
36 int ret;
37
38 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
39 if (!accel_dev)
40 return -EINVAL;
41
42 accel_id = accel_dev->accel_id;
43
44 if (adf_devmgr_in_reset(accel_dev) || adf_dev_in_use(accel_dev)) {
45 dev_info(dev, "Device qat_dev%d is busy\n", accel_id);
46 return -EBUSY;
47 }
48
49 ret = sysfs_match_string(state_operations, buf);
50 if (ret < 0)
51 return ret;
52
53 switch (ret) {
54 case DEV_DOWN:
55 dev_info(dev, "Stopping device qat_dev%d\n", accel_id);
56
57 if (!adf_dev_started(accel_dev)) {
58 dev_info(&GET_DEV(accel_dev), "Device qat_dev%d already down\n",
59 accel_id);
60
61 break;
62 }
63
64 ret = adf_dev_down(accel_dev);
65 if (ret)
66 return ret;
67
68 break;
69 case DEV_UP:
70 dev_info(dev, "Starting device qat_dev%d\n", accel_id);
71
72 ret = adf_dev_up(accel_dev, init_config: true);
73 if (ret == -EALREADY) {
74 break;
75 } else if (ret) {
76 dev_err(dev, "Failed to start device qat_dev%d\n",
77 accel_id);
78 adf_dev_down(accel_dev);
79 return ret;
80 }
81 break;
82 default:
83 return -EINVAL;
84 }
85
86 return count;
87}
88
89static ssize_t cfg_services_show(struct device *dev, struct device_attribute *attr,
90 char *buf)
91{
92 char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {0};
93 struct adf_accel_dev *accel_dev;
94 int ret;
95
96 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
97 if (!accel_dev)
98 return -EINVAL;
99
100 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
101 ADF_SERVICES_ENABLED, value: services);
102 if (ret)
103 return ret;
104
105 return sysfs_emit(buf, fmt: "%s\n", services);
106}
107
108static int adf_sysfs_update_dev_config(struct adf_accel_dev *accel_dev,
109 const char *services)
110{
111 return adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,
112 ADF_SERVICES_ENABLED, val: services,
113 type: ADF_STR);
114}
115
116static ssize_t cfg_services_store(struct device *dev, struct device_attribute *attr,
117 const char *buf, size_t count)
118{
119 char services[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { };
120 struct adf_hw_device_data *hw_data;
121 struct adf_accel_dev *accel_dev;
122 int ret;
123
124 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
125 if (!accel_dev)
126 return -EINVAL;
127
128 ret = adf_parse_service_string(accel_dev, in: buf, in_len: count, out: services,
129 ADF_CFG_MAX_VAL_LEN_IN_BYTES);
130 if (ret)
131 return ret;
132
133 if (adf_dev_started(accel_dev)) {
134 dev_info(dev, "Device qat_dev%d must be down to reconfigure the service.\n",
135 accel_dev->accel_id);
136 return -EINVAL;
137 }
138
139 ret = adf_sysfs_update_dev_config(accel_dev, services);
140 if (ret < 0)
141 return ret;
142
143 hw_data = GET_HW_DATA(accel_dev);
144
145 /* Update capabilities mask after change in configuration.
146 * A call to this function is required as capabilities are, at the
147 * moment, tied to configuration
148 */
149 hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
150 if (!hw_data->accel_capabilities_mask)
151 return -EINVAL;
152
153 return count;
154}
155
156static ssize_t pm_idle_enabled_show(struct device *dev, struct device_attribute *attr,
157 char *buf)
158{
159 char pm_idle_enabled[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = {};
160 struct adf_accel_dev *accel_dev;
161 int ret;
162
163 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
164 if (!accel_dev)
165 return -EINVAL;
166
167 ret = adf_cfg_get_param_value(accel_dev, ADF_GENERAL_SEC,
168 ADF_PM_IDLE_SUPPORT, value: pm_idle_enabled);
169 if (ret)
170 return sysfs_emit(buf, fmt: "1\n");
171
172 return sysfs_emit(buf, fmt: "%s\n", pm_idle_enabled);
173}
174
175static ssize_t pm_idle_enabled_store(struct device *dev, struct device_attribute *attr,
176 const char *buf, size_t count)
177{
178 unsigned long pm_idle_enabled_cfg_val;
179 struct adf_accel_dev *accel_dev;
180 bool pm_idle_enabled;
181 int ret;
182
183 ret = kstrtobool(s: buf, res: &pm_idle_enabled);
184 if (ret)
185 return ret;
186
187 pm_idle_enabled_cfg_val = pm_idle_enabled;
188 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
189 if (!accel_dev)
190 return -EINVAL;
191
192 if (adf_dev_started(accel_dev)) {
193 dev_info(dev, "Device qat_dev%d must be down to set pm_idle_enabled.\n",
194 accel_dev->accel_id);
195 return -EINVAL;
196 }
197
198 ret = adf_cfg_add_key_value_param(accel_dev, ADF_GENERAL_SEC,
199 ADF_PM_IDLE_SUPPORT, val: &pm_idle_enabled_cfg_val,
200 type: ADF_DEC);
201 if (ret)
202 return ret;
203
204 return count;
205}
206static DEVICE_ATTR_RW(pm_idle_enabled);
207
208static ssize_t auto_reset_show(struct device *dev, struct device_attribute *attr,
209 char *buf)
210{
211 struct adf_accel_dev *accel_dev;
212
213 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
214 if (!accel_dev)
215 return -EINVAL;
216
217 return sysfs_emit(buf, fmt: "%s\n", str_on_off(v: accel_dev->autoreset_on_error));
218}
219
220static ssize_t auto_reset_store(struct device *dev, struct device_attribute *attr,
221 const char *buf, size_t count)
222{
223 struct adf_accel_dev *accel_dev;
224 bool enabled = false;
225 int ret;
226
227 ret = kstrtobool(s: buf, res: &enabled);
228 if (ret)
229 return ret;
230
231 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
232 if (!accel_dev)
233 return -EINVAL;
234
235 accel_dev->autoreset_on_error = enabled;
236
237 return count;
238}
239static DEVICE_ATTR_RW(auto_reset);
240
241static DEVICE_ATTR_RW(state);
242static DEVICE_ATTR_RW(cfg_services);
243
244static ssize_t rp2srv_show(struct device *dev, struct device_attribute *attr,
245 char *buf)
246{
247 struct adf_hw_device_data *hw_data;
248 struct adf_accel_dev *accel_dev;
249 enum adf_cfg_service_type svc;
250
251 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
252 if (!accel_dev)
253 return -EINVAL;
254
255 hw_data = GET_HW_DATA(accel_dev);
256
257 if (accel_dev->sysfs.ring_num == UNSET_RING_NUM)
258 return -EINVAL;
259
260 down_read(sem: &accel_dev->sysfs.lock);
261 svc = GET_SRV_TYPE(accel_dev, accel_dev->sysfs.ring_num %
262 hw_data->num_banks_per_vf);
263 up_read(sem: &accel_dev->sysfs.lock);
264
265 switch (svc) {
266 case COMP:
267 return sysfs_emit(buf, fmt: "%s\n", ADF_CFG_DC);
268 case SYM:
269 return sysfs_emit(buf, fmt: "%s\n", ADF_CFG_SYM);
270 case ASYM:
271 return sysfs_emit(buf, fmt: "%s\n", ADF_CFG_ASYM);
272 case DECOMP:
273 return sysfs_emit(buf, fmt: "%s\n", ADF_CFG_DECOMP);
274 default:
275 break;
276 }
277 return -EINVAL;
278}
279
280static ssize_t rp2srv_store(struct device *dev, struct device_attribute *attr,
281 const char *buf, size_t count)
282{
283 struct adf_accel_dev *accel_dev;
284 int num_rings, ret;
285 unsigned int ring;
286
287 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
288 if (!accel_dev)
289 return -EINVAL;
290
291 ret = kstrtouint(s: buf, base: 10, res: &ring);
292 if (ret)
293 return ret;
294
295 num_rings = GET_MAX_BANKS(accel_dev);
296 if (ring >= num_rings) {
297 dev_err(&GET_DEV(accel_dev),
298 "Device does not support more than %u ring pairs\n",
299 num_rings);
300 return -EINVAL;
301 }
302
303 down_write(sem: &accel_dev->sysfs.lock);
304 accel_dev->sysfs.ring_num = ring;
305 up_write(sem: &accel_dev->sysfs.lock);
306
307 return count;
308}
309static DEVICE_ATTR_RW(rp2srv);
310
311static ssize_t num_rps_show(struct device *dev, struct device_attribute *attr,
312 char *buf)
313{
314 struct adf_accel_dev *accel_dev;
315
316 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
317 if (!accel_dev)
318 return -EINVAL;
319
320 return sysfs_emit(buf, fmt: "%u\n", GET_MAX_BANKS(accel_dev));
321}
322static DEVICE_ATTR_RO(num_rps);
323
324static struct attribute *qat_attrs[] = {
325 &dev_attr_state.attr,
326 &dev_attr_cfg_services.attr,
327 &dev_attr_pm_idle_enabled.attr,
328 &dev_attr_rp2srv.attr,
329 &dev_attr_num_rps.attr,
330 &dev_attr_auto_reset.attr,
331 NULL,
332};
333
334static struct attribute_group qat_group = {
335 .attrs = qat_attrs,
336 .name = "qat",
337};
338
339int adf_sysfs_init(struct adf_accel_dev *accel_dev)
340{
341 int ret;
342
343 ret = devm_device_add_group(dev: &GET_DEV(accel_dev), grp: &qat_group);
344 if (ret) {
345 dev_err(&GET_DEV(accel_dev),
346 "Failed to create qat attribute group: %d\n", ret);
347 }
348
349 accel_dev->sysfs.ring_num = UNSET_RING_NUM;
350
351 return ret;
352}
353EXPORT_SYMBOL_GPL(adf_sysfs_init);
354

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