xref: /freebsd/sys/dev/qat/qat_common/adf_freebsd_heartbeat_dbg.c (revision 8aa51e6d7de0a828020de64560d1385e15955a1c)
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