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 <sys/firmware.h>
15 #include <dev/pci/pcivar.h>
16 #include "adf_cfg.h"
17 #include "adf_accel_devices.h"
18 #include "adf_common_drv.h"
19 #include "icp_qat_uclo.h"
20 #include "icp_qat_hw.h"
21
22 #define MMP_VERSION_LEN 4
23
24 struct adf_mmp_version_s {
25 u8 ver_val[MMP_VERSION_LEN];
26 };
27
28 static int
29 request_firmware(const struct firmware **firmware_p, const char *name)
30 {
31 int retval = 0;
32 if (NULL == firmware_p) {
33 return -1;
34 }
35 *firmware_p = firmware_get(name);
36 if (NULL == *firmware_p) {
37 retval = -1;
38 }
39 return retval;
40 }
41
42 int
43 adf_ae_fw_load(struct adf_accel_dev *accel_dev)
44 {
45 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
46 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
47 const void *fw_addr, *mmp_addr;
48 u32 fw_size, mmp_size;
49 s32 i = 0;
50 u32 max_objs = 1;
51 const char *obj_name = NULL;
52 struct adf_mmp_version_s mmp_ver = { { 0 } };
53 unsigned int cfg_ae_mask = 0;
54
55 if (!hw_device->fw_name)
56 return 0;
57
58 if (request_firmware(&loader_data->uof_fw, hw_device->fw_name)) {
59 device_printf(GET_DEV(accel_dev),
60 "Failed to load UOF FW %s\n",
61 hw_device->fw_name);
62 goto out_err;
63 }
64
65 if (request_firmware(&loader_data->mmp_fw, hw_device->fw_mmp_name)) {
66 device_printf(GET_DEV(accel_dev),
67 "Failed to load MMP FW %s\n",
68 hw_device->fw_mmp_name);
69 goto out_err;
70 }
71
72 fw_size = loader_data->uof_fw->datasize;
73 fw_addr = loader_data->uof_fw->data;
74 mmp_size = loader_data->mmp_fw->datasize;
75 mmp_addr = loader_data->mmp_fw->data;
76
77 memcpy(&mmp_ver, mmp_addr, MMP_VERSION_LEN);
78
79 accel_dev->fw_versions.mmp_version_major = mmp_ver.ver_val[0];
80 accel_dev->fw_versions.mmp_version_minor = mmp_ver.ver_val[1];
81 accel_dev->fw_versions.mmp_version_patch = mmp_ver.ver_val[2];
82
83 if (hw_device->accel_capabilities_mask &
84 ADF_ACCEL_CAPABILITIES_CRYPTO_ASYMMETRIC)
85 if (qat_uclo_wr_mimage(loader_data->fw_loader,
86 mmp_addr,
87 mmp_size)) {
88 device_printf(GET_DEV(accel_dev),
89 "Failed to load MMP\n");
90 goto out_err;
91 }
92
93 if (hw_device->get_objs_num)
94 max_objs = hw_device->get_objs_num(accel_dev);
95
96 for (i = max_objs - 1; i >= 0; i--) {
97 /* obj_name is used to indicate the firmware name in MOF,
98 * config unit0 must be loaded at end for authentication
99 */
100 if (hw_device->get_obj_name && hw_device->get_obj_cfg_ae_mask) {
101 unsigned long service_mask = hw_device->service_mask;
102 enum adf_accel_unit_services service_type =
103 ADF_ACCEL_SERVICE_NULL;
104
105 if (hw_device->get_service_type)
106 service_type =
107 hw_device->get_service_type(accel_dev, i);
108 else
109 service_type = BIT(i);
110
111 if (service_mask && !(service_mask & service_type))
112 continue;
113
114 obj_name =
115 hw_device->get_obj_name(accel_dev, service_type);
116 cfg_ae_mask =
117 hw_device->get_obj_cfg_ae_mask(accel_dev,
118 service_type);
119
120 if (!obj_name) {
121 device_printf(
122 GET_DEV(accel_dev),
123 "Invalid object (service = %lx)\n",
124 BIT(i));
125 goto out_err;
126 }
127 if (!cfg_ae_mask)
128 continue;
129 if (qat_uclo_set_cfg_ae_mask(loader_data->fw_loader,
130 cfg_ae_mask)) {
131 device_printf(GET_DEV(accel_dev),
132 "Invalid config AE mask\n");
133 goto out_err;
134 }
135 }
136
137 if (qat_uclo_map_obj(
138 loader_data->fw_loader, fw_addr, fw_size, obj_name)) {
139 device_printf(GET_DEV(accel_dev),
140 "Failed to map UOF firmware\n");
141 goto out_err;
142 }
143 if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) {
144 device_printf(GET_DEV(accel_dev),
145 "Failed to load UOF firmware\n");
146 goto out_err;
147 }
148 qat_uclo_del_obj(loader_data->fw_loader);
149 obj_name = NULL;
150 }
151
152 return 0;
153
154 out_err:
155 adf_ae_fw_release(accel_dev);
156 return EFAULT;
157 }
158
159 void
160 adf_ae_fw_release(struct adf_accel_dev *accel_dev)
161 {
162 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
163 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
164
165 if (!hw_device->fw_name)
166 return;
167 if (loader_data->fw_loader)
168 qat_uclo_del_obj(loader_data->fw_loader);
169 if (loader_data->fw_loader && loader_data->fw_loader->mobj_handle)
170 qat_uclo_del_mof(loader_data->fw_loader);
171 qat_hal_deinit(loader_data->fw_loader);
172 if (loader_data->uof_fw)
173 firmware_put(loader_data->uof_fw, FIRMWARE_UNLOAD);
174 if (loader_data->mmp_fw)
175 firmware_put(loader_data->mmp_fw, FIRMWARE_UNLOAD);
176 loader_data->uof_fw = NULL;
177 loader_data->mmp_fw = NULL;
178 loader_data->fw_loader = NULL;
179 }
180
181 int
182 adf_ae_start(struct adf_accel_dev *accel_dev)
183 {
184 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
185 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
186 uint32_t ae_ctr;
187
188 if (!hw_data->fw_name)
189 return 0;
190
191 ae_ctr = qat_hal_start(loader_data->fw_loader);
192 device_printf(GET_DEV(accel_dev),
193 "qat_dev%d started %d acceleration engines\n",
194 accel_dev->accel_id,
195 ae_ctr);
196 return 0;
197 }
198
199 int
200 adf_ae_stop(struct adf_accel_dev *accel_dev)
201 {
202 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
203 struct adf_hw_device_data *hw_data = accel_dev->hw_device;
204 uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
205
206 if (!hw_data->fw_name)
207 return 0;
208
209 for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
210 if (hw_data->ae_mask & (1 << ae)) {
211 qat_hal_stop(loader_data->fw_loader, ae, 0xFF);
212 ae_ctr++;
213 }
214 }
215 device_printf(GET_DEV(accel_dev),
216 "qat_dev%d stopped %d acceleration engines\n",
217 accel_dev->accel_id,
218 ae_ctr);
219 return 0;
220 }
221
222 static int
223 adf_ae_reset(struct adf_accel_dev *accel_dev, int ae)
224 {
225 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
226
227 qat_hal_reset(loader_data->fw_loader);
228 if (qat_hal_clr_reset(loader_data->fw_loader))
229 return EFAULT;
230
231 return 0;
232 }
233
234 int
235 adf_ae_init(struct adf_accel_dev *accel_dev)
236 {
237 struct adf_fw_loader_data *loader_data;
238 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
239
240 if (!hw_device->fw_name)
241 return 0;
242
243 loader_data = malloc(sizeof(*loader_data), M_QAT, M_WAITOK | M_ZERO);
244
245 accel_dev->fw_loader = loader_data;
246 if (qat_hal_init(accel_dev)) {
247 device_printf(GET_DEV(accel_dev), "Failed to init the AEs\n");
248 free(loader_data, M_QAT);
249 return EFAULT;
250 }
251 if (adf_ae_reset(accel_dev, 0)) {
252 device_printf(GET_DEV(accel_dev), "Failed to reset the AEs\n");
253 qat_hal_deinit(loader_data->fw_loader);
254 free(loader_data, M_QAT);
255 return EFAULT;
256 }
257 return 0;
258 }
259
260 int
261 adf_ae_shutdown(struct adf_accel_dev *accel_dev)
262 {
263 struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
264 struct adf_hw_device_data *hw_device = accel_dev->hw_device;
265
266 if (!hw_device->fw_name)
267 return 0;
268
269 qat_hal_deinit(loader_data->fw_loader);
270 free(accel_dev->fw_loader, M_QAT);
271 accel_dev->fw_loader = NULL;
272 return 0;
273 }
Cache object: 808c696022fb9e7f3e844ed34a56592b
|