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