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