178ee8d1cSJulian Grajkowski /* SPDX-License-Identifier: BSD-3-Clause */
2c38bafeeSHareshx Sankar Raj /* Copyright(c) 2007-2025 Intel Corporation */
378ee8d1cSJulian Grajkowski #include <sys/types.h>
478ee8d1cSJulian Grajkowski #include <sys/sysctl.h>
578ee8d1cSJulian Grajkowski #include <sys/systm.h>
6*8aa51e6dSHareshx Sankar Raj #include <sys/priv.h>
778ee8d1cSJulian Grajkowski #include "adf_heartbeat_dbg.h"
878ee8d1cSJulian Grajkowski #include "adf_common_drv.h"
978ee8d1cSJulian Grajkowski #include "adf_cfg.h"
1078ee8d1cSJulian Grajkowski #include "adf_heartbeat.h"
1178ee8d1cSJulian Grajkowski
1278ee8d1cSJulian Grajkowski #define HB_SYSCTL_ERR(RC) \
1378ee8d1cSJulian Grajkowski do { \
1478ee8d1cSJulian Grajkowski if (RC == NULL) { \
1578ee8d1cSJulian Grajkowski printf( \
1678ee8d1cSJulian Grajkowski "Memory allocation failed in adf_heartbeat_dbg_add\n"); \
1778ee8d1cSJulian Grajkowski return ENOMEM; \
1878ee8d1cSJulian Grajkowski } \
1978ee8d1cSJulian Grajkowski } while (0)
2078ee8d1cSJulian Grajkowski
21*8aa51e6dSHareshx Sankar Raj
qat_dev_hb_read_sent(SYSCTL_HANDLER_ARGS)22*8aa51e6dSHareshx Sankar Raj static int qat_dev_hb_read_sent(SYSCTL_HANDLER_ARGS)
23*8aa51e6dSHareshx Sankar Raj {
24*8aa51e6dSHareshx Sankar Raj struct adf_accel_dev *accel_dev = arg1;
25*8aa51e6dSHareshx Sankar Raj struct adf_heartbeat *hb;
26*8aa51e6dSHareshx Sankar Raj int error = EFAULT;
27*8aa51e6dSHareshx Sankar Raj
28*8aa51e6dSHareshx Sankar Raj if (priv_check(curthread, PRIV_DRIVER) != 0)
29*8aa51e6dSHareshx Sankar Raj return EPERM;
30*8aa51e6dSHareshx Sankar Raj
31*8aa51e6dSHareshx Sankar Raj if (accel_dev == NULL)
32*8aa51e6dSHareshx Sankar Raj return EINVAL;
33*8aa51e6dSHareshx Sankar Raj
34*8aa51e6dSHareshx Sankar Raj hb = accel_dev->heartbeat;
35*8aa51e6dSHareshx Sankar Raj
36*8aa51e6dSHareshx Sankar Raj error = sysctl_handle_int(oidp, &hb->hb_sent_counter, 0, req);
37*8aa51e6dSHareshx Sankar Raj if (error || !req->newptr)
38*8aa51e6dSHareshx Sankar Raj return error;
39*8aa51e6dSHareshx Sankar Raj
40*8aa51e6dSHareshx Sankar Raj return (0);
41*8aa51e6dSHareshx Sankar Raj }
42*8aa51e6dSHareshx Sankar Raj
qat_dev_hb_read_failed(SYSCTL_HANDLER_ARGS)43*8aa51e6dSHareshx Sankar Raj static int qat_dev_hb_read_failed(SYSCTL_HANDLER_ARGS)
44*8aa51e6dSHareshx Sankar Raj {
45*8aa51e6dSHareshx Sankar Raj struct adf_accel_dev *accel_dev = arg1;
46*8aa51e6dSHareshx Sankar Raj struct adf_heartbeat *hb;
47*8aa51e6dSHareshx Sankar Raj int error = EFAULT;
48*8aa51e6dSHareshx Sankar Raj
49*8aa51e6dSHareshx Sankar Raj if (priv_check(curthread, PRIV_DRIVER) != 0)
50*8aa51e6dSHareshx Sankar Raj return EPERM;
51*8aa51e6dSHareshx Sankar Raj
52*8aa51e6dSHareshx Sankar Raj if (accel_dev == NULL)
53*8aa51e6dSHareshx Sankar Raj return EINVAL;
54*8aa51e6dSHareshx Sankar Raj
55*8aa51e6dSHareshx Sankar Raj hb = accel_dev->heartbeat;
56*8aa51e6dSHareshx Sankar Raj
57*8aa51e6dSHareshx Sankar Raj error = sysctl_handle_int(oidp, &hb->hb_failed_counter, 0, req);
58*8aa51e6dSHareshx Sankar Raj if (error || !req->newptr)
59*8aa51e6dSHareshx Sankar Raj return error;
60*8aa51e6dSHareshx Sankar Raj
61*8aa51e6dSHareshx Sankar Raj return (0);
62*8aa51e6dSHareshx Sankar Raj }
63*8aa51e6dSHareshx Sankar Raj
6478ee8d1cSJulian Grajkowski /* Handler for HB status check */
qat_dev_hb_read(SYSCTL_HANDLER_ARGS)6578ee8d1cSJulian Grajkowski static int qat_dev_hb_read(SYSCTL_HANDLER_ARGS)
6678ee8d1cSJulian Grajkowski {
6778ee8d1cSJulian Grajkowski enum adf_device_heartbeat_status hb_status = DEV_HB_UNRESPONSIVE;
6878ee8d1cSJulian Grajkowski struct adf_accel_dev *accel_dev = arg1;
6978ee8d1cSJulian Grajkowski struct adf_heartbeat *hb;
7078ee8d1cSJulian Grajkowski int ret = 0;
71*8aa51e6dSHareshx Sankar Raj
72*8aa51e6dSHareshx Sankar Raj if (priv_check(curthread, PRIV_DRIVER) != 0)
73*8aa51e6dSHareshx Sankar Raj return EPERM;
74*8aa51e6dSHareshx Sankar Raj
7578ee8d1cSJulian Grajkowski if (accel_dev == NULL) {
7678ee8d1cSJulian Grajkowski return EINVAL;
7778ee8d1cSJulian Grajkowski }
7878ee8d1cSJulian Grajkowski hb = accel_dev->heartbeat;
7978ee8d1cSJulian Grajkowski
8078ee8d1cSJulian Grajkowski /* if FW is loaded, proceed else set heartbeat down */
8178ee8d1cSJulian Grajkowski if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
8278ee8d1cSJulian Grajkowski adf_heartbeat_status(accel_dev, &hb_status);
8378ee8d1cSJulian Grajkowski }
8478ee8d1cSJulian Grajkowski if (hb_status == DEV_HB_ALIVE) {
8578ee8d1cSJulian Grajkowski hb->heartbeat.hb_sysctlvar = 1;
8678ee8d1cSJulian Grajkowski } else {
8778ee8d1cSJulian Grajkowski hb->heartbeat.hb_sysctlvar = 0;
8878ee8d1cSJulian Grajkowski }
8978ee8d1cSJulian Grajkowski ret = sysctl_handle_int(oidp, &hb->heartbeat.hb_sysctlvar, 0, req);
9078ee8d1cSJulian Grajkowski return ret;
9178ee8d1cSJulian Grajkowski }
9278ee8d1cSJulian Grajkowski
9378ee8d1cSJulian Grajkowski int
adf_heartbeat_dbg_add(struct adf_accel_dev * accel_dev)9478ee8d1cSJulian Grajkowski adf_heartbeat_dbg_add(struct adf_accel_dev *accel_dev)
9578ee8d1cSJulian Grajkowski {
9678ee8d1cSJulian Grajkowski struct sysctl_ctx_list *qat_hb_sysctl_ctx;
9778ee8d1cSJulian Grajkowski struct sysctl_oid *qat_hb_sysctl_tree;
9878ee8d1cSJulian Grajkowski struct adf_heartbeat *hb;
9978ee8d1cSJulian Grajkowski
10078ee8d1cSJulian Grajkowski if (accel_dev == NULL) {
10178ee8d1cSJulian Grajkowski return EINVAL;
10278ee8d1cSJulian Grajkowski }
10378ee8d1cSJulian Grajkowski
10478ee8d1cSJulian Grajkowski if (adf_heartbeat_init(accel_dev))
10578ee8d1cSJulian Grajkowski return EINVAL;
10678ee8d1cSJulian Grajkowski
10778ee8d1cSJulian Grajkowski hb = accel_dev->heartbeat;
10878ee8d1cSJulian Grajkowski qat_hb_sysctl_ctx =
10978ee8d1cSJulian Grajkowski device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
11078ee8d1cSJulian Grajkowski qat_hb_sysctl_tree =
11178ee8d1cSJulian Grajkowski device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev);
11278ee8d1cSJulian Grajkowski
113c38bafeeSHareshx Sankar Raj hb->heartbeat_sent.oid =
114*8aa51e6dSHareshx Sankar Raj SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
11578ee8d1cSJulian Grajkowski SYSCTL_CHILDREN(qat_hb_sysctl_tree),
11678ee8d1cSJulian Grajkowski OID_AUTO,
11778ee8d1cSJulian Grajkowski "heartbeat_sent",
118*8aa51e6dSHareshx Sankar Raj CTLTYPE_INT | CTLFLAG_RD,
119*8aa51e6dSHareshx Sankar Raj accel_dev,
12078ee8d1cSJulian Grajkowski 0,
121*8aa51e6dSHareshx Sankar Raj qat_dev_hb_read_sent,
122*8aa51e6dSHareshx Sankar Raj "IU",
123*8aa51e6dSHareshx Sankar Raj "HB failed count");
124c38bafeeSHareshx Sankar Raj HB_SYSCTL_ERR(hb->heartbeat_sent.oid);
12578ee8d1cSJulian Grajkowski
126c38bafeeSHareshx Sankar Raj hb->heartbeat_failed.oid =
127*8aa51e6dSHareshx Sankar Raj SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
12878ee8d1cSJulian Grajkowski SYSCTL_CHILDREN(qat_hb_sysctl_tree),
12978ee8d1cSJulian Grajkowski OID_AUTO,
13078ee8d1cSJulian Grajkowski "heartbeat_failed",
131*8aa51e6dSHareshx Sankar Raj CTLTYPE_INT | CTLFLAG_RD,
132*8aa51e6dSHareshx Sankar Raj accel_dev,
13378ee8d1cSJulian Grajkowski 0,
134*8aa51e6dSHareshx Sankar Raj qat_dev_hb_read_failed,
135*8aa51e6dSHareshx Sankar Raj "IU",
13678ee8d1cSJulian Grajkowski "HB failed count");
137c38bafeeSHareshx Sankar Raj HB_SYSCTL_ERR(hb->heartbeat_failed.oid);
13878ee8d1cSJulian Grajkowski
139c38bafeeSHareshx Sankar Raj hb->heartbeat.oid = SYSCTL_ADD_PROC(qat_hb_sysctl_ctx,
14078ee8d1cSJulian Grajkowski SYSCTL_CHILDREN(qat_hb_sysctl_tree),
14178ee8d1cSJulian Grajkowski OID_AUTO,
14278ee8d1cSJulian Grajkowski "heartbeat",
14378ee8d1cSJulian Grajkowski CTLTYPE_INT | CTLFLAG_RD,
14478ee8d1cSJulian Grajkowski accel_dev,
14578ee8d1cSJulian Grajkowski 0,
14678ee8d1cSJulian Grajkowski qat_dev_hb_read,
14778ee8d1cSJulian Grajkowski "IU",
14878ee8d1cSJulian Grajkowski "QAT device status");
149c38bafeeSHareshx Sankar Raj HB_SYSCTL_ERR(hb->heartbeat.oid);
15078ee8d1cSJulian Grajkowski return 0;
15178ee8d1cSJulian Grajkowski }
15278ee8d1cSJulian Grajkowski
15378ee8d1cSJulian Grajkowski int
adf_heartbeat_dbg_del(struct adf_accel_dev * accel_dev)15478ee8d1cSJulian Grajkowski adf_heartbeat_dbg_del(struct adf_accel_dev *accel_dev)
15578ee8d1cSJulian Grajkowski {
156c38bafeeSHareshx Sankar Raj struct sysctl_ctx_list *qat_sysctl_ctx;
157c38bafeeSHareshx Sankar Raj struct adf_heartbeat *hb;
158c38bafeeSHareshx Sankar Raj
159c38bafeeSHareshx Sankar Raj if (!accel_dev) {
160c38bafeeSHareshx Sankar Raj return EINVAL;
161c38bafeeSHareshx Sankar Raj }
162c38bafeeSHareshx Sankar Raj
163c38bafeeSHareshx Sankar Raj hb = accel_dev->heartbeat;
164c38bafeeSHareshx Sankar Raj
165c38bafeeSHareshx Sankar Raj qat_sysctl_ctx =
166c38bafeeSHareshx Sankar Raj device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
167c38bafeeSHareshx Sankar Raj
168c38bafeeSHareshx Sankar Raj if (hb->heartbeat.oid) {
169c38bafeeSHareshx Sankar Raj sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat.oid);
170c38bafeeSHareshx Sankar Raj sysctl_remove_oid(hb->heartbeat.oid, 1, 1);
171c38bafeeSHareshx Sankar Raj hb->heartbeat.oid = NULL;
172c38bafeeSHareshx Sankar Raj }
173c38bafeeSHareshx Sankar Raj
174c38bafeeSHareshx Sankar Raj if (hb->heartbeat_failed.oid) {
175c38bafeeSHareshx Sankar Raj sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat_failed.oid);
176c38bafeeSHareshx Sankar Raj sysctl_remove_oid(hb->heartbeat_failed.oid, 1, 1);
177c38bafeeSHareshx Sankar Raj hb->heartbeat_failed.oid = NULL;
178c38bafeeSHareshx Sankar Raj }
179c38bafeeSHareshx Sankar Raj
180c38bafeeSHareshx Sankar Raj if (hb->heartbeat_sent.oid) {
181c38bafeeSHareshx Sankar Raj sysctl_ctx_entry_del(qat_sysctl_ctx, hb->heartbeat_sent.oid);
182c38bafeeSHareshx Sankar Raj sysctl_remove_oid(hb->heartbeat_sent.oid, 1, 1);
183c38bafeeSHareshx Sankar Raj hb->heartbeat_sent.oid = NULL;
184c38bafeeSHareshx Sankar Raj }
185c38bafeeSHareshx Sankar Raj
18678ee8d1cSJulian Grajkowski adf_heartbeat_clean(accel_dev);
187c38bafeeSHareshx Sankar Raj
18878ee8d1cSJulian Grajkowski return 0;
18978ee8d1cSJulian Grajkowski }
190