1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include <sys/types.h>
5 #include <sys/sysctl.h>
6 #include <sys/systm.h>
7 #include "adf_cnvnr_freq_counters.h"
8 #include "adf_common_drv.h"
9 #include "adf_cfg.h"
10 #include "icp_qat_fw_init_admin.h"
11
12 #define ADF_CNVNR_ERR_MASK 0xFFF
13
14 #define LINE \
15 "+-----------------------------------------------------------------+\n"
16 #define BANNER \
17 "| CNV Error Freq Statistics for Qat Device |\n"
18 #define NEW_LINE "\n"
19 #define REPORT_ENTRY_FORMAT \
20 "|[AE %2d]: TotalErrors: %5d : LastError: %s [%5d] |\n"
21 #define MAX_LINE_LENGTH 128
22 #define MAX_REPORT_SIZE ((ADF_MAX_ACCELENGINES + 3) * MAX_LINE_LENGTH)
23
24 #define PRINT_LINE(line) \
25 (snprintf( \
26 report_ptr, MAX_REPORT_SIZE - (report_ptr - report), "%s", line))
27
28 const char *cnvnr_err_str[] = {"No Error ",
29 "Checksum Error",
30 "Length Error-P",
31 "Decomp Error ",
32 "Xlat Error ",
33 "Length Error-C",
34 "Unknown Error "};
35
36 /* Handler for HB status check */
37 static int qat_cnvnr_ctrs_dbg_read(SYSCTL_HANDLER_ARGS)
38 {
39 struct adf_accel_dev *accel_dev = arg1;
40 struct adf_hw_device_data *hw_device;
41 struct icp_qat_fw_init_admin_req request;
42 struct icp_qat_fw_init_admin_resp response;
43 unsigned long dc_ae_msk = 0;
44 u8 num_aes = 0, ae = 0, error_type = 0, bytes_written = 0;
45 s16 latest_error = 0;
46 char report[MAX_REPORT_SIZE];
47 char *report_ptr = report;
48
49 /* Defensive check */
50 if (!accel_dev || accel_dev->accel_id > ADF_MAX_DEVICES)
51 return EINVAL;
52
53 if (!adf_dev_started(accel_dev)) {
54 device_printf(GET_DEV(accel_dev), "QAT Device not started\n");
55 return EINVAL;
56 }
57
58 hw_device = accel_dev->hw_device;
59 if (!hw_device) {
60 device_printf(GET_DEV(accel_dev), "Failed to get hw_device.\n");
61 return EFAULT;
62 }
63
64 /* Clean report memory */
65 explicit_bzero(report, sizeof(report));
66
67 /* Adding banner to report */
68 bytes_written = PRINT_LINE(NEW_LINE);
69 if (bytes_written <= 0)
70 return EINVAL;
71 report_ptr += bytes_written;
72
73 bytes_written = PRINT_LINE(LINE);
74 if (bytes_written <= 0)
75 return EINVAL;
76 report_ptr += bytes_written;
77
78 bytes_written = PRINT_LINE(BANNER);
79 if (bytes_written <= 0)
80 return EINVAL;
81 report_ptr += bytes_written;
82
83 bytes_written = PRINT_LINE(LINE);
84 if (bytes_written <= 0)
85 return EINVAL;
86 report_ptr += bytes_written;
87
88 if (accel_dev->au_info)
89 dc_ae_msk = accel_dev->au_info->dc_ae_msk;
90
91 /* Extracting number of Acceleration Engines */
92 num_aes = hw_device->get_num_aes(hw_device);
93 for (ae = 0; ae < num_aes; ae++) {
94 if (accel_dev->au_info && !test_bit(ae, &dc_ae_msk))
95 continue;
96 explicit_bzero(&response,
97 sizeof(struct icp_qat_fw_init_admin_resp));
98 request.cmd_id = ICP_QAT_FW_CNV_STATS_GET;
99 if (adf_put_admin_msg_sync(
100 accel_dev, ae, &request, &response) ||
101 response.status) {
102 return EFAULT;
103 }
104 error_type = CNV_ERROR_TYPE_GET(response.latest_error);
105 if (error_type == CNV_ERR_TYPE_DECOMP_PRODUCED_LENGTH_ERROR ||
106 error_type == CNV_ERR_TYPE_DECOMP_CONSUMED_LENGTH_ERROR) {
107 latest_error =
108 CNV_ERROR_LENGTH_DELTA_GET(response.latest_error);
109 } else if (error_type == CNV_ERR_TYPE_DECOMPRESSION_ERROR ||
110 error_type == CNV_ERR_TYPE_TRANSLATION_ERROR) {
111 latest_error =
112 CNV_ERROR_DECOMP_STATUS_GET(response.latest_error);
113 } else {
114 latest_error =
115 response.latest_error & ADF_CNVNR_ERR_MASK;
116 }
117
118 bytes_written =
119 snprintf(report_ptr,
120 MAX_REPORT_SIZE - (report_ptr - report),
121 REPORT_ENTRY_FORMAT,
122 ae,
123 response.error_count,
124 cnvnr_err_str[error_type],
125 latest_error);
126 if (bytes_written <= 0) {
127 printf("ERROR: No space left in CnV ctrs line buffer\n"
128 "\tAcceleration ID: %d, Engine: %d\n",
129 accel_dev->accel_id,
130 ae);
131 break;
132 }
133 report_ptr += bytes_written;
134 }
135
136 sysctl_handle_string(oidp, report, sizeof(report), req);
137 return 0;
138 }
139
140 int
141 adf_cnvnr_freq_counters_add(struct adf_accel_dev *accel_dev)
142 {
143 struct sysctl_ctx_list *qat_sysctl_ctx;
144 struct sysctl_oid *qat_cnvnr_ctrs_sysctl_tree;
145 struct sysctl_oid *oid_rc;
146
147 /* Defensive checks */
148 if (!accel_dev)
149 return EINVAL;
150
151 /* Creating context and tree */
152 qat_sysctl_ctx =
153 device_get_sysctl_ctx(accel_dev->accel_pci_dev.pci_dev);
154 qat_cnvnr_ctrs_sysctl_tree =
155 device_get_sysctl_tree(accel_dev->accel_pci_dev.pci_dev);
156
157 /* Create "cnv_error" string type leaf - with callback */
158 oid_rc = SYSCTL_ADD_PROC(qat_sysctl_ctx,
159 SYSCTL_CHILDREN(qat_cnvnr_ctrs_sysctl_tree),
160 OID_AUTO,
161 "cnv_error",
162 CTLTYPE_STRING | CTLFLAG_RD,
163 accel_dev,
164 0,
165 qat_cnvnr_ctrs_dbg_read,
166 "IU",
167 "QAT CnVnR status");
168
169 if (!oid_rc) {
170 printf("ERROR: Memory allocation failed\n");
171 return ENOMEM;
172 }
173 return 0;
174 }
175
176 void
177 adf_cnvnr_freq_counters_remove(struct adf_accel_dev *accel_dev)
178 {
179 }
Cache object: 4a9e0847402ec3a096732e4965f0dad1
|