1 // SPDX-License-Identifier: GPL-2.0-only
2 /* Copyright(c) 2023 Intel Corporation */
3
4 #include <linux/sysfs.h>
5 #include <linux/pci.h>
6 #include <linux/string.h>
7
8 #include "adf_common_drv.h"
9 #include "adf_sysfs_ras_counters.h"
10
errors_correctable_show(struct device * dev,struct device_attribute * dev_attr,char * buf)11 static ssize_t errors_correctable_show(struct device *dev,
12 struct device_attribute *dev_attr,
13 char *buf)
14 {
15 struct adf_accel_dev *accel_dev;
16 unsigned long counter;
17
18 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
19 if (!accel_dev)
20 return -EINVAL;
21
22 counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_CORR);
23 return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
24 }
25
errors_nonfatal_show(struct device * dev,struct device_attribute * dev_attr,char * buf)26 static ssize_t errors_nonfatal_show(struct device *dev,
27 struct device_attribute *dev_attr,
28 char *buf)
29 {
30 struct adf_accel_dev *accel_dev;
31 unsigned long counter;
32
33 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
34 if (!accel_dev)
35 return -EINVAL;
36
37 counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_UNCORR);
38 return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
39 }
40
errors_fatal_show(struct device * dev,struct device_attribute * dev_attr,char * buf)41 static ssize_t errors_fatal_show(struct device *dev,
42 struct device_attribute *dev_attr,
43 char *buf)
44 {
45 struct adf_accel_dev *accel_dev;
46 unsigned long counter;
47
48 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
49 if (!accel_dev)
50 return -EINVAL;
51
52 counter = ADF_RAS_ERR_CTR_READ(accel_dev->ras_errors, ADF_RAS_FATAL);
53 return scnprintf(buf, PAGE_SIZE, "%ld\n", counter);
54 }
55
reset_error_counters_store(struct device * dev,struct device_attribute * dev_attr,const char * buf,size_t count)56 static ssize_t reset_error_counters_store(struct device *dev,
57 struct device_attribute *dev_attr,
58 const char *buf, size_t count)
59 {
60 struct adf_accel_dev *accel_dev;
61
62 if (buf[0] != '1' || count != 2)
63 return -EINVAL;
64
65 accel_dev = adf_devmgr_pci_to_accel_dev(to_pci_dev(dev));
66 if (!accel_dev)
67 return -EINVAL;
68
69 ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
70
71 return count;
72 }
73
74 static DEVICE_ATTR_RO(errors_correctable);
75 static DEVICE_ATTR_RO(errors_nonfatal);
76 static DEVICE_ATTR_RO(errors_fatal);
77 static DEVICE_ATTR_WO(reset_error_counters);
78
79 static struct attribute *qat_ras_attrs[] = {
80 &dev_attr_errors_correctable.attr,
81 &dev_attr_errors_nonfatal.attr,
82 &dev_attr_errors_fatal.attr,
83 &dev_attr_reset_error_counters.attr,
84 NULL,
85 };
86
87 static struct attribute_group qat_ras_group = {
88 .attrs = qat_ras_attrs,
89 .name = "qat_ras",
90 };
91
adf_sysfs_start_ras(struct adf_accel_dev * accel_dev)92 void adf_sysfs_start_ras(struct adf_accel_dev *accel_dev)
93 {
94 if (!accel_dev->ras_errors.enabled)
95 return;
96
97 ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
98
99 if (device_add_group(&GET_DEV(accel_dev), &qat_ras_group))
100 dev_err(&GET_DEV(accel_dev),
101 "Failed to create qat_ras attribute group.\n");
102
103 accel_dev->ras_errors.sysfs_added = true;
104 }
105
adf_sysfs_stop_ras(struct adf_accel_dev * accel_dev)106 void adf_sysfs_stop_ras(struct adf_accel_dev *accel_dev)
107 {
108 if (!accel_dev->ras_errors.enabled)
109 return;
110
111 if (accel_dev->ras_errors.sysfs_added) {
112 device_remove_group(&GET_DEV(accel_dev), &qat_ras_group);
113 accel_dev->ras_errors.sysfs_added = false;
114 }
115
116 ADF_RAS_ERR_CTR_CLEAR(accel_dev->ras_errors);
117 }
118