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
23struct adf_mmp_version_s {
24	u8 ver_val[MMP_VERSION_LEN];
25};
26
27static int
28request_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
41int
42adf_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
153out_err:
154	adf_ae_fw_release(accel_dev);
155	return EFAULT;
156}
157
158void
159adf_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
180int
181adf_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
198int
199adf_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
221static int
222adf_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
233int
234adf_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
259int
260adf_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