1/* SPDX-License-Identifier: BSD-3-Clause */
2/* Copyright(c) 2007-2022 Intel Corporation */
3#include "qat_freebsd.h"
4#include "adf_cfg.h"
5#include "adf_common_drv.h"
6#include "adf_accel_devices.h"
7#include "icp_qat_uclo.h"
8#include "icp_qat_fw.h"
9#include "icp_qat_fw_init_admin.h"
10#include "adf_cfg_strings.h"
11#include "adf_transport_access_macros.h"
12#include "adf_transport_internal.h"
13#include <sys/malloc.h>
14#include <sys/sbuf.h>
15#include <sys/sysctl.h>
16#include <sys/systm.h>
17
18static int adf_ring_show(SYSCTL_HANDLER_ARGS)
19{
20	struct adf_etr_ring_data *ring = arg1;
21	struct adf_etr_bank_data *bank = ring->bank;
22	struct adf_hw_csr_ops *csr_ops = GET_CSR_OPS(bank->accel_dev);
23	struct resource *csr = ring->bank->csr_addr;
24	struct sbuf sb;
25	int error, word;
26	uint32_t *wp, *end;
27
28	sbuf_new_for_sysctl(&sb, NULL, 128, req);
29	{
30		int head, tail, empty;
31
32		head = csr_ops->read_csr_ring_head(csr,
33						   bank->bank_number,
34						   ring->ring_number);
35		tail = csr_ops->read_csr_ring_tail(csr,
36						   bank->bank_number,
37						   ring->ring_number);
38		empty = csr_ops->read_csr_e_stat(csr, bank->bank_number);
39
40		sbuf_cat(&sb, "\n------- Ring configuration -------\n");
41		sbuf_printf(&sb,
42			    "ring name: %s\n",
43			    ring->ring_debug->ring_name);
44		sbuf_printf(&sb,
45			    "ring num %d, bank num %d\n",
46			    ring->ring_number,
47			    ring->bank->bank_number);
48		sbuf_printf(&sb,
49			    "head %x, tail %x, empty: %d\n",
50			    head,
51			    tail,
52			    (empty & 1 << ring->ring_number) >>
53				ring->ring_number);
54		sbuf_printf(&sb,
55			    "ring size %d, msg size %d\n",
56			    ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size),
57			    ADF_MSG_SIZE_TO_BYTES(ring->msg_size));
58		sbuf_cat(&sb, "----------- Ring data ------------\n");
59	}
60	wp = ring->base_addr;
61	end = (uint32_t *)((char *)ring->base_addr +
62			   ADF_SIZE_TO_RING_SIZE_IN_BYTES(ring->ring_size));
63	while (wp < end) {
64		sbuf_printf(&sb, "%p:", wp);
65		for (word = 0; word < 32 / 4; word++, wp++)
66			sbuf_printf(&sb, " %08x", *wp);
67		sbuf_printf(&sb, "\n");
68	}
69	error = sbuf_finish(&sb);
70	sbuf_delete(&sb);
71	return (error);
72}
73
74int
75adf_ring_debugfs_add(struct adf_etr_ring_data *ring, const char *name)
76{
77	struct adf_etr_ring_debug_entry *ring_debug;
78	char entry_name[8];
79
80	ring_debug = malloc(sizeof(*ring_debug), M_QAT, M_WAITOK | M_ZERO);
81
82	strlcpy(ring_debug->ring_name, name, sizeof(ring_debug->ring_name));
83	snprintf(entry_name,
84		 sizeof(entry_name),
85		 "ring_%02d",
86		 ring->ring_number);
87
88	ring_debug->debug =
89	    SYSCTL_ADD_PROC(&ring->bank->accel_dev->sysctl_ctx,
90			    SYSCTL_CHILDREN(ring->bank->bank_debug_dir),
91			    OID_AUTO,
92			    entry_name,
93			    CTLFLAG_RD | CTLTYPE_STRING,
94			    ring,
95			    0,
96			    adf_ring_show,
97			    "A",
98			    "Ring configuration");
99
100	if (!ring_debug->debug) {
101		printf("QAT: Failed to create ring debug entry.\n");
102		free(ring_debug, M_QAT);
103		return EFAULT;
104	}
105	ring->ring_debug = ring_debug;
106	return 0;
107}
108
109void
110adf_ring_debugfs_rm(struct adf_etr_ring_data *ring)
111{
112	if (ring->ring_debug) {
113		free(ring->ring_debug, M_QAT);
114		ring->ring_debug = NULL;
115	}
116}
117
118static int adf_bank_show(SYSCTL_HANDLER_ARGS)
119{
120	struct adf_etr_bank_data *bank;
121	struct adf_accel_dev *accel_dev = NULL;
122	struct adf_hw_csr_ops *csr_ops = NULL;
123	struct adf_hw_device_data *hw_data = NULL;
124	u8 num_rings_per_bank = 0;
125	struct sbuf sb;
126	int error, ring_id;
127
128	sbuf_new_for_sysctl(&sb, NULL, 128, req);
129	bank = arg1;
130	accel_dev = bank->accel_dev;
131	csr_ops = GET_CSR_OPS(bank->accel_dev);
132	hw_data = accel_dev->hw_device;
133	num_rings_per_bank = hw_data->num_rings_per_bank;
134	sbuf_printf(&sb,
135		    "\n------- Bank %d configuration -------\n",
136		    bank->bank_number);
137	for (ring_id = 0; ring_id < num_rings_per_bank; ring_id++) {
138		struct adf_etr_ring_data *ring = &bank->rings[ring_id];
139		struct resource *csr = bank->csr_addr;
140		int head, tail, empty;
141
142		if (!(bank->ring_mask & 1 << ring_id))
143			continue;
144
145		head = csr_ops->read_csr_ring_head(csr,
146						   bank->bank_number,
147						   ring->ring_number);
148		tail = csr_ops->read_csr_ring_tail(csr,
149						   bank->bank_number,
150						   ring->ring_number);
151		empty = csr_ops->read_csr_e_stat(csr, bank->bank_number);
152
153		sbuf_printf(&sb,
154			    "ring num %02d, head %04x, tail %04x, empty: %d\n",
155			    ring->ring_number,
156			    head,
157			    tail,
158			    (empty & 1 << ring->ring_number) >>
159				ring->ring_number);
160	}
161	error = sbuf_finish(&sb);
162	sbuf_delete(&sb);
163	return (error);
164}
165
166int
167adf_bank_debugfs_add(struct adf_etr_bank_data *bank)
168{
169	struct adf_accel_dev *accel_dev = bank->accel_dev;
170	struct sysctl_oid *parent = accel_dev->transport->debug;
171	char name[9];
172
173	snprintf(name, sizeof(name), "bank_%03d", bank->bank_number);
174
175	bank->bank_debug_dir = SYSCTL_ADD_NODE(&accel_dev->sysctl_ctx,
176					       SYSCTL_CHILDREN(parent),
177					       OID_AUTO,
178					       name,
179					       CTLFLAG_RD | CTLFLAG_SKIP,
180					       NULL,
181					       "");
182
183	if (!bank->bank_debug_dir) {
184		printf("QAT: Failed to create bank debug dir.\n");
185		return EFAULT;
186	}
187
188	bank->bank_debug_cfg =
189	    SYSCTL_ADD_PROC(&accel_dev->sysctl_ctx,
190			    SYSCTL_CHILDREN(bank->bank_debug_dir),
191			    OID_AUTO,
192			    "config",
193			    CTLFLAG_RD | CTLTYPE_STRING,
194			    bank,
195			    0,
196			    adf_bank_show,
197			    "A",
198			    "Bank configuration");
199
200	if (!bank->bank_debug_cfg) {
201		printf("QAT: Failed to create bank debug entry.\n");
202		return EFAULT;
203	}
204
205	return 0;
206}
207
208void
209adf_bank_debugfs_rm(struct adf_etr_bank_data *bank)
210{
211}
212