GNU Linux-libre 4.4.284-gnu1
[releases.git] / 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 otherwise.
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 otherwise.
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 otherwise.
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         int ret;
125
126         if (!hw_data) {
127                 dev_err(&GET_DEV(accel_dev),
128                         "Failed to init device - hw_data not set\n");
129                 return -EFAULT;
130         }
131
132         if (!test_bit(ADF_STATUS_CONFIGURED, &accel_dev->status)) {
133                 dev_err(&GET_DEV(accel_dev), "Device not configured\n");
134                 return -EFAULT;
135         }
136
137         if (adf_init_etr_data(accel_dev)) {
138                 dev_err(&GET_DEV(accel_dev), "Failed initialize etr\n");
139                 return -EFAULT;
140         }
141
142         if (hw_data->init_admin_comms && hw_data->init_admin_comms(accel_dev)) {
143                 dev_err(&GET_DEV(accel_dev), "Failed initialize admin comms\n");
144                 return -EFAULT;
145         }
146
147         if (hw_data->init_arb && hw_data->init_arb(accel_dev)) {
148                 dev_err(&GET_DEV(accel_dev), "Failed initialize hw arbiter\n");
149                 return -EFAULT;
150         }
151
152         hw_data->enable_ints(accel_dev);
153
154         if (adf_ae_init(accel_dev)) {
155                 dev_err(&GET_DEV(accel_dev),
156                         "Failed to initialise Acceleration Engine\n");
157                 return -EFAULT;
158         }
159         set_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status);
160
161         if (adf_ae_fw_load(accel_dev)) {
162                 dev_err(&GET_DEV(accel_dev),
163                         "Failed to load acceleration FW\n");
164                 return -EFAULT;
165         }
166         set_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
167
168         if (hw_data->alloc_irq(accel_dev)) {
169                 dev_err(&GET_DEV(accel_dev), "Failed to allocate interrupts\n");
170                 return -EFAULT;
171         }
172         set_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
173
174         /*
175          * Subservice initialisation is divided into two stages: init and start.
176          * This is to facilitate any ordering dependencies between services
177          * prior to starting any of the accelerators.
178          */
179         list_for_each(list_itr, &service_table) {
180                 service = list_entry(list_itr, struct service_hndl, list);
181                 if (service->event_hld(accel_dev, ADF_EVENT_INIT)) {
182                         dev_err(&GET_DEV(accel_dev),
183                                 "Failed to initialise service %s\n",
184                                 service->name);
185                         return -EFAULT;
186                 }
187                 set_bit(accel_dev->accel_id, &service->init_status);
188         }
189
190         hw_data->enable_error_correction(accel_dev);
191         ret = hw_data->enable_vf2pf_comms(accel_dev);
192
193         return ret;
194 }
195 EXPORT_SYMBOL_GPL(adf_dev_init);
196
197 /**
198  * adf_dev_start() - Start acceleration service for the given accel device
199  * @accel_dev:    Pointer to acceleration device.
200  *
201  * Function notifies all the registered services that the acceleration device
202  * is ready to be used.
203  * To be used by QAT device specific drivers.
204  *
205  * Return: 0 on success, error code otherwise.
206  */
207 int adf_dev_start(struct adf_accel_dev *accel_dev)
208 {
209         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
210         struct service_hndl *service;
211         struct list_head *list_itr;
212
213         set_bit(ADF_STATUS_STARTING, &accel_dev->status);
214
215         if (adf_ae_start(accel_dev)) {
216                 dev_err(&GET_DEV(accel_dev), "AE Start Failed\n");
217                 return -EFAULT;
218         }
219         set_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
220
221         if (hw_data->send_admin_init(accel_dev)) {
222                 dev_err(&GET_DEV(accel_dev), "Failed to send init message\n");
223                 return -EFAULT;
224         }
225
226         list_for_each(list_itr, &service_table) {
227                 service = list_entry(list_itr, struct service_hndl, list);
228                 if (service->event_hld(accel_dev, ADF_EVENT_START)) {
229                         dev_err(&GET_DEV(accel_dev),
230                                 "Failed to start service %s\n",
231                                 service->name);
232                         return -EFAULT;
233                 }
234                 set_bit(accel_dev->accel_id, &service->start_status);
235         }
236
237         clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
238         set_bit(ADF_STATUS_STARTED, &accel_dev->status);
239
240         if (!list_empty(&accel_dev->crypto_list) &&
241             (qat_algs_register() || qat_asym_algs_register())) {
242                 dev_err(&GET_DEV(accel_dev),
243                         "Failed to register crypto algs\n");
244                 set_bit(ADF_STATUS_STARTING, &accel_dev->status);
245                 clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
246                 return -EFAULT;
247         }
248         return 0;
249 }
250 EXPORT_SYMBOL_GPL(adf_dev_start);
251
252 /**
253  * adf_dev_stop() - Stop acceleration service for the given accel device
254  * @accel_dev:    Pointer to acceleration device.
255  *
256  * Function notifies all the registered services that the acceleration device
257  * is shuting down.
258  * To be used by QAT device specific drivers.
259  *
260  * Return: 0 on success, error code otherwise.
261  */
262 int adf_dev_stop(struct adf_accel_dev *accel_dev)
263 {
264         struct service_hndl *service;
265         struct list_head *list_itr;
266         bool wait = false;
267         int ret;
268
269         if (!adf_dev_started(accel_dev) &&
270             !test_bit(ADF_STATUS_STARTING, &accel_dev->status)) {
271                 return 0;
272         }
273         clear_bit(ADF_STATUS_STARTING, &accel_dev->status);
274         clear_bit(ADF_STATUS_STARTED, &accel_dev->status);
275
276         if (!list_empty(&accel_dev->crypto_list)) {
277                 qat_algs_unregister();
278                 qat_asym_algs_unregister();
279         }
280
281         list_for_each(list_itr, &service_table) {
282                 service = list_entry(list_itr, struct service_hndl, list);
283                 if (!test_bit(accel_dev->accel_id, &service->start_status))
284                         continue;
285                 ret = service->event_hld(accel_dev, ADF_EVENT_STOP);
286                 if (!ret) {
287                         clear_bit(accel_dev->accel_id, &service->start_status);
288                 } else if (ret == -EAGAIN) {
289                         wait = true;
290                         clear_bit(accel_dev->accel_id, &service->start_status);
291                 }
292         }
293
294         if (wait)
295                 msleep(100);
296
297         if (test_bit(ADF_STATUS_AE_STARTED, &accel_dev->status)) {
298                 if (adf_ae_stop(accel_dev))
299                         dev_err(&GET_DEV(accel_dev), "failed to stop AE\n");
300                 else
301                         clear_bit(ADF_STATUS_AE_STARTED, &accel_dev->status);
302         }
303
304         return 0;
305 }
306 EXPORT_SYMBOL_GPL(adf_dev_stop);
307
308 /**
309  * adf_dev_shutdown() - shutdown acceleration services and data strucutures
310  * @accel_dev: Pointer to acceleration device
311  *
312  * Cleanup the ring data structures and the admin comms and arbitration
313  * services.
314  */
315 void adf_dev_shutdown(struct adf_accel_dev *accel_dev)
316 {
317         struct adf_hw_device_data *hw_data = accel_dev->hw_device;
318         struct service_hndl *service;
319         struct list_head *list_itr;
320
321         if (!hw_data) {
322                 dev_err(&GET_DEV(accel_dev),
323                         "QAT: Failed to shutdown device - hw_data not set\n");
324                 return;
325         }
326
327         if (test_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status)) {
328                 adf_ae_fw_release(accel_dev);
329                 clear_bit(ADF_STATUS_AE_UCODE_LOADED, &accel_dev->status);
330         }
331
332         if (test_bit(ADF_STATUS_AE_INITIALISED, &accel_dev->status)) {
333                 if (adf_ae_shutdown(accel_dev))
334                         dev_err(&GET_DEV(accel_dev),
335                                 "Failed to shutdown Accel Engine\n");
336                 else
337                         clear_bit(ADF_STATUS_AE_INITIALISED,
338                                   &accel_dev->status);
339         }
340
341         list_for_each(list_itr, &service_table) {
342                 service = list_entry(list_itr, struct service_hndl, list);
343                 if (!test_bit(accel_dev->accel_id, &service->init_status))
344                         continue;
345                 if (service->event_hld(accel_dev, ADF_EVENT_SHUTDOWN))
346                         dev_err(&GET_DEV(accel_dev),
347                                 "Failed to shutdown service %s\n",
348                                 service->name);
349                 else
350                         clear_bit(accel_dev->accel_id, &service->init_status);
351         }
352
353         if (test_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status)) {
354                 hw_data->free_irq(accel_dev);
355                 clear_bit(ADF_STATUS_IRQ_ALLOCATED, &accel_dev->status);
356         }
357
358         /* Delete configuration only if not restarting */
359         if (!test_bit(ADF_STATUS_RESTARTING, &accel_dev->status))
360                 adf_cfg_del_all(accel_dev);
361
362         if (hw_data->exit_arb)
363                 hw_data->exit_arb(accel_dev);
364
365         if (hw_data->exit_admin_comms)
366                 hw_data->exit_admin_comms(accel_dev);
367
368         hw_data->disable_iov(accel_dev);
369         adf_cleanup_etr_data(accel_dev);
370 }
371 EXPORT_SYMBOL_GPL(adf_dev_shutdown);
372
373 int adf_dev_restarting_notify(struct adf_accel_dev *accel_dev)
374 {
375         struct service_hndl *service;
376         struct list_head *list_itr;
377
378         list_for_each(list_itr, &service_table) {
379                 service = list_entry(list_itr, struct service_hndl, list);
380                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTING))
381                         dev_err(&GET_DEV(accel_dev),
382                                 "Failed to restart service %s.\n",
383                                 service->name);
384         }
385         return 0;
386 }
387
388 int adf_dev_restarted_notify(struct adf_accel_dev *accel_dev)
389 {
390         struct service_hndl *service;
391         struct list_head *list_itr;
392
393         list_for_each(list_itr, &service_table) {
394                 service = list_entry(list_itr, struct service_hndl, list);
395                 if (service->event_hld(accel_dev, ADF_EVENT_RESTARTED))
396                         dev_err(&GET_DEV(accel_dev),
397                                 "Failed to restart service %s.\n",
398                                 service->name);
399         }
400         return 0;
401 }