xref: /freebsd/sys/dev/qat/qat_common/adf_init.c (revision a12eb9e4ae534557867d49803a1e28bfe519a207)
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_dev_err.h"
13 #include "adf_transport_access_macros.h"
14 #include "adf_transport_internal.h"
15 #include <sys/mutex.h>
16 #include <linux/delay.h>
17 #include "adf_accel_devices.h"
18 #include "adf_cfg.h"
19 #include "adf_common_drv.h"
20 #include "icp_qat_fw.h"
21 
22 /* Mask used to check the CompressAndVerify capability bit */
23 #define DC_CNV_EXTENDED_CAPABILITY (0x01)
24 
25 /* Mask used to check the CompressAndVerifyAndRecover capability bit */
26 #define DC_CNVNR_EXTENDED_CAPABILITY (0x100)
27 
28 static LIST_HEAD(service_table);
29 static DEFINE_MUTEX(service_lock);
30 
31 static void
32 adf_service_add(struct service_hndl *service)
33 {
34 	mutex_lock(&service_lock);
35 	list_add(&service->list, &service_table);
36 	mutex_unlock(&service_lock);
37 }
38 
39 int
40 adf_service_register(struct service_hndl *service)
41 {
42 	memset(service->init_status, 0, sizeof(service->init_status));
43 	memset(service->start_status, 0, sizeof(service->start_status));
44 	adf_service_add(service);
45 	return 0;
46 }
47 
48 static void
49 adf_service_remove(struct service_hndl *service)
50 {
51 	mutex_lock(&service_lock);
52 	list_del(&service->list);
53 	mutex_unlock(&service_lock);
54 }
55 
56 int
57 adf_service_unregister(struct service_hndl *service)
58 {
59 	int i;
60 
61 	for (i = 0; i < ARRAY_SIZE(service->init_status); i++) {
62 		if (service->init_status[i] || service->start_status[i]) {
63 			pr_err("QAT: Could not remove active service [%d]\n",
64 			       i);
65 			return EFAULT;
66 		}
67 	}
68 	adf_service_remove(service);
69 	return 0;
70 }
71 
72 static int
73 adf_cfg_add_device_params(struct adf_accel_dev *accel_dev)
74 {
75 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
76 	char hw_version[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
77 	char mmp_version[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
78 	struct adf_hw_device_data *hw_data = NULL;
79 	unsigned long val;
80 
81 	if (!accel_dev)
82 		return -EINVAL;
83 
84 	hw_data = accel_dev->hw_device;
85 
86 	if (adf_cfg_section_add(accel_dev, ADF_GENERAL_SEC))
87 		goto err;
88 
89 	snprintf(key, sizeof(key), ADF_DEV_MAX_BANKS);
90 	val = GET_MAX_BANKS(accel_dev);
91 	if (adf_cfg_add_key_value_param(
92 		accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC))
93 		goto err;
94 
95 	snprintf(key, sizeof(key), ADF_DEV_CAPABILITIES_MASK);
96 	val = hw_data->accel_capabilities_mask;
97 	if (adf_cfg_add_key_value_param(
98 		accel_dev, ADF_GENERAL_SEC, key, (void *)val, ADF_HEX))
99 		goto err;
100 
101 	snprintf(key, sizeof(key), ADF_DEV_PKG_ID);
102 	val = accel_dev->accel_id;
103 	if (adf_cfg_add_key_value_param(
104 		accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC))
105 		goto err;
106 
107 	snprintf(key, sizeof(key), ADF_DEV_NODE_ID);
108 	val = dev_to_node(GET_DEV(accel_dev));
109 	if (adf_cfg_add_key_value_param(
110 		accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC))
111 		goto err;
112 
113 	snprintf(key, sizeof(key), ADF_DEV_MAX_RINGS_PER_BANK);
114 	val = hw_data->num_rings_per_bank;
115 	if (adf_cfg_add_key_value_param(
116 		accel_dev, ADF_GENERAL_SEC, key, (void *)&val, ADF_DEC))
117 		goto err;
118 
119 	snprintf(key, sizeof(key), ADF_HW_REV_ID_KEY);
120 	snprintf(hw_version,
121 		 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
122 		 "%d",
123 		 accel_dev->accel_pci_dev.revid);
124 	if (adf_cfg_add_key_value_param(
125 		accel_dev, ADF_GENERAL_SEC, key, (void *)hw_version, ADF_STR))
126 		goto err;
127 
128 	snprintf(key, sizeof(key), ADF_MMP_VER_KEY);
129 	snprintf(mmp_version,
130 		 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
131 		 "%d.%d.%d",
132 		 accel_dev->fw_versions.mmp_version_major,
133 		 accel_dev->fw_versions.mmp_version_minor,
134 		 accel_dev->fw_versions.mmp_version_patch);
135 	if (adf_cfg_add_key_value_param(
136 		accel_dev, ADF_GENERAL_SEC, key, (void *)mmp_version, ADF_STR))
137 		goto err;
138 
139 	return 0;
140 err:
141 	device_printf(GET_DEV(accel_dev),
142 		      "Failed to add internal values to accel_dev cfg\n");
143 	return -EINVAL;
144 }
145 
146 static int
147 adf_cfg_add_fw_version(struct adf_accel_dev *accel_dev)
148 {
149 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
150 	char fw_version[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
151 
152 	snprintf(key, sizeof(key), ADF_UOF_VER_KEY);
153 	snprintf(fw_version,
154 		 ADF_CFG_MAX_VAL_LEN_IN_BYTES,
155 		 "%d.%d.%d",
156 		 accel_dev->fw_versions.fw_version_major,
157 		 accel_dev->fw_versions.fw_version_minor,
158 		 accel_dev->fw_versions.fw_version_patch);
159 	if (adf_cfg_add_key_value_param(
160 		accel_dev, ADF_GENERAL_SEC, key, (void *)fw_version, ADF_STR))
161 		return EFAULT;
162 
163 	return 0;
164 }
165 
166 static int
167 adf_cfg_add_ext_params(struct adf_accel_dev *accel_dev)
168 {
169 	char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES];
170 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
171 	unsigned long val;
172 
173 	snprintf(key, sizeof(key), ADF_DC_EXTENDED_FEATURES);
174 
175 	val = hw_data->extended_dc_capabilities;
176 	if (adf_cfg_add_key_value_param(
177 		accel_dev, ADF_GENERAL_SEC, key, (void *)val, ADF_HEX))
178 		return -EINVAL;
179 
180 	return 0;
181 }
182 
183 void
184 adf_error_notifier(uintptr_t arg)
185 {
186 	struct adf_accel_dev *accel_dev = (struct adf_accel_dev *)arg;
187 	struct service_hndl *service;
188 	struct list_head *list_itr;
189 
190 	list_for_each(list_itr, &service_table)
191 	{
192 		service = list_entry(list_itr, struct service_hndl, list);
193 		if (service->event_hld(accel_dev, ADF_EVENT_ERROR))
194 			device_printf(GET_DEV(accel_dev),
195 				      "Failed to send error event to %s.\n",
196 				      service->name);
197 	}
198 }
199 
200 /**
201  * adf_set_ssm_wdtimer() - Initialize the slice hang watchdog timer.
202  *
203  * Return: 0 on success, error code otherwise.
204  */
205 int
206 adf_set_ssm_wdtimer(struct adf_accel_dev *accel_dev)
207 {
208 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
209 	struct adf_bar *misc_bar =
210 	    &GET_BARS(accel_dev)[hw_data->get_misc_bar_id(hw_data)];
211 	struct resource *csr = misc_bar->virt_addr;
212 	u32 i;
213 	unsigned int mask;
214 	u32 clk_per_sec = hw_data->get_clock_speed(hw_data);
215 	u32 timer_val = ADF_WDT_TIMER_SYM_COMP_MS * (clk_per_sec / 1000);
216 	u32 timer_val_pke = ADF_SSM_WDT_PKE_DEFAULT_VALUE;
217 	char timer_str[ADF_CFG_MAX_VAL_LEN_IN_BYTES] = { 0 };
218 
219 	/* Get Watch Dog Timer for CySym+Comp from the configuration */
220 	if (!adf_cfg_get_param_value(accel_dev,
221 				     ADF_GENERAL_SEC,
222 				     ADF_DEV_SSM_WDT_BULK,
223 				     (char *)timer_str)) {
224 		if (!compat_strtouint((char *)timer_str,
225 				      ADF_CFG_BASE_DEC,
226 				      &timer_val))
227 			/* Convert msec to CPP clocks */
228 			timer_val = timer_val * (clk_per_sec / 1000);
229 	}
230 	/* Get Watch Dog Timer for CyAsym from the configuration */
231 	if (!adf_cfg_get_param_value(accel_dev,
232 				     ADF_GENERAL_SEC,
233 				     ADF_DEV_SSM_WDT_PKE,
234 				     (char *)timer_str)) {
235 		if (!compat_strtouint((char *)timer_str,
236 				      ADF_CFG_BASE_DEC,
237 				      &timer_val_pke))
238 			/* Convert msec to CPP clocks */
239 			timer_val_pke = timer_val_pke * (clk_per_sec / 1000);
240 	}
241 
242 	for (i = 0, mask = hw_data->accel_mask; mask; i++, mask >>= 1) {
243 		if (!(mask & 1))
244 			continue;
245 		/* Enable Watch Dog Timer for CySym + Comp */
246 		ADF_CSR_WR(csr, ADF_SSMWDT(i), timer_val);
247 		/* Enable Watch Dog Timer for CyAsym */
248 		ADF_CSR_WR(csr, ADF_SSMWDTPKE(i), timer_val_pke);
249 	}
250 	return 0;
251 }
252 
253 /**
254  * adf_dev_init() - Init data structures and services for the given accel device
255  * @accel_dev: Pointer to acceleration device.
256  *
257  * Initialize the ring data structures and the admin comms and arbitration
258  * services.
259  *
260  * Return: 0 on success, error code otherwise.
261  */
262 int
263 adf_dev_init(struct adf_accel_dev *accel_dev)
264 {
265 	struct service_hndl *service;
266 	struct list_head *list_itr;
267 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
268 	char value[ADF_CFG_MAX_VAL_LEN_IN_BYTES];
269 	int ret = 0;
270 	sysctl_ctx_init(&accel_dev->sysctl_ctx);
271 	set_bit(ADF_STATUS_SYSCTL_CTX_INITIALISED, &accel_dev->status);
272 
273 	if (!hw_data) {
274 		device_printf(GET_DEV(accel_dev),
275 			      "Failed to init device - hw_data not set\n");
276 		return EFAULT;
277 	}
278 	if (hw_data->reset_hw_units)
279 		hw_data->reset_hw_units(accel_dev);
280 
281 	if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status) &&
282 	    !accel_dev->is_vf) {
283 		device_printf(GET_DEV(accel_dev), "Device not configured\n");
284 		return EFAULT;
285 	}
286 
287 	if (adf_init_etr_data(accel_dev)) {
288 		device_printf(GET_DEV(accel_dev), "Failed initialize etr\n");
289 		return EFAULT;
290 	}
291 
292 	if (hw_data->init_accel_units && hw_data->init_accel_units(accel_dev)) {
293 		device_printf(GET_DEV(accel_dev),
294 			      "Failed initialize accel_units\n");
295 		return EFAULT;
296 	}
297 
298 	if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) {
299 		device_printf(GET_DEV(accel_dev),
300 			      "Failed initialize admin comms\n");
301 		return EFAULT;
302 	}
303 
304 	if (hw_data->init_arb && hw_data->init_arb(accel_dev)) {
305 		device_printf(GET_DEV(accel_dev),
306 			      "Failed initialize hw arbiter\n");
307 		return EFAULT;
308 	}
309 
310 	if (hw_data->set_asym_rings_mask)
311 		hw_data->set_asym_rings_mask(accel_dev);
312 
313 	hw_data->enable_ints(accel_dev);
314 
315 	if (adf_ae_init(accel_dev)) {
316 		device_printf(GET_DEV(accel_dev),
317 			      "Failed to initialise Acceleration Engine\n");
318 		return EFAULT;
319 	}
320 
321 	set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
322 
323 	if (adf_ae_fw_load(accel_dev)) {
324 		device_printf(GET_DEV(accel_dev),
325 			      "Failed to load acceleration FW\n");
326 		return EFAULT;
327 	}
328 	set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
329 
330 	if (hw_data->alloc_irq(accel_dev)) {
331 		device_printf(GET_DEV(accel_dev),
332 			      "Failed to allocate interrupts\n");
333 		return EFAULT;
334 	}
335 	set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
336 
337 	if (hw_data->init_ras && hw_data->init_ras(accel_dev)) {
338 		device_printf(GET_DEV(accel_dev), "Failed to init RAS\n");
339 		return EFAULT;
340 	}
341 
342 	hw_data->enable_ints(accel_dev);
343 
344 	hw_data->enable_error_correction(accel_dev);
345 
346 	if (hw_data->enable_vf2pf_comms(accel_dev)) {
347 		device_printf(GET_DEV(accel_dev),
348 			      "QAT: Failed to enable vf2pf comms\n");
349 		return EFAULT;
350 	}
351 
352 	if (adf_pf_vf_capabilities_init(accel_dev))
353 		return EFAULT;
354 
355 	if (adf_pf_vf_ring_to_svc_init(accel_dev))
356 		return EFAULT;
357 
358 	if (adf_cfg_add_device_params(accel_dev))
359 		return EFAULT;
360 
361 	if (hw_data->add_pke_stats && hw_data->add_pke_stats(accel_dev))
362 		return EFAULT;
363 
364 	if (hw_data->add_misc_error && hw_data->add_misc_error(accel_dev))
365 		return EFAULT;
366 	/*
367 	 * Subservice initialisation is divided into two stages: init and start.
368 	 * This is to facilitate any ordering dependencies between services
369 	 * prior to starting any of the accelerators.
370 	 */
371 	list_for_each(list_itr, &service_table)
372 	{
373 		service = list_entry(list_itr, struct service_hndl, list);
374 		if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
375 			device_printf(GET_DEV(accel_dev),
376 				      "Failed to initialise service %s\n",
377 				      service->name);
378 			return EFAULT;
379 		}
380 		set_bit(accel_dev->accel_id, service->init_status);
381 	}
382 
383 	/* Read autoreset on error parameter */
384 	ret = adf_cfg_get_param_value(accel_dev,
385 				      ADF_GENERAL_SEC,
386 				      ADF_AUTO_RESET_ON_ERROR,
387 				      value);
388 	if (!ret) {
389 		if (compat_strtouint(value,
390 				     10,
391 				     &accel_dev->autoreset_on_error)) {
392 			device_printf(
393 			    GET_DEV(accel_dev),
394 			    "Failed converting %s to a decimal value\n",
395 			    ADF_AUTO_RESET_ON_ERROR);
396 			return EFAULT;
397 		}
398 	}
399 
400 	return 0;
401 }
402 
403 /**
404  * adf_dev_start() - Start acceleration service for the given accel device
405  * @accel_dev:    Pointer to acceleration device.
406  *
407  * Function notifies all the registered services that the acceleration device
408  * is ready to be used.
409  * To be used by QAT device specific drivers.
410  *
411  * Return: 0 on success, error code otherwise.
412  */
413 int
414 adf_dev_start(struct adf_accel_dev *accel_dev)
415 {
416 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
417 	struct service_hndl *service;
418 	struct list_head *list_itr;
419 
420 	set_bit(ADF_STATUS_STARTING, &accel_dev->status);
421 	if (adf_devmgr_verify_id(&accel_dev->accel_id)) {
422 		device_printf(GET_DEV(accel_dev),
423 			      "QAT: Device %d not found\n",
424 			      accel_dev->accel_id);
425 		return ENODEV;
426 	}
427 	if (adf_ae_start(accel_dev)) {
428 		device_printf(GET_DEV(accel_dev), "AE Start Failed\n");
429 		return EFAULT;
430 	}
431 
432 	set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
433 	if (hw_data->send_admin_init(accel_dev)) {
434 		device_printf(GET_DEV(accel_dev),
435 			      "Failed to send init message\n");
436 		return EFAULT;
437 	}
438 
439 	if (adf_cfg_add_fw_version(accel_dev)) {
440 		device_printf(GET_DEV(accel_dev),
441 			      "Failed to update configuration FW version\n");
442 		return EFAULT;
443 	}
444 
445 	if (hw_data->measure_clock)
446 		hw_data->measure_clock(accel_dev);
447 
448 	/*
449 	 * Set ssm watch dog timer for slice hang detection
450 	 * Note! Not supported on devices older than C62x
451 	 */
452 	if (hw_data->set_ssm_wdtimer && hw_data->set_ssm_wdtimer(accel_dev)) {
453 		device_printf(GET_DEV(accel_dev),
454 			      "QAT: Failed to set ssm watch dog timer\n");
455 		return EFAULT;
456 	}
457 
458 	list_for_each(list_itr, &service_table)
459 	{
460 		service = list_entry(list_itr, struct service_hndl, list);
461 		if (service->event_hld(accel_dev, ADF_EVENT_START)) {
462 			device_printf(GET_DEV(accel_dev),
463 				      "Failed to start service %s\n",
464 				      service->name);
465 			return EFAULT;
466 		}
467 		set_bit(accel_dev->accel_id, service->start_status);
468 	}
469 
470 	if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status) &&
471 	    adf_cfg_add_ext_params(accel_dev))
472 		return EFAULT;
473 
474 	clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
475 	set_bit(ADF_STATUS_STARTED, &accel_dev->status);
476 
477 	return 0;
478 }
479 
480 /**
481  * adf_dev_stop() - Stop acceleration service for the given accel device
482  * @accel_dev:    Pointer to acceleration device.
483  *
484  * Function notifies all the registered services that the acceleration device
485  * is shuting down.
486  * To be used by QAT device specific drivers.
487  *
488  * Return: 0 on success, error code otherwise.
489  */
490 int
491 adf_dev_stop(struct adf_accel_dev *accel_dev)
492 {
493 	struct service_hndl *service;
494 	struct list_head *list_itr;
495 
496 	if (adf_devmgr_verify_id(&accel_dev->accel_id)) {
497 		device_printf(GET_DEV(accel_dev),
498 			      "QAT: Device %d not found\n",
499 			      accel_dev->accel_id);
500 		return ENODEV;
501 	}
502 	if (!adf_dev_started(accel_dev) &&
503 	    !test_bit(ADF_STATUS_STARTING, &accel_dev->status)) {
504 		return 0;
505 	}
506 
507 	if (adf_dev_stop_notify_sync(accel_dev)) {
508 		device_printf(
509 		    GET_DEV(accel_dev),
510 		    "Waiting for device un-busy failed. Retries limit reached\n");
511 		return EBUSY;
512 	}
513 
514 	clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
515 	clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
516 
517 	list_for_each(list_itr, &service_table)
518 	{
519 		service = list_entry(list_itr, struct service_hndl, list);
520 		if (!test_bit(accel_dev->accel_id, service->start_status))
521 			continue;
522 		clear_bit(accel_dev->accel_id, service->start_status);
523 	}
524 
525 	if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) {
526 		if (adf_ae_stop(accel_dev))
527 			device_printf(GET_DEV(accel_dev),
528 				      "failed to stop AE\n");
529 		else
530 			clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
531 	}
532 
533 	return 0;
534 }
535 
536 /**
537  * adf_dev_shutdown() - shutdown acceleration services and data strucutures
538  * @accel_dev: Pointer to acceleration device
539  *
540  * Cleanup the ring data structures and the admin comms and arbitration
541  * services.
542  */
543 void
544 adf_dev_shutdown(struct adf_accel_dev *accel_dev)
545 {
546 	struct adf_hw_device_data *hw_data = accel_dev->hw_device;
547 	struct service_hndl *service;
548 	struct list_head *list_itr;
549 
550 	if (test_bit(ADF_STATUS_SYSCTL_CTX_INITIALISED, &accel_dev->status)) {
551 		sysctl_ctx_free(&accel_dev->sysctl_ctx);
552 		clear_bit(ADF_STATUS_SYSCTL_CTX_INITIALISED,
553 			  &accel_dev->status);
554 	}
555 
556 	if (!hw_data) {
557 		device_printf(
558 		    GET_DEV(accel_dev),
559 		    "QAT: Failed to shutdown device - hw_data not set\n");
560 		return;
561 	}
562 
563 	if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
564 		adf_ae_fw_release(accel_dev);
565 		clear_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
566 	}
567 
568 	if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
569 		if (adf_ae_shutdown(accel_dev))
570 			device_printf(GET_DEV(accel_dev),
571 				      "Failed to shutdown Accel Engine\n");
572 		else
573 			clear_bit(ADF_STATUS_AE_INITIALISED,
574 				  &accel_dev->status);
575 	}
576 
577 	list_for_each(list_itr, &service_table)
578 	{
579 		service = list_entry(list_itr, struct service_hndl, list);
580 		if (!test_bit(accel_dev->accel_id, service->init_status))
581 			continue;
582 		if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
583 			device_printf(GET_DEV(accel_dev),
584 				      "Failed to shutdown service %s\n",
585 				      service->name);
586 		else
587 			clear_bit(accel_dev->accel_id, service->init_status);
588 	}
589 
590 	hw_data->disable_iov(accel_dev);
591 
592 	if (hw_data->disable_vf2pf_comms)
593 		hw_data->disable_vf2pf_comms(accel_dev);
594 
595 	if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
596 		hw_data->free_irq(accel_dev);
597 		clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
598 	}
599 
600 	/* Delete configuration only if not restarting */
601 	if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
602 		adf_cfg_del_all(accel_dev);
603 
604 	if (hw_data->remove_pke_stats)
605 		hw_data->remove_pke_stats(accel_dev);
606 
607 	if (hw_data->remove_misc_error)
608 		hw_data->remove_misc_error(accel_dev);
609 
610 	if (hw_data->exit_ras)
611 		hw_data->exit_ras(accel_dev);
612 
613 	if (hw_data->exit_arb)
614 		hw_data->exit_arb(accel_dev);
615 
616 	if (hw_data->exit_admin_comms)
617 		hw_data->exit_admin_comms(accel_dev);
618 
619 	if (hw_data->exit_accel_units)
620 		hw_data->exit_accel_units(accel_dev);
621 
622 	adf_cleanup_etr_data(accel_dev);
623 	if (hw_data->restore_device)
624 		hw_data->restore_device(accel_dev);
625 }
626 
627 /**
628  * adf_dev_reset() - Reset acceleration service for the given accel device
629  * @accel_dev:    Pointer to acceleration device.
630  * @mode: Specifies reset mode - synchronous or asynchronous.
631  * Function notifies all the registered services that the acceleration device
632  * is resetting.
633  * To be used by QAT device specific drivers.
634  *
635  * Return: 0 on success, error code otherwise.
636  */
637 int
638 adf_dev_reset(struct adf_accel_dev *accel_dev, enum adf_dev_reset_mode mode)
639 {
640 	return adf_dev_aer_schedule_reset(accel_dev, mode);
641 }
642 
643 int
644 adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
645 {
646 	struct service_hndl *service;
647 	struct list_head *list_itr;
648 
649 	list_for_each(list_itr, &service_table)
650 	{
651 		service = list_entry(list_itr, struct service_hndl, list);
652 		if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
653 			device_printf(GET_DEV(accel_dev),
654 				      "Failed to restart service %s.\n",
655 				      service->name);
656 	}
657 	return 0;
658 }
659 
660 int
661 adf_dev_restarting_notify_sync(struct adf_accel_dev *accel_dev)
662 {
663 	int times;
664 
665 	adf_dev_restarting_notify(accel_dev);
666 	for (times = 0; times < ADF_STOP_RETRY; times++) {
667 		if (!adf_dev_in_use(accel_dev))
668 			break;
669 		dev_dbg(GET_DEV(accel_dev), "retry times=%d\n", times);
670 		pause_ms("adfstop", 100);
671 	}
672 	if (adf_dev_in_use(accel_dev)) {
673 		clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
674 		device_printf(GET_DEV(accel_dev),
675 			      "Device still in use during reset sequence.\n");
676 		return EBUSY;
677 	}
678 
679 	return 0;
680 }
681 
682 int
683 adf_dev_stop_notify_sync(struct adf_accel_dev *accel_dev)
684 {
685 	int times;
686 
687 	struct service_hndl *service;
688 	struct list_head *list_itr;
689 
690 	list_for_each(list_itr, &service_table)
691 	{
692 		service = list_entry(list_itr, struct service_hndl, list);
693 		if (service->event_hld(accel_dev, ADF_EVENT_STOP))
694 			device_printf(GET_DEV(accel_dev),
695 				      "Failed to restart service %s.\n",
696 				      service->name);
697 	}
698 
699 	for (times = 0; times < ADF_STOP_RETRY; times++) {
700 		if (!adf_dev_in_use(accel_dev))
701 			break;
702 		dev_dbg(GET_DEV(accel_dev), "retry times=%d\n", times);
703 		pause_ms("adfstop", 100);
704 	}
705 	if (adf_dev_in_use(accel_dev)) {
706 		clear_bit(ADF_STATUS_RESTARTING, &accel_dev->status);
707 		device_printf(GET_DEV(accel_dev),
708 			      "Device still in use during stop sequence.\n");
709 		return EBUSY;
710 	}
711 
712 	return 0;
713 }
714 
715 int
716 adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
717 {
718 	struct service_hndl *service;
719 	struct list_head *list_itr;
720 
721 	list_for_each(list_itr, &service_table)
722 	{
723 		service = list_entry(list_itr, struct service_hndl, list);
724 		if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
725 			device_printf(GET_DEV(accel_dev),
726 				      "Failed to restart service %s.\n",
727 				      service->name);
728 	}
729 	return 0;
730 }
731