1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2022 Intel Corporation */
3 /* $FreeBSD$ */
4 #include "adf_accel_devices.h"
5 #include "adf_common_drv.h"
6 #include "adf_dev_err.h"
7 #include "adf_freebsd_pfvf_ctrs_dbg.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
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 
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 (!pfvf_counters)
97 		return EINVAL;
98 
99 	explicit_bzero(report, sizeof(report));
100 	adf_pfvf_ctrs_prepare_report(report, pfvf_counters);
101 	sysctl_handle_string(oidp, report, sizeof(report), req);
102 	return 0;
103 }
104 
105 int
106 adf_pfvf_ctrs_dbg_add(struct adf_accel_dev *accel_dev)
107 {
108 	struct sysctl_ctx_list *qat_sysctl_ctx;
109 	struct sysctl_oid *qat_pfvf_ctrs_sysctl_tree;
110 	struct sysctl_oid *oid_pfvf;
111 	device_t dev;
112 
113 	if (!accel_dev || accel_dev->accel_id > ADF_MAX_DEVICES)
114 		return EINVAL;
115 
116 	dev = GET_DEV(accel_dev);
117 
118 	qat_sysctl_ctx = device_get_sysctl_ctx(dev);
119 	qat_pfvf_ctrs_sysctl_tree = device_get_sysctl_tree(dev);
120 
121 	oid_pfvf = SYSCTL_ADD_PROC(qat_sysctl_ctx,
122 				   SYSCTL_CHILDREN(qat_pfvf_ctrs_sysctl_tree),
123 				   OID_AUTO,
124 				   "pfvf_counters",
125 				   CTLTYPE_STRING | CTLFLAG_RD,
126 				   &accel_dev->u1.vf.pfvf_counters,
127 				   0,
128 				   adf_pfvf_ctrs_show,
129 				   "A",
130 				   "QAT PFVF counters");
131 
132 	if (!oid_pfvf) {
133 		device_printf(dev, "Failure creating PFVF counters sysctl\n");
134 		return ENOMEM;
135 	}
136 	return 0;
137 }
138