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