Skip to content

Commit 7afa232

Browse files
tstrukherbertx
authored andcommitted
crypto: qat - Intel(R) QAT DH895xcc accelerator
This patch adds DH895xCC hardware specific code. It hooks to the common infrastructure and provides acceleration for crypto algorithms. Acked-by: John Griffin <john.griffin@intel.com> Reviewed-by: Bruce W. Allan <bruce.w.allan@intel.com> Signed-off-by: Tadeusz Struk <tadeusz.struk@intel.com> Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
1 parent b3416fb commit 7afa232

File tree

9 files changed

+1499
-0
lines changed

9 files changed

+1499
-0
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
ccflags-y := -I$(CURDIR)/drivers/crypto/qat/qat_common
2+
obj-$(CONFIG_CRYPTO_DEV_QAT_DH895xCC) += qat_dh895xcc.o
3+
qat_dh895xcc-objs := adf_drv.o \
4+
adf_isr.o \
5+
adf_dh895xcc_hw_data.o \
6+
adf_hw_arbiter.o \
7+
qat_admin.o \
8+
adf_admin.o
Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
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/types.h>
48+
#include <linux/mutex.h>
49+
#include <linux/slab.h>
50+
#include <linux/delay.h>
51+
#include <linux/pci.h>
52+
#include <linux/dma-mapping.h>
53+
#include <adf_accel_devices.h>
54+
#include "adf_drv.h"
55+
#include "adf_dh895xcc_hw_data.h"
56+
57+
#define ADF_ADMINMSG_LEN 32
58+
59+
struct adf_admin_comms {
60+
dma_addr_t phy_addr;
61+
void *virt_addr;
62+
void __iomem *mailbox_addr;
63+
struct mutex lock; /* protects adf_admin_comms struct */
64+
};
65+
66+
int adf_put_admin_msg_sync(struct adf_accel_dev *accel_dev,
67+
uint32_t ae, void *in, void *out)
68+
{
69+
struct adf_admin_comms *admin = accel_dev->admin;
70+
int offset = ae * ADF_ADMINMSG_LEN * 2;
71+
void __iomem *mailbox = admin->mailbox_addr;
72+
int mb_offset = ae * ADF_DH895XCC_MAILBOX_STRIDE;
73+
int times, received;
74+
75+
mutex_lock(&admin->lock);
76+
77+
if (ADF_CSR_RD(mailbox, mb_offset) == 1) {
78+
mutex_unlock(&admin->lock);
79+
return -EAGAIN;
80+
}
81+
82+
memcpy(admin->virt_addr + offset, in, ADF_ADMINMSG_LEN);
83+
ADF_CSR_WR(mailbox, mb_offset, 1);
84+
received = 0;
85+
for (times = 0; times < 50; times++) {
86+
msleep(20);
87+
if (ADF_CSR_RD(mailbox, mb_offset) == 0) {
88+
received = 1;
89+
break;
90+
}
91+
}
92+
if (received)
93+
memcpy(out, admin->virt_addr + offset +
94+
ADF_ADMINMSG_LEN, ADF_ADMINMSG_LEN);
95+
else
96+
pr_err("QAT: Failed to send admin msg to accelerator\n");
97+
98+
mutex_unlock(&admin->lock);
99+
return received ? 0 : -EFAULT;
100+
}
101+
102+
int adf_init_admin_comms(struct adf_accel_dev *accel_dev)
103+
{
104+
struct adf_admin_comms *admin;
105+
struct adf_bar *pmisc = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR];
106+
void __iomem *csr = pmisc->virt_addr;
107+
void __iomem *mailbox = csr + ADF_DH895XCC_MAILBOX_BASE_OFFSET;
108+
uint64_t reg_val;
109+
110+
admin = kzalloc_node(sizeof(*accel_dev->admin), GFP_KERNEL,
111+
accel_dev->numa_node);
112+
if (!admin)
113+
return -ENOMEM;
114+
admin->virt_addr = dma_zalloc_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
115+
&admin->phy_addr, GFP_KERNEL);
116+
if (!admin->virt_addr) {
117+
dev_err(&GET_DEV(accel_dev), "Failed to allocate dma buff\n");
118+
kfree(admin);
119+
return -ENOMEM;
120+
}
121+
reg_val = (uint64_t)admin->phy_addr;
122+
ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGUR_OFFSET, reg_val >> 32);
123+
ADF_CSR_WR(csr, ADF_DH895XCC_ADMINMSGLR_OFFSET, reg_val);
124+
mutex_init(&admin->lock);
125+
admin->mailbox_addr = mailbox;
126+
accel_dev->admin = admin;
127+
return 0;
128+
}
129+
130+
void adf_exit_admin_comms(struct adf_accel_dev *accel_dev)
131+
{
132+
struct adf_admin_comms *admin = accel_dev->admin;
133+
134+
if (!admin)
135+
return;
136+
137+
if (admin->virt_addr)
138+
dma_free_coherent(&GET_DEV(accel_dev), PAGE_SIZE,
139+
admin->virt_addr, admin->phy_addr);
140+
141+
mutex_destroy(&admin->lock);
142+
kfree(admin);
143+
accel_dev->admin = NULL;
144+
}
Lines changed: 214 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,214 @@
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 <adf_accel_devices.h>
48+
#include "adf_dh895xcc_hw_data.h"
49+
#include "adf_drv.h"
50+
51+
/* Worker thread to service arbiter mappings based on dev SKUs */
52+
static const uint32_t thrd_to_arb_map_sku4[] = {
53+
0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666,
54+
0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222,
55+
0x00000000, 0x00000000, 0x00000000, 0x00000000
56+
};
57+
58+
static const uint32_t thrd_to_arb_map_sku6[] = {
59+
0x12222AAA, 0x11666666, 0x12222AAA, 0x11666666,
60+
0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222,
61+
0x12222AAA, 0x11222222, 0x12222AAA, 0x11222222
62+
};
63+
64+
static struct adf_hw_device_class dh895xcc_class = {
65+
.name = ADF_DH895XCC_DEVICE_NAME,
66+
.type = DEV_DH895XCC,
67+
.instances = 0
68+
};
69+
70+
static uint32_t get_accel_mask(uint32_t fuse)
71+
{
72+
return (~fuse) >> ADF_DH895XCC_ACCELERATORS_REG_OFFSET &
73+
ADF_DH895XCC_ACCELERATORS_MASK;
74+
}
75+
76+
static uint32_t get_ae_mask(uint32_t fuse)
77+
{
78+
return (~fuse) & ADF_DH895XCC_ACCELENGINES_MASK;
79+
}
80+
81+
static uint32_t get_num_accels(struct adf_hw_device_data *self)
82+
{
83+
uint32_t i, ctr = 0;
84+
85+
if (!self || !self->accel_mask)
86+
return 0;
87+
88+
for (i = 0; i < ADF_DH895XCC_MAX_ACCELERATORS; i++) {
89+
if (self->accel_mask & (1 << i))
90+
ctr++;
91+
}
92+
return ctr;
93+
}
94+
95+
static uint32_t get_num_aes(struct adf_hw_device_data *self)
96+
{
97+
uint32_t i, ctr = 0;
98+
99+
if (!self || !self->ae_mask)
100+
return 0;
101+
102+
for (i = 0; i < ADF_DH895XCC_MAX_ACCELENGINES; i++) {
103+
if (self->ae_mask & (1 << i))
104+
ctr++;
105+
}
106+
return ctr;
107+
}
108+
109+
static uint32_t get_misc_bar_id(struct adf_hw_device_data *self)
110+
{
111+
return ADF_DH895XCC_PMISC_BAR;
112+
}
113+
114+
static uint32_t get_etr_bar_id(struct adf_hw_device_data *self)
115+
{
116+
return ADF_DH895XCC_ETR_BAR;
117+
}
118+
119+
static enum dev_sku_info get_sku(struct adf_hw_device_data *self)
120+
{
121+
int sku = (self->fuses & ADF_DH895XCC_FUSECTL_SKU_MASK)
122+
>> ADF_DH895XCC_FUSECTL_SKU_SHIFT;
123+
124+
switch (sku) {
125+
case ADF_DH895XCC_FUSECTL_SKU_1:
126+
return DEV_SKU_1;
127+
case ADF_DH895XCC_FUSECTL_SKU_2:
128+
return DEV_SKU_2;
129+
case ADF_DH895XCC_FUSECTL_SKU_3:
130+
return DEV_SKU_3;
131+
case ADF_DH895XCC_FUSECTL_SKU_4:
132+
return DEV_SKU_4;
133+
default:
134+
return DEV_SKU_UNKNOWN;
135+
}
136+
return DEV_SKU_UNKNOWN;
137+
}
138+
139+
void adf_get_arbiter_mapping(struct adf_accel_dev *accel_dev,
140+
uint32_t const **arb_map_config)
141+
{
142+
switch (accel_dev->accel_pci_dev.sku) {
143+
case DEV_SKU_1:
144+
*arb_map_config = thrd_to_arb_map_sku4;
145+
break;
146+
147+
case DEV_SKU_2:
148+
case DEV_SKU_4:
149+
*arb_map_config = thrd_to_arb_map_sku6;
150+
break;
151+
default:
152+
pr_err("QAT: The configuration doesn't match any SKU");
153+
*arb_map_config = NULL;
154+
}
155+
}
156+
157+
static void adf_enable_error_correction(struct adf_accel_dev *accel_dev)
158+
{
159+
struct adf_hw_device_data *hw_device = accel_dev->hw_device;
160+
struct adf_bar *misc_bar = &GET_BARS(accel_dev)[ADF_DH895XCC_PMISC_BAR];
161+
void __iomem *csr = misc_bar->virt_addr;
162+
unsigned int val, i;
163+
164+
/* Enable Accel Engine error detection & correction */
165+
for (i = 0; i < hw_device->get_num_aes(hw_device); i++) {
166+
val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_CTX_ENABLES(i));
167+
val |= ADF_DH895XCC_ENABLE_AE_ECC_ERR;
168+
ADF_CSR_WR(csr, ADF_DH895XCC_AE_CTX_ENABLES(i), val);
169+
val = ADF_CSR_RD(csr, ADF_DH895XCC_AE_MISC_CONTROL(i));
170+
val |= ADF_DH895XCC_ENABLE_AE_ECC_PARITY_CORR;
171+
ADF_CSR_WR(csr, ADF_DH895XCC_AE_MISC_CONTROL(i), val);
172+
}
173+
174+
/* Enable shared memory error detection & correction */
175+
for (i = 0; i < hw_device->get_num_accels(hw_device); i++) {
176+
val = ADF_CSR_RD(csr, ADF_DH895XCC_UERRSSMSH(i));
177+
val |= ADF_DH895XCC_ERRSSMSH_EN;
178+
ADF_CSR_WR(csr, ADF_DH895XCC_UERRSSMSH(i), val);
179+
val = ADF_CSR_RD(csr, ADF_DH895XCC_CERRSSMSH(i));
180+
val |= ADF_DH895XCC_ERRSSMSH_EN;
181+
ADF_CSR_WR(csr, ADF_DH895XCC_CERRSSMSH(i), val);
182+
}
183+
}
184+
185+
void adf_init_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
186+
{
187+
hw_data->dev_class = &dh895xcc_class;
188+
hw_data->instance_id = dh895xcc_class.instances++;
189+
hw_data->num_banks = ADF_DH895XCC_ETR_MAX_BANKS;
190+
hw_data->num_accel = ADF_DH895XCC_MAX_ACCELERATORS;
191+
hw_data->pci_dev_id = ADF_DH895XCC_PCI_DEVICE_ID;
192+
hw_data->num_logical_accel = 1;
193+
hw_data->num_engines = ADF_DH895XCC_MAX_ACCELENGINES;
194+
hw_data->tx_rx_gap = ADF_DH895XCC_RX_RINGS_OFFSET;
195+
hw_data->tx_rings_mask = ADF_DH895XCC_TX_RINGS_MASK;
196+
hw_data->alloc_irq = adf_isr_resource_alloc;
197+
hw_data->free_irq = adf_isr_resource_free;
198+
hw_data->enable_error_correction = adf_enable_error_correction;
199+
hw_data->hw_arb_ring_enable = adf_update_ring_arb_enable;
200+
hw_data->hw_arb_ring_disable = adf_update_ring_arb_enable;
201+
hw_data->get_accel_mask = get_accel_mask;
202+
hw_data->get_ae_mask = get_ae_mask;
203+
hw_data->get_num_accels = get_num_accels;
204+
hw_data->get_num_aes = get_num_aes;
205+
hw_data->get_etr_bar_id = get_etr_bar_id;
206+
hw_data->get_misc_bar_id = get_misc_bar_id;
207+
hw_data->get_sku = get_sku;
208+
hw_data->fw_name = ADF_DH895XCC_FW;
209+
}
210+
211+
void adf_clean_hw_data_dh895xcc(struct adf_hw_device_data *hw_data)
212+
{
213+
hw_data->dev_class->instances--;
214+
}

0 commit comments

Comments
 (0)