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