xref: /linux/drivers/crypto/intel/qat/qat_common/adf_sysfs_kpt.c (revision b2128290c29902315e632ea59e0504d6bc9e9b42)
1*fb98254aSJunyuan Wang // SPDX-License-Identifier: GPL-2.0-only
2*fb98254aSJunyuan Wang /* Copyright(c) 2026 Intel Corporation */
3*fb98254aSJunyuan Wang #include <linux/sysfs.h>
4*fb98254aSJunyuan Wang #include <linux/types.h>
5*fb98254aSJunyuan Wang 
6*fb98254aSJunyuan Wang #include "adf_cfg.h"
7*fb98254aSJunyuan Wang #include "adf_cfg_services.h"
8*fb98254aSJunyuan Wang #include "adf_common_drv.h"
9*fb98254aSJunyuan Wang #include "adf_kpt.h"
10*fb98254aSJunyuan Wang #include "adf_sysfs_kpt.h"
11*fb98254aSJunyuan Wang 
12*fb98254aSJunyuan Wang static ssize_t enable_show(struct device *dev, struct device_attribute *attr,
13*fb98254aSJunyuan Wang 			   char *buf)
14*fb98254aSJunyuan Wang {
15*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
16*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
17*fb98254aSJunyuan Wang 
18*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
19*fb98254aSJunyuan Wang 	if (!accel_dev)
20*fb98254aSJunyuan Wang 		return -EINVAL;
21*fb98254aSJunyuan Wang 
22*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
23*fb98254aSJunyuan Wang 
24*fb98254aSJunyuan Wang 	return sysfs_emit(buf, "%d\n", user_data->enable);
25*fb98254aSJunyuan Wang }
26*fb98254aSJunyuan Wang 
27*fb98254aSJunyuan Wang static ssize_t enable_store(struct device *dev, struct device_attribute *attr,
28*fb98254aSJunyuan Wang 			    const char *buf, size_t count)
29*fb98254aSJunyuan Wang {
30*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
31*fb98254aSJunyuan Wang 	struct adf_hw_device_data *hw_data;
32*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
33*fb98254aSJunyuan Wang 	bool enable;
34*fb98254aSJunyuan Wang 	int ret;
35*fb98254aSJunyuan Wang 
36*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
37*fb98254aSJunyuan Wang 	if (!accel_dev)
38*fb98254aSJunyuan Wang 		return -EINVAL;
39*fb98254aSJunyuan Wang 
40*fb98254aSJunyuan Wang 	if (adf_dev_started(accel_dev)) {
41*fb98254aSJunyuan Wang 		dev_info(dev, "Device qat_dev%d must be down before enabling KPT\n",
42*fb98254aSJunyuan Wang 			 accel_dev->accel_id);
43*fb98254aSJunyuan Wang 		return -EINVAL;
44*fb98254aSJunyuan Wang 	}
45*fb98254aSJunyuan Wang 
46*fb98254aSJunyuan Wang 	if (adf_get_service_enabled(accel_dev) != SVC_ASYM) {
47*fb98254aSJunyuan Wang 		dev_info(dev, "KPT can only be enabled when the asymmetric service is enabled\n");
48*fb98254aSJunyuan Wang 		return -EINVAL;
49*fb98254aSJunyuan Wang 	}
50*fb98254aSJunyuan Wang 
51*fb98254aSJunyuan Wang 	hw_data = GET_HW_DATA(accel_dev);
52*fb98254aSJunyuan Wang 
53*fb98254aSJunyuan Wang 	/*
54*fb98254aSJunyuan Wang 	 * Restore the KPT capability bit in the device's capabilities mask
55*fb98254aSJunyuan Wang 	 * before processing user input, as the bit may have been cleared if
56*fb98254aSJunyuan Wang 	 * KPT was previously disabled by the user.
57*fb98254aSJunyuan Wang 	 */
58*fb98254aSJunyuan Wang 	hw_data->accel_capabilities_mask = hw_data->get_accel_cap(accel_dev);
59*fb98254aSJunyuan Wang 	if (!hw_data->accel_capabilities_mask)
60*fb98254aSJunyuan Wang 		return -EINVAL;
61*fb98254aSJunyuan Wang 
62*fb98254aSJunyuan Wang 	ret = kstrtobool(buf, &enable);
63*fb98254aSJunyuan Wang 	if (ret)
64*fb98254aSJunyuan Wang 		return ret;
65*fb98254aSJunyuan Wang 
66*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
67*fb98254aSJunyuan Wang 	user_data->enable = enable;
68*fb98254aSJunyuan Wang 
69*fb98254aSJunyuan Wang 	return count;
70*fb98254aSJunyuan Wang }
71*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(enable);
72*fb98254aSJunyuan Wang 
73*fb98254aSJunyuan Wang static ssize_t swk_shared_show(struct device *dev,
74*fb98254aSJunyuan Wang 			       struct device_attribute *attr, char *buf)
75*fb98254aSJunyuan Wang {
76*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
77*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
78*fb98254aSJunyuan Wang 
79*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
80*fb98254aSJunyuan Wang 	if (!accel_dev)
81*fb98254aSJunyuan Wang 		return -EINVAL;
82*fb98254aSJunyuan Wang 
83*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
84*fb98254aSJunyuan Wang 
85*fb98254aSJunyuan Wang 	return sysfs_emit(buf, "%d\n", user_data->swk_shared);
86*fb98254aSJunyuan Wang }
87*fb98254aSJunyuan Wang 
88*fb98254aSJunyuan Wang static ssize_t swk_shared_store(struct device *dev, struct device_attribute *attr,
89*fb98254aSJunyuan Wang 				const char *buf, size_t count)
90*fb98254aSJunyuan Wang {
91*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
92*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
93*fb98254aSJunyuan Wang 	bool swk_shared;
94*fb98254aSJunyuan Wang 	int ret;
95*fb98254aSJunyuan Wang 
96*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
97*fb98254aSJunyuan Wang 	if (!accel_dev)
98*fb98254aSJunyuan Wang 		return -EINVAL;
99*fb98254aSJunyuan Wang 
100*fb98254aSJunyuan Wang 	if (adf_dev_started(accel_dev)) {
101*fb98254aSJunyuan Wang 		dev_info(dev, "Device qat_dev%d must be down before setting swk_shared\n",
102*fb98254aSJunyuan Wang 			 accel_dev->accel_id);
103*fb98254aSJunyuan Wang 		return -EINVAL;
104*fb98254aSJunyuan Wang 	}
105*fb98254aSJunyuan Wang 
106*fb98254aSJunyuan Wang 	ret = kstrtobool(buf, &swk_shared);
107*fb98254aSJunyuan Wang 	if (ret)
108*fb98254aSJunyuan Wang 		return ret;
109*fb98254aSJunyuan Wang 
110*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
111*fb98254aSJunyuan Wang 	user_data->swk_shared = swk_shared;
112*fb98254aSJunyuan Wang 
113*fb98254aSJunyuan Wang 	return count;
114*fb98254aSJunyuan Wang }
115*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_shared);
116*fb98254aSJunyuan Wang 
117*fb98254aSJunyuan Wang static ssize_t swk_max_ttl_show(struct device *dev, struct device_attribute *attr,
118*fb98254aSJunyuan Wang 				char *buf)
119*fb98254aSJunyuan Wang {
120*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
121*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
122*fb98254aSJunyuan Wang 
123*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
124*fb98254aSJunyuan Wang 	if (!accel_dev)
125*fb98254aSJunyuan Wang 		return -EINVAL;
126*fb98254aSJunyuan Wang 
127*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
128*fb98254aSJunyuan Wang 
129*fb98254aSJunyuan Wang 	return sysfs_emit(buf, "%u\n", user_data->swk_max_ttl);
130*fb98254aSJunyuan Wang }
131*fb98254aSJunyuan Wang 
132*fb98254aSJunyuan Wang static ssize_t swk_max_ttl_store(struct device *dev, struct device_attribute *attr,
133*fb98254aSJunyuan Wang 				 const char *buf, size_t count)
134*fb98254aSJunyuan Wang {
135*fb98254aSJunyuan Wang 	struct adf_kpt_hw_data *kpt_data;
136*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
137*fb98254aSJunyuan Wang 	unsigned int swk_max_ttl;
138*fb98254aSJunyuan Wang 	int ret;
139*fb98254aSJunyuan Wang 
140*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
141*fb98254aSJunyuan Wang 	if (!accel_dev)
142*fb98254aSJunyuan Wang 		return -EINVAL;
143*fb98254aSJunyuan Wang 
144*fb98254aSJunyuan Wang 	if (adf_dev_started(accel_dev)) {
145*fb98254aSJunyuan Wang 		dev_info(dev, "Device qat_dev%d must be down before setting swk_max_ttl\n",
146*fb98254aSJunyuan Wang 			 accel_dev->accel_id);
147*fb98254aSJunyuan Wang 		return -EINVAL;
148*fb98254aSJunyuan Wang 	}
149*fb98254aSJunyuan Wang 
150*fb98254aSJunyuan Wang 	ret = kstrtouint(buf, 10, &swk_max_ttl);
151*fb98254aSJunyuan Wang 	if (ret)
152*fb98254aSJunyuan Wang 		return ret;
153*fb98254aSJunyuan Wang 
154*fb98254aSJunyuan Wang 	kpt_data = GET_KPT_CFG_DATA(accel_dev);
155*fb98254aSJunyuan Wang 
156*fb98254aSJunyuan Wang 	if (swk_max_ttl > kpt_data->max_swk_ttl) {
157*fb98254aSJunyuan Wang 		dev_info(dev, "Configuration value is out of range (%u - %u)\n",
158*fb98254aSJunyuan Wang 			 0, kpt_data->max_swk_ttl);
159*fb98254aSJunyuan Wang 		return -EINVAL;
160*fb98254aSJunyuan Wang 	}
161*fb98254aSJunyuan Wang 
162*fb98254aSJunyuan Wang 	kpt_data->user_input.swk_max_ttl = swk_max_ttl;
163*fb98254aSJunyuan Wang 
164*fb98254aSJunyuan Wang 	return count;
165*fb98254aSJunyuan Wang }
166*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_max_ttl);
167*fb98254aSJunyuan Wang 
168*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_fn_show(struct device *dev, struct device_attribute *attr,
169*fb98254aSJunyuan Wang 				   char *buf)
170*fb98254aSJunyuan Wang {
171*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
172*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
173*fb98254aSJunyuan Wang 
174*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
175*fb98254aSJunyuan Wang 	if (!accel_dev)
176*fb98254aSJunyuan Wang 		return -EINVAL;
177*fb98254aSJunyuan Wang 
178*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
179*fb98254aSJunyuan Wang 
180*fb98254aSJunyuan Wang 	return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_fn);
181*fb98254aSJunyuan Wang }
182*fb98254aSJunyuan Wang 
183*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_fn_store(struct device *dev, struct device_attribute *attr,
184*fb98254aSJunyuan Wang 				    const char *buf, size_t count)
185*fb98254aSJunyuan Wang {
186*fb98254aSJunyuan Wang 	struct adf_kpt_hw_data *kpt_data;
187*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
188*fb98254aSJunyuan Wang 	unsigned int swk_cnt_per_fn;
189*fb98254aSJunyuan Wang 	int ret;
190*fb98254aSJunyuan Wang 
191*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
192*fb98254aSJunyuan Wang 	if (!accel_dev)
193*fb98254aSJunyuan Wang 		return -EINVAL;
194*fb98254aSJunyuan Wang 
195*fb98254aSJunyuan Wang 	if (adf_dev_started(accel_dev)) {
196*fb98254aSJunyuan Wang 		dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_fn\n",
197*fb98254aSJunyuan Wang 			 accel_dev->accel_id);
198*fb98254aSJunyuan Wang 		return -EINVAL;
199*fb98254aSJunyuan Wang 	}
200*fb98254aSJunyuan Wang 
201*fb98254aSJunyuan Wang 	ret = kstrtouint(buf, 10, &swk_cnt_per_fn);
202*fb98254aSJunyuan Wang 	if (ret)
203*fb98254aSJunyuan Wang 		return ret;
204*fb98254aSJunyuan Wang 
205*fb98254aSJunyuan Wang 	kpt_data = GET_KPT_CFG_DATA(accel_dev);
206*fb98254aSJunyuan Wang 
207*fb98254aSJunyuan Wang 	if (swk_cnt_per_fn > kpt_data->max_swk_cnt_per_fn_pasid) {
208*fb98254aSJunyuan Wang 		dev_info(dev, "swk_cnt_per_fn: value out of range (0 - %u)\n",
209*fb98254aSJunyuan Wang 			 kpt_data->max_swk_cnt_per_fn_pasid);
210*fb98254aSJunyuan Wang 		return -EINVAL;
211*fb98254aSJunyuan Wang 	}
212*fb98254aSJunyuan Wang 
213*fb98254aSJunyuan Wang 	kpt_data->user_input.swk_cnt_per_fn = swk_cnt_per_fn;
214*fb98254aSJunyuan Wang 
215*fb98254aSJunyuan Wang 	return count;
216*fb98254aSJunyuan Wang }
217*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_cnt_per_fn);
218*fb98254aSJunyuan Wang 
219*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_pasid_show(struct device *dev, struct device_attribute *attr,
220*fb98254aSJunyuan Wang 				      char *buf)
221*fb98254aSJunyuan Wang {
222*fb98254aSJunyuan Wang 	struct adf_kpt_interface_data *user_data;
223*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
224*fb98254aSJunyuan Wang 
225*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
226*fb98254aSJunyuan Wang 	if (!accel_dev)
227*fb98254aSJunyuan Wang 		return -EINVAL;
228*fb98254aSJunyuan Wang 
229*fb98254aSJunyuan Wang 	user_data = GET_KPT_USER_DATA(accel_dev);
230*fb98254aSJunyuan Wang 
231*fb98254aSJunyuan Wang 	return sysfs_emit(buf, "%u\n", user_data->swk_cnt_per_pasid);
232*fb98254aSJunyuan Wang }
233*fb98254aSJunyuan Wang 
234*fb98254aSJunyuan Wang static ssize_t swk_cnt_per_pasid_store(struct device *dev, struct device_attribute *attr,
235*fb98254aSJunyuan Wang 				       const char *buf, size_t count)
236*fb98254aSJunyuan Wang {
237*fb98254aSJunyuan Wang 	struct adf_kpt_hw_data *kpt_data;
238*fb98254aSJunyuan Wang 	struct adf_accel_dev *accel_dev;
239*fb98254aSJunyuan Wang 	unsigned int swk_cnt_per_pasid;
240*fb98254aSJunyuan Wang 	int ret;
241*fb98254aSJunyuan Wang 
242*fb98254aSJunyuan Wang 	accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
243*fb98254aSJunyuan Wang 	if (!accel_dev)
244*fb98254aSJunyuan Wang 		return -EINVAL;
245*fb98254aSJunyuan Wang 
246*fb98254aSJunyuan Wang 	if (adf_dev_started(accel_dev)) {
247*fb98254aSJunyuan Wang 		dev_info(dev, "Device qat_dev%d must be down before setting swk_cnt_per_pasid\n",
248*fb98254aSJunyuan Wang 			 accel_dev->accel_id);
249*fb98254aSJunyuan Wang 		return -EINVAL;
250*fb98254aSJunyuan Wang 	}
251*fb98254aSJunyuan Wang 
252*fb98254aSJunyuan Wang 	ret = kstrtouint(buf, 10, &swk_cnt_per_pasid);
253*fb98254aSJunyuan Wang 	if (ret)
254*fb98254aSJunyuan Wang 		return ret;
255*fb98254aSJunyuan Wang 
256*fb98254aSJunyuan Wang 	kpt_data = GET_KPT_CFG_DATA(accel_dev);
257*fb98254aSJunyuan Wang 
258*fb98254aSJunyuan Wang 	if (swk_cnt_per_pasid > kpt_data->max_swk_cnt_per_fn_pasid) {
259*fb98254aSJunyuan Wang 		dev_info(dev, "swk_cnt_per_pasid: value out of range (0 - %u)\n",
260*fb98254aSJunyuan Wang 			 kpt_data->max_swk_cnt_per_fn_pasid);
261*fb98254aSJunyuan Wang 		return -EINVAL;
262*fb98254aSJunyuan Wang 	}
263*fb98254aSJunyuan Wang 
264*fb98254aSJunyuan Wang 	kpt_data->user_input.swk_cnt_per_pasid = swk_cnt_per_pasid;
265*fb98254aSJunyuan Wang 
266*fb98254aSJunyuan Wang 	return count;
267*fb98254aSJunyuan Wang }
268*fb98254aSJunyuan Wang static DEVICE_ATTR_RW(swk_cnt_per_pasid);
269*fb98254aSJunyuan Wang 
270*fb98254aSJunyuan Wang static struct attribute *qat_kpt_attrs[] = {
271*fb98254aSJunyuan Wang 	&dev_attr_enable.attr,
272*fb98254aSJunyuan Wang 	&dev_attr_swk_shared.attr,
273*fb98254aSJunyuan Wang 	&dev_attr_swk_max_ttl.attr,
274*fb98254aSJunyuan Wang 	&dev_attr_swk_cnt_per_fn.attr,
275*fb98254aSJunyuan Wang 	&dev_attr_swk_cnt_per_pasid.attr,
276*fb98254aSJunyuan Wang 	NULL,
277*fb98254aSJunyuan Wang };
278*fb98254aSJunyuan Wang 
279*fb98254aSJunyuan Wang static const struct attribute_group qat_kpt_group = {
280*fb98254aSJunyuan Wang 	.attrs = qat_kpt_attrs,
281*fb98254aSJunyuan Wang 	.name = "qat_kpt",
282*fb98254aSJunyuan Wang };
283*fb98254aSJunyuan Wang 
284*fb98254aSJunyuan Wang int adf_sysfs_init_kpt(struct adf_accel_dev *accel_dev)
285*fb98254aSJunyuan Wang {
286*fb98254aSJunyuan Wang 	int ret;
287*fb98254aSJunyuan Wang 
288*fb98254aSJunyuan Wang 	ret = devm_device_add_group(&GET_DEV(accel_dev), &qat_kpt_group);
289*fb98254aSJunyuan Wang 	if (ret) {
290*fb98254aSJunyuan Wang 		dev_err(&GET_DEV(accel_dev), "Failed to create qat_kpt attribute group\n");
291*fb98254aSJunyuan Wang 		return ret;
292*fb98254aSJunyuan Wang 	}
293*fb98254aSJunyuan Wang 
294*fb98254aSJunyuan Wang 	return 0;
295*fb98254aSJunyuan Wang }
296*fb98254aSJunyuan Wang EXPORT_SYMBOL_GPL(adf_sysfs_init_kpt);
297