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 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 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 */ 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 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 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