Merge branch 'parisc-5.1-1' of git://git.kernel.org/pub/scm/linux/kernel/git/deller...
[sfrench/cifs-2.6.git] / drivers / crypto / qat / qat_dh895xccvf / adf_drv.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/kernel.h>
48 #include <linux/module.h>
49 #include <linux/pci.h>
50 #include <linux/init.h>
51 #include <linux/types.h>
52 #include <linux/fs.h>
53 #include <linux/slab.h>
54 #include <linux/errno.h>
55 #include <linux/device.h>
56 #include <linux/dma-mapping.h>
57 #include <linux/platform_device.h>
58 #include <linux/workqueue.h>
59 #include <linux/io.h>
60 #include <adf_accel_devices.h>
61 #include <adf_common_drv.h>
62 #include <adf_cfg.h>
63 #include "adf_dh895xccvf_hw_data.h"
64
65 #define ADF_SYSTEM_DEVICE(device_id) \
66         {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)}
67
68 static const struct pci_device_id adf_pci_tbl[] = {
69         ADF_SYSTEM_DEVICE(ADF_DH895XCCIOV_PCI_DEVICE_ID),
70         {0,}
71 };
72 MODULE_DEVICE_TABLE(pci, adf_pci_tbl);
73
74 static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent);
75 static void adf_remove(struct pci_dev *dev);
76
77 static struct pci_driver adf_driver = {
78         .id_table = adf_pci_tbl,
79         .name = ADF_DH895XCCVF_DEVICE_NAME,
80         .probe = adf_probe,
81         .remove = adf_remove,
82 };
83
84 static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev)
85 {
86         pci_release_regions(accel_dev->accel_pci_dev.pci_dev);
87         pci_disable_device(accel_dev->accel_pci_dev.pci_dev);
88 }
89
90 static void adf_cleanup_accel(struct adf_accel_dev *accel_dev)
91 {
92         struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev;
93         struct adf_accel_dev *pf;
94         int i;
95
96         for (i = 0; i < ADF_PCI_MAX_BARS; i++) {
97                 struct adf_bar *bar = &accel_pci_dev->pci_bars[i];
98
99                 if (bar->virt_addr)
100                         pci_iounmap(accel_pci_dev->pci_dev, bar->virt_addr);
101         }
102
103         if (accel_dev->hw_device) {
104                 switch (accel_pci_dev->pci_dev->device) {
105                 case ADF_DH895XCCIOV_PCI_DEVICE_ID:
106                         adf_clean_hw_data_dh895xcciov(accel_dev->hw_device);
107                         break;
108                 default:
109                         break;
110                 }
111                 kfree(accel_dev->hw_device);
112                 accel_dev->hw_device = NULL;
113         }
114         adf_cfg_dev_remove(accel_dev);
115         debugfs_remove(accel_dev->debugfs_dir);
116         pf = adf_devmgr_pci_to_accel_dev(accel_pci_dev->pci_dev->physfn);
117         adf_devmgr_rm_dev(accel_dev, pf);
118 }
119
120 static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
121 {
122         struct adf_accel_dev *accel_dev;
123         struct adf_accel_dev *pf;
124         struct adf_accel_pci *accel_pci_dev;
125         struct adf_hw_device_data *hw_data;
126         char name[ADF_DEVICE_NAME_LENGTH];
127         unsigned int i, bar_nr;
128         unsigned long bar_mask;
129         int ret;
130
131         switch (ent->device) {
132         case ADF_DH895XCCIOV_PCI_DEVICE_ID:
133                 break;
134         default:
135                 dev_err(&pdev->dev, "Invalid device 0x%x.\n", ent->device);
136                 return -ENODEV;
137         }
138
139         accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL,
140                                  dev_to_node(&pdev->dev));
141         if (!accel_dev)
142                 return -ENOMEM;
143
144         accel_dev->is_vf = true;
145         pf = adf_devmgr_pci_to_accel_dev(pdev->physfn);
146         accel_pci_dev = &accel_dev->accel_pci_dev;
147         accel_pci_dev->pci_dev = pdev;
148
149         /* Add accel device to accel table */
150         if (adf_devmgr_add_dev(accel_dev, pf)) {
151                 dev_err(&pdev->dev, "Failed to add new accelerator device.\n");
152                 kfree(accel_dev);
153                 return -EFAULT;
154         }
155         INIT_LIST_HEAD(&accel_dev->crypto_list);
156
157         accel_dev->owner = THIS_MODULE;
158         /* Allocate and configure device configuration structure */
159         hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL,
160                                dev_to_node(&pdev->dev));
161         if (!hw_data) {
162                 ret = -ENOMEM;
163                 goto out_err;
164         }
165         accel_dev->hw_device = hw_data;
166         adf_init_hw_data_dh895xcciov(accel_dev->hw_device);
167
168         /* Get Accelerators and Accelerators Engines masks */
169         hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses);
170         hw_data->ae_mask = hw_data->get_ae_mask(hw_data->fuses);
171         accel_pci_dev->sku = hw_data->get_sku(hw_data);
172
173         /* Create dev top level debugfs entry */
174         snprintf(name, sizeof(name), "%s%s_%02x:%02d.%d",
175                  ADF_DEVICE_NAME_PREFIX, hw_data->dev_class->name,
176                  pdev->bus->number, PCI_SLOT(pdev->devfn),
177                  PCI_FUNC(pdev->devfn));
178
179         accel_dev->debugfs_dir = debugfs_create_dir(name, NULL);
180
181         /* Create device configuration table */
182         ret = adf_cfg_dev_add(accel_dev);
183         if (ret)
184                 goto out_err;
185
186         /* enable PCI device */
187         if (pci_enable_device(pdev)) {
188                 ret = -EFAULT;
189                 goto out_err;
190         }
191
192         /* set dma identifier */
193         if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) {
194                 if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) {
195                         dev_err(&pdev->dev, "No usable DMA configuration\n");
196                         ret = -EFAULT;
197                         goto out_err_disable;
198                 } else {
199                         pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
200                 }
201
202         } else {
203                 pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64));
204         }
205
206         if (pci_request_regions(pdev, ADF_DH895XCCVF_DEVICE_NAME)) {
207                 ret = -EFAULT;
208                 goto out_err_disable;
209         }
210
211         /* Find and map all the device's BARS */
212         i = 0;
213         bar_mask = pci_select_bars(pdev, IORESOURCE_MEM);
214         for_each_set_bit(bar_nr, &bar_mask, ADF_PCI_MAX_BARS * 2) {
215                 struct adf_bar *bar = &accel_pci_dev->pci_bars[i++];
216
217                 bar->base_addr = pci_resource_start(pdev, bar_nr);
218                 if (!bar->base_addr)
219                         break;
220                 bar->size = pci_resource_len(pdev, bar_nr);
221                 bar->virt_addr = pci_iomap(accel_pci_dev->pci_dev, bar_nr, 0);
222                 if (!bar->virt_addr) {
223                         dev_err(&pdev->dev, "Failed to map BAR %d\n", bar_nr);
224                         ret = -EFAULT;
225                         goto out_err_free_reg;
226                 }
227         }
228         pci_set_master(pdev);
229         /* Completion for VF2PF request/response message exchange */
230         init_completion(&accel_dev->vf.iov_msg_completion);
231
232         ret = qat_crypto_dev_config(accel_dev);
233         if (ret)
234                 goto out_err_free_reg;
235
236         set_bit(ADF_STATUS_PF_RUNNING, &accel_dev->status);
237
238         ret = adf_dev_init(accel_dev);
239         if (ret)
240                 goto out_err_dev_shutdown;
241
242         ret = adf_dev_start(accel_dev);
243         if (ret)
244                 goto out_err_dev_stop;
245
246         return ret;
247
248 out_err_dev_stop:
249         adf_dev_stop(accel_dev);
250 out_err_dev_shutdown:
251         adf_dev_shutdown(accel_dev);
252 out_err_free_reg:
253         pci_release_regions(accel_pci_dev->pci_dev);
254 out_err_disable:
255         pci_disable_device(accel_pci_dev->pci_dev);
256 out_err:
257         adf_cleanup_accel(accel_dev);
258         kfree(accel_dev);
259         return ret;
260 }
261
262 static void adf_remove(struct pci_dev *pdev)
263 {
264         struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev);
265
266         if (!accel_dev) {
267                 pr_err("QAT: Driver removal failed\n");
268                 return;
269         }
270         adf_dev_stop(accel_dev);
271         adf_dev_shutdown(accel_dev);
272         adf_cleanup_accel(accel_dev);
273         adf_cleanup_pci_dev(accel_dev);
274         kfree(accel_dev);
275 }
276
277 static int __init adfdrv_init(void)
278 {
279         request_module("intel_qat");
280
281         if (pci_register_driver(&adf_driver)) {
282                 pr_err("QAT: Driver initialization failed\n");
283                 return -EFAULT;
284         }
285         return 0;
286 }
287
288 static void __exit adfdrv_release(void)
289 {
290         pci_unregister_driver(&adf_driver);
291         adf_clean_vf_map(true);
292 }
293
294 module_init(adfdrv_init);
295 module_exit(adfdrv_release);
296
297 MODULE_LICENSE("Dual BSD/GPL");
298 MODULE_AUTHOR("Intel");
299 MODULE_DESCRIPTION("Intel(R) QuickAssist Technology");
300 MODULE_VERSION(ADF_DRV_VERSION);