1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2025 Intel Corporation */
3 #include "adf_accel_devices.h"
4 #include "adf_common_drv.h"
5 #include "adf_dev_err.h"
6 #include "adf_freebsd_pfvf_ctrs_dbg.h"
7 #include <sys/priv.h>
8
9 #define MAX_REPORT_LINES (14)
10 #define MAX_REPORT_LINE_LEN (64)
11 #define MAX_REPORT_SIZE (MAX_REPORT_LINES * MAX_REPORT_LINE_LEN)
12
13 static void
adf_pfvf_ctrs_prepare_report(char * rep,struct pfvf_stats * pfvf_counters)14 adf_pfvf_ctrs_prepare_report(char *rep, struct pfvf_stats *pfvf_counters)
15 {
16 unsigned int value = 0;
17 char *string = "unknown";
18 unsigned int pos = 0;
19 char *ptr = rep;
20
21 for (pos = 0; pos < MAX_REPORT_LINES; pos++) {
22 switch (pos) {
23 case 0:
24 string = "Messages written to CSR";
25 value = pfvf_counters->tx;
26 break;
27 case 1:
28 string = "Messages read from CSR";
29 value = pfvf_counters->rx;
30 break;
31 case 2:
32 string = "Spurious Interrupt";
33 value = pfvf_counters->spurious;
34 break;
35 case 3:
36 string = "Block messages sent";
37 value = pfvf_counters->blk_tx;
38 break;
39 case 4:
40 string = "Block messages received";
41 value = pfvf_counters->blk_rx;
42 break;
43 case 5:
44 string = "Blocks received with CRC errors";
45 value = pfvf_counters->crc_err;
46 break;
47 case 6:
48 string = "CSR in use";
49 value = pfvf_counters->busy;
50 break;
51 case 7:
52 string = "No acknowledgment";
53 value = pfvf_counters->no_ack;
54 break;
55 case 8:
56 string = "Collisions";
57 value = pfvf_counters->collision;
58 break;
59 case 9:
60 string = "Put msg timeout";
61 value = pfvf_counters->tx_timeout;
62 break;
63 case 10:
64 string = "No response received";
65 value = pfvf_counters->rx_timeout;
66 break;
67 case 11:
68 string = "Responses received";
69 value = pfvf_counters->rx_rsp;
70 break;
71 case 12:
72 string = "Messages re-transmitted";
73 value = pfvf_counters->retry;
74 break;
75 case 13:
76 string = "Put event timeout";
77 value = pfvf_counters->event_timeout;
78 break;
79 default:
80 value = 0;
81 }
82 if (value)
83 ptr += snprintf(ptr,
84 (MAX_REPORT_SIZE - (ptr - rep)),
85 "%s %u\n",
86 string,
87 value);
88 }
89 }
90
adf_pfvf_ctrs_show(SYSCTL_HANDLER_ARGS)91 static int adf_pfvf_ctrs_show(SYSCTL_HANDLER_ARGS)
92 {
93 struct pfvf_stats *pfvf_counters = arg1;
94 char report[MAX_REPORT_SIZE];
95
96 if (priv_check(curthread, PRIV_DRIVER) != 0)
97 return EPERM;
98
99 if (!pfvf_counters)
100 return EINVAL;
101
102 explicit_bzero(report, sizeof(report));
103 adf_pfvf_ctrs_prepare_report(report, pfvf_counters);
104 sysctl_handle_string(oidp, report, sizeof(report), req);
105 return 0;
106 }
107
108 int
adf_pfvf_ctrs_dbg_add(struct adf_accel_dev * accel_dev)109 adf_pfvf_ctrs_dbg_add(struct adf_accel_dev *accel_dev)
110 {
111 struct sysctl_ctx_list *qat_sysctl_ctx;
112 struct sysctl_oid *qat_pfvf_ctrs_sysctl_tree;
113 struct sysctl_oid *oid_pfvf;
114 device_t dev;
115
116 if (!accel_dev || accel_dev->accel_id > ADF_MAX_DEVICES)
117 return EINVAL;
118
119 dev = GET_DEV(accel_dev);
120
121 qat_sysctl_ctx = device_get_sysctl_ctx(dev);
122 qat_pfvf_ctrs_sysctl_tree = device_get_sysctl_tree(dev);
123
124 oid_pfvf = SYSCTL_ADD_PROC(qat_sysctl_ctx,
125 SYSCTL_CHILDREN(qat_pfvf_ctrs_sysctl_tree),
126 OID_AUTO,
127 "pfvf_counters",
128 CTLTYPE_STRING | CTLFLAG_RD,
129 &accel_dev->u1.vf.pfvf_counters,
130 0,
131 adf_pfvf_ctrs_show,
132 "A",
133 "QAT PFVF counters");
134
135 if (!oid_pfvf) {
136 device_printf(dev, "Failure creating PFVF counters sysctl\n");
137 return ENOMEM;
138 }
139 return 0;
140 }
141