xref: /freebsd/sys/dev/qat/qat_common/adf_freebsd_admin.c (revision 682f135f5de39cfc24cfd529ea8a161e94c76c8e)
1 /* SPDX-License-Identifier: BSD-3-Clause */
2 /* Copyright(c) 2007-2026 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 "adf_heartbeat.h"
14 #include <sys/types.h>
15 #include <sys/lock.h>
16 #include <sys/sx.h>
17 #include <sys/malloc.h>
18 #include <sys/systm.h>
19 #include <dev/pci/pcivar.h>
20 #include <machine/bus_dma.h>
21 
22 #include <linux/delay.h>
23 
24 #define ADF_CONST_TABLE_VERSION_BYTE (0)
25 /* Keep version number in range 0-255 */
26 #define ADF_CONST_TABLE_VERSION (1)
27 
28 /* Admin Messages Registers */
29 #define ADF_MAILBOX_STRIDE 0x1000
30 #define ADF_ADMINMSG_LEN 32
31 #define FREEBSD_ALLIGNMENT_SIZE 64
32 #define ADF_INIT_CONFIG_SIZE 1024
33 
34 static u8 const_tab[1024] __aligned(1024) = {
35 ADF_CONST_TABLE_VERSION,
36 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
37 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
38 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
39 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
40 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
41 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00,
42 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00,
43 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
44 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00,
45 0x00, 0x00, 0x00, 0x03, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x01,
46 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
47 0x00, 0x13, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x02, 0x00, 0x00,
48 0x00, 0x00, 0x00, 0x00, 0x13, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13,
49 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00,
50 0x00, 0x00, 0x33, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00,
51 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
52 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
53 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
54 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
55 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
57 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
58 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00,
59 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
60 0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, 0xfe, 0xdc, 0xba, 0x98, 0x76,
61 0x54, 0x32, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
62 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x45, 0x23, 0x01, 0xef, 0xcd, 0xab,
63 0x89, 0x98, 0xba, 0xdc, 0xfe, 0x10, 0x32, 0x54, 0x76, 0xc3, 0xd2, 0xe1, 0xf0,
64 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
65 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc1, 0x05, 0x9e,
67 0xd8, 0x36, 0x7c, 0xd5, 0x07, 0x30, 0x70, 0xdd, 0x17, 0xf7, 0x0e, 0x59, 0x39,
68 0xff, 0xc0, 0x0b, 0x31, 0x68, 0x58, 0x15, 0x11, 0x64, 0xf9, 0x8f, 0xa7, 0xbe,
69 0xfa, 0x4f, 0xa4, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
70 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xbb, 0x67, 0xae,
71 0x85, 0x3c, 0x6e, 0xf3, 0x72, 0xa5, 0x4f, 0xf5, 0x3a, 0x51, 0x0e, 0x52, 0x7f,
72 0x9b, 0x05, 0x68, 0x8c, 0x1f, 0x83, 0xd9, 0xab, 0x5b, 0xe0, 0xcd, 0x19, 0x05,
73 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
74 0x00, 0x00, 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8, 0x62, 0x9a, 0x29,
75 0x2a, 0x36, 0x7c, 0xd5, 0x07, 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
76 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39, 0x67, 0x33, 0x26, 0x67, 0xff,
77 0xc0, 0x0b, 0x31, 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11, 0xdb, 0x0c,
78 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7, 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f,
79 0xa4, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
80 0x00, 0x00, 0x00, 0x00, 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08, 0xbb,
81 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b, 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94,
82 0xf8, 0x2b, 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1, 0x51, 0x0e, 0x52,
83 0x7f, 0xad, 0xe6, 0x82, 0xd1, 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
84 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b, 0x5b, 0xe0, 0xcd, 0x19, 0x13,
85 0x7e, 0x21, 0x79, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
86 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x16, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
87 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00,
88 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x18,
89 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
90 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x01, 0x00,
91 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 0x15, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, 0x00,
93 0x00, 0x00, 0x00, 0x14, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x02,
94 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00,
95 0x00, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x00, 0x00, 0x00,
96 0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25,
97 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, 0x00,
98 0x00, 0x00, 0x12, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x00, 0x00,
99 0x00, 0x00, 0x00, 0x00, 0x00, 0x43, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
100 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x45, 0x01, 0x00, 0x00, 0x00,
101 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x44, 0x01,
102 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
103 0x00, 0x2B, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
104 0x00, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
105 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00,
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00,
107 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
108 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
109 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
111 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
112 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
113 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
114 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
115 
116 #define ADF_ADMIN_POLL_INTERVAL_US 20
117 #define ADF_ADMIN_POLL_RETRIES 5000
118 
119 static void
dma_callback(void * arg,bus_dma_segment_t * segs,int nseg,int error)120 dma_callback(void *arg, bus_dma_segment_t *segs, int nseg, int error)
121 {
122 	bus_addr_t *addr;
123 
124 	addr = arg;
125 	if (error == 0 && nseg == 1)
126 		*addr = segs[0].ds_addr;
127 	else
128 		*addr = 0;
129 }
130 
131 int
adf_put_admin_msg_sync(struct adf_accel_dev * accel_dev,u32 ae,void * in,void * out)132 adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev,
133 		       u32 ae,
134 		       void *in,
135 		       void *out)
136 {
137 	struct adf_admin_comms *admin = accel_dev->admin;
138 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
139 	struct resource *mailbox = admin->mailbox_addr;
140 	struct admin_info admin_csrs_info;
141 
142 	hw_data->get_admin_info(&admin_csrs_info);
143 	int offset = ae * ADF_ADMINMSG_LEN * 2;
144 	int mb_offset =
145 	    ae * ADF_MAILBOX_STRIDE + admin_csrs_info.mailbox_offset;
146 
147 	int times, received;
148 	struct icp_qat_fw_init_admin_req *request = in;
149 
150 	sx_xlock(&admin->lock);
151 
152 	if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
153 		sx_xunlock(&admin->lock);
154 		return EAGAIN;
155 	}
156 
157 	memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
158 	ADF_CSR_WR(mailbox, mb_offset, 1);
159 	received = 0;
160 	for (times = 0; times < ADF_ADMIN_POLL_RETRIES; times++) {
161 		usleep_range(ADF_ADMIN_POLL_INTERVAL_US,
162 			     ADF_ADMIN_POLL_INTERVAL_US * 2);
163 		if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
164 			received = 1;
165 			break;
166 		}
167 	}
168 	if (received)
169 		memcpy(out,
170 		       admin->virt_addr + offset + ADF_ADMINMSG_LEN,
171 		       ADF_ADMINMSG_LEN);
172 	else
173 		device_printf(GET_DEV(accel_dev),
174 			      "Failed to send admin msg %d to accelerator %d\n",
175 			      request->cmd_id,
176 			      ae);
177 
178 	sx_xunlock(&admin->lock);
179 	return received ? 0 : EFAULT;
180 }
181 
182 static inline int
adf_set_dc_ibuf(struct adf_accel_dev * accel_dev,struct icp_qat_fw_init_admin_req * req)183 adf_set_dc_ibuf(struct adf_accel_dev *accel_dev,
184 		struct icp_qat_fw_init_admin_req *req)
185 {
186 	char val[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
187 	unsigned long ibuf_size = 0;
188 
189 	if (!adf_cfg_get_param_value(
190 		accel_dev, ADF_GENERAL_SEC, ADF_INTER_BUF_SIZE, val)) {
191 		if (compat_strtoul(val, 0, &ibuf_size))
192 			return EFAULT;
193 	}
194 
195 	if (ibuf_size != 32 && ibuf_size != 64)
196 		ibuf_size = 64;
197 
198 	req->ibuf_size_in_kb = ibuf_size;
199 
200 	return 0;
201 }
202 
203 int
adf_send_admin(struct adf_accel_dev * accel_dev,struct icp_qat_fw_init_admin_req * req,struct icp_qat_fw_init_admin_resp * resp,u64 ae_mask)204 adf_send_admin(struct adf_accel_dev *accel_dev,
205 	       struct icp_qat_fw_init_admin_req *req,
206 	       struct icp_qat_fw_init_admin_resp *resp,
207 	       u64 ae_mask)
208 {
209 	int i;
210 	u64 mask;
211 
212 	for (i = 0, mask = ae_mask; mask; i++, mask >>= 1) {
213 		if (!(mask & 1))
214 			continue;
215 		if (adf_put_admin_msg_sync(accel_dev, i, req, resp) ||
216 		    resp->status)
217 			return EFAULT;
218 	}
219 
220 	return 0;
221 }
222 
223 static int
adf_init_me(struct adf_accel_dev * accel_dev)224 adf_init_me(struct adf_accel_dev *accel_dev)
225 {
226 	struct icp_qat_fw_init_admin_req req;
227 	struct icp_qat_fw_init_admin_resp resp;
228 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
229 	u64 ae_mask = hw_device->ae_mask;
230 
231 	explicit_bzero(&req, sizeof(req));
232 	explicit_bzero(&resp, sizeof(resp));
233 	req.cmd_id = ICP_QAT_FW_INIT_ME;
234 
235 	if (adf_set_dc_ibuf(accel_dev, &req))
236 		return EFAULT;
237 	if (accel_dev->aram_info) {
238 		req.init_cfg_sz = sizeof(*accel_dev->aram_info);
239 		req.init_cfg_ptr = (u64)accel_dev->admin->aram_map_phys_addr;
240 	}
241 	if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
242 		return EFAULT;
243 
244 	return 0;
245 }
246 
247 static int
adf_set_heartbeat_timer(struct adf_accel_dev * accel_dev)248 adf_set_heartbeat_timer(struct adf_accel_dev *accel_dev)
249 {
250 	struct icp_qat_fw_init_admin_req req;
251 	struct icp_qat_fw_init_admin_resp resp;
252 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
253 	u64 ae_mask = hw_device->ae_mask;
254 	u32 heartbeat_ticks;
255 
256 	explicit_bzero(&req, sizeof(req));
257 	req.cmd_id = ICP_QAT_FW_HEARTBEAT_TIMER_SET;
258 	req.hb_cfg_ptr = accel_dev->admin->phy_hb_addr;
259 	if (adf_get_hb_timer(accel_dev, &heartbeat_ticks))
260 		return EINVAL;
261 	req.heartbeat_ticks = heartbeat_ticks;
262 
263 	if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
264 		return EFAULT;
265 
266 	return 0;
267 }
268 
269 static int
adf_get_dc_capabilities(struct adf_accel_dev * accel_dev,u32 * capabilities)270 adf_get_dc_capabilities(struct adf_accel_dev *accel_dev, u32 *capabilities)
271 {
272 	struct icp_qat_fw_init_admin_req req;
273 	struct icp_qat_fw_init_admin_resp resp;
274 	u64 ae_mask = 1;
275 
276 	explicit_bzero(&req, sizeof(req));
277 	req.cmd_id = ICP_QAT_FW_COMP_CAPABILITY_GET;
278 
279 	if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
280 		return EFAULT;
281 
282 	*capabilities = resp.extended_features;
283 
284 	return 0;
285 }
286 
287 static int
adf_set_fw_constants(struct adf_accel_dev * accel_dev)288 adf_set_fw_constants(struct adf_accel_dev *accel_dev)
289 {
290 	struct icp_qat_fw_init_admin_req req;
291 	struct icp_qat_fw_init_admin_resp resp;
292 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
293 	u64 ae_mask = hw_device->admin_ae_mask;
294 
295 	explicit_bzero(&req, sizeof(req));
296 	req.cmd_id = ICP_QAT_FW_CONSTANTS_CFG;
297 
298 	req.init_cfg_sz = sizeof(const_tab);
299 	req.init_cfg_ptr = accel_dev->admin->const_tbl_addr;
300 
301 	if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
302 		return EFAULT;
303 
304 	return 0;
305 }
306 
307 static int
adf_get_fw_status(struct adf_accel_dev * accel_dev,u16 * major,u16 * minor,u32 * patch)308 adf_get_fw_status(struct adf_accel_dev *accel_dev,
309 		  u16 *major,
310 		  u16 *minor,
311 		  u32 *patch)
312 {
313 	struct icp_qat_fw_init_admin_req req;
314 	struct icp_qat_fw_init_admin_resp resp;
315 	u64 ae_mask = 1;
316 
317 	explicit_bzero(&req, sizeof(req));
318 	req.cmd_id = ICP_QAT_FW_STATUS_GET;
319 
320 	if (adf_send_admin(accel_dev, &req, &resp, ae_mask))
321 		return EFAULT;
322 
323 	*major = resp.version_major_num;
324 	*minor = resp.version_minor_num;
325 	*patch = resp.version_patch_num;
326 
327 	return 0;
328 }
329 
330 int
adf_get_fw_timestamp(struct adf_accel_dev * accel_dev,u64 * timestamp)331 adf_get_fw_timestamp(struct adf_accel_dev *accel_dev, u64 *timestamp)
332 {
333 	struct icp_qat_fw_init_admin_req req;
334 	struct icp_qat_fw_init_admin_resp rsp;
335 	u64 ae_mask = 1;
336 
337 	if (!accel_dev || !timestamp)
338 		return EFAULT;
339 
340 	explicit_bzero(&req, sizeof(req));
341 	req.cmd_id = ICP_QAT_FW_TIMER_GET;
342 
343 	if (adf_send_admin(accel_dev, &req, &rsp, ae_mask))
344 		return EFAULT;
345 
346 	*timestamp = rsp.timestamp;
347 	return 0;
348 }
349 
350 int
adf_get_fw_pke_stats(struct adf_accel_dev * accel_dev,u64 * suc_count,u64 * unsuc_count)351 adf_get_fw_pke_stats(struct adf_accel_dev *accel_dev,
352 		     u64 *suc_count,
353 		     u64 *unsuc_count)
354 {
355 	struct icp_qat_fw_init_admin_req req = { 0 };
356 	struct icp_qat_fw_init_admin_resp resp = { 0 };
357 	u64 sym_ae_msk = 0;
358 	u64 mask;
359 	u8 i = 0;
360 
361 	if (!suc_count || !unsuc_count)
362 		return EFAULT;
363 
364 	sym_ae_msk = accel_dev->au_info->sym_ae_msk;
365 
366 	req.cmd_id = ICP_QAT_FW_PKE_REPLAY_STATS_GET;
367 	for (i = 0, mask = sym_ae_msk; mask; i++, mask >>= 1) {
368 		if (!(mask & 1ULL))
369 			continue;
370 		memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
371 		if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
372 		    resp.status) {
373 			return EFAULT;
374 		}
375 		*suc_count += resp.successful_count;
376 		*unsuc_count += resp.unsuccessful_count;
377 	}
378 	return 0;
379 }
380 
381 /**
382  * adf_send_admin_init() - Function sends init message to FW
383  * @accel_dev: Pointer to acceleration device.
384  *
385  * Function sends admin init message to the FW
386  *
387  * Return: 0 on success, error code otherwise.
388  */
389 int
adf_send_admin_init(struct adf_accel_dev * accel_dev)390 adf_send_admin_init(struct adf_accel_dev *accel_dev)
391 {
392 	int ret;
393 	u32 dc_capabilities = 0;
394 	unsigned int storage_enabled = 0;
395 
396 	if (GET_HW_DATA(accel_dev)->query_storage_cap) {
397 		ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities);
398 		if (ret) {
399 			device_printf(GET_DEV(accel_dev),
400 				      "Cannot get dc capabilities\n");
401 			return ret;
402 		}
403 		accel_dev->hw_device->extended_dc_capabilities =
404 		    dc_capabilities;
405 	} else {
406 		ret = GET_HW_DATA(accel_dev)->get_storage_enabled(
407 		    accel_dev, &storage_enabled);
408 		if (ret) {
409 			device_printf(GET_DEV(accel_dev),
410 				      "Cannot get storage enabled\n");
411 			return ret;
412 		}
413 	}
414 
415 	ret = adf_set_heartbeat_timer(accel_dev);
416 	if (ret) {
417 		if (ret == EINVAL) {
418 			device_printf(GET_DEV(accel_dev),
419 				      "Cannot set heartbeat timer\n");
420 			return ret;
421 		}
422 		device_printf(GET_DEV(accel_dev),
423 			      "Heartbeat is not supported\n");
424 	}
425 
426 	ret = adf_get_fw_status(accel_dev,
427 				&accel_dev->fw_versions.fw_version_major,
428 				&accel_dev->fw_versions.fw_version_minor,
429 				&accel_dev->fw_versions.fw_version_patch);
430 	if (ret) {
431 		device_printf(GET_DEV(accel_dev), "Cannot get fw version\n");
432 		return ret;
433 	}
434 
435 	device_printf(GET_DEV(accel_dev),
436 		      "FW version: %d.%d.%d\n",
437 		      accel_dev->fw_versions.fw_version_major,
438 		      accel_dev->fw_versions.fw_version_minor,
439 		      accel_dev->fw_versions.fw_version_patch);
440 
441 	ret = adf_set_fw_constants(accel_dev);
442 	if (ret) {
443 		device_printf(GET_DEV(accel_dev), "Cannot set fw constants\n");
444 		return ret;
445 	}
446 
447 	ret = adf_init_me(accel_dev);
448 	if (ret)
449 		device_printf(GET_DEV(accel_dev), "Cannot init AE\n");
450 
451 	return ret;
452 }
453 
454 int
adf_init_admin_comms(struct adf_accel_dev * accel_dev)455 adf_init_admin_comms(struct adf_accel_dev *accel_dev)
456 {
457 	struct adf_admin_comms *admin = NULL;
458 	struct adf_hw_device_data *hw_data = NULL;
459 	struct adf_bar *pmisc = NULL;
460 	struct resource *csr = NULL;
461 	struct admin_info admin_csrs_info;
462 	unsigned int adminmsg_u, adminmsg_l;
463 	u64 reg_val = 0;
464 	int ret = 0;
465 
466 	admin = kzalloc_node(sizeof(*accel_dev->admin),
467 			     M_WAITOK | M_ZERO,
468 			     dev_to_node(GET_DEV(accel_dev)));
469 	hw_data = accel_dev->hw_device;
470 	pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
471 	csr = pmisc->virt_addr;
472 	ret = bus_dma_mem_create(&admin->dma_mem,
473 				 accel_dev->dma_tag,
474 				 FREEBSD_ALLIGNMENT_SIZE,
475 				 BUS_SPACE_MAXADDR,
476 				 PAGE_SIZE,
477 				 0);
478 	if (ret != 0) {
479 		device_printf(GET_DEV(accel_dev),
480 			      "Failed to allocate dma buff\n");
481 		kfree(admin);
482 		return ret;
483 	}
484 	admin->virt_addr = admin->dma_mem.dma_vaddr;
485 	admin->phy_addr = admin->dma_mem.dma_baddr;
486 	bzero(admin->virt_addr, PAGE_SIZE);
487 
488 	ret = bus_dmamap_create(accel_dev->dma_tag, 0, &admin->const_tbl_map);
489 	if (ret != 0) {
490 		device_printf(GET_DEV(accel_dev), "Failed to create DMA map\n");
491 		bus_dma_mem_free(&admin->dma_mem);
492 		kfree(admin);
493 		return ret;
494 	}
495 
496 	ret = bus_dmamap_load(accel_dev->dma_tag,
497 			      admin->const_tbl_map,
498 			      (void *)const_tab,
499 			      1024,
500 			      dma_callback,
501 			      &admin->const_tbl_addr,
502 			      BUS_DMA_NOWAIT);
503 	if (ret == 0 && admin->const_tbl_addr == 0)
504 		ret = EFBIG;
505 	if (ret != 0) {
506 		device_printf(GET_DEV(accel_dev),
507 			      "Failed to map const table for DMA\n");
508 		bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
509 		bus_dma_mem_free(&admin->dma_mem);
510 		kfree(admin);
511 		return ret;
512 	}
513 
514 	/* DMA ARAM address map */
515 	if (accel_dev->aram_info) {
516 		ret =
517 		    bus_dmamap_create(accel_dev->dma_tag, 0, &admin->aram_map);
518 		if (ret != 0) {
519 			device_printf(GET_DEV(accel_dev),
520 				      "Failed to create DMA map\n");
521 			bus_dma_mem_free(&admin->dma_mem);
522 			kfree(admin);
523 			return ret;
524 		}
525 		ret = bus_dmamap_load(accel_dev->dma_tag,
526 				      admin->aram_map,
527 				      (void *)accel_dev->aram_info,
528 				      sizeof(*accel_dev->aram_info),
529 				      dma_callback,
530 				      &admin->aram_map_phys_addr,
531 				      BUS_DMA_NOWAIT);
532 
533 		if (ret == 0 && admin->aram_map_phys_addr == 0)
534 			ret = EFBIG;
535 		if (ret != 0) {
536 			device_printf(GET_DEV(accel_dev),
537 				      "Failed to map aram phys addr for DMA\n");
538 			bus_dmamap_destroy(accel_dev->dma_tag, admin->aram_map);
539 			bus_dma_mem_free(&admin->dma_mem);
540 			kfree(admin);
541 			return ret;
542 		}
543 	}
544 
545 	ret = bus_dma_mem_create(&admin->dma_hb,
546 				 accel_dev->dma_tag,
547 				 FREEBSD_ALLIGNMENT_SIZE,
548 				 BUS_SPACE_MAXADDR,
549 				 PAGE_SIZE,
550 				 0);
551 	if (ret != 0) {
552 		device_printf(GET_DEV(accel_dev),
553 			      "Failed to allocate dma buff\n");
554 		bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
555 		bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
556 		bus_dma_mem_free(&admin->dma_mem);
557 		kfree(admin);
558 		return ret;
559 	}
560 
561 	admin->virt_hb_addr = admin->dma_hb.dma_vaddr;
562 	admin->phy_hb_addr = admin->dma_hb.dma_baddr;
563 	bzero(admin->virt_hb_addr, PAGE_SIZE);
564 
565 	hw_data->get_admin_info(&admin_csrs_info);
566 
567 	adminmsg_u = admin_csrs_info.admin_msg_ur;
568 	adminmsg_l = admin_csrs_info.admin_msg_lr;
569 	reg_val = (u64)admin->phy_addr;
570 	ADF_CSR_WR(csr, adminmsg_u, reg_val >> 32);
571 	ADF_CSR_WR(csr, adminmsg_l, reg_val);
572 	sx_init(&admin->lock, "qat admin");
573 	admin->mailbox_addr = csr;
574 	accel_dev->admin = admin;
575 	return 0;
576 }
577 
578 void
adf_exit_admin_comms(struct adf_accel_dev * accel_dev)579 adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
580 {
581 	struct adf_admin_comms *admin = accel_dev->admin;
582 
583 	if (!admin)
584 		return;
585 
586 	if (admin->virt_addr)
587 		bus_dma_mem_free(&admin->dma_mem);
588 
589 	if (admin->virt_hb_addr)
590 		bus_dma_mem_free(&admin->dma_hb);
591 
592 	bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
593 	bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
594 	sx_destroy(&admin->lock);
595 	kfree(admin);
596 	accel_dev->admin = NULL;
597 }
598