xref: /freebsd/sys/dev/qat/qat_common/adf_accel_engine.c (revision a64729f5077d77e13b9497cb33ecb3c82e606ee8)
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
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
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
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
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
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
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
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
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