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