diff options
author | Tadeusz Struk <tadeusz.struk@intel.com> | 2015-08-07 14:34:31 -0400 |
---|---|---|
committer | Herbert Xu <herbert@gondor.apana.org.au> | 2015-08-10 11:20:16 -0400 |
commit | dd0f368398ea100e34259bf812bc482e15c81991 (patch) | |
tree | 0c670cff970337cfcb651556e7ede9c10a5a26c3 | |
parent | ed8ccaef52fa03fb03cff45b380f72c9f869f273 (diff) |
crypto: qat - Add qat dh895xcc VF driver
Add code specific for the dh895xcc virtual function.
Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
-rw-r--r-- | drivers/crypto/qat/Kconfig | 11 | ||||
-rw-r--r-- | drivers/crypto/qat/Makefile | 1 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/Makefile | 5 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c | 172 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h | 68 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | 393 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/adf_drv.h | 57 | ||||
-rw-r--r-- | drivers/crypto/qat/qat_dh895xccvf/adf_isr.c | 258 |
8 files changed, 965 insertions, 0 deletions
diff --git a/drivers/crypto/qat/Kconfig b/drivers/crypto/qat/Kconfig index d8c3d595d98b..95a956625a2e 100644 --- a/drivers/crypto/qat/Kconfig +++ b/drivers/crypto/qat/Kconfig | |||
@@ -21,3 +21,14 @@ config CRYPTO_DEV_QAT_DH895xCC | |||
21 | 21 | ||
22 | To compile this as a module, choose M here: the module | 22 | To compile this as a module, choose M here: the module |
23 | will be called qat_dh895xcc. | 23 | will be called qat_dh895xcc. |
24 | |||
25 | config CRYPTO_DEV_QAT_DH895xCCVF | ||
26 | tristate "Support for Intel(R) DH895xCC Virtual Function" | ||
27 | select PCI_IOV | ||
28 | |||
29 | help | ||
30 | Support for Intel(R) DH895xcc with Intel(R) QuickAssist Technology | ||
31 | Virtual Function for accelerating crypto and compression workloads. | ||
32 | |||
33 | To compile this as a module, choose M here: the module | ||
34 | will be called qat_dh895xccvf. | ||
diff --git a/drivers/crypto/qat/Makefile b/drivers/crypto/qat/Makefile index d11481be225e..a3ce0b70e32f 100644 --- a/drivers/crypto/qat/Makefile +++ b/drivers/crypto/qat/Makefile | |||
@@ -1,2 +1,3 @@ | |||
1 | obj-$(CONFIG_CRYPTO_DEV_QAT) += qat_common/ | 1 | obj-$(CONFIG_CRYPTO_DEV_QAT) += qat_common/ |
2 | obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc/ | 2 | obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc/ |
3 | obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCCVF) += qat_dh895xccvf/ | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/Makefile b/drivers/crypto/qat/qat_dh895xccvf/Makefile new file mode 100644 index 000000000000..85399fcbbad4 --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/Makefile | |||
@@ -0,0 +1,5 @@ | |||
1 | ccflags-y := -I$(src)/../qat_common | ||
2 | obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCCVF) += qat_dh895xccvf.o | ||
3 | qat_dh895xccvf-objs := adf_drv.o \ | ||
4 | adf_isr.o \ | ||
5 | adf_dh895xccvf_hw_data.o | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c new file mode 100644 index 000000000000..7bbf846a53ca --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.c | |||
@@ -0,0 +1,172 @@ | |||
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) 2015 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) 2015 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 <adf_accel_devices.h> | ||
48 | #include <adf_pf2vf_msg.h> | ||
49 | #include <adf_common_drv.h> | ||
50 | #include "adf_dh895xccvf_hw_data.h" | ||
51 | #include "adf_drv.h" | ||
52 | |||
53 | static struct adf_hw_device_class dh895xcciov_class = { | ||
54 | .name = ADF_DH895XCCVF_DEVICE_NAME, | ||
55 | .type = DEV_DH895XCCVF, | ||
56 | .instances = 0 | ||
57 | }; | ||
58 | |||
59 | static u32 get_accel_mask(u32 fuse) | ||
60 | { | ||
61 | return ADF_DH895XCCIOV_ACCELERATORS_MASK; | ||
62 | } | ||
63 | |||
64 | static u32 get_ae_mask(u32 fuse) | ||
65 | { | ||
66 | return ADF_DH895XCCIOV_ACCELENGINES_MASK; | ||
67 | } | ||
68 | |||
69 | static u32 get_num_accels(struct adf_hw_device_data *self) | ||
70 | { | ||
71 | return ADF_DH895XCCIOV_MAX_ACCELERATORS; | ||
72 | } | ||
73 | |||
74 | static u32 get_num_aes(struct adf_hw_device_data *self) | ||
75 | { | ||
76 | return ADF_DH895XCCIOV_MAX_ACCELENGINES; | ||
77 | } | ||
78 | |||
79 | static u32 get_misc_bar_id(struct adf_hw_device_data *self) | ||
80 | { | ||
81 | return ADF_DH895XCCIOV_PMISC_BAR; | ||
82 | } | ||
83 | |||
84 | static u32 get_etr_bar_id(struct adf_hw_device_data *self) | ||
85 | { | ||
86 | return ADF_DH895XCCIOV_ETR_BAR; | ||
87 | } | ||
88 | |||
89 | static enum dev_sku_info get_sku(struct adf_hw_device_data *self) | ||
90 | { | ||
91 | return DEV_SKU_VF; | ||
92 | } | ||
93 | |||
94 | static u32 get_pf2vf_offset(u32 i) | ||
95 | { | ||
96 | return ADF_DH895XCCIOV_PF2VF_OFFSET; | ||
97 | } | ||
98 | |||
99 | static u32 get_vintmsk_offset(u32 i) | ||
100 | { | ||
101 | return ADF_DH895XCCIOV_VINTMSK_OFFSET; | ||
102 | } | ||
103 | |||
104 | static int adf_vf_int_noop(struct adf_accel_dev *accel_dev) | ||
105 | { | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | static void adf_vf_void_noop(struct adf_accel_dev *accel_dev) | ||
110 | { | ||
111 | } | ||
112 | |||
113 | static int adf_vf2pf_init(struct adf_accel_dev *accel_dev) | ||
114 | { | ||
115 | u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | | ||
116 | (ADF_VF2PF_MSGTYPE_INIT << ADF_VF2PF_MSGTYPE_SHIFT)); | ||
117 | |||
118 | if (adf_iov_putmsg(accel_dev, msg, 0)) { | ||
119 | dev_err(&GET_DEV(accel_dev), | ||
120 | "Failed to send Init event to PF\n"); | ||
121 | return -EFAULT; | ||
122 | } | ||
123 | return 0; | ||
124 | } | ||
125 | |||
126 | static void adf_vf2pf_shutdown(struct adf_accel_dev *accel_dev) | ||
127 | { | ||
128 | u32 msg = (ADF_VF2PF_MSGORIGIN_SYSTEM | | ||
129 | (ADF_VF2PF_MSGTYPE_SHUTDOWN << ADF_VF2PF_MSGTYPE_SHIFT)); | ||
130 | |||
131 | if (adf_iov_putmsg(accel_dev, msg, 0)) | ||
132 | dev_err(&GET_DEV(accel_dev), | ||
133 | "Failed to send Shutdown event to PF\n"); | ||
134 | } | ||
135 | |||
136 | void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) | ||
137 | { | ||
138 | hw_data->dev_class = &dh895xcciov_class; | ||
139 | hw_data->instance_id = dh895xcciov_class.instances++; | ||
140 | hw_data->num_banks = ADF_DH895XCCIOV_ETR_MAX_BANKS; | ||
141 | hw_data->num_accel = ADF_DH895XCCIOV_MAX_ACCELERATORS; | ||
142 | hw_data->num_logical_accel = 1; | ||
143 | hw_data->num_engines = ADF_DH895XCCIOV_MAX_ACCELENGINES; | ||
144 | hw_data->tx_rx_gap = ADF_DH895XCCIOV_RX_RINGS_OFFSET; | ||
145 | hw_data->tx_rings_mask = ADF_DH895XCCIOV_TX_RINGS_MASK; | ||
146 | hw_data->alloc_irq = adf_isr_resource_alloc; | ||
147 | hw_data->free_irq = adf_isr_resource_free; | ||
148 | hw_data->enable_error_correction = adf_vf_void_noop; | ||
149 | hw_data->init_admin_comms = adf_vf_int_noop; | ||
150 | hw_data->exit_admin_comms = adf_vf_void_noop; | ||
151 | hw_data->send_admin_init = adf_vf2pf_init; | ||
152 | hw_data->init_arb = adf_vf_int_noop; | ||
153 | hw_data->exit_arb = adf_vf_void_noop; | ||
154 | hw_data->disable_iov = adf_vf2pf_shutdown; | ||
155 | hw_data->get_accel_mask = get_accel_mask; | ||
156 | hw_data->get_ae_mask = get_ae_mask; | ||
157 | hw_data->get_num_accels = get_num_accels; | ||
158 | hw_data->get_num_aes = get_num_aes; | ||
159 | hw_data->get_etr_bar_id = get_etr_bar_id; | ||
160 | hw_data->get_misc_bar_id = get_misc_bar_id; | ||
161 | hw_data->get_pf2vf_offset = get_pf2vf_offset; | ||
162 | hw_data->get_vintmsk_offset = get_vintmsk_offset; | ||
163 | hw_data->get_sku = get_sku; | ||
164 | hw_data->enable_ints = adf_vf_void_noop; | ||
165 | hw_data->enable_vf2pf_comms = adf_enable_vf2pf_comms; | ||
166 | hw_data->min_iov_compat_ver = ADF_PFVF_COMPATIBILITY_VERSION; | ||
167 | } | ||
168 | |||
169 | void adf_clean_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data) | ||
170 | { | ||
171 | hw_data->dev_class->instances--; | ||
172 | } | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h new file mode 100644 index 000000000000..8f6babfef629 --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_dh895xccvf_hw_data.h | |||
@@ -0,0 +1,68 @@ | |||
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) 2015 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) 2015 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 | #ifndef ADF_DH895XVF_HW_DATA_H_ | ||
48 | #define ADF_DH895XVF_HW_DATA_H_ | ||
49 | |||
50 | #define ADF_DH895XCCIOV_PMISC_BAR 1 | ||
51 | #define ADF_DH895XCCIOV_ACCELERATORS_MASK 0x1 | ||
52 | #define ADF_DH895XCCIOV_ACCELENGINES_MASK 0x1 | ||
53 | #define ADF_DH895XCCIOV_MAX_ACCELERATORS 1 | ||
54 | #define ADF_DH895XCCIOV_MAX_ACCELENGINES 1 | ||
55 | #define ADF_DH895XCCIOV_RX_RINGS_OFFSET 8 | ||
56 | #define ADF_DH895XCCIOV_TX_RINGS_MASK 0xFF | ||
57 | #define ADF_DH895XCCIOV_ETR_BAR 0 | ||
58 | #define ADF_DH895XCCIOV_ETR_MAX_BANKS 1 | ||
59 | |||
60 | #define ADF_DH895XCCIOV_PF2VF_OFFSET 0x200 | ||
61 | #define ADF_DH895XCC_PF2VF_PF2VFINT BIT(0) | ||
62 | |||
63 | #define ADF_DH895XCCIOV_VINTSOU_OFFSET 0x204 | ||
64 | #define ADF_DH895XCC_VINTSOU_BUN BIT(0) | ||
65 | #define ADF_DH895XCC_VINTSOU_PF2VF BIT(1) | ||
66 | |||
67 | #define ADF_DH895XCCIOV_VINTMSK_OFFSET 0x208 | ||
68 | #endif | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c new file mode 100644 index 000000000000..789426f21882 --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.c | |||
@@ -0,0 +1,393 @@ | |||
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_transport_access_macros.h> | ||
64 | #include "adf_dh895xccvf_hw_data.h" | ||
65 | #include "adf_drv.h" | ||
66 | |||
67 | static const char adf_driver_name[] = ADF_DH895XCCVF_DEVICE_NAME; | ||
68 | |||
69 | #define ADF_SYSTEM_DEVICE(device_id) \ | ||
70 | {PCI_DEVICE(PCI_VENDOR_ID_INTEL, device_id)} | ||
71 | |||
72 | static const struct pci_device_id adf_pci_tbl[] = { | ||
73 | ADF_SYSTEM_DEVICE(ADF_DH895XCCIOV_PCI_DEVICE_ID), | ||
74 | {0,} | ||
75 | }; | ||
76 | MODULE_DEVICE_TABLE(pci, adf_pci_tbl); | ||
77 | |||
78 | static int adf_probe(struct pci_dev *dev, const struct pci_device_id *ent); | ||
79 | static void adf_remove(struct pci_dev *dev); | ||
80 | |||
81 | static struct pci_driver adf_driver = { | ||
82 | .id_table = adf_pci_tbl, | ||
83 | .name = adf_driver_name, | ||
84 | .probe = adf_probe, | ||
85 | .remove = adf_remove, | ||
86 | }; | ||
87 | |||
88 | static void adf_cleanup_pci_dev(struct adf_accel_dev *accel_dev) | ||
89 | { | ||
90 | pci_release_regions(accel_dev->accel_pci_dev.pci_dev); | ||
91 | pci_disable_device(accel_dev->accel_pci_dev.pci_dev); | ||
92 | } | ||
93 | |||
94 | static void adf_cleanup_accel(struct adf_accel_dev *accel_dev) | ||
95 | { | ||
96 | struct adf_accel_pci *accel_pci_dev = &accel_dev->accel_pci_dev; | ||
97 | struct adf_accel_dev *pf; | ||
98 | int i; | ||
99 | |||
100 | for (i = 0; i < ADF_PCI_MAX_BARS; i++) { | ||
101 | struct adf_bar *bar = &accel_pci_dev->pci_bars[i]; | ||
102 | |||
103 | if (bar->virt_addr) | ||
104 | pci_iounmap(accel_pci_dev->pci_dev, bar->virt_addr); | ||
105 | } | ||
106 | |||
107 | if (accel_dev->hw_device) { | ||
108 | switch (accel_pci_dev->pci_dev->device) { | ||
109 | case ADF_DH895XCCIOV_PCI_DEVICE_ID: | ||
110 | adf_clean_hw_data_dh895xcciov(accel_dev->hw_device); | ||
111 | break; | ||
112 | default: | ||
113 | break; | ||
114 | } | ||
115 | kfree(accel_dev->hw_device); | ||
116 | accel_dev->hw_device = NULL; | ||
117 | } | ||
118 | adf_cfg_dev_remove(accel_dev); | ||
119 | debugfs_remove(accel_dev->debugfs_dir); | ||
120 | pf = adf_devmgr_pci_to_accel_dev(accel_pci_dev->pci_dev->physfn); | ||
121 | adf_devmgr_rm_dev(accel_dev, pf); | ||
122 | } | ||
123 | |||
124 | static int adf_dev_configure(struct adf_accel_dev *accel_dev) | ||
125 | { | ||
126 | char key[ADF_CFG_MAX_KEY_LEN_IN_BYTES]; | ||
127 | unsigned long val, bank = 0; | ||
128 | |||
129 | if (adf_cfg_section_add(accel_dev, ADF_KERNEL_SEC)) | ||
130 | goto err; | ||
131 | if (adf_cfg_section_add(accel_dev, "Accelerator0")) | ||
132 | goto err; | ||
133 | |||
134 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_BANK_NUM, 0); | ||
135 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key, | ||
136 | (void *)&bank, ADF_DEC)) | ||
137 | goto err; | ||
138 | |||
139 | val = bank; | ||
140 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_ETRMGR_CORE_AFFINITY, 0); | ||
141 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key, | ||
142 | (void *)&val, ADF_DEC)) | ||
143 | goto err; | ||
144 | |||
145 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_SIZE, 0); | ||
146 | |||
147 | val = 128; | ||
148 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, key, | ||
149 | (void *)&val, ADF_DEC)) | ||
150 | goto err; | ||
151 | |||
152 | val = 512; | ||
153 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_SIZE, 0); | ||
154 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
155 | key, (void *)&val, ADF_DEC)) | ||
156 | goto err; | ||
157 | |||
158 | val = 0; | ||
159 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_TX, 0); | ||
160 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
161 | key, (void *)&val, ADF_DEC)) | ||
162 | goto err; | ||
163 | |||
164 | val = 2; | ||
165 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_TX, 0); | ||
166 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
167 | key, (void *)&val, ADF_DEC)) | ||
168 | goto err; | ||
169 | |||
170 | val = 8; | ||
171 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_ASYM_RX, 0); | ||
172 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
173 | key, (void *)&val, ADF_DEC)) | ||
174 | goto err; | ||
175 | |||
176 | val = 10; | ||
177 | snprintf(key, sizeof(key), ADF_CY "%d" ADF_RING_SYM_RX, 0); | ||
178 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
179 | key, (void *)&val, ADF_DEC)) | ||
180 | goto err; | ||
181 | |||
182 | val = ADF_COALESCING_DEF_TIME; | ||
183 | snprintf(key, sizeof(key), ADF_ETRMGR_COALESCE_TIMER_FORMAT, | ||
184 | (int)bank); | ||
185 | if (adf_cfg_add_key_value_param(accel_dev, "Accelerator0", | ||
186 | key, (void *)&val, ADF_DEC)) | ||
187 | goto err; | ||
188 | |||
189 | val = 1; | ||
190 | if (adf_cfg_add_key_value_param(accel_dev, ADF_KERNEL_SEC, | ||
191 | ADF_NUM_CY, (void *)&val, ADF_DEC)) | ||
192 | goto err; | ||
193 | |||
194 | set_bit(ADF_STATUS_CONFIGURED, &accel_dev->status); | ||
195 | return 0; | ||
196 | err: | ||
197 | dev_err(&GET_DEV(accel_dev), "Failed to configure QAT accel dev\n"); | ||
198 | return -EINVAL; | ||
199 | } | ||
200 | |||
201 | static int adf_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
202 | { | ||
203 | struct adf_accel_dev *accel_dev; | ||
204 | struct adf_accel_dev *pf; | ||
205 | struct adf_accel_pci *accel_pci_dev; | ||
206 | struct adf_hw_device_data *hw_data; | ||
207 | char name[ADF_DEVICE_NAME_LENGTH]; | ||
208 | unsigned int i, bar_nr; | ||
209 | int ret, bar_mask; | ||
210 | |||
211 | switch (ent->device) { | ||
212 | case ADF_DH895XCCIOV_PCI_DEVICE_ID: | ||
213 | break; | ||
214 | default: | ||
215 | dev_err(&pdev->dev, "Invalid device 0x%x.\n", ent->device); | ||
216 | return -ENODEV; | ||
217 | } | ||
218 | |||
219 | accel_dev = kzalloc_node(sizeof(*accel_dev), GFP_KERNEL, | ||
220 | dev_to_node(&pdev->dev)); | ||
221 | if (!accel_dev) | ||
222 | return -ENOMEM; | ||
223 | |||
224 | accel_dev->is_vf = true; | ||
225 | pf = adf_devmgr_pci_to_accel_dev(pdev->physfn); | ||
226 | accel_pci_dev = &accel_dev->accel_pci_dev; | ||
227 | accel_pci_dev->pci_dev = pdev; | ||
228 | |||
229 | /* Add accel device to accel table */ | ||
230 | if (adf_devmgr_add_dev(accel_dev, pf)) { | ||
231 | dev_err(&pdev->dev, "Failed to add new accelerator device.\n"); | ||
232 | kfree(accel_dev); | ||
233 | return -EFAULT; | ||
234 | } | ||
235 | INIT_LIST_HEAD(&accel_dev->crypto_list); | ||
236 | |||
237 | accel_dev->owner = THIS_MODULE; | ||
238 | /* Allocate and configure device configuration structure */ | ||
239 | hw_data = kzalloc_node(sizeof(*hw_data), GFP_KERNEL, | ||
240 | dev_to_node(&pdev->dev)); | ||
241 | if (!hw_data) { | ||
242 | ret = -ENOMEM; | ||
243 | goto out_err; | ||
244 | } | ||
245 | accel_dev->hw_device = hw_data; | ||
246 | switch (ent->device) { | ||
247 | case ADF_DH895XCCIOV_PCI_DEVICE_ID: | ||
248 | adf_init_hw_data_dh895xcciov(accel_dev->hw_device); | ||
249 | break; | ||
250 | default: | ||
251 | ret = -ENODEV; | ||
252 | goto out_err; | ||
253 | } | ||
254 | |||
255 | /* Get Accelerators and Accelerators Engines masks */ | ||
256 | hw_data->accel_mask = hw_data->get_accel_mask(hw_data->fuses); | ||
257 | hw_data->ae_mask = hw_data->get_ae_mask(hw_data->fuses); | ||
258 | accel_pci_dev->sku = hw_data->get_sku(hw_data); | ||
259 | |||
260 | /* Create dev top level debugfs entry */ | ||
261 | snprintf(name, sizeof(name), "%s%s_%02x:%02d.%02d", | ||
262 | ADF_DEVICE_NAME_PREFIX, hw_data->dev_class->name, | ||
263 | pdev->bus->number, PCI_SLOT(pdev->devfn), | ||
264 | PCI_FUNC(pdev->devfn)); | ||
265 | |||
266 | accel_dev->debugfs_dir = debugfs_create_dir(name, NULL); | ||
267 | if (!accel_dev->debugfs_dir) { | ||
268 | dev_err(&pdev->dev, "Could not create debugfs dir %s\n", name); | ||
269 | ret = -EINVAL; | ||
270 | goto out_err; | ||
271 | } | ||
272 | |||
273 | /* Create device configuration table */ | ||
274 | ret = adf_cfg_dev_add(accel_dev); | ||
275 | if (ret) | ||
276 | goto out_err; | ||
277 | |||
278 | /* enable PCI device */ | ||
279 | if (pci_enable_device(pdev)) { | ||
280 | ret = -EFAULT; | ||
281 | goto out_err; | ||
282 | } | ||
283 | |||
284 | /* set dma identifier */ | ||
285 | if (pci_set_dma_mask(pdev, DMA_BIT_MASK(64))) { | ||
286 | if ((pci_set_dma_mask(pdev, DMA_BIT_MASK(32)))) { | ||
287 | dev_err(&pdev->dev, "No usable DMA configuration\n"); | ||
288 | ret = -EFAULT; | ||
289 | goto out_err_disable; | ||
290 | } else { | ||
291 | pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32)); | ||
292 | } | ||
293 | |||
294 | } else { | ||
295 | pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(64)); | ||
296 | } | ||
297 | |||
298 | if (pci_request_regions(pdev, adf_driver_name)) { | ||
299 | ret = -EFAULT; | ||
300 | goto out_err_disable; | ||
301 | } | ||
302 | |||
303 | /* Find and map all the device's BARS */ | ||
304 | i = 0; | ||
305 | bar_mask = pci_select_bars(pdev, IORESOURCE_MEM); | ||
306 | for_each_set_bit(bar_nr, (const unsigned long *)&bar_mask, | ||
307 | ADF_PCI_MAX_BARS * 2) { | ||
308 | struct adf_bar *bar = &accel_pci_dev->pci_bars[i++]; | ||
309 | |||
310 | bar->base_addr = pci_resource_start(pdev, bar_nr); | ||
311 | if (!bar->base_addr) | ||
312 | break; | ||
313 | bar->size = pci_resource_len(pdev, bar_nr); | ||
314 | bar->virt_addr = pci_iomap(accel_pci_dev->pci_dev, bar_nr, 0); | ||
315 | if (!bar->virt_addr) { | ||
316 | dev_err(&pdev->dev, "Failed to map BAR %d\n", bar_nr); | ||
317 | ret = -EFAULT; | ||
318 | goto out_err_free_reg; | ||
319 | } | ||
320 | } | ||
321 | pci_set_master(pdev); | ||
322 | /* Completion for VF2PF request/response message exchange */ | ||
323 | init_completion(&accel_dev->vf.iov_msg_completion); | ||
324 | |||
325 | ret = adf_dev_configure(accel_dev); | ||
326 | if (ret) | ||
327 | goto out_err_free_reg; | ||
328 | |||
329 | ret = adf_dev_init(accel_dev); | ||
330 | if (ret) | ||
331 | goto out_err_dev_shutdown; | ||
332 | |||
333 | ret = adf_dev_start(accel_dev); | ||
334 | if (ret) | ||
335 | goto out_err_dev_stop; | ||
336 | |||
337 | return ret; | ||
338 | |||
339 | out_err_dev_stop: | ||
340 | adf_dev_stop(accel_dev); | ||
341 | out_err_dev_shutdown: | ||
342 | adf_dev_shutdown(accel_dev); | ||
343 | out_err_free_reg: | ||
344 | pci_release_regions(accel_pci_dev->pci_dev); | ||
345 | out_err_disable: | ||
346 | pci_disable_device(accel_pci_dev->pci_dev); | ||
347 | out_err: | ||
348 | adf_cleanup_accel(accel_dev); | ||
349 | kfree(accel_dev); | ||
350 | return ret; | ||
351 | } | ||
352 | |||
353 | static void adf_remove(struct pci_dev *pdev) | ||
354 | { | ||
355 | struct adf_accel_dev *accel_dev = adf_devmgr_pci_to_accel_dev(pdev); | ||
356 | |||
357 | if (!accel_dev) { | ||
358 | pr_err("QAT: Driver removal failed\n"); | ||
359 | return; | ||
360 | } | ||
361 | if (adf_dev_stop(accel_dev)) | ||
362 | dev_err(&GET_DEV(accel_dev), "Failed to stop QAT accel dev\n"); | ||
363 | |||
364 | adf_dev_shutdown(accel_dev); | ||
365 | adf_cleanup_accel(accel_dev); | ||
366 | adf_cleanup_pci_dev(accel_dev); | ||
367 | kfree(accel_dev); | ||
368 | } | ||
369 | |||
370 | static int __init adfdrv_init(void) | ||
371 | { | ||
372 | request_module("intel_qat"); | ||
373 | |||
374 | if (pci_register_driver(&adf_driver)) { | ||
375 | pr_err("QAT: Driver initialization failed\n"); | ||
376 | return -EFAULT; | ||
377 | } | ||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static void __exit adfdrv_release(void) | ||
382 | { | ||
383 | pci_unregister_driver(&adf_driver); | ||
384 | adf_clean_vf_map(true); | ||
385 | } | ||
386 | |||
387 | module_init(adfdrv_init); | ||
388 | module_exit(adfdrv_release); | ||
389 | |||
390 | MODULE_LICENSE("Dual BSD/GPL"); | ||
391 | MODULE_AUTHOR("Intel"); | ||
392 | MODULE_DESCRIPTION("Intel(R) QuickAssist Technology"); | ||
393 | MODULE_VERSION(ADF_DRV_VERSION); | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_drv.h b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.h new file mode 100644 index 000000000000..041d2a0a0215 --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_drv.h | |||
@@ -0,0 +1,57 @@ | |||
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 | #ifndef ADF_DH895xVF_DRV_H_ | ||
48 | #define ADF_DH895xVF_DRV_H_ | ||
49 | #include <adf_accel_devices.h> | ||
50 | #include <adf_transport.h> | ||
51 | |||
52 | void adf_init_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data); | ||
53 | void adf_clean_hw_data_dh895xcciov(struct adf_hw_device_data *hw_data); | ||
54 | int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev); | ||
55 | void adf_isr_resource_free(struct adf_accel_dev *accel_dev); | ||
56 | void adf_update_ring_arb_enable(struct adf_etr_ring_data *ring); | ||
57 | #endif | ||
diff --git a/drivers/crypto/qat/qat_dh895xccvf/adf_isr.c b/drivers/crypto/qat/qat_dh895xccvf/adf_isr.c new file mode 100644 index 000000000000..7fdc84a407cc --- /dev/null +++ b/drivers/crypto/qat/qat_dh895xccvf/adf_isr.c | |||
@@ -0,0 +1,258 @@ | |||
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/init.h> | ||
49 | #include <linux/types.h> | ||
50 | #include <linux/pci.h> | ||
51 | #include <linux/slab.h> | ||
52 | #include <linux/errno.h> | ||
53 | #include <linux/interrupt.h> | ||
54 | #include <adf_accel_devices.h> | ||
55 | #include <adf_common_drv.h> | ||
56 | #include <adf_cfg.h> | ||
57 | #include <adf_cfg_strings.h> | ||
58 | #include <adf_cfg_common.h> | ||
59 | #include <adf_transport_access_macros.h> | ||
60 | #include <adf_transport_internal.h> | ||
61 | #include <adf_pf2vf_msg.h> | ||
62 | #include "adf_drv.h" | ||
63 | #include "adf_dh895xccvf_hw_data.h" | ||
64 | |||
65 | static int adf_enable_msi(struct adf_accel_dev *accel_dev) | ||
66 | { | ||
67 | struct adf_accel_pci *pci_dev_info = &accel_dev->accel_pci_dev; | ||
68 | int stat = pci_enable_msi(pci_dev_info->pci_dev); | ||
69 | |||
70 | if (stat) { | ||
71 | dev_err(&GET_DEV(accel_dev), | ||
72 | "Failed to enable MSI interrupts\n"); | ||
73 | return stat; | ||
74 | } | ||
75 | |||
76 | accel_dev->vf.irq_name = kzalloc(ADF_MAX_MSIX_VECTOR_NAME, GFP_KERNEL); | ||
77 | if (!accel_dev->vf.irq_name) | ||
78 | return -ENOMEM; | ||
79 | |||
80 | return stat; | ||
81 | } | ||
82 | |||
83 | static void adf_disable_msi(struct adf_accel_dev *accel_dev) | ||
84 | { | ||
85 | struct pci_dev *pdev = accel_to_pci_dev(accel_dev); | ||
86 | |||
87 | kfree(accel_dev->vf.irq_name); | ||
88 | pci_disable_msi(pdev); | ||
89 | } | ||
90 | |||
91 | static void adf_pf2vf_bh_handler(void *data) | ||
92 | { | ||
93 | struct adf_accel_dev *accel_dev = data; | ||
94 | void __iomem *pmisc_bar_addr = | ||
95 | (&GET_BARS(accel_dev)[ADF_DH895XCCIOV_PMISC_BAR])->virt_addr; | ||
96 | u32 msg; | ||
97 | |||
98 | /* Read the message from PF */ | ||
99 | msg = ADF_CSR_RD(pmisc_bar_addr, ADF_DH895XCCIOV_PF2VF_OFFSET); | ||
100 | |||
101 | if (!(msg & ADF_PF2VF_MSGORIGIN_SYSTEM)) | ||
102 | /* Ignore legacy non-system (non-kernel) PF2VF messages */ | ||
103 | goto err; | ||
104 | |||
105 | switch ((msg & ADF_PF2VF_MSGTYPE_MASK) >> ADF_PF2VF_MSGTYPE_SHIFT) { | ||
106 | case ADF_PF2VF_MSGTYPE_RESTARTING: | ||
107 | dev_dbg(&GET_DEV(accel_dev), | ||
108 | "Restarting msg received from PF 0x%x\n", msg); | ||
109 | adf_dev_stop(accel_dev); | ||
110 | break; | ||
111 | case ADF_PF2VF_MSGTYPE_VERSION_RESP: | ||
112 | dev_dbg(&GET_DEV(accel_dev), | ||
113 | "Version resp received from PF 0x%x\n", msg); | ||
114 | accel_dev->vf.pf_version = | ||
115 | (msg & ADF_PF2VF_VERSION_RESP_VERS_MASK) >> | ||
116 | ADF_PF2VF_VERSION_RESP_VERS_SHIFT; | ||
117 | accel_dev->vf.compatible = | ||
118 | (msg & ADF_PF2VF_VERSION_RESP_RESULT_MASK) >> | ||
119 | ADF_PF2VF_VERSION_RESP_RESULT_SHIFT; | ||
120 | complete(&accel_dev->vf.iov_msg_completion); | ||
121 | break; | ||
122 | default: | ||
123 | goto err; | ||
124 | } | ||
125 | |||
126 | /* To ack, clear the PF2VFINT bit */ | ||
127 | msg &= ~ADF_DH895XCC_PF2VF_PF2VFINT; | ||
128 | ADF_CSR_WR(pmisc_bar_addr, ADF_DH895XCCIOV_PF2VF_OFFSET, msg); | ||
129 | |||
130 | /* Re-enable PF2VF interrupts */ | ||
131 | adf_enable_pf2vf_interrupts(accel_dev); | ||
132 | return; | ||
133 | err: | ||
134 | dev_err(&GET_DEV(accel_dev), | ||
135 | "Unknown message from PF (0x%x); leaving PF2VF ints disabled\n", | ||
136 | msg); | ||
137 | } | ||
138 | |||
139 | static int adf_setup_pf2vf_bh(struct adf_accel_dev *accel_dev) | ||
140 | { | ||
141 | tasklet_init(&accel_dev->vf.pf2vf_bh_tasklet, | ||
142 | (void *)adf_pf2vf_bh_handler, (unsigned long)accel_dev); | ||
143 | |||
144 | mutex_init(&accel_dev->vf.vf2pf_lock); | ||
145 | return 0; | ||
146 | } | ||
147 | |||
148 | static void adf_cleanup_pf2vf_bh(struct adf_accel_dev *accel_dev) | ||
149 | { | ||
150 | tasklet_disable(&accel_dev->vf.pf2vf_bh_tasklet); | ||
151 | tasklet_kill(&accel_dev->vf.pf2vf_bh_tasklet); | ||
152 | mutex_destroy(&accel_dev->vf.vf2pf_lock); | ||
153 | } | ||
154 | |||
155 | static irqreturn_t adf_isr(int irq, void *privdata) | ||
156 | { | ||
157 | struct adf_accel_dev *accel_dev = privdata; | ||
158 | void __iomem *pmisc_bar_addr = | ||
159 | (&GET_BARS(accel_dev)[ADF_DH895XCCIOV_PMISC_BAR])->virt_addr; | ||
160 | u32 v_int; | ||
161 | |||
162 | /* Read VF INT source CSR to determine the source of VF interrupt */ | ||
163 | v_int = ADF_CSR_RD(pmisc_bar_addr, ADF_DH895XCCIOV_VINTSOU_OFFSET); | ||
164 | |||
165 | /* Check for PF2VF interrupt */ | ||
166 | if (v_int & ADF_DH895XCC_VINTSOU_PF2VF) { | ||
167 | /* Disable PF to VF interrupt */ | ||
168 | adf_disable_pf2vf_interrupts(accel_dev); | ||
169 | |||
170 | /* Schedule tasklet to handle interrupt BH */ | ||
171 | tasklet_hi_schedule(&accel_dev->vf.pf2vf_bh_tasklet); | ||
172 | return IRQ_HANDLED; | ||
173 | } | ||
174 | |||
175 | /* Check bundle interrupt */ | ||
176 | if (v_int & ADF_DH895XCC_VINTSOU_BUN) { | ||
177 | struct adf_etr_data *etr_data = accel_dev->transport; | ||
178 | struct adf_etr_bank_data *bank = &etr_data->banks[0]; | ||
179 | |||
180 | /* Disable Flag and Coalesce Ring Interrupts */ | ||
181 | WRITE_CSR_INT_FLAG_AND_COL(bank->csr_addr, bank->bank_number, | ||
182 | 0); | ||
183 | tasklet_hi_schedule(&bank->resp_handler); | ||
184 | return IRQ_HANDLED; | ||
185 | } | ||
186 | |||
187 | return IRQ_NONE; | ||
188 | } | ||
189 | |||
190 | static int adf_request_msi_irq(struct adf_accel_dev *accel_dev) | ||
191 | { | ||
192 | struct pci_dev *pdev = accel_to_pci_dev(accel_dev); | ||
193 | unsigned int cpu; | ||
194 | int ret; | ||
195 | |||
196 | snprintf(accel_dev->vf.irq_name, ADF_MAX_MSIX_VECTOR_NAME, | ||
197 | "qat_%02x:%02d.%02d", pdev->bus->number, PCI_SLOT(pdev->devfn), | ||
198 | PCI_FUNC(pdev->devfn)); | ||
199 | ret = request_irq(pdev->irq, adf_isr, 0, accel_dev->vf.irq_name, | ||
200 | (void *)accel_dev); | ||
201 | if (ret) { | ||
202 | dev_err(&GET_DEV(accel_dev), "failed to enable irq for %s\n", | ||
203 | accel_dev->vf.irq_name); | ||
204 | return ret; | ||
205 | } | ||
206 | cpu = accel_dev->accel_id % num_online_cpus(); | ||
207 | irq_set_affinity_hint(pdev->irq, get_cpu_mask(cpu)); | ||
208 | |||
209 | return ret; | ||
210 | } | ||
211 | |||
212 | static int adf_setup_bh(struct adf_accel_dev *accel_dev) | ||
213 | { | ||
214 | struct adf_etr_data *priv_data = accel_dev->transport; | ||
215 | |||
216 | tasklet_init(&priv_data->banks[0].resp_handler, adf_response_handler, | ||
217 | (unsigned long)priv_data->banks); | ||
218 | return 0; | ||
219 | } | ||
220 | |||
221 | static void adf_cleanup_bh(struct adf_accel_dev *accel_dev) | ||
222 | { | ||
223 | struct adf_etr_data *priv_data = accel_dev->transport; | ||
224 | |||
225 | tasklet_disable(&priv_data->banks[0].resp_handler); | ||
226 | tasklet_kill(&priv_data->banks[0].resp_handler); | ||
227 | } | ||
228 | |||
229 | void adf_isr_resource_free(struct adf_accel_dev *accel_dev) | ||
230 | { | ||
231 | struct pci_dev *pdev = accel_to_pci_dev(accel_dev); | ||
232 | |||
233 | irq_set_affinity_hint(pdev->irq, NULL); | ||
234 | free_irq(pdev->irq, (void *)accel_dev); | ||
235 | adf_cleanup_bh(accel_dev); | ||
236 | adf_cleanup_pf2vf_bh(accel_dev); | ||
237 | adf_disable_msi(accel_dev); | ||
238 | } | ||
239 | |||
240 | int adf_isr_resource_alloc(struct adf_accel_dev *accel_dev) | ||
241 | { | ||
242 | if (adf_enable_msi(accel_dev)) | ||
243 | goto err_out; | ||
244 | |||
245 | if (adf_setup_pf2vf_bh(accel_dev)) | ||
246 | goto err_out; | ||
247 | |||
248 | if (adf_setup_bh(accel_dev)) | ||
249 | goto err_out; | ||
250 | |||
251 | if (adf_request_msi_irq(accel_dev)) | ||
252 | goto err_out; | ||
253 | |||
254 | return 0; | ||
255 | err_out: | ||
256 | adf_isr_resource_free(accel_dev); | ||
257 | return -EFAULT; | ||
258 | } | ||