xref: /freebsd/sys/dev/qat/qat_common/adf_accel_engine.c (revision 9d54812421274e490dc5f0fe4722ab8d35d9b258)
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 
103 			if (hw_device->service_mask &&
104 			    !(test_bit(i, &service_mask)))
105 				continue;
106 			obj_name = hw_device->get_obj_name(accel_dev, BIT(i));
107 			if (!obj_name) {
108 				device_printf(
109 				    GET_DEV(accel_dev),
110 				    "Invalid object (service = %lx)\n",
111 				    BIT(i));
112 				goto out_err;
113 			}
114 			if (!hw_device->get_obj_cfg_ae_mask(accel_dev, BIT(i)))
115 				continue;
116 			cfg_ae_mask =
117 			    hw_device->get_obj_cfg_ae_mask(accel_dev, BIT(i));
118 			if (qat_uclo_set_cfg_ae_mask(loader_data->fw_loader,
119 						     cfg_ae_mask)) {
120 				device_printf(GET_DEV(accel_dev),
121 					      "Invalid config AE mask\n");
122 				goto out_err;
123 			}
124 		}
125 
126 		if (qat_uclo_map_obj(
127 			loader_data->fw_loader, fw_addr, fw_size, obj_name)) {
128 			device_printf(GET_DEV(accel_dev),
129 				      "Failed to map UOF firmware\n");
130 			goto out_err;
131 		}
132 		if (qat_uclo_wr_all_uimage(loader_data->fw_loader)) {
133 			device_printf(GET_DEV(accel_dev),
134 				      "Failed to load UOF firmware\n");
135 			goto out_err;
136 		}
137 		qat_uclo_del_obj(loader_data->fw_loader);
138 		obj_name = NULL;
139 	}
140 
141 	return 0;
142 
143 out_err:
144 	adf_ae_fw_release(accel_dev);
145 	return EFAULT;
146 }
147 
148 void
149 adf_ae_fw_release(struct adf_accel_dev *accel_dev)
150 {
151 	struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
152 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
153 
154 	if (!hw_device->fw_name)
155 		return;
156 	if (loader_data->fw_loader)
157 		qat_uclo_del_obj(loader_data->fw_loader);
158 	if (loader_data->fw_loader && loader_data->fw_loader->mobj_handle)
159 		qat_uclo_del_mof(loader_data->fw_loader);
160 	qat_hal_deinit(loader_data->fw_loader);
161 	if (loader_data->uof_fw)
162 		firmware_put(loader_data->uof_fw, FIRMWARE_UNLOAD);
163 	if (loader_data->mmp_fw)
164 		firmware_put(loader_data->mmp_fw, FIRMWARE_UNLOAD);
165 	loader_data->uof_fw = NULL;
166 	loader_data->mmp_fw = NULL;
167 	loader_data->fw_loader = NULL;
168 }
169 
170 int
171 adf_ae_start(struct adf_accel_dev *accel_dev)
172 {
173 	struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
174 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
175 	uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
176 
177 	if (!hw_data->fw_name)
178 		return 0;
179 
180 	for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
181 		if (hw_data->ae_mask & (1 << ae)) {
182 			qat_hal_start(loader_data->fw_loader, ae, 0xFF);
183 			ae_ctr++;
184 		}
185 	}
186 	device_printf(GET_DEV(accel_dev),
187 		      "qat_dev%d started %d acceleration engines\n",
188 		      accel_dev->accel_id,
189 		      ae_ctr);
190 	return 0;
191 }
192 
193 int
194 adf_ae_stop(struct adf_accel_dev *accel_dev)
195 {
196 	struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
197 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
198 	uint32_t ae_ctr, ae, max_aes = GET_MAX_ACCELENGINES(accel_dev);
199 
200 	if (!hw_data->fw_name)
201 		return 0;
202 
203 	for (ae = 0, ae_ctr = 0; ae < max_aes; ae++) {
204 		if (hw_data->ae_mask & (1 << ae)) {
205 			qat_hal_stop(loader_data->fw_loader, ae, 0xFF);
206 			ae_ctr++;
207 		}
208 	}
209 	device_printf(GET_DEV(accel_dev),
210 		      "qat_dev%d stopped %d acceleration engines\n",
211 		      accel_dev->accel_id,
212 		      ae_ctr);
213 	return 0;
214 }
215 
216 static int
217 adf_ae_reset(struct adf_accel_dev *accel_dev, int ae)
218 {
219 	struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
220 
221 	qat_hal_reset(loader_data->fw_loader);
222 	if (qat_hal_clr_reset(loader_data->fw_loader))
223 		return EFAULT;
224 
225 	return 0;
226 }
227 
228 int
229 adf_ae_init(struct adf_accel_dev *accel_dev)
230 {
231 	struct adf_fw_loader_data *loader_data;
232 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
233 
234 	if (!hw_device->fw_name)
235 		return 0;
236 
237 	loader_data = malloc(sizeof(*loader_data), M_QAT, M_WAITOK | M_ZERO);
238 
239 	accel_dev->fw_loader = loader_data;
240 	if (qat_hal_init(accel_dev)) {
241 		device_printf(GET_DEV(accel_dev), "Failed to init the AEs\n");
242 		free(loader_data, M_QAT);
243 		return EFAULT;
244 	}
245 	if (adf_ae_reset(accel_dev, 0)) {
246 		device_printf(GET_DEV(accel_dev), "Failed to reset the AEs\n");
247 		qat_hal_deinit(loader_data->fw_loader);
248 		free(loader_data, M_QAT);
249 		return EFAULT;
250 	}
251 	return 0;
252 }
253 
254 int
255 adf_ae_shutdown(struct adf_accel_dev *accel_dev)
256 {
257 	struct adf_fw_loader_data *loader_data = accel_dev->fw_loader;
258 	struct adf_hw_device_data *hw_device = accel_dev->hw_device;
259 
260 	if (!hw_device->fw_name)
261 		return 0;
262 
263 	qat_hal_deinit(loader_data->fw_loader);
264 	free(accel_dev->fw_loader, M_QAT);
265 	accel_dev->fw_loader = NULL;
266 	return 0;
267 }
268