1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 #include <sys/types.h>
4 #include <sys/sysctl.h>
5 #include <sys/systm.h>
6 #include <sys/priv.h>
7 #include "adf_heartbeat_dbg.h"
8 #include "adf_common_drv.h"
9 #include "adf_cfg.h"
10 #include "adf_heartbeat.h"
11
12 #define HB_SYSCTL_ERR(RC) \
13 do { \
14 if (RC == NULL) { \
15 printf( \
16 "Memory allocation failed in adf_heartbeat_dbg_add\n"); \
17 return ENOMEM; \
18 } \
19 } while (0)
20
21
qat_dev_hb_read_sent(SYSCTL_HANDLER_ARGS)22 static int qat_dev_hb_read_sent(SYSCTL_HANDLER_ARGS)
23 {
24 struct adf_accel_dev *accel_dev = arg1;
25 struct adf_heartbeat *hb;
26 int error = EFAULT;
27
28 if (priv_check(curthread, PRIV_DRIVER) != 0)
29 return EPERM;
30
31 if (accel_dev == NULL)
32 return EINVAL;
33
34 hb = accel_dev->heartbeat;
35
36 error = sysctl_handle_int(oidp, &hb->hb_sent_counter, 0, req);
37 if (error || !req->newptr)
38 return error;
39
40 return (0);
41 }
42
qat_dev_hb_read_failed(SYSCTL_HANDLER_ARGS)43 static int qat_dev_hb_read_failed(SYSCTL_HANDLER_ARGS)
44 {
45 struct adf_accel_dev *accel_dev = arg1;
46 struct adf_heartbeat *hb;
47 int error = EFAULT;
48
49 if (priv_check(curthread, PRIV_DRIVER) != 0)
50 return EPERM;
51
52 if (accel_dev == NULL)
53 return EINVAL;
54
55 hb = accel_dev->heartbeat;
56
57 error = sysctl_handle_int(oidp, &hb->hb_failed_counter, 0, req);
58 if (error || !req->newptr)
59 return error;
60
61 return (0);
62 }
63
64 /* Handler for HB status check */
qat_dev_hb_read(SYSCTL_HANDLER_ARGS)65 static int qat_dev_hb_read(SYSCTL_HANDLER_ARGS)
66 {
67 enum adf_device_heartbeat_status hb_status = DEV_HB_UNRESPONSIVE;
68 struct adf_accel_dev *accel_dev = arg1;
69 struct adf_heartbeat *hb;
70 int ret = 0;
71
72 if (priv_check(curthread, PRIV_DRIVER) != 0)
73 return EPERM;
74
75 if (accel_dev == NULL) {
76 return EINVAL;
77 }
78 hb = accel_dev->heartbeat;
79
80 /* if FW is loaded, proceed else set heartbeat down */
81 if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
82 adf_heartbeat_status(accel_dev, &hb_status);
83 }
84 if (hb_status == DEV_HB_ALIVE) {
85 hb->heartbeat.hb_sysctlvar = 1;
86 } else {
87 hb->heartbeat.hb_sysctlvar = 0;
88 }
89 ret = sysctl_handle_int(oidp, &hb->heartbeat.hb_sysctlvar, 0, req);
90 return ret;
91 }
92
93 int
adf_heartbeat_dbg_add(struct adf_accel_dev * accel_dev)94 adf_heartbeat_dbg_add(struct adf_accel_dev *accel_dev)
95 {
96 struct sysctl_ctx_list *qat_hb_sysctl_ctx;
97 struct sysctl_oid *qat_hb_sysctl_tree;
98 struct adf_heartbeat *hb;
99
100 if (accel_dev == NULL) {
101 return EINVAL;
102 }
103
104 if (adf_heartbeat_init(accel_dev))
105 return EINVAL;
106
107 hb = accel_dev->heartbeat;
108 qat_hb_sysctl_ctx =
109 device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
110 qat_hb_sysctl_tree =
111 device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev);
112
113 hb->heartbeat_sent.oid =
114 SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
115 SYSCTL_CHILDREN(qat_hb_sysctl_tree),
116 OID_AUTO,
117 "heartbeat_sent",
118 CTLTYPE_INT | CTLFLAG_RD,
119 accel_dev,
120 0,
121 qat_dev_hb_read_sent,
122 "IU",
123 "HB failed count");
124 HB_SYSCTL_ERR(hb->heartbeat_sent.oid);
125
126 hb->heartbeat_failed.oid =
127 SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
128 SYSCTL_CHILDREN(qat_hb_sysctl_tree),
129 OID_AUTO,
130 "heartbeat_failed",
131 CTLTYPE_INT | CTLFLAG_RD,
132 accel_dev,
133 0,
134 qat_dev_hb_read_failed,
135 "IU",
136 "HB failed count");
137 HB_SYSCTL_ERR(hb->heartbeat_failed.oid);
138
139 hb->heartbeat.oid = SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
140 SYSCTL_CHILDREN(qat_hb_sysctl_tree),
141 OID_AUTO,
142 "heartbeat",
143 CTLTYPE_INT | CTLFLAG_RD,
144 accel_dev,
145 0,
146 qat_dev_hb_read,
147 "IU",
148 "QAT device status");
149 HB_SYSCTL_ERR(hb->heartbeat.oid);
150 return 0;
151 }
152
153 int
adf_heartbeat_dbg_del(struct adf_accel_dev * accel_dev)154 adf_heartbeat_dbg_del(struct adf_accel_dev *accel_dev)
155 {
156 struct sysctl_ctx_list *qat_sysctl_ctx;
157 struct adf_heartbeat *hb;
158
159 if (!accel_dev) {
160 return EINVAL;
161 }
162
163 hb = accel_dev->heartbeat;
164
165 qat_sysctl_ctx =
166 device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
167
168 if (hb->heartbeat.oid) {
169 sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat.oid);
170 sysctl_remove_oid(hb->heartbeat.oid, 1, 1);
171 hb->heartbeat.oid = NULL;
172 }
173
174 if (hb->heartbeat_failed.oid) {
175 sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat_failed.oid);
176 sysctl_remove_oid(hb->heartbeat_failed.oid, 1, 1);
177 hb->heartbeat_failed.oid = NULL;
178 }
179
180 if (hb->heartbeat_sent.oid) {
181 sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat_sent.oid);
182 sysctl_remove_oid(hb->heartbeat_sent.oid, 1, 1);
183 hb->heartbeat_sent.oid = NULL;
184 }
185
186 adf_heartbeat_clean(accel_dev);
187
188 return 0;
189 }
190