Add the rt linux 4.1.3-rt3 as base
[kvmfornfv.git] / kernel / drivers / crypto / qat / qat_common / adf_init.c
1 /*
2   This file is provided under a dual BSD/GPLv2 license.  When using or
3   redistributing this file, you may do so under either license.
4
5   GPL LICENSE SUMMARY
6   Copyright(c) 2014 Intel Corporation.
7   This program is free software; you can redistribute it and/or modify
8   it under the terms of version 2 of the GNU General Public License as
9   published by the Free Software Foundation.
10
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   General Public License for more details.
15
16   Contact Information:
17   qat-linux@intel.com
18
19   BSD LICENSE
20   Copyright(c) 2014 Intel Corporation.
21   Redistribution and use in source and binary forms, with or without
22   modification, are permitted provided that the following conditions
23   are met:
24
25     * Redistributions of source code must retain the above copyright
26       notice, this list of conditions and the following disclaimer.
27     * Redistributions in binary form must reproduce the above copyright
28       notice, this list of conditions and the following disclaimer in
29       the documentation and/or other materials provided with the
30       distribution.
31     * Neither the name of Intel Corporation nor the names of its
32       contributors may be used to endorse or promote products derived
33       from this software without specific prior written permission.
34
35   THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
36   "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
37   LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
38   A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
39   OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
40   SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
41   LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
42   DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
43   THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
44   (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
45   OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
46 */
47 #include <linux/mutex.h>
48 #include <linux/list.h>
49 #include <linux/bitops.h>
50 #include <linux/delay.h>
51 #include "adf_accel_devices.h"
52 #include "adf_cfg.h"
53 #include "adf_common_drv.h"
54
55 static LIST_HEAD(service_table);
56 static DEFINE_MUTEX(service_lock);
57
58 static void adf_service_add(struct service_hndl *service)
59 {
60         mutex_lock(&service_lock);
61         list_add(&service->list, &service_table);
62         mutex_unlock(&service_lock);
63 }
64
65 /**
66  * adf_service_register() - Register acceleration service in the accel framework
67  * @service:    Pointer to the service
68  *
69  * Function adds the acceleration service to the acceleration framework.
70  * To be used by QAT device specific drivers.
71  *
72  * Return: 0 on success, error code othewise.
73  */
74 int adf_service_register(struct service_hndl *service)
75 {
76         service->init_status = 0;
77         service->start_status = 0;
78         adf_service_add(service);
79         return 0;
80 }
81 EXPORT_SYMBOL_GPL(adf_service_register);
82
83 static void adf_service_remove(struct service_hndl *service)
84 {
85         mutex_lock(&service_lock);
86         list_del(&service->list);
87         mutex_unlock(&service_lock);
88 }
89
90 /**
91  * adf_service_unregister() - Unregister acceleration service from the framework
92  * @service:    Pointer to the service
93  *
94  * Function remove the acceleration service from the acceleration framework.
95  * To be used by QAT device specific drivers.
96  *
97  * Return: 0 on success, error code othewise.
98  */
99 int adf_service_unregister(struct service_hndl *service)
100 {
101         if (service->init_status || service->start_status) {
102                 pr_err("QAT: Could not remove active service\n");
103                 return -EFAULT;
104         }
105         adf_service_remove(service);
106         return 0;
107 }
108 EXPORT_SYMBOL_GPL(adf_service_unregister);
109
110 /**
111  * adf_dev_init() - Init data structures and services for the given accel device
112  * @accel_dev: Pointer to acceleration device.
113  *
114  * Initialize the ring data structures and the admin comms and arbitration
115  * services.
116  *
117  * Return: 0 on success, error code othewise.
118  */
119 int adf_dev_init(struct adf_accel_dev *accel_dev)
120 {
121         struct service_hndl *service;
122         struct list_head *list_itr;
123         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
124
125         if (!hw_data) {
126                 dev_err(&GET_DEV(accel_dev),
127                         "Failed to init device - hw_data not set\n");
128                 return -EFAULT;
129         }
130
131         if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
132                 dev_err(&GET_DEV(accel_dev), "Device not configured\n");
133                 return -EFAULT;
134         }
135
136         if (adf_init_etr_data(accel_dev)) {
137                 dev_err(&GET_DEV(accel_dev), "Failed initialize etr\n");
138                 return -EFAULT;
139         }
140
141         if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) {
142                 dev_err(&GET_DEV(accel_dev), "Failed initialize admin comms\n");
143                 return -EFAULT;
144         }
145
146         if (hw_data->init_arb && hw_data->init_arb(accel_dev)) {
147                 dev_err(&GET_DEV(accel_dev), "Failed initialize hw arbiter\n");
148                 return -EFAULT;
149         }
150
151         hw_data->enable_ints(accel_dev);
152
153         if (adf_ae_init(accel_dev)) {
154                 dev_err(&GET_DEV(accel_dev),
155                         "Failed to initialise Acceleration Engine\n");
156                 return -EFAULT;
157         }
158         set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
159
160         if (adf_ae_fw_load(accel_dev)) {
161                 dev_err(&GET_DEV(accel_dev),
162                         "Failed to load acceleration FW\n");
163                 return -EFAULT;
164         }
165         set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
166
167         if (hw_data->alloc_irq(accel_dev)) {
168                 dev_err(&GET_DEV(accel_dev), "Failed to allocate interrupts\n");
169                 return -EFAULT;
170         }
171         set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
172
173         /*
174          * Subservice initialisation is divided into two stages: init and start.
175          * This is to facilitate any ordering dependencies between services
176          * prior to starting any of the accelerators.
177          */
178         list_for_each(list_itr, &service_table) {
179                 service = list_entry(list_itr, struct service_hndl, list);
180                 if (!service->admin)
181                         continue;
182                 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
183                         dev_err(&GET_DEV(accel_dev),
184                                 "Failed to initialise service %s\n",
185                                 service->name);
186                         return -EFAULT;
187                 }
188                 set_bit(accel_dev->accel_id, &service->init_status);
189         }
190         list_for_each(list_itr, &service_table) {
191                 service = list_entry(list_itr, struct service_hndl, list);
192                 if (service->admin)
193                         continue;
194                 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
195                         dev_err(&GET_DEV(accel_dev),
196                                 "Failed to initialise service %s\n",
197                                 service->name);
198                         return -EFAULT;
199                 }
200                 set_bit(accel_dev->accel_id, &service->init_status);
201         }
202
203         hw_data->enable_error_correction(accel_dev);
204
205         return 0;
206 }
207 EXPORT_SYMBOL_GPL(adf_dev_init);
208
209 /**
210  * adf_dev_start() - Start acceleration service for the given accel device
211  * @accel_dev:    Pointer to acceleration device.
212  *
213  * Function notifies all the registered services that the acceleration device
214  * is ready to be used.
215  * To be used by QAT device specific drivers.
216  *
217  * Return: 0 on success, error code othewise.
218  */
219 int adf_dev_start(struct adf_accel_dev *accel_dev)
220 {
221         struct service_hndl *service;
222         struct list_head *list_itr;
223
224         set_bit(ADF_STATUS_STARTING, &accel_dev->status);
225
226         if (adf_ae_start(accel_dev)) {
227                 dev_err(&GET_DEV(accel_dev), "AE Start Failed\n");
228                 return -EFAULT;
229         }
230         set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
231
232         list_for_each(list_itr, &service_table) {
233                 service = list_entry(list_itr, struct service_hndl, list);
234                 if (!service->admin)
235                         continue;
236                 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
237                         dev_err(&GET_DEV(accel_dev),
238                                 "Failed to start service %s\n",
239                                 service->name);
240                         return -EFAULT;
241                 }
242                 set_bit(accel_dev->accel_id, &service->start_status);
243         }
244         list_for_each(list_itr, &service_table) {
245                 service = list_entry(list_itr, struct service_hndl, list);
246                 if (service->admin)
247                         continue;
248                 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
249                         dev_err(&GET_DEV(accel_dev),
250                                 "Failed to start service %s\n",
251                                 service->name);
252                         return -EFAULT;
253                 }
254                 set_bit(accel_dev->accel_id, &service->start_status);
255         }
256
257         clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
258         set_bit(ADF_STATUS_STARTED, &accel_dev->status);
259
260         if (qat_algs_register()) {
261                 dev_err(&GET_DEV(accel_dev),
262                         "Failed to register crypto algs\n");
263                 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
264                 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
265                 return -EFAULT;
266         }
267         return 0;
268 }
269 EXPORT_SYMBOL_GPL(adf_dev_start);
270
271 /**
272  * adf_dev_stop() - Stop acceleration service for the given accel device
273  * @accel_dev:    Pointer to acceleration device.
274  *
275  * Function notifies all the registered services that the acceleration device
276  * is shuting down.
277  * To be used by QAT device specific drivers.
278  *
279  * Return: 0 on success, error code othewise.
280  */
281 int adf_dev_stop(struct adf_accel_dev *accel_dev)
282 {
283         struct service_hndl *service;
284         struct list_head *list_itr;
285         bool wait = false;
286         int ret;
287
288         if (!adf_dev_started(accel_dev) &&
289             !test_bit(ADF_STATUS_STARTING, &accel_dev->status)) {
290                 return 0;
291         }
292         clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
293         clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
294
295         if (qat_algs_unregister())
296                 dev_err(&GET_DEV(accel_dev),
297                         "Failed to unregister crypto algs\n");
298
299         list_for_each(list_itr, &service_table) {
300                 service = list_entry(list_itr, struct service_hndl, list);
301                 if (service->admin)
302                         continue;
303                 if (!test_bit(accel_dev->accel_id, &service->start_status))
304                         continue;
305                 ret = service->event_hld(accel_dev, ADF_EVENT_STOP);
306                 if (!ret) {
307                         clear_bit(accel_dev->accel_id, &service->start_status);
308                 } else if (ret == -EAGAIN) {
309                         wait = true;
310                         clear_bit(accel_dev->accel_id, &service->start_status);
311                 }
312         }
313         list_for_each(list_itr, &service_table) {
314                 service = list_entry(list_itr, struct service_hndl, list);
315                 if (!service->admin)
316                         continue;
317                 if (!test_bit(accel_dev->accel_id, &service->start_status))
318                         continue;
319                 if (service->event_hld(accel_dev, ADF_EVENT_STOP))
320                         dev_err(&GET_DEV(accel_dev),
321                                 "Failed to shutdown service %s\n",
322                                 service->name);
323                 else
324                         clear_bit(accel_dev->accel_id, &service->start_status);
325         }
326
327         if (wait)
328                 msleep(100);
329
330         if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) {
331                 if (adf_ae_stop(accel_dev))
332                         dev_err(&GET_DEV(accel_dev), "failed to stop AE\n");
333                 else
334                         clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
335         }
336
337         return 0;
338 }
339 EXPORT_SYMBOL_GPL(adf_dev_stop);
340
341 /**
342  * adf_dev_shutdown() - shutdown acceleration services and data strucutures
343  * @accel_dev: Pointer to acceleration device
344  *
345  * Cleanup the ring data structures and the admin comms and arbitration
346  * services.
347  */
348 void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
349 {
350         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
351         struct service_hndl *service;
352         struct list_head *list_itr;
353
354         if (!hw_data) {
355                 dev_err(&GET_DEV(accel_dev),
356                         "QAT: Failed to shutdown device - hw_data not set\n");
357                 return;
358         }
359
360         if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
361                 adf_ae_fw_release(accel_dev);
362                 clear_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
363         }
364
365         if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
366                 if (adf_ae_shutdown(accel_dev))
367                         dev_err(&GET_DEV(accel_dev),
368                                 "Failed to shutdown Accel Engine\n");
369                 else
370                         clear_bit(ADF_STATUS_AE_INITIALISED,
371                                   &accel_dev->status);
372         }
373
374         list_for_each(list_itr, &service_table) {
375                 service = list_entry(list_itr, struct service_hndl, list);
376                 if (service->admin)
377                         continue;
378                 if (!test_bit(accel_dev->accel_id, &service->init_status))
379                         continue;
380                 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
381                         dev_err(&GET_DEV(accel_dev),
382                                 "Failed to shutdown service %s\n",
383                                 service->name);
384                 else
385                         clear_bit(accel_dev->accel_id, &service->init_status);
386         }
387         list_for_each(list_itr, &service_table) {
388                 service = list_entry(list_itr, struct service_hndl, list);
389                 if (!service->admin)
390                         continue;
391                 if (!test_bit(accel_dev->accel_id, &service->init_status))
392                         continue;
393                 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
394                         dev_err(&GET_DEV(accel_dev),
395                                 "Failed to shutdown service %s\n",
396                                 service->name);
397                 else
398                         clear_bit(accel_dev->accel_id, &service->init_status);
399         }
400
401         if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
402                 hw_data->free_irq(accel_dev);
403                 clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
404         }
405
406         /* Delete configuration only if not restarting */
407         if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
408                 adf_cfg_del_all(accel_dev);
409
410         if (hw_data->exit_arb)
411                 hw_data->exit_arb(accel_dev);
412
413         if (hw_data->exit_admin_comms)
414                 hw_data->exit_admin_comms(accel_dev);
415
416         adf_cleanup_etr_data(accel_dev);
417 }
418 EXPORT_SYMBOL_GPL(adf_dev_shutdown);
419
420 int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
421 {
422         struct service_hndl *service;
423         struct list_head *list_itr;
424
425         list_for_each(list_itr, &service_table) {
426                 service = list_entry(list_itr, struct service_hndl, list);
427                 if (service->admin)
428                         continue;
429                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
430                         dev_err(&GET_DEV(accel_dev),
431                                 "Failed to restart service %s.\n",
432                                 service->name);
433         }
434         list_for_each(list_itr, &service_table) {
435                 service = list_entry(list_itr, struct service_hndl, list);
436                 if (!service->admin)
437                         continue;
438                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
439                         dev_err(&GET_DEV(accel_dev),
440                                 "Failed to restart service %s.\n",
441                                 service->name);
442         }
443         return 0;
444 }
445
446 int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
447 {
448         struct service_hndl *service;
449         struct list_head *list_itr;
450
451         list_for_each(list_itr, &service_table) {
452                 service = list_entry(list_itr, struct service_hndl, list);
453                 if (service->admin)
454                         continue;
455                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
456                         dev_err(&GET_DEV(accel_dev),
457                                 "Failed to restart service %s.\n",
458                                 service->name);
459         }
460         list_for_each(list_itr, &service_table) {
461                 service = list_entry(list_itr, struct service_hndl, list);
462                 if (!service->admin)
463                         continue;
464                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
465                         dev_err(&GET_DEV(accel_dev),
466                                 "Failed to restart service %s.\n",
467                                 service->name);
468         }
469         return 0;
470 }