1 // SPDX-License-Identifier: (BSD-3-Clause OR GPL-2.0-only)
2 /* Copyright(c) 2014 - 2020 Intel Corporation */
3 #include <linux/mutex.h>
4 #include <linux/list.h>
5 #include <linux/bitops.h>
6 #include <linux/delay.h>
7 #include "adf_accel_devices.h"
9 #include "adf_common_drv.h"
11 static LIST_HEAD(service_table
);
12 static DEFINE_MUTEX(service_lock
);
14 static void adf_service_add(struct service_hndl
*service
)
16 mutex_lock(&service_lock
);
17 list_add(&service
->list
, &service_table
);
18 mutex_unlock(&service_lock
);
21 int adf_service_register(struct service_hndl
*service
)
23 memset(service
->init_status
, 0, sizeof(service
->init_status
));
24 memset(service
->start_status
, 0, sizeof(service
->start_status
));
25 adf_service_add(service
);
29 static void adf_service_remove(struct service_hndl
*service
)
31 mutex_lock(&service_lock
);
32 list_del(&service
->list
);
33 mutex_unlock(&service_lock
);
36 int adf_service_unregister(struct service_hndl
*service
)
40 for (i
= 0; i
< ARRAY_SIZE(service
->init_status
); i
++) {
41 if (service
->init_status
[i
] || service
->start_status
[i
]) {
42 pr_err("QAT: Could not remove active service\n");
46 adf_service_remove(service
);
51 * adf_dev_init() - Init data structures and services for the given accel device
52 * @accel_dev: Pointer to acceleration device.
54 * Initialize the ring data structures and the admin comms and arbitration
57 * Return: 0 on success, error code otherwise.
59 int adf_dev_init(struct adf_accel_dev
*accel_dev
)
61 struct service_hndl
*service
;
62 struct list_head
*list_itr
;
63 struct adf_hw_device_data
*hw_data
= accel_dev
->hw_device
;
66 dev_err(&GET_DEV(accel_dev
),
67 "Failed to init device - hw_data not set\n");
71 if (!test_bit(ADF_STATUS_CONFIGURED
, &accel_dev
->status
)) {
72 dev_err(&GET_DEV(accel_dev
), "Device not configured\n");
76 if (adf_init_etr_data(accel_dev
)) {
77 dev_err(&GET_DEV(accel_dev
), "Failed initialize etr\n");
81 if (hw_data
->init_admin_comms
&& hw_data
->init_admin_comms(accel_dev
)) {
82 dev_err(&GET_DEV(accel_dev
), "Failed initialize admin comms\n");
86 if (hw_data
->init_arb
&& hw_data
->init_arb(accel_dev
)) {
87 dev_err(&GET_DEV(accel_dev
), "Failed initialize hw arbiter\n");
91 hw_data
->enable_ints(accel_dev
);
93 if (adf_ae_init(accel_dev
)) {
94 dev_err(&GET_DEV(accel_dev
),
95 "Failed to initialise Acceleration Engine\n");
98 set_bit(ADF_STATUS_AE_INITIALISED
, &accel_dev
->status
);
100 if (adf_ae_fw_load(accel_dev
)) {
101 dev_err(&GET_DEV(accel_dev
),
102 "Failed to load acceleration FW\n");
105 set_bit(ADF_STATUS_AE_UCODE_LOADED
, &accel_dev
->status
);
107 if (hw_data
->alloc_irq(accel_dev
)) {
108 dev_err(&GET_DEV(accel_dev
), "Failed to allocate interrupts\n");
111 set_bit(ADF_STATUS_IRQ_ALLOCATED
, &accel_dev
->status
);
114 * Subservice initialisation is divided into two stages: init and start.
115 * This is to facilitate any ordering dependencies between services
116 * prior to starting any of the accelerators.
118 list_for_each(list_itr
, &service_table
) {
119 service
= list_entry(list_itr
, struct service_hndl
, list
);
120 if (service
->event_hld(accel_dev
, ADF_EVENT_INIT
)) {
121 dev_err(&GET_DEV(accel_dev
),
122 "Failed to initialise service %s\n",
126 set_bit(accel_dev
->accel_id
, service
->init_status
);
129 hw_data
->enable_error_correction(accel_dev
);
130 hw_data
->enable_vf2pf_comms(accel_dev
);
134 EXPORT_SYMBOL_GPL(adf_dev_init
);
137 * adf_dev_start() - Start acceleration service for the given accel device
138 * @accel_dev: Pointer to acceleration device.
140 * Function notifies all the registered services that the acceleration device
141 * is ready to be used.
142 * To be used by QAT device specific drivers.
144 * Return: 0 on success, error code otherwise.
146 int adf_dev_start(struct adf_accel_dev
*accel_dev
)
148 struct adf_hw_device_data
*hw_data
= accel_dev
->hw_device
;
149 struct service_hndl
*service
;
150 struct list_head
*list_itr
;
152 set_bit(ADF_STATUS_STARTING
, &accel_dev
->status
);
154 if (adf_ae_start(accel_dev
)) {
155 dev_err(&GET_DEV(accel_dev
), "AE Start Failed\n");
158 set_bit(ADF_STATUS_AE_STARTED
, &accel_dev
->status
);
160 if (hw_data
->send_admin_init(accel_dev
)) {
161 dev_err(&GET_DEV(accel_dev
), "Failed to send init message\n");
165 list_for_each(list_itr
, &service_table
) {
166 service
= list_entry(list_itr
, struct service_hndl
, list
);
167 if (service
->event_hld(accel_dev
, ADF_EVENT_START
)) {
168 dev_err(&GET_DEV(accel_dev
),
169 "Failed to start service %s\n",
173 set_bit(accel_dev
->accel_id
, service
->start_status
);
176 clear_bit(ADF_STATUS_STARTING
, &accel_dev
->status
);
177 set_bit(ADF_STATUS_STARTED
, &accel_dev
->status
);
179 if (!list_empty(&accel_dev
->crypto_list
) &&
180 (qat_algs_register() || qat_asym_algs_register())) {
181 dev_err(&GET_DEV(accel_dev
),
182 "Failed to register crypto algs\n");
183 set_bit(ADF_STATUS_STARTING
, &accel_dev
->status
);
184 clear_bit(ADF_STATUS_STARTED
, &accel_dev
->status
);
189 EXPORT_SYMBOL_GPL(adf_dev_start
);
192 * adf_dev_stop() - Stop acceleration service for the given accel device
193 * @accel_dev: Pointer to acceleration device.
195 * Function notifies all the registered services that the acceleration device
197 * To be used by QAT device specific drivers.
201 void adf_dev_stop(struct adf_accel_dev
*accel_dev
)
203 struct service_hndl
*service
;
204 struct list_head
*list_itr
;
208 if (!adf_dev_started(accel_dev
) &&
209 !test_bit(ADF_STATUS_STARTING
, &accel_dev
->status
))
212 clear_bit(ADF_STATUS_STARTING
, &accel_dev
->status
);
213 clear_bit(ADF_STATUS_STARTED
, &accel_dev
->status
);
215 if (!list_empty(&accel_dev
->crypto_list
)) {
216 qat_algs_unregister();
217 qat_asym_algs_unregister();
220 list_for_each(list_itr
, &service_table
) {
221 service
= list_entry(list_itr
, struct service_hndl
, list
);
222 if (!test_bit(accel_dev
->accel_id
, service
->start_status
))
224 ret
= service
->event_hld(accel_dev
, ADF_EVENT_STOP
);
226 clear_bit(accel_dev
->accel_id
, service
->start_status
);
227 } else if (ret
== -EAGAIN
) {
229 clear_bit(accel_dev
->accel_id
, service
->start_status
);
236 if (test_bit(ADF_STATUS_AE_STARTED
, &accel_dev
->status
)) {
237 if (adf_ae_stop(accel_dev
))
238 dev_err(&GET_DEV(accel_dev
), "failed to stop AE\n");
240 clear_bit(ADF_STATUS_AE_STARTED
, &accel_dev
->status
);
243 EXPORT_SYMBOL_GPL(adf_dev_stop
);
246 * adf_dev_shutdown() - shutdown acceleration services and data strucutures
247 * @accel_dev: Pointer to acceleration device
249 * Cleanup the ring data structures and the admin comms and arbitration
252 void adf_dev_shutdown(struct adf_accel_dev
*accel_dev
)
254 struct adf_hw_device_data
*hw_data
= accel_dev
->hw_device
;
255 struct service_hndl
*service
;
256 struct list_head
*list_itr
;
259 dev_err(&GET_DEV(accel_dev
),
260 "QAT: Failed to shutdown device - hw_data not set\n");
264 if (test_bit(ADF_STATUS_AE_UCODE_LOADED
, &accel_dev
->status
)) {
265 adf_ae_fw_release(accel_dev
);
266 clear_bit(ADF_STATUS_AE_UCODE_LOADED
, &accel_dev
->status
);
269 if (test_bit(ADF_STATUS_AE_INITIALISED
, &accel_dev
->status
)) {
270 if (adf_ae_shutdown(accel_dev
))
271 dev_err(&GET_DEV(accel_dev
),
272 "Failed to shutdown Accel Engine\n");
274 clear_bit(ADF_STATUS_AE_INITIALISED
,
278 list_for_each(list_itr
, &service_table
) {
279 service
= list_entry(list_itr
, struct service_hndl
, list
);
280 if (!test_bit(accel_dev
->accel_id
, service
->init_status
))
282 if (service
->event_hld(accel_dev
, ADF_EVENT_SHUTDOWN
))
283 dev_err(&GET_DEV(accel_dev
),
284 "Failed to shutdown service %s\n",
287 clear_bit(accel_dev
->accel_id
, service
->init_status
);
290 hw_data
->disable_iov(accel_dev
);
292 if (test_bit(ADF_STATUS_IRQ_ALLOCATED
, &accel_dev
->status
)) {
293 hw_data
->free_irq(accel_dev
);
294 clear_bit(ADF_STATUS_IRQ_ALLOCATED
, &accel_dev
->status
);
297 /* Delete configuration only if not restarting */
298 if (!test_bit(ADF_STATUS_RESTARTING
, &accel_dev
->status
))
299 adf_cfg_del_all(accel_dev
);
301 if (hw_data
->exit_arb
)
302 hw_data
->exit_arb(accel_dev
);
304 if (hw_data
->exit_admin_comms
)
305 hw_data
->exit_admin_comms(accel_dev
);
307 adf_cleanup_etr_data(accel_dev
);
308 adf_dev_restore(accel_dev
);
310 EXPORT_SYMBOL_GPL(adf_dev_shutdown
);
312 int adf_dev_restarting_notify(struct adf_accel_dev
*accel_dev
)
314 struct service_hndl
*service
;
315 struct list_head
*list_itr
;
317 list_for_each(list_itr
, &service_table
) {
318 service
= list_entry(list_itr
, struct service_hndl
, list
);
319 if (service
->event_hld(accel_dev
, ADF_EVENT_RESTARTING
))
320 dev_err(&GET_DEV(accel_dev
),
321 "Failed to restart service %s.\n",
327 int adf_dev_restarted_notify(struct adf_accel_dev
*accel_dev
)
329 struct service_hndl
*service
;
330 struct list_head
*list_itr
;
332 list_for_each(list_itr
, &service_table
) {
333 service
= list_entry(list_itr
, struct service_hndl
, list
);
334 if (service
->event_hld(accel_dev
, ADF_EVENT_RESTARTED
))
335 dev_err(&GET_DEV(accel_dev
),
336 "Failed to restart service %s.\n",