xref: /freebsd/sys/dev/qat/qat_common/adf_freebsd_admin.c (revision 8aac90f18aef7c9eea906c3ff9a001ca7b94f375)
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 "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
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
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
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
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 	       u32 ae_mask)
208 {
209 	int i;
210 	unsigned int 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
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 	u32 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
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 	u32 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
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 	u32 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
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 	u32 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
308 adf_get_fw_status(struct adf_accel_dev *accel_dev,
309 		  u8 *major,
310 		  u8 *minor,
311 		  u8 *patch)
312 {
313 	struct icp_qat_fw_init_admin_req req;
314 	struct icp_qat_fw_init_admin_resp resp;
315 	u32 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
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 	unsigned int 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
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 	unsigned long sym_ae_msk = 0;
358 	u8 sym_ae_msk_size = 0;
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 	sym_ae_msk_size =
366 	    sizeof(accel_dev->au_info->sym_ae_msk) * BITS_PER_BYTE;
367 
368 	req.cmd_id = ICP_QAT_FW_PKE_REPLAY_STATS_GET;
369 	for_each_set_bit(i, &sym_ae_msk, sym_ae_msk_size)
370 	{
371 		memset(&resp, 0, sizeof(struct icp_qat_fw_init_admin_resp));
372 		if (adf_put_admin_msg_sync(accel_dev, i, &req, &resp) ||
373 		    resp.status) {
374 			return EFAULT;
375 		}
376 		*suc_count += resp.successful_count;
377 		*unsuc_count += resp.unsuccessful_count;
378 	}
379 	return 0;
380 }
381 
382 /**
383  * adf_send_admin_init() - Function sends init message to FW
384  * @accel_dev: Pointer to acceleration device.
385  *
386  * Function sends admin init message to the FW
387  *
388  * Return: 0 on success, error code otherwise.
389  */
390 int
391 adf_send_admin_init(struct adf_accel_dev *accel_dev)
392 {
393 	int ret;
394 	u32 dc_capabilities = 0;
395 	unsigned int storage_enabled = 0;
396 
397 	if (GET_HW_DATA(accel_dev)->query_storage_cap) {
398 		ret = adf_get_dc_capabilities(accel_dev, &dc_capabilities);
399 		if (ret) {
400 			device_printf(GET_DEV(accel_dev),
401 				      "Cannot get dc capabilities\n");
402 			return ret;
403 		}
404 		accel_dev->hw_device->extended_dc_capabilities =
405 		    dc_capabilities;
406 	} else {
407 		ret = GET_HW_DATA(accel_dev)->get_storage_enabled(
408 		    accel_dev, &storage_enabled);
409 		if (ret) {
410 			device_printf(GET_DEV(accel_dev),
411 				      "Cannot get storage enabled\n");
412 			return ret;
413 		}
414 	}
415 
416 	ret = adf_set_heartbeat_timer(accel_dev);
417 	if (ret) {
418 		if (ret == EINVAL) {
419 			device_printf(GET_DEV(accel_dev),
420 				      "Cannot set heartbeat timer\n");
421 			return ret;
422 		}
423 		device_printf(GET_DEV(accel_dev),
424 			      "Heartbeat is not supported\n");
425 	}
426 
427 	ret = adf_get_fw_status(accel_dev,
428 				&accel_dev->fw_versions.fw_version_major,
429 				&accel_dev->fw_versions.fw_version_minor,
430 				&accel_dev->fw_versions.fw_version_patch);
431 	if (ret) {
432 		device_printf(GET_DEV(accel_dev), "Cannot get fw version\n");
433 		return ret;
434 	}
435 
436 	device_printf(GET_DEV(accel_dev),
437 		      "FW version: %d.%d.%d\n",
438 		      accel_dev->fw_versions.fw_version_major,
439 		      accel_dev->fw_versions.fw_version_minor,
440 		      accel_dev->fw_versions.fw_version_patch);
441 
442 	ret = adf_set_fw_constants(accel_dev);
443 	if (ret) {
444 		device_printf(GET_DEV(accel_dev), "Cannot set fw constants\n");
445 		return ret;
446 	}
447 
448 	ret = adf_init_me(accel_dev);
449 	if (ret)
450 		device_printf(GET_DEV(accel_dev), "Cannot init AE\n");
451 
452 	return ret;
453 }
454 
455 int
456 adf_init_admin_comms(struct adf_accel_dev *accel_dev)
457 {
458 	struct adf_admin_comms *admin = NULL;
459 	struct adf_hw_device_data *hw_data = NULL;
460 	struct adf_bar *pmisc = NULL;
461 	struct resource *csr = NULL;
462 	struct admin_info admin_csrs_info;
463 	unsigned int adminmsg_u, adminmsg_l;
464 	u64 reg_val = 0;
465 	int ret = 0;
466 
467 	admin = kzalloc_node(sizeof(*accel_dev->admin),
468 			     M_WAITOK | M_ZERO,
469 			     dev_to_node(GET_DEV(accel_dev)));
470 	hw_data = accel_dev->hw_device;
471 	pmisc = &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
472 	csr = pmisc->virt_addr;
473 	ret = bus_dma_mem_create(&admin->dma_mem,
474 				 accel_dev->dma_tag,
475 				 FREEBSD_ALLIGNMENT_SIZE,
476 				 BUS_SPACE_MAXADDR,
477 				 PAGE_SIZE,
478 				 0);
479 	if (ret != 0) {
480 		device_printf(GET_DEV(accel_dev),
481 			      "Failed to allocate dma buff\n");
482 		kfree(admin);
483 		return ret;
484 	}
485 	admin->virt_addr = admin->dma_mem.dma_vaddr;
486 	admin->phy_addr = admin->dma_mem.dma_baddr;
487 	bzero(admin->virt_addr, PAGE_SIZE);
488 
489 	ret = bus_dmamap_create(accel_dev->dma_tag, 0, &admin->const_tbl_map);
490 	if (ret != 0) {
491 		device_printf(GET_DEV(accel_dev), "Failed to create DMA map\n");
492 		bus_dma_mem_free(&admin->dma_mem);
493 		kfree(admin);
494 		return ret;
495 	}
496 
497 	ret = bus_dmamap_load(accel_dev->dma_tag,
498 			      admin->const_tbl_map,
499 			      (void *)const_tab,
500 			      1024,
501 			      dma_callback,
502 			      &admin->const_tbl_addr,
503 			      BUS_DMA_NOWAIT);
504 	if (ret == 0 && admin->const_tbl_addr == 0)
505 		ret = EFBIG;
506 	if (ret != 0) {
507 		device_printf(GET_DEV(accel_dev),
508 			      "Failed to map const table for DMA\n");
509 		bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
510 		bus_dma_mem_free(&admin->dma_mem);
511 		kfree(admin);
512 		return ret;
513 	}
514 
515 	/* DMA ARAM address map */
516 	if (accel_dev->aram_info) {
517 		ret =
518 		    bus_dmamap_create(accel_dev->dma_tag, 0, &admin->aram_map);
519 		if (ret != 0) {
520 			device_printf(GET_DEV(accel_dev),
521 				      "Failed to create DMA map\n");
522 			bus_dma_mem_free(&admin->dma_mem);
523 			kfree(admin);
524 			return ret;
525 		}
526 		ret = bus_dmamap_load(accel_dev->dma_tag,
527 				      admin->aram_map,
528 				      (void *)accel_dev->aram_info,
529 				      sizeof(*accel_dev->aram_info),
530 				      dma_callback,
531 				      &admin->aram_map_phys_addr,
532 				      BUS_DMA_NOWAIT);
533 
534 		if (ret == 0 && admin->aram_map_phys_addr == 0)
535 			ret = EFBIG;
536 		if (ret != 0) {
537 			device_printf(GET_DEV(accel_dev),
538 				      "Failed to map aram phys addr for DMA\n");
539 			bus_dmamap_destroy(accel_dev->dma_tag, admin->aram_map);
540 			bus_dma_mem_free(&admin->dma_mem);
541 			kfree(admin);
542 			return ret;
543 		}
544 	}
545 
546 	ret = bus_dma_mem_create(&admin->dma_hb,
547 				 accel_dev->dma_tag,
548 				 FREEBSD_ALLIGNMENT_SIZE,
549 				 BUS_SPACE_MAXADDR,
550 				 PAGE_SIZE,
551 				 0);
552 	if (ret != 0) {
553 		device_printf(GET_DEV(accel_dev),
554 			      "Failed to allocate dma buff\n");
555 		bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
556 		bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
557 		bus_dma_mem_free(&admin->dma_mem);
558 		kfree(admin);
559 		return ret;
560 	}
561 
562 	admin->virt_hb_addr = admin->dma_hb.dma_vaddr;
563 	admin->phy_hb_addr = admin->dma_hb.dma_baddr;
564 	bzero(admin->virt_hb_addr, PAGE_SIZE);
565 
566 	hw_data->get_admin_info(&admin_csrs_info);
567 
568 	adminmsg_u = admin_csrs_info.admin_msg_ur;
569 	adminmsg_l = admin_csrs_info.admin_msg_lr;
570 	reg_val = (u64)admin->phy_addr;
571 	ADF_CSR_WR(csr, adminmsg_u, reg_val >> 32);
572 	ADF_CSR_WR(csr, adminmsg_l, reg_val);
573 	sx_init(&admin->lock, "qat admin");
574 	admin->mailbox_addr = csr;
575 	accel_dev->admin = admin;
576 	return 0;
577 }
578 
579 void
580 adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
581 {
582 	struct adf_admin_comms *admin = accel_dev->admin;
583 
584 	if (!admin)
585 		return;
586 
587 	if (admin->virt_addr)
588 		bus_dma_mem_free(&admin->dma_mem);
589 
590 	if (admin->virt_hb_addr)
591 		bus_dma_mem_free(&admin->dma_hb);
592 
593 	bus_dmamap_unload(accel_dev->dma_tag, admin->const_tbl_map);
594 	bus_dmamap_destroy(accel_dev->dma_tag, admin->const_tbl_map);
595 	sx_destroy(&admin->lock);
596 	kfree(admin);
597 	accel_dev->admin = NULL;
598 }
599