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