1*b61a5730SWarner Losh /* SPDX-License-Identifier: BSD-2-Clause AND BSD-3-Clause */
2f4f56ff4SMark Johnston /* $NetBSD: qat.c,v 1.6 2020/06/14 23:23:12 riastradh Exp $ */
3f4f56ff4SMark Johnston
4f4f56ff4SMark Johnston /*
5f4f56ff4SMark Johnston * Copyright (c) 2019 Internet Initiative Japan, Inc.
6f4f56ff4SMark Johnston * All rights reserved.
7f4f56ff4SMark Johnston *
8f4f56ff4SMark Johnston * Redistribution and use in source and binary forms, with or without
9f4f56ff4SMark Johnston * modification, are permitted provided that the following conditions
10f4f56ff4SMark Johnston * are met:
11f4f56ff4SMark Johnston * 1. Redistributions of source code must retain the above copyright
12f4f56ff4SMark Johnston * notice, this list of conditions and the following disclaimer.
13f4f56ff4SMark Johnston * 2. Redistributions in binary form must reproduce the above copyright
14f4f56ff4SMark Johnston * notice, this list of conditions and the following disclaimer in the
15f4f56ff4SMark Johnston * documentation and/or other materials provided with the distribution.
16f4f56ff4SMark Johnston *
17f4f56ff4SMark Johnston * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18f4f56ff4SMark Johnston * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19f4f56ff4SMark Johnston * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20f4f56ff4SMark Johnston * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21f4f56ff4SMark Johnston * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22f4f56ff4SMark Johnston * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23f4f56ff4SMark Johnston * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24f4f56ff4SMark Johnston * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25f4f56ff4SMark Johnston * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26f4f56ff4SMark Johnston * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27f4f56ff4SMark Johnston * POSSIBILITY OF SUCH DAMAGE.
28f4f56ff4SMark Johnston */
29f4f56ff4SMark Johnston
30f4f56ff4SMark Johnston /*
31f4f56ff4SMark Johnston * Copyright(c) 2007-2019 Intel Corporation. All rights reserved.
32f4f56ff4SMark Johnston *
33f4f56ff4SMark Johnston * Redistribution and use in source and binary forms, with or without
34f4f56ff4SMark Johnston * modification, are permitted provided that the following conditions
35f4f56ff4SMark Johnston * are met:
36f4f56ff4SMark Johnston *
37f4f56ff4SMark Johnston * * Redistributions of source code must retain the above copyright
38f4f56ff4SMark Johnston * notice, this list of conditions and the following disclaimer.
39f4f56ff4SMark Johnston * * Redistributions in binary form must reproduce the above copyright
40f4f56ff4SMark Johnston * notice, this list of conditions and the following disclaimer in
41f4f56ff4SMark Johnston * the documentation and/or other materials provided with the
42f4f56ff4SMark Johnston * distribution.
43f4f56ff4SMark Johnston * * Neither the name of Intel Corporation nor the names of its
44f4f56ff4SMark Johnston * contributors may be used to endorse or promote products derived
45f4f56ff4SMark Johnston * from this software without specific prior written permission.
46f4f56ff4SMark Johnston *
47f4f56ff4SMark Johnston * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
48f4f56ff4SMark Johnston * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
49f4f56ff4SMark Johnston * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
50f4f56ff4SMark Johnston * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
51f4f56ff4SMark Johnston * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
52f4f56ff4SMark Johnston * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
53f4f56ff4SMark Johnston * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
54f4f56ff4SMark Johnston * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
55f4f56ff4SMark Johnston * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
56f4f56ff4SMark Johnston * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
57f4f56ff4SMark Johnston * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
58f4f56ff4SMark Johnston */
59f4f56ff4SMark Johnston
60f4f56ff4SMark Johnston #include <sys/cdefs.h>
61f4f56ff4SMark Johnston #if 0
62f4f56ff4SMark Johnston __KERNEL_RCSID(0, "$NetBSD: qat.c,v 1.6 2020/06/14 23:23:12 riastradh Exp $");
63f4f56ff4SMark Johnston #endif
64f4f56ff4SMark Johnston
65f4f56ff4SMark Johnston #include <sys/param.h>
66f4f56ff4SMark Johnston #include <sys/systm.h>
67f4f56ff4SMark Johnston #include <sys/bus.h>
68f4f56ff4SMark Johnston #include <sys/cpu.h>
69f4f56ff4SMark Johnston #include <sys/firmware.h>
70f4f56ff4SMark Johnston #include <sys/kernel.h>
71f4f56ff4SMark Johnston #include <sys/mbuf.h>
72f4f56ff4SMark Johnston #include <sys/md5.h>
73f4f56ff4SMark Johnston #include <sys/module.h>
74f4f56ff4SMark Johnston #include <sys/mutex.h>
75f4f56ff4SMark Johnston #include <sys/smp.h>
76f4f56ff4SMark Johnston #include <sys/sysctl.h>
77f4f56ff4SMark Johnston #include <sys/rman.h>
78f4f56ff4SMark Johnston
79f4f56ff4SMark Johnston #include <machine/bus.h>
80f4f56ff4SMark Johnston
81f4f56ff4SMark Johnston #include <opencrypto/cryptodev.h>
82f4f56ff4SMark Johnston #include <opencrypto/xform.h>
83f4f56ff4SMark Johnston
84f4f56ff4SMark Johnston #include "cryptodev_if.h"
85f4f56ff4SMark Johnston
86f4f56ff4SMark Johnston #include <dev/pci/pcireg.h>
87f4f56ff4SMark Johnston #include <dev/pci/pcivar.h>
88f4f56ff4SMark Johnston
89f4f56ff4SMark Johnston #include "qatreg.h"
90f4f56ff4SMark Johnston #include "qatvar.h"
91f4f56ff4SMark Johnston #include "qat_aevar.h"
92f4f56ff4SMark Johnston
93f4f56ff4SMark Johnston extern struct qat_hw qat_hw_c2xxx;
94f4f56ff4SMark Johnston
95f4f56ff4SMark Johnston #define PCI_VENDOR_INTEL 0x8086
96f4f56ff4SMark Johnston #define PCI_PRODUCT_INTEL_C2000_IQIA_PHYS 0x1f18
97f4f56ff4SMark Johnston
98f4f56ff4SMark Johnston static const struct qat_product {
99f4f56ff4SMark Johnston uint16_t qatp_vendor;
100f4f56ff4SMark Johnston uint16_t qatp_product;
101f4f56ff4SMark Johnston const char *qatp_name;
102f4f56ff4SMark Johnston enum qat_chip_type qatp_chip;
103f4f56ff4SMark Johnston const struct qat_hw *qatp_hw;
104f4f56ff4SMark Johnston } qat_products[] = {
105f4f56ff4SMark Johnston { PCI_VENDOR_INTEL, PCI_PRODUCT_INTEL_C2000_IQIA_PHYS,
106f4f56ff4SMark Johnston "Intel C2000 QuickAssist PF",
107f4f56ff4SMark Johnston QAT_CHIP_C2XXX, &qat_hw_c2xxx },
108f4f56ff4SMark Johnston { 0, 0, NULL, 0, NULL },
109f4f56ff4SMark Johnston };
110f4f56ff4SMark Johnston
111f4f56ff4SMark Johnston /* Hash Algorithm specific structure */
112f4f56ff4SMark Johnston
113f4f56ff4SMark Johnston /* SHA1 - 20 bytes - Initialiser state can be found in FIPS stds 180-2 */
114f4f56ff4SMark Johnston static const uint8_t sha1_initial_state[QAT_HASH_SHA1_STATE_SIZE] = {
115f4f56ff4SMark Johnston 0x67, 0x45, 0x23, 0x01,
116f4f56ff4SMark Johnston 0xef, 0xcd, 0xab, 0x89,
117f4f56ff4SMark Johnston 0x98, 0xba, 0xdc, 0xfe,
118f4f56ff4SMark Johnston 0x10, 0x32, 0x54, 0x76,
119f4f56ff4SMark Johnston 0xc3, 0xd2, 0xe1, 0xf0
120f4f56ff4SMark Johnston };
121f4f56ff4SMark Johnston
122f4f56ff4SMark Johnston /* SHA 256 - 32 bytes - Initialiser state can be found in FIPS stds 180-2 */
123f4f56ff4SMark Johnston static const uint8_t sha256_initial_state[QAT_HASH_SHA256_STATE_SIZE] = {
124f4f56ff4SMark Johnston 0x6a, 0x09, 0xe6, 0x67,
125f4f56ff4SMark Johnston 0xbb, 0x67, 0xae, 0x85,
126f4f56ff4SMark Johnston 0x3c, 0x6e, 0xf3, 0x72,
127f4f56ff4SMark Johnston 0xa5, 0x4f, 0xf5, 0x3a,
128f4f56ff4SMark Johnston 0x51, 0x0e, 0x52, 0x7f,
129f4f56ff4SMark Johnston 0x9b, 0x05, 0x68, 0x8c,
130f4f56ff4SMark Johnston 0x1f, 0x83, 0xd9, 0xab,
131f4f56ff4SMark Johnston 0x5b, 0xe0, 0xcd, 0x19
132f4f56ff4SMark Johnston };
133f4f56ff4SMark Johnston
134f4f56ff4SMark Johnston /* SHA 384 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */
135f4f56ff4SMark Johnston static const uint8_t sha384_initial_state[QAT_HASH_SHA384_STATE_SIZE] = {
136f4f56ff4SMark Johnston 0xcb, 0xbb, 0x9d, 0x5d, 0xc1, 0x05, 0x9e, 0xd8,
137f4f56ff4SMark Johnston 0x62, 0x9a, 0x29, 0x2a, 0x36, 0x7c, 0xd5, 0x07,
138f4f56ff4SMark Johnston 0x91, 0x59, 0x01, 0x5a, 0x30, 0x70, 0xdd, 0x17,
139f4f56ff4SMark Johnston 0x15, 0x2f, 0xec, 0xd8, 0xf7, 0x0e, 0x59, 0x39,
140f4f56ff4SMark Johnston 0x67, 0x33, 0x26, 0x67, 0xff, 0xc0, 0x0b, 0x31,
141f4f56ff4SMark Johnston 0x8e, 0xb4, 0x4a, 0x87, 0x68, 0x58, 0x15, 0x11,
142f4f56ff4SMark Johnston 0xdb, 0x0c, 0x2e, 0x0d, 0x64, 0xf9, 0x8f, 0xa7,
143f4f56ff4SMark Johnston 0x47, 0xb5, 0x48, 0x1d, 0xbe, 0xfa, 0x4f, 0xa4
144f4f56ff4SMark Johnston };
145f4f56ff4SMark Johnston
146f4f56ff4SMark Johnston /* SHA 512 - 64 bytes - Initialiser state can be found in FIPS stds 180-2 */
147f4f56ff4SMark Johnston static const uint8_t sha512_initial_state[QAT_HASH_SHA512_STATE_SIZE] = {
148f4f56ff4SMark Johnston 0x6a, 0x09, 0xe6, 0x67, 0xf3, 0xbc, 0xc9, 0x08,
149f4f56ff4SMark Johnston 0xbb, 0x67, 0xae, 0x85, 0x84, 0xca, 0xa7, 0x3b,
150f4f56ff4SMark Johnston 0x3c, 0x6e, 0xf3, 0x72, 0xfe, 0x94, 0xf8, 0x2b,
151f4f56ff4SMark Johnston 0xa5, 0x4f, 0xf5, 0x3a, 0x5f, 0x1d, 0x36, 0xf1,
152f4f56ff4SMark Johnston 0x51, 0x0e, 0x52, 0x7f, 0xad, 0xe6, 0x82, 0xd1,
153f4f56ff4SMark Johnston 0x9b, 0x05, 0x68, 0x8c, 0x2b, 0x3e, 0x6c, 0x1f,
154f4f56ff4SMark Johnston 0x1f, 0x83, 0xd9, 0xab, 0xfb, 0x41, 0xbd, 0x6b,
155f4f56ff4SMark Johnston 0x5b, 0xe0, 0xcd, 0x19, 0x13, 0x7e, 0x21, 0x79
156f4f56ff4SMark Johnston };
157f4f56ff4SMark Johnston
158f4f56ff4SMark Johnston static const struct qat_sym_hash_alg_info sha1_info = {
159f4f56ff4SMark Johnston .qshai_digest_len = QAT_HASH_SHA1_DIGEST_SIZE,
160f4f56ff4SMark Johnston .qshai_block_len = QAT_HASH_SHA1_BLOCK_SIZE,
161f4f56ff4SMark Johnston .qshai_state_size = QAT_HASH_SHA1_STATE_SIZE,
162f4f56ff4SMark Johnston .qshai_init_state = sha1_initial_state,
163f4f56ff4SMark Johnston .qshai_sah = &auth_hash_hmac_sha1,
164f4f56ff4SMark Johnston .qshai_state_offset = 0,
165f4f56ff4SMark Johnston .qshai_state_word = 4,
166f4f56ff4SMark Johnston };
167f4f56ff4SMark Johnston
168f4f56ff4SMark Johnston static const struct qat_sym_hash_alg_info sha256_info = {
169f4f56ff4SMark Johnston .qshai_digest_len = QAT_HASH_SHA256_DIGEST_SIZE,
170f4f56ff4SMark Johnston .qshai_block_len = QAT_HASH_SHA256_BLOCK_SIZE,
171f4f56ff4SMark Johnston .qshai_state_size = QAT_HASH_SHA256_STATE_SIZE,
172f4f56ff4SMark Johnston .qshai_init_state = sha256_initial_state,
173f4f56ff4SMark Johnston .qshai_sah = &auth_hash_hmac_sha2_256,
174f4f56ff4SMark Johnston .qshai_state_offset = offsetof(SHA256_CTX, state),
175f4f56ff4SMark Johnston .qshai_state_word = 4,
176f4f56ff4SMark Johnston };
177f4f56ff4SMark Johnston
178f4f56ff4SMark Johnston static const struct qat_sym_hash_alg_info sha384_info = {
179f4f56ff4SMark Johnston .qshai_digest_len = QAT_HASH_SHA384_DIGEST_SIZE,
180f4f56ff4SMark Johnston .qshai_block_len = QAT_HASH_SHA384_BLOCK_SIZE,
181f4f56ff4SMark Johnston .qshai_state_size = QAT_HASH_SHA384_STATE_SIZE,
182f4f56ff4SMark Johnston .qshai_init_state = sha384_initial_state,
183f4f56ff4SMark Johnston .qshai_sah = &auth_hash_hmac_sha2_384,
184f4f56ff4SMark Johnston .qshai_state_offset = offsetof(SHA384_CTX, state),
185f4f56ff4SMark Johnston .qshai_state_word = 8,
186f4f56ff4SMark Johnston };
187f4f56ff4SMark Johnston
188f4f56ff4SMark Johnston static const struct qat_sym_hash_alg_info sha512_info = {
189f4f56ff4SMark Johnston .qshai_digest_len = QAT_HASH_SHA512_DIGEST_SIZE,
190f4f56ff4SMark Johnston .qshai_block_len = QAT_HASH_SHA512_BLOCK_SIZE,
191f4f56ff4SMark Johnston .qshai_state_size = QAT_HASH_SHA512_STATE_SIZE,
192f4f56ff4SMark Johnston .qshai_init_state = sha512_initial_state,
193f4f56ff4SMark Johnston .qshai_sah = &auth_hash_hmac_sha2_512,
194f4f56ff4SMark Johnston .qshai_state_offset = offsetof(SHA512_CTX, state),
195f4f56ff4SMark Johnston .qshai_state_word = 8,
196f4f56ff4SMark Johnston };
197f4f56ff4SMark Johnston
198f4f56ff4SMark Johnston static const struct qat_sym_hash_alg_info aes_gcm_info = {
199f4f56ff4SMark Johnston .qshai_digest_len = QAT_HASH_AES_GCM_DIGEST_SIZE,
200f4f56ff4SMark Johnston .qshai_block_len = QAT_HASH_AES_GCM_BLOCK_SIZE,
201f4f56ff4SMark Johnston .qshai_state_size = QAT_HASH_AES_GCM_STATE_SIZE,
202f4f56ff4SMark Johnston .qshai_sah = &auth_hash_nist_gmac_aes_128,
203f4f56ff4SMark Johnston };
204f4f56ff4SMark Johnston
205f4f56ff4SMark Johnston /* Hash QAT specific structures */
206f4f56ff4SMark Johnston
207f4f56ff4SMark Johnston static const struct qat_sym_hash_qat_info sha1_config = {
208f4f56ff4SMark Johnston .qshqi_algo_enc = HW_AUTH_ALGO_SHA1,
209f4f56ff4SMark Johnston .qshqi_auth_counter = QAT_HASH_SHA1_BLOCK_SIZE,
210f4f56ff4SMark Johnston .qshqi_state1_len = HW_SHA1_STATE1_SZ,
211f4f56ff4SMark Johnston .qshqi_state2_len = HW_SHA1_STATE2_SZ,
212f4f56ff4SMark Johnston };
213f4f56ff4SMark Johnston
214f4f56ff4SMark Johnston static const struct qat_sym_hash_qat_info sha256_config = {
215f4f56ff4SMark Johnston .qshqi_algo_enc = HW_AUTH_ALGO_SHA256,
216f4f56ff4SMark Johnston .qshqi_auth_counter = QAT_HASH_SHA256_BLOCK_SIZE,
217f4f56ff4SMark Johnston .qshqi_state1_len = HW_SHA256_STATE1_SZ,
218f4f56ff4SMark Johnston .qshqi_state2_len = HW_SHA256_STATE2_SZ
219f4f56ff4SMark Johnston };
220f4f56ff4SMark Johnston
221f4f56ff4SMark Johnston static const struct qat_sym_hash_qat_info sha384_config = {
222f4f56ff4SMark Johnston .qshqi_algo_enc = HW_AUTH_ALGO_SHA384,
223f4f56ff4SMark Johnston .qshqi_auth_counter = QAT_HASH_SHA384_BLOCK_SIZE,
224f4f56ff4SMark Johnston .qshqi_state1_len = HW_SHA384_STATE1_SZ,
225f4f56ff4SMark Johnston .qshqi_state2_len = HW_SHA384_STATE2_SZ
226f4f56ff4SMark Johnston };
227f4f56ff4SMark Johnston
228f4f56ff4SMark Johnston static const struct qat_sym_hash_qat_info sha512_config = {
229f4f56ff4SMark Johnston .qshqi_algo_enc = HW_AUTH_ALGO_SHA512,
230f4f56ff4SMark Johnston .qshqi_auth_counter = QAT_HASH_SHA512_BLOCK_SIZE,
231f4f56ff4SMark Johnston .qshqi_state1_len = HW_SHA512_STATE1_SZ,
232f4f56ff4SMark Johnston .qshqi_state2_len = HW_SHA512_STATE2_SZ
233f4f56ff4SMark Johnston };
234f4f56ff4SMark Johnston
235f4f56ff4SMark Johnston static const struct qat_sym_hash_qat_info aes_gcm_config = {
236f4f56ff4SMark Johnston .qshqi_algo_enc = HW_AUTH_ALGO_GALOIS_128,
237f4f56ff4SMark Johnston .qshqi_auth_counter = QAT_HASH_AES_GCM_BLOCK_SIZE,
238f4f56ff4SMark Johnston .qshqi_state1_len = HW_GALOIS_128_STATE1_SZ,
239f4f56ff4SMark Johnston .qshqi_state2_len =
240f4f56ff4SMark Johnston HW_GALOIS_H_SZ + HW_GALOIS_LEN_A_SZ + HW_GALOIS_E_CTR0_SZ,
241f4f56ff4SMark Johnston };
242f4f56ff4SMark Johnston
243f4f56ff4SMark Johnston static const struct qat_sym_hash_def qat_sym_hash_defs[] = {
244f4f56ff4SMark Johnston [QAT_SYM_HASH_SHA1] = { &sha1_info, &sha1_config },
245f4f56ff4SMark Johnston [QAT_SYM_HASH_SHA256] = { &sha256_info, &sha256_config },
246f4f56ff4SMark Johnston [QAT_SYM_HASH_SHA384] = { &sha384_info, &sha384_config },
247f4f56ff4SMark Johnston [QAT_SYM_HASH_SHA512] = { &sha512_info, &sha512_config },
248f4f56ff4SMark Johnston [QAT_SYM_HASH_AES_GCM] = { &aes_gcm_info, &aes_gcm_config },
249f4f56ff4SMark Johnston };
250f4f56ff4SMark Johnston
251f4f56ff4SMark Johnston static const struct qat_product *qat_lookup(device_t);
252f4f56ff4SMark Johnston static int qat_probe(device_t);
253f4f56ff4SMark Johnston static int qat_attach(device_t);
254f4f56ff4SMark Johnston static int qat_init(device_t);
255f4f56ff4SMark Johnston static int qat_start(device_t);
256f4f56ff4SMark Johnston static int qat_detach(device_t);
257f4f56ff4SMark Johnston
258f4f56ff4SMark Johnston static int qat_newsession(device_t dev, crypto_session_t cses,
259f4f56ff4SMark Johnston const struct crypto_session_params *csp);
260f4f56ff4SMark Johnston static void qat_freesession(device_t dev, crypto_session_t cses);
261f4f56ff4SMark Johnston
262f4f56ff4SMark Johnston static int qat_setup_msix_intr(struct qat_softc *);
263f4f56ff4SMark Johnston
264f4f56ff4SMark Johnston static void qat_etr_init(struct qat_softc *);
265f4f56ff4SMark Johnston static void qat_etr_deinit(struct qat_softc *);
266f4f56ff4SMark Johnston static void qat_etr_bank_init(struct qat_softc *, int);
267f4f56ff4SMark Johnston static void qat_etr_bank_deinit(struct qat_softc *sc, int);
268f4f56ff4SMark Johnston
269f4f56ff4SMark Johnston static void qat_etr_ap_bank_init(struct qat_softc *);
270f4f56ff4SMark Johnston static void qat_etr_ap_bank_set_ring_mask(uint32_t *, uint32_t, int);
271f4f56ff4SMark Johnston static void qat_etr_ap_bank_set_ring_dest(struct qat_softc *, uint32_t *,
272f4f56ff4SMark Johnston uint32_t, int);
273f4f56ff4SMark Johnston static void qat_etr_ap_bank_setup_ring(struct qat_softc *,
274f4f56ff4SMark Johnston struct qat_ring *);
275f4f56ff4SMark Johnston static int qat_etr_verify_ring_size(uint32_t, uint32_t);
276f4f56ff4SMark Johnston
277f4f56ff4SMark Johnston static int qat_etr_ring_intr(struct qat_softc *, struct qat_bank *,
278f4f56ff4SMark Johnston struct qat_ring *);
279f4f56ff4SMark Johnston static void qat_etr_bank_intr(void *);
280f4f56ff4SMark Johnston
281f4f56ff4SMark Johnston static void qat_arb_update(struct qat_softc *, struct qat_bank *);
282f4f56ff4SMark Johnston
283f4f56ff4SMark Johnston static struct qat_sym_cookie *qat_crypto_alloc_sym_cookie(
284f4f56ff4SMark Johnston struct qat_crypto_bank *);
285f4f56ff4SMark Johnston static void qat_crypto_free_sym_cookie(struct qat_crypto_bank *,
286f4f56ff4SMark Johnston struct qat_sym_cookie *);
287f4f56ff4SMark Johnston static int qat_crypto_setup_ring(struct qat_softc *,
288f4f56ff4SMark Johnston struct qat_crypto_bank *);
289f4f56ff4SMark Johnston static int qat_crypto_bank_init(struct qat_softc *,
290f4f56ff4SMark Johnston struct qat_crypto_bank *);
291f4f56ff4SMark Johnston static int qat_crypto_init(struct qat_softc *);
292f4f56ff4SMark Johnston static void qat_crypto_deinit(struct qat_softc *);
293f4f56ff4SMark Johnston static int qat_crypto_start(struct qat_softc *);
294f4f56ff4SMark Johnston static void qat_crypto_stop(struct qat_softc *);
295f4f56ff4SMark Johnston static int qat_crypto_sym_rxintr(struct qat_softc *, void *, void *);
296f4f56ff4SMark Johnston
297f4f56ff4SMark Johnston static MALLOC_DEFINE(M_QAT, "qat", "Intel QAT driver");
298f4f56ff4SMark Johnston
299f4f56ff4SMark Johnston static const struct qat_product *
qat_lookup(device_t dev)300f4f56ff4SMark Johnston qat_lookup(device_t dev)
301f4f56ff4SMark Johnston {
302f4f56ff4SMark Johnston const struct qat_product *qatp;
303f4f56ff4SMark Johnston
304f4f56ff4SMark Johnston for (qatp = qat_products; qatp->qatp_name != NULL; qatp++) {
305f4f56ff4SMark Johnston if (pci_get_vendor(dev) == qatp->qatp_vendor &&
306f4f56ff4SMark Johnston pci_get_device(dev) == qatp->qatp_product)
307f4f56ff4SMark Johnston return qatp;
308f4f56ff4SMark Johnston }
309f4f56ff4SMark Johnston return NULL;
310f4f56ff4SMark Johnston }
311f4f56ff4SMark Johnston
312f4f56ff4SMark Johnston static int
qat_probe(device_t dev)313f4f56ff4SMark Johnston qat_probe(device_t dev)
314f4f56ff4SMark Johnston {
315f4f56ff4SMark Johnston const struct qat_product *prod;
316f4f56ff4SMark Johnston
317f4f56ff4SMark Johnston prod = qat_lookup(dev);
318f4f56ff4SMark Johnston if (prod != NULL) {
319f4f56ff4SMark Johnston device_set_desc(dev, prod->qatp_name);
320f4f56ff4SMark Johnston return BUS_PROBE_DEFAULT;
321f4f56ff4SMark Johnston }
322f4f56ff4SMark Johnston return ENXIO;
323f4f56ff4SMark Johnston }
324f4f56ff4SMark Johnston
325f4f56ff4SMark Johnston static int
qat_attach(device_t dev)326f4f56ff4SMark Johnston qat_attach(device_t dev)
327f4f56ff4SMark Johnston {
328f4f56ff4SMark Johnston struct qat_softc *sc = device_get_softc(dev);
329f4f56ff4SMark Johnston const struct qat_product *qatp;
330f4f56ff4SMark Johnston int bar, count, error, i;
331f4f56ff4SMark Johnston
332f4f56ff4SMark Johnston sc->sc_dev = dev;
333f4f56ff4SMark Johnston sc->sc_rev = pci_get_revid(dev);
334f4f56ff4SMark Johnston sc->sc_crypto.qcy_cid = -1;
335f4f56ff4SMark Johnston
336f4f56ff4SMark Johnston qatp = qat_lookup(dev);
337f4f56ff4SMark Johnston memcpy(&sc->sc_hw, qatp->qatp_hw, sizeof(struct qat_hw));
338f4f56ff4SMark Johnston
339f4f56ff4SMark Johnston /* Determine active accelerators and engines */
340f4f56ff4SMark Johnston sc->sc_accel_mask = sc->sc_hw.qhw_get_accel_mask(sc);
341f4f56ff4SMark Johnston sc->sc_ae_mask = sc->sc_hw.qhw_get_ae_mask(sc);
342f4f56ff4SMark Johnston
343f4f56ff4SMark Johnston sc->sc_accel_num = 0;
344f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_accel; i++) {
345f4f56ff4SMark Johnston if (sc->sc_accel_mask & (1 << i))
346f4f56ff4SMark Johnston sc->sc_accel_num++;
347f4f56ff4SMark Johnston }
348f4f56ff4SMark Johnston sc->sc_ae_num = 0;
349f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_engines; i++) {
350f4f56ff4SMark Johnston if (sc->sc_ae_mask & (1 << i))
351f4f56ff4SMark Johnston sc->sc_ae_num++;
352f4f56ff4SMark Johnston }
353f4f56ff4SMark Johnston
354f4f56ff4SMark Johnston if (!sc->sc_accel_mask || (sc->sc_ae_mask & 0x01) == 0) {
355f4f56ff4SMark Johnston device_printf(sc->sc_dev, "couldn't find acceleration");
356f4f56ff4SMark Johnston goto fail;
357f4f56ff4SMark Johnston }
358f4f56ff4SMark Johnston
359f4f56ff4SMark Johnston MPASS(sc->sc_accel_num <= MAX_NUM_ACCEL);
360f4f56ff4SMark Johnston MPASS(sc->sc_ae_num <= MAX_NUM_AE);
361f4f56ff4SMark Johnston
362f4f56ff4SMark Johnston /* Determine SKU and capabilities */
363f4f56ff4SMark Johnston sc->sc_sku = sc->sc_hw.qhw_get_sku(sc);
364f4f56ff4SMark Johnston sc->sc_accel_cap = sc->sc_hw.qhw_get_accel_cap(sc);
365f4f56ff4SMark Johnston sc->sc_fw_uof_name = sc->sc_hw.qhw_get_fw_uof_name(sc);
366f4f56ff4SMark Johnston
367f4f56ff4SMark Johnston i = 0;
368f4f56ff4SMark Johnston if (sc->sc_hw.qhw_sram_bar_id != NO_PCI_REG) {
369f4f56ff4SMark Johnston MPASS(sc->sc_hw.qhw_sram_bar_id == 0);
370f4f56ff4SMark Johnston uint32_t fusectl = pci_read_config(dev, FUSECTL_REG, 4);
371f4f56ff4SMark Johnston /* Skip SRAM BAR */
372f4f56ff4SMark Johnston i = (fusectl & FUSECTL_MASK) ? 1 : 0;
373f4f56ff4SMark Johnston }
374f4f56ff4SMark Johnston for (bar = 0; bar < PCIR_MAX_BAR_0; bar++) {
375f4f56ff4SMark Johnston uint32_t val = pci_read_config(dev, PCIR_BAR(bar), 4);
376f4f56ff4SMark Johnston if (val == 0 || !PCI_BAR_MEM(val))
377f4f56ff4SMark Johnston continue;
378f4f56ff4SMark Johnston
379f4f56ff4SMark Johnston sc->sc_rid[i] = PCIR_BAR(bar);
380f4f56ff4SMark Johnston sc->sc_res[i] = bus_alloc_resource_any(dev, SYS_RES_MEMORY,
381f4f56ff4SMark Johnston &sc->sc_rid[i], RF_ACTIVE);
382f4f56ff4SMark Johnston if (sc->sc_res[i] == NULL) {
383f4f56ff4SMark Johnston device_printf(dev, "couldn't map BAR %d\n", bar);
384f4f56ff4SMark Johnston goto fail;
385f4f56ff4SMark Johnston }
386f4f56ff4SMark Johnston
387f4f56ff4SMark Johnston sc->sc_csrt[i] = rman_get_bustag(sc->sc_res[i]);
388f4f56ff4SMark Johnston sc->sc_csrh[i] = rman_get_bushandle(sc->sc_res[i]);
389f4f56ff4SMark Johnston
390f4f56ff4SMark Johnston i++;
391f4f56ff4SMark Johnston if ((val & PCIM_BAR_MEM_TYPE) == PCIM_BAR_MEM_64)
392f4f56ff4SMark Johnston bar++;
393f4f56ff4SMark Johnston }
394f4f56ff4SMark Johnston
395f4f56ff4SMark Johnston pci_enable_busmaster(dev);
396f4f56ff4SMark Johnston
397f4f56ff4SMark Johnston count = sc->sc_hw.qhw_num_banks + 1;
398f4f56ff4SMark Johnston if (pci_msix_count(dev) < count) {
399f4f56ff4SMark Johnston device_printf(dev, "insufficient MSI-X vectors (%d vs. %d)\n",
400f4f56ff4SMark Johnston pci_msix_count(dev), count);
401f4f56ff4SMark Johnston goto fail;
402f4f56ff4SMark Johnston }
403f4f56ff4SMark Johnston error = pci_alloc_msix(dev, &count);
404f4f56ff4SMark Johnston if (error != 0) {
405f4f56ff4SMark Johnston device_printf(dev, "failed to allocate MSI-X vectors\n");
406f4f56ff4SMark Johnston goto fail;
407f4f56ff4SMark Johnston }
408f4f56ff4SMark Johnston
409f4f56ff4SMark Johnston error = qat_init(dev);
410f4f56ff4SMark Johnston if (error == 0)
411f4f56ff4SMark Johnston return 0;
412f4f56ff4SMark Johnston
413f4f56ff4SMark Johnston fail:
414f4f56ff4SMark Johnston qat_detach(dev);
415f4f56ff4SMark Johnston return ENXIO;
416f4f56ff4SMark Johnston }
417f4f56ff4SMark Johnston
418f4f56ff4SMark Johnston static int
qat_init(device_t dev)419f4f56ff4SMark Johnston qat_init(device_t dev)
420f4f56ff4SMark Johnston {
421f4f56ff4SMark Johnston struct qat_softc *sc = device_get_softc(dev);
422f4f56ff4SMark Johnston int error;
423f4f56ff4SMark Johnston
424f4f56ff4SMark Johnston qat_etr_init(sc);
425f4f56ff4SMark Johnston
426f4f56ff4SMark Johnston if (sc->sc_hw.qhw_init_admin_comms != NULL &&
427f4f56ff4SMark Johnston (error = sc->sc_hw.qhw_init_admin_comms(sc)) != 0) {
428f4f56ff4SMark Johnston device_printf(sc->sc_dev,
429f4f56ff4SMark Johnston "Could not initialize admin comms: %d\n", error);
430f4f56ff4SMark Johnston return error;
431f4f56ff4SMark Johnston }
432f4f56ff4SMark Johnston
433f4f56ff4SMark Johnston if (sc->sc_hw.qhw_init_arb != NULL &&
434f4f56ff4SMark Johnston (error = sc->sc_hw.qhw_init_arb(sc)) != 0) {
435f4f56ff4SMark Johnston device_printf(sc->sc_dev,
436f4f56ff4SMark Johnston "Could not initialize hw arbiter: %d\n", error);
437f4f56ff4SMark Johnston return error;
438f4f56ff4SMark Johnston }
439f4f56ff4SMark Johnston
440f4f56ff4SMark Johnston error = qat_ae_init(sc);
441f4f56ff4SMark Johnston if (error) {
442f4f56ff4SMark Johnston device_printf(sc->sc_dev,
443f4f56ff4SMark Johnston "Could not initialize Acceleration Engine: %d\n", error);
444f4f56ff4SMark Johnston return error;
445f4f56ff4SMark Johnston }
446f4f56ff4SMark Johnston
447f4f56ff4SMark Johnston error = qat_aefw_load(sc);
448f4f56ff4SMark Johnston if (error) {
449f4f56ff4SMark Johnston device_printf(sc->sc_dev,
450f4f56ff4SMark Johnston "Could not load firmware: %d\n", error);
451f4f56ff4SMark Johnston return error;
452f4f56ff4SMark Johnston }
453f4f56ff4SMark Johnston
454f4f56ff4SMark Johnston error = qat_setup_msix_intr(sc);
455f4f56ff4SMark Johnston if (error) {
456f4f56ff4SMark Johnston device_printf(sc->sc_dev,
457f4f56ff4SMark Johnston "Could not setup interrupts: %d\n", error);
458f4f56ff4SMark Johnston return error;
459f4f56ff4SMark Johnston }
460f4f56ff4SMark Johnston
461f4f56ff4SMark Johnston sc->sc_hw.qhw_enable_intr(sc);
462f4f56ff4SMark Johnston
463f4f56ff4SMark Johnston error = qat_crypto_init(sc);
464f4f56ff4SMark Johnston if (error) {
465f4f56ff4SMark Johnston device_printf(sc->sc_dev,
466f4f56ff4SMark Johnston "Could not initialize service: %d\n", error);
467f4f56ff4SMark Johnston return error;
468f4f56ff4SMark Johnston }
469f4f56ff4SMark Johnston
470f4f56ff4SMark Johnston if (sc->sc_hw.qhw_enable_error_correction != NULL)
471f4f56ff4SMark Johnston sc->sc_hw.qhw_enable_error_correction(sc);
472f4f56ff4SMark Johnston
473f4f56ff4SMark Johnston if (sc->sc_hw.qhw_set_ssm_wdtimer != NULL &&
474f4f56ff4SMark Johnston (error = sc->sc_hw.qhw_set_ssm_wdtimer(sc)) != 0) {
475f4f56ff4SMark Johnston device_printf(sc->sc_dev,
476f4f56ff4SMark Johnston "Could not initialize watchdog timer: %d\n", error);
477f4f56ff4SMark Johnston return error;
478f4f56ff4SMark Johnston }
479f4f56ff4SMark Johnston
480f4f56ff4SMark Johnston error = qat_start(dev);
481f4f56ff4SMark Johnston if (error) {
482f4f56ff4SMark Johnston device_printf(sc->sc_dev,
483f4f56ff4SMark Johnston "Could not start: %d\n", error);
484f4f56ff4SMark Johnston return error;
485f4f56ff4SMark Johnston }
486f4f56ff4SMark Johnston
487f4f56ff4SMark Johnston return 0;
488f4f56ff4SMark Johnston }
489f4f56ff4SMark Johnston
490f4f56ff4SMark Johnston static int
qat_start(device_t dev)491f4f56ff4SMark Johnston qat_start(device_t dev)
492f4f56ff4SMark Johnston {
493f4f56ff4SMark Johnston struct qat_softc *sc = device_get_softc(dev);
494f4f56ff4SMark Johnston int error;
495f4f56ff4SMark Johnston
496f4f56ff4SMark Johnston error = qat_ae_start(sc);
497f4f56ff4SMark Johnston if (error)
498f4f56ff4SMark Johnston return error;
499f4f56ff4SMark Johnston
500f4f56ff4SMark Johnston if (sc->sc_hw.qhw_send_admin_init != NULL &&
501f4f56ff4SMark Johnston (error = sc->sc_hw.qhw_send_admin_init(sc)) != 0) {
502f4f56ff4SMark Johnston return error;
503f4f56ff4SMark Johnston }
504f4f56ff4SMark Johnston
505f4f56ff4SMark Johnston error = qat_crypto_start(sc);
506f4f56ff4SMark Johnston if (error)
507f4f56ff4SMark Johnston return error;
508f4f56ff4SMark Johnston
509f4f56ff4SMark Johnston return 0;
510f4f56ff4SMark Johnston }
511f4f56ff4SMark Johnston
512f4f56ff4SMark Johnston static int
qat_detach(device_t dev)513f4f56ff4SMark Johnston qat_detach(device_t dev)
514f4f56ff4SMark Johnston {
515f4f56ff4SMark Johnston struct qat_softc *sc;
516f4f56ff4SMark Johnston int bar, i;
517f4f56ff4SMark Johnston
518f4f56ff4SMark Johnston sc = device_get_softc(dev);
519f4f56ff4SMark Johnston
520f4f56ff4SMark Johnston qat_crypto_stop(sc);
521f4f56ff4SMark Johnston qat_crypto_deinit(sc);
522f4f56ff4SMark Johnston qat_aefw_unload(sc);
523f4f56ff4SMark Johnston
524f4f56ff4SMark Johnston if (sc->sc_etr_banks != NULL) {
525f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_banks; i++) {
526f4f56ff4SMark Johnston struct qat_bank *qb = &sc->sc_etr_banks[i];
527f4f56ff4SMark Johnston
528f4f56ff4SMark Johnston if (qb->qb_ih_cookie != NULL)
529f4f56ff4SMark Johnston (void)bus_teardown_intr(dev, qb->qb_ih,
530f4f56ff4SMark Johnston qb->qb_ih_cookie);
531f4f56ff4SMark Johnston if (qb->qb_ih != NULL)
532f4f56ff4SMark Johnston (void)bus_release_resource(dev, SYS_RES_IRQ,
533f4f56ff4SMark Johnston i + 1, qb->qb_ih);
534f4f56ff4SMark Johnston }
535f4f56ff4SMark Johnston }
536f4f56ff4SMark Johnston if (sc->sc_ih_cookie != NULL) {
537f4f56ff4SMark Johnston (void)bus_teardown_intr(dev, sc->sc_ih, sc->sc_ih_cookie);
538f4f56ff4SMark Johnston sc->sc_ih_cookie = NULL;
539f4f56ff4SMark Johnston }
540f4f56ff4SMark Johnston if (sc->sc_ih != NULL) {
541f4f56ff4SMark Johnston (void)bus_release_resource(dev, SYS_RES_IRQ,
542f4f56ff4SMark Johnston sc->sc_hw.qhw_num_banks + 1, sc->sc_ih);
543f4f56ff4SMark Johnston sc->sc_ih = NULL;
544f4f56ff4SMark Johnston }
545f4f56ff4SMark Johnston pci_release_msi(dev);
546f4f56ff4SMark Johnston
547f4f56ff4SMark Johnston qat_etr_deinit(sc);
548f4f56ff4SMark Johnston
549f4f56ff4SMark Johnston for (bar = 0; bar < MAX_BARS; bar++) {
550f4f56ff4SMark Johnston if (sc->sc_res[bar] != NULL) {
551f4f56ff4SMark Johnston (void)bus_release_resource(dev, SYS_RES_MEMORY,
552f4f56ff4SMark Johnston sc->sc_rid[bar], sc->sc_res[bar]);
553f4f56ff4SMark Johnston sc->sc_res[bar] = NULL;
554f4f56ff4SMark Johnston }
555f4f56ff4SMark Johnston }
556f4f56ff4SMark Johnston
557f4f56ff4SMark Johnston return 0;
558f4f56ff4SMark Johnston }
559f4f56ff4SMark Johnston
560f4f56ff4SMark Johnston void *
qat_alloc_mem(size_t size)561f4f56ff4SMark Johnston qat_alloc_mem(size_t size)
562f4f56ff4SMark Johnston {
563f4f56ff4SMark Johnston return (malloc(size, M_QAT, M_WAITOK | M_ZERO));
564f4f56ff4SMark Johnston }
565f4f56ff4SMark Johnston
566f4f56ff4SMark Johnston void
qat_free_mem(void * ptr)567f4f56ff4SMark Johnston qat_free_mem(void *ptr)
568f4f56ff4SMark Johnston {
569f4f56ff4SMark Johnston free(ptr, M_QAT);
570f4f56ff4SMark Johnston }
571f4f56ff4SMark Johnston
572f4f56ff4SMark Johnston static void
qat_alloc_dmamem_cb(void * arg,bus_dma_segment_t * segs,int nseg,int error)573f4f56ff4SMark Johnston qat_alloc_dmamem_cb(void *arg, bus_dma_segment_t *segs, int nseg,
574f4f56ff4SMark Johnston int error)
575f4f56ff4SMark Johnston {
576f4f56ff4SMark Johnston struct qat_dmamem *qdm;
577f4f56ff4SMark Johnston
578f4f56ff4SMark Johnston if (error != 0)
579f4f56ff4SMark Johnston return;
580f4f56ff4SMark Johnston
581f4f56ff4SMark Johnston KASSERT(nseg == 1, ("%s: nsegs is %d", __func__, nseg));
582f4f56ff4SMark Johnston qdm = arg;
583f4f56ff4SMark Johnston qdm->qdm_dma_seg = segs[0];
584f4f56ff4SMark Johnston }
585f4f56ff4SMark Johnston
586f4f56ff4SMark Johnston int
qat_alloc_dmamem(struct qat_softc * sc,struct qat_dmamem * qdm,int nseg,bus_size_t size,bus_size_t alignment)587f4f56ff4SMark Johnston qat_alloc_dmamem(struct qat_softc *sc, struct qat_dmamem *qdm,
588f4f56ff4SMark Johnston int nseg, bus_size_t size, bus_size_t alignment)
589f4f56ff4SMark Johnston {
590f4f56ff4SMark Johnston int error;
591f4f56ff4SMark Johnston
592f4f56ff4SMark Johnston KASSERT(qdm->qdm_dma_vaddr == NULL,
593f4f56ff4SMark Johnston ("%s: DMA memory descriptor in use", __func__));
594f4f56ff4SMark Johnston
595f4f56ff4SMark Johnston error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),
596f4f56ff4SMark Johnston alignment, 0, /* alignment, boundary */
597f4f56ff4SMark Johnston BUS_SPACE_MAXADDR, /* lowaddr */
598f4f56ff4SMark Johnston BUS_SPACE_MAXADDR, /* highaddr */
599f4f56ff4SMark Johnston NULL, NULL, /* filter, filterarg */
600f4f56ff4SMark Johnston size, /* maxsize */
601f4f56ff4SMark Johnston nseg, /* nsegments */
602f4f56ff4SMark Johnston size, /* maxsegsize */
603f4f56ff4SMark Johnston BUS_DMA_COHERENT, /* flags */
604f4f56ff4SMark Johnston NULL, NULL, /* lockfunc, lockarg */
605f4f56ff4SMark Johnston &qdm->qdm_dma_tag);
606f4f56ff4SMark Johnston if (error != 0)
607f4f56ff4SMark Johnston return error;
608f4f56ff4SMark Johnston
609f4f56ff4SMark Johnston error = bus_dmamem_alloc(qdm->qdm_dma_tag, &qdm->qdm_dma_vaddr,
610f4f56ff4SMark Johnston BUS_DMA_NOWAIT | BUS_DMA_ZERO | BUS_DMA_COHERENT,
611f4f56ff4SMark Johnston &qdm->qdm_dma_map);
612f4f56ff4SMark Johnston if (error != 0) {
613f4f56ff4SMark Johnston device_printf(sc->sc_dev,
614f4f56ff4SMark Johnston "couldn't allocate dmamem, error = %d\n", error);
615f4f56ff4SMark Johnston goto fail_0;
616f4f56ff4SMark Johnston }
617f4f56ff4SMark Johnston
618f4f56ff4SMark Johnston error = bus_dmamap_load(qdm->qdm_dma_tag, qdm->qdm_dma_map,
619f4f56ff4SMark Johnston qdm->qdm_dma_vaddr, size, qat_alloc_dmamem_cb, qdm,
620f4f56ff4SMark Johnston BUS_DMA_NOWAIT);
621f4f56ff4SMark Johnston if (error) {
622f4f56ff4SMark Johnston device_printf(sc->sc_dev,
623f4f56ff4SMark Johnston "couldn't load dmamem map, error = %d\n", error);
624f4f56ff4SMark Johnston goto fail_1;
625f4f56ff4SMark Johnston }
626f4f56ff4SMark Johnston
627f4f56ff4SMark Johnston return 0;
628f4f56ff4SMark Johnston fail_1:
629f4f56ff4SMark Johnston bus_dmamem_free(qdm->qdm_dma_tag, qdm->qdm_dma_vaddr, qdm->qdm_dma_map);
630f4f56ff4SMark Johnston fail_0:
631f4f56ff4SMark Johnston bus_dma_tag_destroy(qdm->qdm_dma_tag);
632f4f56ff4SMark Johnston return error;
633f4f56ff4SMark Johnston }
634f4f56ff4SMark Johnston
635f4f56ff4SMark Johnston void
qat_free_dmamem(struct qat_softc * sc,struct qat_dmamem * qdm)636f4f56ff4SMark Johnston qat_free_dmamem(struct qat_softc *sc, struct qat_dmamem *qdm)
637f4f56ff4SMark Johnston {
638f4f56ff4SMark Johnston if (qdm->qdm_dma_tag != NULL) {
639f4f56ff4SMark Johnston bus_dmamap_unload(qdm->qdm_dma_tag, qdm->qdm_dma_map);
640f4f56ff4SMark Johnston bus_dmamem_free(qdm->qdm_dma_tag, qdm->qdm_dma_vaddr,
641f4f56ff4SMark Johnston qdm->qdm_dma_map);
642f4f56ff4SMark Johnston bus_dma_tag_destroy(qdm->qdm_dma_tag);
643f4f56ff4SMark Johnston explicit_bzero(qdm, sizeof(*qdm));
644f4f56ff4SMark Johnston }
645f4f56ff4SMark Johnston }
646f4f56ff4SMark Johnston
647f4f56ff4SMark Johnston static int
qat_setup_msix_intr(struct qat_softc * sc)648f4f56ff4SMark Johnston qat_setup_msix_intr(struct qat_softc *sc)
649f4f56ff4SMark Johnston {
650f4f56ff4SMark Johnston device_t dev;
651f4f56ff4SMark Johnston int error, i, rid;
652f4f56ff4SMark Johnston
653f4f56ff4SMark Johnston dev = sc->sc_dev;
654f4f56ff4SMark Johnston
655f4f56ff4SMark Johnston for (i = 1; i <= sc->sc_hw.qhw_num_banks; i++) {
656f4f56ff4SMark Johnston struct qat_bank *qb = &sc->sc_etr_banks[i - 1];
657f4f56ff4SMark Johnston
658f4f56ff4SMark Johnston rid = i;
659f4f56ff4SMark Johnston qb->qb_ih = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
660f4f56ff4SMark Johnston RF_ACTIVE);
661f4f56ff4SMark Johnston if (qb->qb_ih == NULL) {
662f4f56ff4SMark Johnston device_printf(dev,
663f4f56ff4SMark Johnston "failed to allocate bank intr resource\n");
664f4f56ff4SMark Johnston return ENXIO;
665f4f56ff4SMark Johnston }
666f4f56ff4SMark Johnston error = bus_setup_intr(dev, qb->qb_ih,
667f4f56ff4SMark Johnston INTR_TYPE_NET | INTR_MPSAFE, NULL, qat_etr_bank_intr, qb,
668f4f56ff4SMark Johnston &qb->qb_ih_cookie);
669f4f56ff4SMark Johnston if (error != 0) {
670f4f56ff4SMark Johnston device_printf(dev, "failed to set up bank intr\n");
671f4f56ff4SMark Johnston return error;
672f4f56ff4SMark Johnston }
673f4f56ff4SMark Johnston error = bus_bind_intr(dev, qb->qb_ih, (i - 1) % mp_ncpus);
674f4f56ff4SMark Johnston if (error != 0)
675f4f56ff4SMark Johnston device_printf(dev, "failed to bind intr %d\n", i);
676f4f56ff4SMark Johnston }
677f4f56ff4SMark Johnston
678f4f56ff4SMark Johnston rid = i;
679f4f56ff4SMark Johnston sc->sc_ih = bus_alloc_resource_any(dev, SYS_RES_IRQ, &rid,
680f4f56ff4SMark Johnston RF_ACTIVE);
681f4f56ff4SMark Johnston if (sc->sc_ih == NULL)
682f4f56ff4SMark Johnston return ENXIO;
683f4f56ff4SMark Johnston error = bus_setup_intr(dev, sc->sc_ih, INTR_TYPE_NET | INTR_MPSAFE,
684f4f56ff4SMark Johnston NULL, qat_ae_cluster_intr, sc, &sc->sc_ih_cookie);
685f4f56ff4SMark Johnston
686f4f56ff4SMark Johnston return error;
687f4f56ff4SMark Johnston }
688f4f56ff4SMark Johnston
689f4f56ff4SMark Johnston static void
qat_etr_init(struct qat_softc * sc)690f4f56ff4SMark Johnston qat_etr_init(struct qat_softc *sc)
691f4f56ff4SMark Johnston {
692f4f56ff4SMark Johnston int i;
693f4f56ff4SMark Johnston
694f4f56ff4SMark Johnston sc->sc_etr_banks = qat_alloc_mem(
695f4f56ff4SMark Johnston sizeof(struct qat_bank) * sc->sc_hw.qhw_num_banks);
696f4f56ff4SMark Johnston
697f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_banks; i++)
698f4f56ff4SMark Johnston qat_etr_bank_init(sc, i);
699f4f56ff4SMark Johnston
700f4f56ff4SMark Johnston if (sc->sc_hw.qhw_num_ap_banks) {
701f4f56ff4SMark Johnston sc->sc_etr_ap_banks = qat_alloc_mem(
702f4f56ff4SMark Johnston sizeof(struct qat_ap_bank) * sc->sc_hw.qhw_num_ap_banks);
703f4f56ff4SMark Johnston qat_etr_ap_bank_init(sc);
704f4f56ff4SMark Johnston }
705f4f56ff4SMark Johnston }
706f4f56ff4SMark Johnston
707f4f56ff4SMark Johnston static void
qat_etr_deinit(struct qat_softc * sc)708f4f56ff4SMark Johnston qat_etr_deinit(struct qat_softc *sc)
709f4f56ff4SMark Johnston {
710f4f56ff4SMark Johnston int i;
711f4f56ff4SMark Johnston
712f4f56ff4SMark Johnston if (sc->sc_etr_banks != NULL) {
713f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_banks; i++)
714f4f56ff4SMark Johnston qat_etr_bank_deinit(sc, i);
715f4f56ff4SMark Johnston qat_free_mem(sc->sc_etr_banks);
716f4f56ff4SMark Johnston sc->sc_etr_banks = NULL;
717f4f56ff4SMark Johnston }
718f4f56ff4SMark Johnston if (sc->sc_etr_ap_banks != NULL) {
719f4f56ff4SMark Johnston qat_free_mem(sc->sc_etr_ap_banks);
720f4f56ff4SMark Johnston sc->sc_etr_ap_banks = NULL;
721f4f56ff4SMark Johnston }
722f4f56ff4SMark Johnston }
723f4f56ff4SMark Johnston
724f4f56ff4SMark Johnston static void
qat_etr_bank_init(struct qat_softc * sc,int bank)725f4f56ff4SMark Johnston qat_etr_bank_init(struct qat_softc *sc, int bank)
726f4f56ff4SMark Johnston {
727f4f56ff4SMark Johnston struct qat_bank *qb = &sc->sc_etr_banks[bank];
728f4f56ff4SMark Johnston int i, tx_rx_gap = sc->sc_hw.qhw_tx_rx_gap;
729f4f56ff4SMark Johnston
730f4f56ff4SMark Johnston MPASS(bank < sc->sc_hw.qhw_num_banks);
731f4f56ff4SMark Johnston
732f4f56ff4SMark Johnston mtx_init(&qb->qb_bank_mtx, "qb bank", NULL, MTX_DEF);
733f4f56ff4SMark Johnston
734f4f56ff4SMark Johnston qb->qb_sc = sc;
735f4f56ff4SMark Johnston qb->qb_bank = bank;
736f4f56ff4SMark Johnston qb->qb_coalescing_time = COALESCING_TIME_INTERVAL_DEFAULT;
737f4f56ff4SMark Johnston
738f4f56ff4SMark Johnston /* Clean CSRs for all rings within the bank */
739f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_rings_per_bank; i++) {
740f4f56ff4SMark Johnston struct qat_ring *qr = &qb->qb_et_rings[i];
741f4f56ff4SMark Johnston
742f4f56ff4SMark Johnston qat_etr_bank_ring_write_4(sc, bank, i,
743f4f56ff4SMark Johnston ETR_RING_CONFIG, 0);
744f4f56ff4SMark Johnston qat_etr_bank_ring_base_write_8(sc, bank, i, 0);
745f4f56ff4SMark Johnston
746f4f56ff4SMark Johnston if (sc->sc_hw.qhw_tx_rings_mask & (1 << i)) {
747f4f56ff4SMark Johnston qr->qr_inflight = qat_alloc_mem(sizeof(uint32_t));
748f4f56ff4SMark Johnston } else if (sc->sc_hw.qhw_tx_rings_mask &
749f4f56ff4SMark Johnston (1 << (i - tx_rx_gap))) {
750f4f56ff4SMark Johnston /* Share inflight counter with rx and tx */
751f4f56ff4SMark Johnston qr->qr_inflight =
752f4f56ff4SMark Johnston qb->qb_et_rings[i - tx_rx_gap].qr_inflight;
753f4f56ff4SMark Johnston }
754f4f56ff4SMark Johnston }
755f4f56ff4SMark Johnston
756f4f56ff4SMark Johnston if (sc->sc_hw.qhw_init_etr_intr != NULL) {
757f4f56ff4SMark Johnston sc->sc_hw.qhw_init_etr_intr(sc, bank);
758f4f56ff4SMark Johnston } else {
759f4f56ff4SMark Johnston /* common code in qat 1.7 */
760f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, bank, ETR_INT_REG,
761f4f56ff4SMark Johnston ETR_INT_REG_CLEAR_MASK);
762f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_rings_per_bank /
763f4f56ff4SMark Johnston ETR_RINGS_PER_INT_SRCSEL; i++) {
764f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, bank, ETR_INT_SRCSEL +
765f4f56ff4SMark Johnston (i * ETR_INT_SRCSEL_NEXT_OFFSET),
766f4f56ff4SMark Johnston ETR_INT_SRCSEL_MASK);
767f4f56ff4SMark Johnston }
768f4f56ff4SMark Johnston }
769f4f56ff4SMark Johnston }
770f4f56ff4SMark Johnston
771f4f56ff4SMark Johnston static void
qat_etr_bank_deinit(struct qat_softc * sc,int bank)772f4f56ff4SMark Johnston qat_etr_bank_deinit(struct qat_softc *sc, int bank)
773f4f56ff4SMark Johnston {
774f4f56ff4SMark Johnston struct qat_bank *qb;
775f4f56ff4SMark Johnston struct qat_ring *qr;
776f4f56ff4SMark Johnston int i;
777f4f56ff4SMark Johnston
778f4f56ff4SMark Johnston qb = &sc->sc_etr_banks[bank];
779f4f56ff4SMark Johnston for (i = 0; i < sc->sc_hw.qhw_num_rings_per_bank; i++) {
780f4f56ff4SMark Johnston if (sc->sc_hw.qhw_tx_rings_mask & (1 << i)) {
781f4f56ff4SMark Johnston qr = &qb->qb_et_rings[i];
782f4f56ff4SMark Johnston qat_free_mem(qr->qr_inflight);
783f4f56ff4SMark Johnston }
784f4f56ff4SMark Johnston }
785f4f56ff4SMark Johnston }
786f4f56ff4SMark Johnston
787f4f56ff4SMark Johnston static void
qat_etr_ap_bank_init(struct qat_softc * sc)788f4f56ff4SMark Johnston qat_etr_ap_bank_init(struct qat_softc *sc)
789f4f56ff4SMark Johnston {
790f4f56ff4SMark Johnston int ap_bank;
791f4f56ff4SMark Johnston
792f4f56ff4SMark Johnston for (ap_bank = 0; ap_bank < sc->sc_hw.qhw_num_ap_banks; ap_bank++) {
793f4f56ff4SMark Johnston struct qat_ap_bank *qab = &sc->sc_etr_ap_banks[ap_bank];
794f4f56ff4SMark Johnston
795f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NF_MASK,
796f4f56ff4SMark Johnston ETR_AP_NF_MASK_INIT);
797f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NF_DEST, 0);
798f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NE_MASK,
799f4f56ff4SMark Johnston ETR_AP_NE_MASK_INIT);
800f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NE_DEST, 0);
801f4f56ff4SMark Johnston
802f4f56ff4SMark Johnston memset(qab, 0, sizeof(*qab));
803f4f56ff4SMark Johnston }
804f4f56ff4SMark Johnston }
805f4f56ff4SMark Johnston
806f4f56ff4SMark Johnston static void
qat_etr_ap_bank_set_ring_mask(uint32_t * ap_mask,uint32_t ring,int set_mask)807f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_mask(uint32_t *ap_mask, uint32_t ring, int set_mask)
808f4f56ff4SMark Johnston {
809f4f56ff4SMark Johnston if (set_mask)
810f4f56ff4SMark Johnston *ap_mask |= (1 << ETR_RING_NUMBER_IN_AP_BANK(ring));
811f4f56ff4SMark Johnston else
812f4f56ff4SMark Johnston *ap_mask &= ~(1 << ETR_RING_NUMBER_IN_AP_BANK(ring));
813f4f56ff4SMark Johnston }
814f4f56ff4SMark Johnston
815f4f56ff4SMark Johnston static void
qat_etr_ap_bank_set_ring_dest(struct qat_softc * sc,uint32_t * ap_dest,uint32_t ring,int set_dest)816f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_dest(struct qat_softc *sc, uint32_t *ap_dest,
817f4f56ff4SMark Johnston uint32_t ring, int set_dest)
818f4f56ff4SMark Johnston {
819f4f56ff4SMark Johnston uint32_t ae_mask;
820f4f56ff4SMark Johnston uint8_t mailbox, ae, nae;
821f4f56ff4SMark Johnston uint8_t *dest = (uint8_t *)ap_dest;
822f4f56ff4SMark Johnston
823f4f56ff4SMark Johnston mailbox = ETR_RING_AP_MAILBOX_NUMBER(ring);
824f4f56ff4SMark Johnston
825f4f56ff4SMark Johnston nae = 0;
826f4f56ff4SMark Johnston ae_mask = sc->sc_ae_mask;
827f4f56ff4SMark Johnston for (ae = 0; ae < sc->sc_hw.qhw_num_engines; ae++) {
828f4f56ff4SMark Johnston if ((ae_mask & (1 << ae)) == 0)
829f4f56ff4SMark Johnston continue;
830f4f56ff4SMark Johnston
831f4f56ff4SMark Johnston if (set_dest) {
832f4f56ff4SMark Johnston dest[nae] = __SHIFTIN(ae, ETR_AP_DEST_AE) |
833f4f56ff4SMark Johnston __SHIFTIN(mailbox, ETR_AP_DEST_MAILBOX) |
834f4f56ff4SMark Johnston ETR_AP_DEST_ENABLE;
835f4f56ff4SMark Johnston } else {
836f4f56ff4SMark Johnston dest[nae] = 0;
837f4f56ff4SMark Johnston }
838f4f56ff4SMark Johnston nae++;
839f4f56ff4SMark Johnston if (nae == ETR_MAX_AE_PER_MAILBOX)
840f4f56ff4SMark Johnston break;
841f4f56ff4SMark Johnston }
842f4f56ff4SMark Johnston }
843f4f56ff4SMark Johnston
844f4f56ff4SMark Johnston static void
qat_etr_ap_bank_setup_ring(struct qat_softc * sc,struct qat_ring * qr)845f4f56ff4SMark Johnston qat_etr_ap_bank_setup_ring(struct qat_softc *sc, struct qat_ring *qr)
846f4f56ff4SMark Johnston {
847f4f56ff4SMark Johnston struct qat_ap_bank *qab;
848f4f56ff4SMark Johnston int ap_bank;
849f4f56ff4SMark Johnston
850f4f56ff4SMark Johnston if (sc->sc_hw.qhw_num_ap_banks == 0)
851f4f56ff4SMark Johnston return;
852f4f56ff4SMark Johnston
853f4f56ff4SMark Johnston ap_bank = ETR_RING_AP_BANK_NUMBER(qr->qr_ring);
854f4f56ff4SMark Johnston MPASS(ap_bank < sc->sc_hw.qhw_num_ap_banks);
855f4f56ff4SMark Johnston qab = &sc->sc_etr_ap_banks[ap_bank];
856f4f56ff4SMark Johnston
857f4f56ff4SMark Johnston if (qr->qr_cb == NULL) {
858f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_mask(&qab->qab_ne_mask, qr->qr_ring, 1);
859f4f56ff4SMark Johnston if (!qab->qab_ne_dest) {
860f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_dest(sc, &qab->qab_ne_dest,
861f4f56ff4SMark Johnston qr->qr_ring, 1);
862f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NE_DEST,
863f4f56ff4SMark Johnston qab->qab_ne_dest);
864f4f56ff4SMark Johnston }
865f4f56ff4SMark Johnston } else {
866f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_mask(&qab->qab_nf_mask, qr->qr_ring, 1);
867f4f56ff4SMark Johnston if (!qab->qab_nf_dest) {
868f4f56ff4SMark Johnston qat_etr_ap_bank_set_ring_dest(sc, &qab->qab_nf_dest,
869f4f56ff4SMark Johnston qr->qr_ring, 1);
870f4f56ff4SMark Johnston qat_etr_ap_bank_write_4(sc, ap_bank, ETR_AP_NF_DEST,
871f4f56ff4SMark Johnston qab->qab_nf_dest);
872f4f56ff4SMark Johnston }
873f4f56ff4SMark Johnston }
874f4f56ff4SMark Johnston }
875f4f56ff4SMark Johnston
876f4f56ff4SMark Johnston static int
qat_etr_verify_ring_size(uint32_t msg_size,uint32_t num_msgs)877f4f56ff4SMark Johnston qat_etr_verify_ring_size(uint32_t msg_size, uint32_t num_msgs)
878f4f56ff4SMark Johnston {
879f4f56ff4SMark Johnston int i = QAT_MIN_RING_SIZE;
880f4f56ff4SMark Johnston
881f4f56ff4SMark Johnston for (; i <= QAT_MAX_RING_SIZE; i++)
882f4f56ff4SMark Johnston if ((msg_size * num_msgs) == QAT_SIZE_TO_RING_SIZE_IN_BYTES(i))
883f4f56ff4SMark Johnston return i;
884f4f56ff4SMark Johnston
885f4f56ff4SMark Johnston return QAT_DEFAULT_RING_SIZE;
886f4f56ff4SMark Johnston }
887f4f56ff4SMark Johnston
888f4f56ff4SMark Johnston int
qat_etr_setup_ring(struct qat_softc * sc,int bank,uint32_t ring,uint32_t num_msgs,uint32_t msg_size,qat_cb_t cb,void * cb_arg,const char * name,struct qat_ring ** rqr)889f4f56ff4SMark Johnston qat_etr_setup_ring(struct qat_softc *sc, int bank, uint32_t ring,
890f4f56ff4SMark Johnston uint32_t num_msgs, uint32_t msg_size, qat_cb_t cb, void *cb_arg,
891f4f56ff4SMark Johnston const char *name, struct qat_ring **rqr)
892f4f56ff4SMark Johnston {
893f4f56ff4SMark Johnston struct qat_bank *qb;
894f4f56ff4SMark Johnston struct qat_ring *qr = NULL;
895f4f56ff4SMark Johnston int error;
896f4f56ff4SMark Johnston uint32_t ring_size_bytes, ring_config;
897f4f56ff4SMark Johnston uint64_t ring_base;
898f4f56ff4SMark Johnston uint32_t wm_nf = ETR_RING_CONFIG_NEAR_WM_512;
899f4f56ff4SMark Johnston uint32_t wm_ne = ETR_RING_CONFIG_NEAR_WM_0;
900f4f56ff4SMark Johnston
901f4f56ff4SMark Johnston MPASS(bank < sc->sc_hw.qhw_num_banks);
902f4f56ff4SMark Johnston
903f4f56ff4SMark Johnston /* Allocate a ring from specified bank */
904f4f56ff4SMark Johnston qb = &sc->sc_etr_banks[bank];
905f4f56ff4SMark Johnston
906f4f56ff4SMark Johnston if (ring >= sc->sc_hw.qhw_num_rings_per_bank)
907f4f56ff4SMark Johnston return EINVAL;
908f4f56ff4SMark Johnston if (qb->qb_allocated_rings & (1 << ring))
909f4f56ff4SMark Johnston return ENOENT;
910f4f56ff4SMark Johnston qr = &qb->qb_et_rings[ring];
911f4f56ff4SMark Johnston qb->qb_allocated_rings |= 1 << ring;
912f4f56ff4SMark Johnston
913f4f56ff4SMark Johnston /* Initialize allocated ring */
914f4f56ff4SMark Johnston qr->qr_ring = ring;
915f4f56ff4SMark Johnston qr->qr_bank = bank;
916f4f56ff4SMark Johnston qr->qr_name = name;
917f4f56ff4SMark Johnston qr->qr_ring_id = qr->qr_bank * sc->sc_hw.qhw_num_rings_per_bank + ring;
918f4f56ff4SMark Johnston qr->qr_ring_mask = (1 << ring);
919f4f56ff4SMark Johnston qr->qr_cb = cb;
920f4f56ff4SMark Johnston qr->qr_cb_arg = cb_arg;
921f4f56ff4SMark Johnston
922f4f56ff4SMark Johnston /* Setup the shadow variables */
923f4f56ff4SMark Johnston qr->qr_head = 0;
924f4f56ff4SMark Johnston qr->qr_tail = 0;
925f4f56ff4SMark Johnston qr->qr_msg_size = QAT_BYTES_TO_MSG_SIZE(msg_size);
926f4f56ff4SMark Johnston qr->qr_ring_size = qat_etr_verify_ring_size(msg_size, num_msgs);
927f4f56ff4SMark Johnston
928f4f56ff4SMark Johnston /*
929f4f56ff4SMark Johnston * To make sure that ring is alligned to ring size allocate
930f4f56ff4SMark Johnston * at least 4k and then tell the user it is smaller.
931f4f56ff4SMark Johnston */
932f4f56ff4SMark Johnston ring_size_bytes = QAT_SIZE_TO_RING_SIZE_IN_BYTES(qr->qr_ring_size);
933f4f56ff4SMark Johnston ring_size_bytes = QAT_RING_SIZE_BYTES_MIN(ring_size_bytes);
934f4f56ff4SMark Johnston error = qat_alloc_dmamem(sc, &qr->qr_dma, 1, ring_size_bytes,
935f4f56ff4SMark Johnston ring_size_bytes);
936f4f56ff4SMark Johnston if (error)
937f4f56ff4SMark Johnston return error;
938f4f56ff4SMark Johnston
939f4f56ff4SMark Johnston qr->qr_ring_vaddr = qr->qr_dma.qdm_dma_vaddr;
940f4f56ff4SMark Johnston qr->qr_ring_paddr = qr->qr_dma.qdm_dma_seg.ds_addr;
941f4f56ff4SMark Johnston
942f4f56ff4SMark Johnston memset(qr->qr_ring_vaddr, QAT_RING_PATTERN,
943f4f56ff4SMark Johnston qr->qr_dma.qdm_dma_seg.ds_len);
944f4f56ff4SMark Johnston
945f4f56ff4SMark Johnston bus_dmamap_sync(qr->qr_dma.qdm_dma_tag, qr->qr_dma.qdm_dma_map,
946f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
947f4f56ff4SMark Johnston
948f4f56ff4SMark Johnston if (cb == NULL) {
949f4f56ff4SMark Johnston ring_config = ETR_RING_CONFIG_BUILD(qr->qr_ring_size);
950f4f56ff4SMark Johnston } else {
951f4f56ff4SMark Johnston ring_config =
952f4f56ff4SMark Johnston ETR_RING_CONFIG_BUILD_RESP(qr->qr_ring_size, wm_nf, wm_ne);
953f4f56ff4SMark Johnston }
954f4f56ff4SMark Johnston qat_etr_bank_ring_write_4(sc, bank, ring, ETR_RING_CONFIG, ring_config);
955f4f56ff4SMark Johnston
956f4f56ff4SMark Johnston ring_base = ETR_RING_BASE_BUILD(qr->qr_ring_paddr, qr->qr_ring_size);
957f4f56ff4SMark Johnston qat_etr_bank_ring_base_write_8(sc, bank, ring, ring_base);
958f4f56ff4SMark Johnston
959f4f56ff4SMark Johnston if (sc->sc_hw.qhw_init_arb != NULL)
960f4f56ff4SMark Johnston qat_arb_update(sc, qb);
961f4f56ff4SMark Johnston
962f4f56ff4SMark Johnston mtx_init(&qr->qr_ring_mtx, "qr ring", NULL, MTX_DEF);
963f4f56ff4SMark Johnston
964f4f56ff4SMark Johnston qat_etr_ap_bank_setup_ring(sc, qr);
965f4f56ff4SMark Johnston
966f4f56ff4SMark Johnston if (cb != NULL) {
967f4f56ff4SMark Johnston uint32_t intr_mask;
968f4f56ff4SMark Johnston
969f4f56ff4SMark Johnston qb->qb_intr_mask |= qr->qr_ring_mask;
970f4f56ff4SMark Johnston intr_mask = qb->qb_intr_mask;
971f4f56ff4SMark Johnston
972f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, bank, ETR_INT_COL_EN, intr_mask);
973f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, bank, ETR_INT_COL_CTL,
974f4f56ff4SMark Johnston ETR_INT_COL_CTL_ENABLE | qb->qb_coalescing_time);
975f4f56ff4SMark Johnston }
976f4f56ff4SMark Johnston
977f4f56ff4SMark Johnston *rqr = qr;
978f4f56ff4SMark Johnston
979f4f56ff4SMark Johnston return 0;
980f4f56ff4SMark Johnston }
981f4f56ff4SMark Johnston
982f4f56ff4SMark Johnston static inline u_int
qat_modulo(u_int data,u_int shift)983f4f56ff4SMark Johnston qat_modulo(u_int data, u_int shift)
984f4f56ff4SMark Johnston {
985f4f56ff4SMark Johnston u_int div = data >> shift;
986f4f56ff4SMark Johnston u_int mult = div << shift;
987f4f56ff4SMark Johnston return data - mult;
988f4f56ff4SMark Johnston }
989f4f56ff4SMark Johnston
990f4f56ff4SMark Johnston int
qat_etr_put_msg(struct qat_softc * sc,struct qat_ring * qr,uint32_t * msg)991f4f56ff4SMark Johnston qat_etr_put_msg(struct qat_softc *sc, struct qat_ring *qr, uint32_t *msg)
992f4f56ff4SMark Johnston {
993f4f56ff4SMark Johnston uint32_t inflight;
994f4f56ff4SMark Johnston uint32_t *addr;
995f4f56ff4SMark Johnston
996f4f56ff4SMark Johnston mtx_lock(&qr->qr_ring_mtx);
997f4f56ff4SMark Johnston
998f4f56ff4SMark Johnston inflight = atomic_fetchadd_32(qr->qr_inflight, 1) + 1;
999f4f56ff4SMark Johnston if (inflight > QAT_MAX_INFLIGHTS(qr->qr_ring_size, qr->qr_msg_size)) {
1000f4f56ff4SMark Johnston atomic_subtract_32(qr->qr_inflight, 1);
1001f4f56ff4SMark Johnston qr->qr_need_wakeup = true;
1002f4f56ff4SMark Johnston mtx_unlock(&qr->qr_ring_mtx);
1003f4f56ff4SMark Johnston counter_u64_add(sc->sc_ring_full_restarts, 1);
1004f4f56ff4SMark Johnston return ERESTART;
1005f4f56ff4SMark Johnston }
1006f4f56ff4SMark Johnston
1007f4f56ff4SMark Johnston addr = (uint32_t *)((uintptr_t)qr->qr_ring_vaddr + qr->qr_tail);
1008f4f56ff4SMark Johnston
1009f4f56ff4SMark Johnston memcpy(addr, msg, QAT_MSG_SIZE_TO_BYTES(qr->qr_msg_size));
1010f4f56ff4SMark Johnston
1011f4f56ff4SMark Johnston bus_dmamap_sync(qr->qr_dma.qdm_dma_tag, qr->qr_dma.qdm_dma_map,
1012f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE);
1013f4f56ff4SMark Johnston
1014f4f56ff4SMark Johnston qr->qr_tail = qat_modulo(qr->qr_tail +
1015f4f56ff4SMark Johnston QAT_MSG_SIZE_TO_BYTES(qr->qr_msg_size),
1016f4f56ff4SMark Johnston QAT_RING_SIZE_MODULO(qr->qr_ring_size));
1017f4f56ff4SMark Johnston
1018f4f56ff4SMark Johnston qat_etr_bank_ring_write_4(sc, qr->qr_bank, qr->qr_ring,
1019f4f56ff4SMark Johnston ETR_RING_TAIL_OFFSET, qr->qr_tail);
1020f4f56ff4SMark Johnston
1021f4f56ff4SMark Johnston mtx_unlock(&qr->qr_ring_mtx);
1022f4f56ff4SMark Johnston
1023f4f56ff4SMark Johnston return 0;
1024f4f56ff4SMark Johnston }
1025f4f56ff4SMark Johnston
1026f4f56ff4SMark Johnston static int
qat_etr_ring_intr(struct qat_softc * sc,struct qat_bank * qb,struct qat_ring * qr)1027f4f56ff4SMark Johnston qat_etr_ring_intr(struct qat_softc *sc, struct qat_bank *qb,
1028f4f56ff4SMark Johnston struct qat_ring *qr)
1029f4f56ff4SMark Johnston {
1030f4f56ff4SMark Johnston uint32_t *msg, nmsg = 0;
1031f4f56ff4SMark Johnston int handled = 0;
1032f4f56ff4SMark Johnston bool blocked = false;
1033f4f56ff4SMark Johnston
1034f4f56ff4SMark Johnston mtx_lock(&qr->qr_ring_mtx);
1035f4f56ff4SMark Johnston
1036f4f56ff4SMark Johnston msg = (uint32_t *)((uintptr_t)qr->qr_ring_vaddr + qr->qr_head);
1037f4f56ff4SMark Johnston
1038f4f56ff4SMark Johnston bus_dmamap_sync(qr->qr_dma.qdm_dma_tag, qr->qr_dma.qdm_dma_map,
1039f4f56ff4SMark Johnston BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1040f4f56ff4SMark Johnston
1041f4f56ff4SMark Johnston while (atomic_load_32(msg) != ETR_RING_EMPTY_ENTRY_SIG) {
1042f4f56ff4SMark Johnston atomic_subtract_32(qr->qr_inflight, 1);
1043f4f56ff4SMark Johnston
1044f4f56ff4SMark Johnston if (qr->qr_cb != NULL) {
1045f4f56ff4SMark Johnston mtx_unlock(&qr->qr_ring_mtx);
1046f4f56ff4SMark Johnston handled |= qr->qr_cb(sc, qr->qr_cb_arg, msg);
1047f4f56ff4SMark Johnston mtx_lock(&qr->qr_ring_mtx);
1048f4f56ff4SMark Johnston }
1049f4f56ff4SMark Johnston
1050f4f56ff4SMark Johnston atomic_store_32(msg, ETR_RING_EMPTY_ENTRY_SIG);
1051f4f56ff4SMark Johnston
1052f4f56ff4SMark Johnston qr->qr_head = qat_modulo(qr->qr_head +
1053f4f56ff4SMark Johnston QAT_MSG_SIZE_TO_BYTES(qr->qr_msg_size),
1054f4f56ff4SMark Johnston QAT_RING_SIZE_MODULO(qr->qr_ring_size));
1055f4f56ff4SMark Johnston nmsg++;
1056f4f56ff4SMark Johnston
1057f4f56ff4SMark Johnston msg = (uint32_t *)((uintptr_t)qr->qr_ring_vaddr + qr->qr_head);
1058f4f56ff4SMark Johnston }
1059f4f56ff4SMark Johnston
1060f4f56ff4SMark Johnston bus_dmamap_sync(qr->qr_dma.qdm_dma_tag, qr->qr_dma.qdm_dma_map,
1061f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
1062f4f56ff4SMark Johnston
1063f4f56ff4SMark Johnston if (nmsg > 0) {
1064f4f56ff4SMark Johnston qat_etr_bank_ring_write_4(sc, qr->qr_bank, qr->qr_ring,
1065f4f56ff4SMark Johnston ETR_RING_HEAD_OFFSET, qr->qr_head);
1066f4f56ff4SMark Johnston if (qr->qr_need_wakeup) {
1067f4f56ff4SMark Johnston blocked = true;
1068f4f56ff4SMark Johnston qr->qr_need_wakeup = false;
1069f4f56ff4SMark Johnston }
1070f4f56ff4SMark Johnston }
1071f4f56ff4SMark Johnston
1072f4f56ff4SMark Johnston mtx_unlock(&qr->qr_ring_mtx);
1073f4f56ff4SMark Johnston
1074f4f56ff4SMark Johnston if (blocked)
1075f4f56ff4SMark Johnston crypto_unblock(sc->sc_crypto.qcy_cid, CRYPTO_SYMQ);
1076f4f56ff4SMark Johnston
1077f4f56ff4SMark Johnston return handled;
1078f4f56ff4SMark Johnston }
1079f4f56ff4SMark Johnston
1080f4f56ff4SMark Johnston static void
qat_etr_bank_intr(void * arg)1081f4f56ff4SMark Johnston qat_etr_bank_intr(void *arg)
1082f4f56ff4SMark Johnston {
1083f4f56ff4SMark Johnston struct qat_bank *qb = arg;
1084f4f56ff4SMark Johnston struct qat_softc *sc = qb->qb_sc;
1085f4f56ff4SMark Johnston uint32_t estat;
1086f4f56ff4SMark Johnston int i;
1087f4f56ff4SMark Johnston
1088f4f56ff4SMark Johnston mtx_lock(&qb->qb_bank_mtx);
1089f4f56ff4SMark Johnston
1090f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, qb->qb_bank, ETR_INT_COL_CTL, 0);
1091f4f56ff4SMark Johnston
1092f4f56ff4SMark Johnston /* Now handle all the responses */
1093f4f56ff4SMark Johnston estat = ~qat_etr_bank_read_4(sc, qb->qb_bank, ETR_E_STAT);
1094f4f56ff4SMark Johnston estat &= qb->qb_intr_mask;
1095f4f56ff4SMark Johnston
1096f4f56ff4SMark Johnston qat_etr_bank_write_4(sc, qb->qb_bank, ETR_INT_COL_CTL,
1097f4f56ff4SMark Johnston ETR_INT_COL_CTL_ENABLE | qb->qb_coalescing_time);
1098f4f56ff4SMark Johnston
1099f4f56ff4SMark Johnston mtx_unlock(&qb->qb_bank_mtx);
1100f4f56ff4SMark Johnston
1101f4f56ff4SMark Johnston while ((i = ffs(estat)) != 0) {
1102f4f56ff4SMark Johnston struct qat_ring *qr = &qb->qb_et_rings[--i];
1103f4f56ff4SMark Johnston estat &= ~(1 << i);
1104f4f56ff4SMark Johnston (void)qat_etr_ring_intr(sc, qb, qr);
1105f4f56ff4SMark Johnston }
1106f4f56ff4SMark Johnston }
1107f4f56ff4SMark Johnston
1108f4f56ff4SMark Johnston void
qat_arb_update(struct qat_softc * sc,struct qat_bank * qb)1109f4f56ff4SMark Johnston qat_arb_update(struct qat_softc *sc, struct qat_bank *qb)
1110f4f56ff4SMark Johnston {
1111f4f56ff4SMark Johnston
1112f4f56ff4SMark Johnston qat_arb_ringsrvarben_write_4(sc, qb->qb_bank,
1113f4f56ff4SMark Johnston qb->qb_allocated_rings & 0xff);
1114f4f56ff4SMark Johnston }
1115f4f56ff4SMark Johnston
1116f4f56ff4SMark Johnston static struct qat_sym_cookie *
qat_crypto_alloc_sym_cookie(struct qat_crypto_bank * qcb)1117f4f56ff4SMark Johnston qat_crypto_alloc_sym_cookie(struct qat_crypto_bank *qcb)
1118f4f56ff4SMark Johnston {
1119f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1120f4f56ff4SMark Johnston
1121f4f56ff4SMark Johnston mtx_lock(&qcb->qcb_bank_mtx);
1122f4f56ff4SMark Johnston
1123f4f56ff4SMark Johnston if (qcb->qcb_symck_free_count == 0) {
1124f4f56ff4SMark Johnston mtx_unlock(&qcb->qcb_bank_mtx);
1125f4f56ff4SMark Johnston return NULL;
1126f4f56ff4SMark Johnston }
1127f4f56ff4SMark Johnston
1128f4f56ff4SMark Johnston qsc = qcb->qcb_symck_free[--qcb->qcb_symck_free_count];
1129f4f56ff4SMark Johnston
1130f4f56ff4SMark Johnston mtx_unlock(&qcb->qcb_bank_mtx);
1131f4f56ff4SMark Johnston
1132f4f56ff4SMark Johnston return qsc;
1133f4f56ff4SMark Johnston }
1134f4f56ff4SMark Johnston
1135f4f56ff4SMark Johnston static void
qat_crypto_free_sym_cookie(struct qat_crypto_bank * qcb,struct qat_sym_cookie * qsc)1136f4f56ff4SMark Johnston qat_crypto_free_sym_cookie(struct qat_crypto_bank *qcb,
1137f4f56ff4SMark Johnston struct qat_sym_cookie *qsc)
1138f4f56ff4SMark Johnston {
1139f4f56ff4SMark Johnston explicit_bzero(qsc->qsc_iv_buf, EALG_MAX_BLOCK_LEN);
1140f4f56ff4SMark Johnston explicit_bzero(qsc->qsc_auth_res, QAT_SYM_HASH_BUFFER_LEN);
1141f4f56ff4SMark Johnston
1142f4f56ff4SMark Johnston mtx_lock(&qcb->qcb_bank_mtx);
1143f4f56ff4SMark Johnston qcb->qcb_symck_free[qcb->qcb_symck_free_count++] = qsc;
1144f4f56ff4SMark Johnston mtx_unlock(&qcb->qcb_bank_mtx);
1145f4f56ff4SMark Johnston }
1146f4f56ff4SMark Johnston
1147f4f56ff4SMark Johnston void
qat_memcpy_htobe64(void * dst,const void * src,size_t len)1148f4f56ff4SMark Johnston qat_memcpy_htobe64(void *dst, const void *src, size_t len)
1149f4f56ff4SMark Johnston {
1150f4f56ff4SMark Johnston uint64_t *dst0 = dst;
1151f4f56ff4SMark Johnston const uint64_t *src0 = src;
1152f4f56ff4SMark Johnston size_t i;
1153f4f56ff4SMark Johnston
1154f4f56ff4SMark Johnston MPASS(len % sizeof(*dst0) == 0);
1155f4f56ff4SMark Johnston
1156f4f56ff4SMark Johnston for (i = 0; i < len / sizeof(*dst0); i++)
1157f4f56ff4SMark Johnston *(dst0 + i) = htobe64(*(src0 + i));
1158f4f56ff4SMark Johnston }
1159f4f56ff4SMark Johnston
1160f4f56ff4SMark Johnston void
qat_memcpy_htobe32(void * dst,const void * src,size_t len)1161f4f56ff4SMark Johnston qat_memcpy_htobe32(void *dst, const void *src, size_t len)
1162f4f56ff4SMark Johnston {
1163f4f56ff4SMark Johnston uint32_t *dst0 = dst;
1164f4f56ff4SMark Johnston const uint32_t *src0 = src;
1165f4f56ff4SMark Johnston size_t i;
1166f4f56ff4SMark Johnston
1167f4f56ff4SMark Johnston MPASS(len % sizeof(*dst0) == 0);
1168f4f56ff4SMark Johnston
1169f4f56ff4SMark Johnston for (i = 0; i < len / sizeof(*dst0); i++)
1170f4f56ff4SMark Johnston *(dst0 + i) = htobe32(*(src0 + i));
1171f4f56ff4SMark Johnston }
1172f4f56ff4SMark Johnston
1173f4f56ff4SMark Johnston void
qat_memcpy_htobe(void * dst,const void * src,size_t len,uint32_t wordbyte)1174f4f56ff4SMark Johnston qat_memcpy_htobe(void *dst, const void *src, size_t len, uint32_t wordbyte)
1175f4f56ff4SMark Johnston {
1176f4f56ff4SMark Johnston switch (wordbyte) {
1177f4f56ff4SMark Johnston case 4:
1178f4f56ff4SMark Johnston qat_memcpy_htobe32(dst, src, len);
1179f4f56ff4SMark Johnston break;
1180f4f56ff4SMark Johnston case 8:
1181f4f56ff4SMark Johnston qat_memcpy_htobe64(dst, src, len);
1182f4f56ff4SMark Johnston break;
1183f4f56ff4SMark Johnston default:
1184f4f56ff4SMark Johnston panic("invalid word size %u", wordbyte);
1185f4f56ff4SMark Johnston }
1186f4f56ff4SMark Johnston }
1187f4f56ff4SMark Johnston
1188f4f56ff4SMark Johnston void
qat_crypto_gmac_precompute(const struct qat_crypto_desc * desc,const uint8_t * key,int klen,const struct qat_sym_hash_def * hash_def,uint8_t * state)1189f4f56ff4SMark Johnston qat_crypto_gmac_precompute(const struct qat_crypto_desc *desc,
1190f4f56ff4SMark Johnston const uint8_t *key, int klen, const struct qat_sym_hash_def *hash_def,
1191f4f56ff4SMark Johnston uint8_t *state)
1192f4f56ff4SMark Johnston {
1193f4f56ff4SMark Johnston uint32_t ks[4 * (RIJNDAEL_MAXNR + 1)];
1194f4f56ff4SMark Johnston char zeros[AES_BLOCK_LEN];
1195f4f56ff4SMark Johnston int rounds;
1196f4f56ff4SMark Johnston
1197f4f56ff4SMark Johnston memset(zeros, 0, sizeof(zeros));
1198f4f56ff4SMark Johnston rounds = rijndaelKeySetupEnc(ks, key, klen * NBBY);
1199f4f56ff4SMark Johnston rijndaelEncrypt(ks, rounds, zeros, state);
1200f4f56ff4SMark Johnston explicit_bzero(ks, sizeof(ks));
1201f4f56ff4SMark Johnston }
1202f4f56ff4SMark Johnston
1203f4f56ff4SMark Johnston void
qat_crypto_hmac_precompute(const struct qat_crypto_desc * desc,const uint8_t * key,int klen,const struct qat_sym_hash_def * hash_def,uint8_t * state1,uint8_t * state2)1204f4f56ff4SMark Johnston qat_crypto_hmac_precompute(const struct qat_crypto_desc *desc,
1205f4f56ff4SMark Johnston const uint8_t *key, int klen, const struct qat_sym_hash_def *hash_def,
1206f4f56ff4SMark Johnston uint8_t *state1, uint8_t *state2)
1207f4f56ff4SMark Johnston {
1208f4f56ff4SMark Johnston union authctx ctx;
1209f4f56ff4SMark Johnston const struct auth_hash *sah = hash_def->qshd_alg->qshai_sah;
1210f4f56ff4SMark Johnston uint32_t state_offset = hash_def->qshd_alg->qshai_state_offset;
1211f4f56ff4SMark Johnston uint32_t state_size = hash_def->qshd_alg->qshai_state_size;
1212f4f56ff4SMark Johnston uint32_t state_word = hash_def->qshd_alg->qshai_state_word;
1213f4f56ff4SMark Johnston
1214f4f56ff4SMark Johnston hmac_init_ipad(sah, key, klen, &ctx);
1215f4f56ff4SMark Johnston qat_memcpy_htobe(state1, (uint8_t *)&ctx + state_offset, state_size,
1216f4f56ff4SMark Johnston state_word);
1217f4f56ff4SMark Johnston hmac_init_opad(sah, key, klen, &ctx);
1218f4f56ff4SMark Johnston qat_memcpy_htobe(state2, (uint8_t *)&ctx + state_offset, state_size,
1219f4f56ff4SMark Johnston state_word);
1220f4f56ff4SMark Johnston explicit_bzero(&ctx, sizeof(ctx));
1221f4f56ff4SMark Johnston }
1222f4f56ff4SMark Johnston
1223f4f56ff4SMark Johnston static enum hw_cipher_algo
qat_aes_cipher_algo(int klen)1224f4f56ff4SMark Johnston qat_aes_cipher_algo(int klen)
1225f4f56ff4SMark Johnston {
1226f4f56ff4SMark Johnston switch (klen) {
1227f4f56ff4SMark Johnston case HW_AES_128_KEY_SZ:
1228f4f56ff4SMark Johnston return HW_CIPHER_ALGO_AES128;
1229f4f56ff4SMark Johnston case HW_AES_192_KEY_SZ:
1230f4f56ff4SMark Johnston return HW_CIPHER_ALGO_AES192;
1231f4f56ff4SMark Johnston case HW_AES_256_KEY_SZ:
1232f4f56ff4SMark Johnston return HW_CIPHER_ALGO_AES256;
1233f4f56ff4SMark Johnston default:
1234f4f56ff4SMark Johnston panic("invalid key length %d", klen);
1235f4f56ff4SMark Johnston }
1236f4f56ff4SMark Johnston }
1237f4f56ff4SMark Johnston
1238f4f56ff4SMark Johnston uint16_t
qat_crypto_load_cipher_session(const struct qat_crypto_desc * desc,const struct qat_session * qs)1239f4f56ff4SMark Johnston qat_crypto_load_cipher_session(const struct qat_crypto_desc *desc,
1240f4f56ff4SMark Johnston const struct qat_session *qs)
1241f4f56ff4SMark Johnston {
1242f4f56ff4SMark Johnston enum hw_cipher_algo algo;
1243f4f56ff4SMark Johnston enum hw_cipher_dir dir;
1244f4f56ff4SMark Johnston enum hw_cipher_convert key_convert;
1245f4f56ff4SMark Johnston enum hw_cipher_mode mode;
1246f4f56ff4SMark Johnston
1247f4f56ff4SMark Johnston dir = desc->qcd_cipher_dir;
1248f4f56ff4SMark Johnston key_convert = HW_CIPHER_NO_CONVERT;
1249f4f56ff4SMark Johnston mode = qs->qs_cipher_mode;
1250f4f56ff4SMark Johnston switch (mode) {
1251f4f56ff4SMark Johnston case HW_CIPHER_CBC_MODE:
1252f4f56ff4SMark Johnston case HW_CIPHER_XTS_MODE:
1253f4f56ff4SMark Johnston algo = qs->qs_cipher_algo;
1254f4f56ff4SMark Johnston
1255f4f56ff4SMark Johnston /*
1256f4f56ff4SMark Johnston * AES decrypt key needs to be reversed.
1257f4f56ff4SMark Johnston * Instead of reversing the key at session registration,
1258f4f56ff4SMark Johnston * it is instead reversed on-the-fly by setting the KEY_CONVERT
1259f4f56ff4SMark Johnston * bit here.
1260f4f56ff4SMark Johnston */
1261f4f56ff4SMark Johnston if (desc->qcd_cipher_dir == HW_CIPHER_DECRYPT)
1262f4f56ff4SMark Johnston key_convert = HW_CIPHER_KEY_CONVERT;
1263f4f56ff4SMark Johnston break;
1264f4f56ff4SMark Johnston case HW_CIPHER_CTR_MODE:
1265f4f56ff4SMark Johnston algo = qs->qs_cipher_algo;
1266f4f56ff4SMark Johnston dir = HW_CIPHER_ENCRYPT;
1267f4f56ff4SMark Johnston break;
1268f4f56ff4SMark Johnston default:
1269f4f56ff4SMark Johnston panic("unhandled cipher mode %d", mode);
1270f4f56ff4SMark Johnston break;
1271f4f56ff4SMark Johnston }
1272f4f56ff4SMark Johnston
1273f4f56ff4SMark Johnston return HW_CIPHER_CONFIG_BUILD(mode, algo, key_convert, dir);
1274f4f56ff4SMark Johnston }
1275f4f56ff4SMark Johnston
1276f4f56ff4SMark Johnston uint16_t
qat_crypto_load_auth_session(const struct qat_crypto_desc * desc,const struct qat_session * qs,const struct qat_sym_hash_def ** hash_def)1277f4f56ff4SMark Johnston qat_crypto_load_auth_session(const struct qat_crypto_desc *desc,
1278f4f56ff4SMark Johnston const struct qat_session *qs, const struct qat_sym_hash_def **hash_def)
1279f4f56ff4SMark Johnston {
1280f4f56ff4SMark Johnston enum qat_sym_hash_algorithm algo;
1281f4f56ff4SMark Johnston
1282f4f56ff4SMark Johnston switch (qs->qs_auth_algo) {
1283f4f56ff4SMark Johnston case HW_AUTH_ALGO_SHA1:
1284f4f56ff4SMark Johnston algo = QAT_SYM_HASH_SHA1;
1285f4f56ff4SMark Johnston break;
1286f4f56ff4SMark Johnston case HW_AUTH_ALGO_SHA256:
1287f4f56ff4SMark Johnston algo = QAT_SYM_HASH_SHA256;
1288f4f56ff4SMark Johnston break;
1289f4f56ff4SMark Johnston case HW_AUTH_ALGO_SHA384:
1290f4f56ff4SMark Johnston algo = QAT_SYM_HASH_SHA384;
1291f4f56ff4SMark Johnston break;
1292f4f56ff4SMark Johnston case HW_AUTH_ALGO_SHA512:
1293f4f56ff4SMark Johnston algo = QAT_SYM_HASH_SHA512;
1294f4f56ff4SMark Johnston break;
1295f4f56ff4SMark Johnston case HW_AUTH_ALGO_GALOIS_128:
1296f4f56ff4SMark Johnston algo = QAT_SYM_HASH_AES_GCM;
1297f4f56ff4SMark Johnston break;
1298f4f56ff4SMark Johnston default:
1299f4f56ff4SMark Johnston panic("unhandled auth algorithm %d", qs->qs_auth_algo);
1300f4f56ff4SMark Johnston break;
1301f4f56ff4SMark Johnston }
1302f4f56ff4SMark Johnston *hash_def = &qat_sym_hash_defs[algo];
1303f4f56ff4SMark Johnston
1304f4f56ff4SMark Johnston return HW_AUTH_CONFIG_BUILD(qs->qs_auth_mode,
1305f4f56ff4SMark Johnston (*hash_def)->qshd_qat->qshqi_algo_enc,
1306f4f56ff4SMark Johnston (*hash_def)->qshd_alg->qshai_digest_len);
1307f4f56ff4SMark Johnston }
1308f4f56ff4SMark Johnston
1309f4f56ff4SMark Johnston struct qat_crypto_load_cb_arg {
1310f4f56ff4SMark Johnston struct qat_session *qs;
1311f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1312f4f56ff4SMark Johnston struct cryptop *crp;
1313f4f56ff4SMark Johnston int error;
1314f4f56ff4SMark Johnston };
1315f4f56ff4SMark Johnston
1316f4f56ff4SMark Johnston static int
qat_crypto_populate_buf_list(struct buffer_list_desc * buffers,bus_dma_segment_t * segs,int niseg,int noseg,int skip)1317f4f56ff4SMark Johnston qat_crypto_populate_buf_list(struct buffer_list_desc *buffers,
1318f4f56ff4SMark Johnston bus_dma_segment_t *segs, int niseg, int noseg, int skip)
1319f4f56ff4SMark Johnston {
1320f4f56ff4SMark Johnston struct flat_buffer_desc *flatbuf;
1321f4f56ff4SMark Johnston bus_addr_t addr;
1322f4f56ff4SMark Johnston bus_size_t len;
1323f4f56ff4SMark Johnston int iseg, oseg;
1324f4f56ff4SMark Johnston
1325f4f56ff4SMark Johnston for (iseg = 0, oseg = noseg; iseg < niseg && oseg < QAT_MAXSEG;
1326f4f56ff4SMark Johnston iseg++) {
1327f4f56ff4SMark Johnston addr = segs[iseg].ds_addr;
1328f4f56ff4SMark Johnston len = segs[iseg].ds_len;
1329f4f56ff4SMark Johnston
1330f4f56ff4SMark Johnston if (skip > 0) {
1331f4f56ff4SMark Johnston if (skip < len) {
1332f4f56ff4SMark Johnston addr += skip;
1333f4f56ff4SMark Johnston len -= skip;
1334f4f56ff4SMark Johnston skip = 0;
1335f4f56ff4SMark Johnston } else {
1336f4f56ff4SMark Johnston skip -= len;
1337f4f56ff4SMark Johnston continue;
1338f4f56ff4SMark Johnston }
1339f4f56ff4SMark Johnston }
1340f4f56ff4SMark Johnston
1341f4f56ff4SMark Johnston flatbuf = &buffers->flat_bufs[oseg++];
1342f4f56ff4SMark Johnston flatbuf->data_len_in_bytes = (uint32_t)len;
1343f4f56ff4SMark Johnston flatbuf->phy_buffer = (uint64_t)addr;
1344f4f56ff4SMark Johnston }
1345f4f56ff4SMark Johnston buffers->num_buffers = oseg;
1346f4f56ff4SMark Johnston return iseg < niseg ? E2BIG : 0;
1347f4f56ff4SMark Johnston }
1348f4f56ff4SMark Johnston
1349f4f56ff4SMark Johnston static void
qat_crypto_load_aadbuf_cb(void * _arg,bus_dma_segment_t * segs,int nseg,int error)1350f4f56ff4SMark Johnston qat_crypto_load_aadbuf_cb(void *_arg, bus_dma_segment_t *segs, int nseg,
1351f4f56ff4SMark Johnston int error)
1352f4f56ff4SMark Johnston {
1353f4f56ff4SMark Johnston struct qat_crypto_load_cb_arg *arg;
1354f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1355f4f56ff4SMark Johnston
1356f4f56ff4SMark Johnston arg = _arg;
1357f4f56ff4SMark Johnston if (error != 0) {
1358f4f56ff4SMark Johnston arg->error = error;
1359f4f56ff4SMark Johnston return;
1360f4f56ff4SMark Johnston }
1361f4f56ff4SMark Johnston
1362f4f56ff4SMark Johnston qsc = arg->qsc;
1363f4f56ff4SMark Johnston arg->error = qat_crypto_populate_buf_list(&qsc->qsc_buf_list, segs,
1364f4f56ff4SMark Johnston nseg, 0, 0);
1365f4f56ff4SMark Johnston }
1366f4f56ff4SMark Johnston
1367f4f56ff4SMark Johnston static void
qat_crypto_load_buf_cb(void * _arg,bus_dma_segment_t * segs,int nseg,int error)1368f4f56ff4SMark Johnston qat_crypto_load_buf_cb(void *_arg, bus_dma_segment_t *segs, int nseg,
1369f4f56ff4SMark Johnston int error)
1370f4f56ff4SMark Johnston {
1371f4f56ff4SMark Johnston struct cryptop *crp;
1372f4f56ff4SMark Johnston struct qat_crypto_load_cb_arg *arg;
1373f4f56ff4SMark Johnston struct qat_session *qs;
1374f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1375f4f56ff4SMark Johnston int noseg, skip;
1376f4f56ff4SMark Johnston
1377f4f56ff4SMark Johnston arg = _arg;
1378f4f56ff4SMark Johnston if (error != 0) {
1379f4f56ff4SMark Johnston arg->error = error;
1380f4f56ff4SMark Johnston return;
1381f4f56ff4SMark Johnston }
1382f4f56ff4SMark Johnston
1383f4f56ff4SMark Johnston crp = arg->crp;
1384f4f56ff4SMark Johnston qs = arg->qs;
1385f4f56ff4SMark Johnston qsc = arg->qsc;
1386f4f56ff4SMark Johnston
1387f4f56ff4SMark Johnston if (qs->qs_auth_algo == HW_AUTH_ALGO_GALOIS_128) {
1388f4f56ff4SMark Johnston /* AAD was handled in qat_crypto_load(). */
1389f4f56ff4SMark Johnston skip = crp->crp_payload_start;
1390f4f56ff4SMark Johnston noseg = 0;
1391f4f56ff4SMark Johnston } else if (crp->crp_aad == NULL && crp->crp_aad_length > 0) {
1392f4f56ff4SMark Johnston skip = crp->crp_aad_start;
1393f4f56ff4SMark Johnston noseg = 0;
1394f4f56ff4SMark Johnston } else {
1395f4f56ff4SMark Johnston skip = crp->crp_payload_start;
1396f4f56ff4SMark Johnston noseg = crp->crp_aad == NULL ?
1397f4f56ff4SMark Johnston 0 : qsc->qsc_buf_list.num_buffers;
1398f4f56ff4SMark Johnston }
1399f4f56ff4SMark Johnston arg->error = qat_crypto_populate_buf_list(&qsc->qsc_buf_list, segs,
1400f4f56ff4SMark Johnston nseg, noseg, skip);
1401f4f56ff4SMark Johnston }
1402f4f56ff4SMark Johnston
1403f4f56ff4SMark Johnston static void
qat_crypto_load_obuf_cb(void * _arg,bus_dma_segment_t * segs,int nseg,int error)1404f4f56ff4SMark Johnston qat_crypto_load_obuf_cb(void *_arg, bus_dma_segment_t *segs, int nseg,
1405f4f56ff4SMark Johnston int error)
1406f4f56ff4SMark Johnston {
1407f4f56ff4SMark Johnston struct buffer_list_desc *ibufs, *obufs;
1408f4f56ff4SMark Johnston struct flat_buffer_desc *ibuf, *obuf;
1409f4f56ff4SMark Johnston struct cryptop *crp;
1410f4f56ff4SMark Johnston struct qat_crypto_load_cb_arg *arg;
1411f4f56ff4SMark Johnston struct qat_session *qs;
1412f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1413f4f56ff4SMark Johnston int buflen, osegs, tocopy;
1414f4f56ff4SMark Johnston
1415f4f56ff4SMark Johnston arg = _arg;
1416f4f56ff4SMark Johnston if (error != 0) {
1417f4f56ff4SMark Johnston arg->error = error;
1418f4f56ff4SMark Johnston return;
1419f4f56ff4SMark Johnston }
1420f4f56ff4SMark Johnston
1421f4f56ff4SMark Johnston crp = arg->crp;
1422f4f56ff4SMark Johnston qs = arg->qs;
1423f4f56ff4SMark Johnston qsc = arg->qsc;
1424f4f56ff4SMark Johnston
1425f4f56ff4SMark Johnston /*
1426f4f56ff4SMark Johnston * The payload must start at the same offset in the output SG list as in
1427f4f56ff4SMark Johnston * the input SG list. Copy over SG entries from the input corresponding
1428f4f56ff4SMark Johnston * to the AAD buffer.
1429f4f56ff4SMark Johnston */
1430f4f56ff4SMark Johnston osegs = 0;
1431f4f56ff4SMark Johnston if (qs->qs_auth_algo != HW_AUTH_ALGO_GALOIS_128 &&
1432f4f56ff4SMark Johnston crp->crp_aad_length > 0) {
1433f4f56ff4SMark Johnston tocopy = crp->crp_aad == NULL ?
1434f4f56ff4SMark Johnston crp->crp_payload_start - crp->crp_aad_start :
1435f4f56ff4SMark Johnston crp->crp_aad_length;
1436f4f56ff4SMark Johnston
1437f4f56ff4SMark Johnston ibufs = &qsc->qsc_buf_list;
1438f4f56ff4SMark Johnston obufs = &qsc->qsc_obuf_list;
1439f4f56ff4SMark Johnston for (; osegs < ibufs->num_buffers && tocopy > 0; osegs++) {
1440f4f56ff4SMark Johnston ibuf = &ibufs->flat_bufs[osegs];
1441f4f56ff4SMark Johnston obuf = &obufs->flat_bufs[osegs];
1442f4f56ff4SMark Johnston
1443f4f56ff4SMark Johnston obuf->phy_buffer = ibuf->phy_buffer;
1444f4f56ff4SMark Johnston buflen = imin(ibuf->data_len_in_bytes, tocopy);
1445f4f56ff4SMark Johnston obuf->data_len_in_bytes = buflen;
1446f4f56ff4SMark Johnston tocopy -= buflen;
1447f4f56ff4SMark Johnston }
1448f4f56ff4SMark Johnston }
1449f4f56ff4SMark Johnston
1450f4f56ff4SMark Johnston arg->error = qat_crypto_populate_buf_list(&qsc->qsc_obuf_list, segs,
1451f4f56ff4SMark Johnston nseg, osegs, crp->crp_payload_output_start);
1452f4f56ff4SMark Johnston }
1453f4f56ff4SMark Johnston
1454f4f56ff4SMark Johnston static int
qat_crypto_load(struct qat_session * qs,struct qat_sym_cookie * qsc,struct qat_crypto_desc const * desc,struct cryptop * crp)1455f4f56ff4SMark Johnston qat_crypto_load(struct qat_session *qs, struct qat_sym_cookie *qsc,
1456f4f56ff4SMark Johnston struct qat_crypto_desc const *desc, struct cryptop *crp)
1457f4f56ff4SMark Johnston {
1458f4f56ff4SMark Johnston struct qat_crypto_load_cb_arg arg;
1459f4f56ff4SMark Johnston int error;
1460f4f56ff4SMark Johnston
1461f4f56ff4SMark Johnston crypto_read_iv(crp, qsc->qsc_iv_buf);
1462f4f56ff4SMark Johnston
1463f4f56ff4SMark Johnston arg.crp = crp;
1464f4f56ff4SMark Johnston arg.qs = qs;
1465f4f56ff4SMark Johnston arg.qsc = qsc;
1466f4f56ff4SMark Johnston arg.error = 0;
1467f4f56ff4SMark Johnston
1468f4f56ff4SMark Johnston error = 0;
1469f4f56ff4SMark Johnston if (qs->qs_auth_algo == HW_AUTH_ALGO_GALOIS_128 &&
1470f4f56ff4SMark Johnston crp->crp_aad_length > 0) {
1471f4f56ff4SMark Johnston /*
1472f4f56ff4SMark Johnston * The firmware expects AAD to be in a contiguous buffer and
1473f4f56ff4SMark Johnston * padded to a multiple of 16 bytes. To satisfy these
1474f4f56ff4SMark Johnston * constraints we bounce the AAD into a per-request buffer.
1475f4f56ff4SMark Johnston * There is a small limit on the AAD size so this is not too
1476f4f56ff4SMark Johnston * onerous.
1477f4f56ff4SMark Johnston */
1478f4f56ff4SMark Johnston memset(qsc->qsc_gcm_aad, 0, QAT_GCM_AAD_SIZE_MAX);
1479f4f56ff4SMark Johnston if (crp->crp_aad == NULL) {
1480f4f56ff4SMark Johnston crypto_copydata(crp, crp->crp_aad_start,
1481f4f56ff4SMark Johnston crp->crp_aad_length, qsc->qsc_gcm_aad);
1482f4f56ff4SMark Johnston } else {
1483f4f56ff4SMark Johnston memcpy(qsc->qsc_gcm_aad, crp->crp_aad,
1484f4f56ff4SMark Johnston crp->crp_aad_length);
1485f4f56ff4SMark Johnston }
1486f4f56ff4SMark Johnston } else if (crp->crp_aad != NULL) {
1487f4f56ff4SMark Johnston error = bus_dmamap_load(
1488f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_AADBUF].qsd_dma_tag,
1489f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_AADBUF].qsd_dmamap,
1490f4f56ff4SMark Johnston crp->crp_aad, crp->crp_aad_length,
1491f4f56ff4SMark Johnston qat_crypto_load_aadbuf_cb, &arg, BUS_DMA_NOWAIT);
1492f4f56ff4SMark Johnston if (error == 0)
1493f4f56ff4SMark Johnston error = arg.error;
1494f4f56ff4SMark Johnston }
1495f4f56ff4SMark Johnston if (error == 0) {
1496f4f56ff4SMark Johnston error = bus_dmamap_load_crp_buffer(
1497f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_BUF].qsd_dma_tag,
1498f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_BUF].qsd_dmamap,
1499f4f56ff4SMark Johnston &crp->crp_buf, qat_crypto_load_buf_cb, &arg,
1500f4f56ff4SMark Johnston BUS_DMA_NOWAIT);
1501f4f56ff4SMark Johnston if (error == 0)
1502f4f56ff4SMark Johnston error = arg.error;
1503f4f56ff4SMark Johnston }
1504f4f56ff4SMark Johnston if (error == 0 && CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
1505f4f56ff4SMark Johnston error = bus_dmamap_load_crp_buffer(
1506f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_OBUF].qsd_dma_tag,
1507f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_OBUF].qsd_dmamap,
1508f4f56ff4SMark Johnston &crp->crp_obuf, qat_crypto_load_obuf_cb, &arg,
1509f4f56ff4SMark Johnston BUS_DMA_NOWAIT);
1510f4f56ff4SMark Johnston if (error == 0)
1511f4f56ff4SMark Johnston error = arg.error;
1512f4f56ff4SMark Johnston }
1513f4f56ff4SMark Johnston return error;
1514f4f56ff4SMark Johnston }
1515f4f56ff4SMark Johnston
1516f4f56ff4SMark Johnston static inline struct qat_crypto_bank *
qat_crypto_select_bank(struct qat_crypto * qcy)1517f4f56ff4SMark Johnston qat_crypto_select_bank(struct qat_crypto *qcy)
1518f4f56ff4SMark Johnston {
1519f4f56ff4SMark Johnston u_int cpuid = PCPU_GET(cpuid);
1520f4f56ff4SMark Johnston
1521f4f56ff4SMark Johnston return &qcy->qcy_banks[cpuid % qcy->qcy_num_banks];
1522f4f56ff4SMark Johnston }
1523f4f56ff4SMark Johnston
1524f4f56ff4SMark Johnston static int
qat_crypto_setup_ring(struct qat_softc * sc,struct qat_crypto_bank * qcb)1525f4f56ff4SMark Johnston qat_crypto_setup_ring(struct qat_softc *sc, struct qat_crypto_bank *qcb)
1526f4f56ff4SMark Johnston {
1527f4f56ff4SMark Johnston char *name;
1528f4f56ff4SMark Johnston int bank, curname, error, i, j;
1529f4f56ff4SMark Johnston
1530f4f56ff4SMark Johnston bank = qcb->qcb_bank;
1531f4f56ff4SMark Johnston curname = 0;
1532f4f56ff4SMark Johnston
1533f4f56ff4SMark Johnston name = qcb->qcb_ring_names[curname++];
1534f4f56ff4SMark Johnston snprintf(name, QAT_RING_NAME_SIZE, "bank%d sym_tx", bank);
1535f4f56ff4SMark Johnston error = qat_etr_setup_ring(sc, qcb->qcb_bank,
1536f4f56ff4SMark Johnston sc->sc_hw.qhw_ring_sym_tx, QAT_NSYMREQ, sc->sc_hw.qhw_fw_req_size,
1537f4f56ff4SMark Johnston NULL, NULL, name, &qcb->qcb_sym_tx);
1538f4f56ff4SMark Johnston if (error)
1539f4f56ff4SMark Johnston return error;
1540f4f56ff4SMark Johnston
1541f4f56ff4SMark Johnston name = qcb->qcb_ring_names[curname++];
1542f4f56ff4SMark Johnston snprintf(name, QAT_RING_NAME_SIZE, "bank%d sym_rx", bank);
1543f4f56ff4SMark Johnston error = qat_etr_setup_ring(sc, qcb->qcb_bank,
1544f4f56ff4SMark Johnston sc->sc_hw.qhw_ring_sym_rx, QAT_NSYMREQ, sc->sc_hw.qhw_fw_resp_size,
1545f4f56ff4SMark Johnston qat_crypto_sym_rxintr, qcb, name, &qcb->qcb_sym_rx);
1546f4f56ff4SMark Johnston if (error)
1547f4f56ff4SMark Johnston return error;
1548f4f56ff4SMark Johnston
1549f4f56ff4SMark Johnston for (i = 0; i < QAT_NSYMCOOKIE; i++) {
1550f4f56ff4SMark Johnston struct qat_dmamem *qdm = &qcb->qcb_symck_dmamems[i];
1551f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1552f4f56ff4SMark Johnston
1553f4f56ff4SMark Johnston error = qat_alloc_dmamem(sc, qdm, 1,
1554f4f56ff4SMark Johnston sizeof(struct qat_sym_cookie), QAT_OPTIMAL_ALIGN);
1555f4f56ff4SMark Johnston if (error)
1556f4f56ff4SMark Johnston return error;
1557f4f56ff4SMark Johnston
1558f4f56ff4SMark Johnston qsc = qdm->qdm_dma_vaddr;
1559f4f56ff4SMark Johnston qsc->qsc_self_dmamap = qdm->qdm_dma_map;
1560f4f56ff4SMark Johnston qsc->qsc_self_dma_tag = qdm->qdm_dma_tag;
1561f4f56ff4SMark Johnston qsc->qsc_bulk_req_params_buf_paddr =
1562f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1563f4f56ff4SMark Johnston qsc_bulk_cookie.qsbc_req_params_buf);
1564f4f56ff4SMark Johnston qsc->qsc_buffer_list_desc_paddr =
1565f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1566f4f56ff4SMark Johnston qsc_buf_list);
1567f4f56ff4SMark Johnston qsc->qsc_obuffer_list_desc_paddr =
1568f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1569f4f56ff4SMark Johnston qsc_obuf_list);
1570f4f56ff4SMark Johnston qsc->qsc_obuffer_list_desc_paddr =
1571f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1572f4f56ff4SMark Johnston qsc_obuf_list);
1573f4f56ff4SMark Johnston qsc->qsc_iv_buf_paddr =
1574f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1575f4f56ff4SMark Johnston qsc_iv_buf);
1576f4f56ff4SMark Johnston qsc->qsc_auth_res_paddr =
1577f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1578f4f56ff4SMark Johnston qsc_auth_res);
1579f4f56ff4SMark Johnston qsc->qsc_gcm_aad_paddr =
1580f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1581f4f56ff4SMark Johnston qsc_gcm_aad);
1582f4f56ff4SMark Johnston qsc->qsc_content_desc_paddr =
1583f4f56ff4SMark Johnston qdm->qdm_dma_seg.ds_addr + offsetof(struct qat_sym_cookie,
1584f4f56ff4SMark Johnston qsc_content_desc);
1585f4f56ff4SMark Johnston qcb->qcb_symck_free[i] = qsc;
1586f4f56ff4SMark Johnston qcb->qcb_symck_free_count++;
1587f4f56ff4SMark Johnston
1588f4f56ff4SMark Johnston for (j = 0; j < QAT_SYM_DMA_COUNT; j++) {
1589f4f56ff4SMark Johnston error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev),
1590f4f56ff4SMark Johnston 1, 0, /* alignment, boundary */
1591f4f56ff4SMark Johnston BUS_SPACE_MAXADDR, /* lowaddr */
1592f4f56ff4SMark Johnston BUS_SPACE_MAXADDR, /* highaddr */
1593f4f56ff4SMark Johnston NULL, NULL, /* filter, filterarg */
1594f4f56ff4SMark Johnston QAT_MAXLEN, /* maxsize */
1595f4f56ff4SMark Johnston QAT_MAXSEG, /* nsegments */
1596f4f56ff4SMark Johnston QAT_MAXLEN, /* maxsegsize */
1597f4f56ff4SMark Johnston BUS_DMA_COHERENT, /* flags */
1598f4f56ff4SMark Johnston NULL, NULL, /* lockfunc, lockarg */
1599f4f56ff4SMark Johnston &qsc->qsc_dma[j].qsd_dma_tag);
1600f4f56ff4SMark Johnston if (error != 0)
1601f4f56ff4SMark Johnston return error;
1602f4f56ff4SMark Johnston error = bus_dmamap_create(qsc->qsc_dma[j].qsd_dma_tag,
1603f4f56ff4SMark Johnston BUS_DMA_COHERENT, &qsc->qsc_dma[j].qsd_dmamap);
1604f4f56ff4SMark Johnston if (error != 0)
1605f4f56ff4SMark Johnston return error;
1606f4f56ff4SMark Johnston }
1607f4f56ff4SMark Johnston }
1608f4f56ff4SMark Johnston
1609f4f56ff4SMark Johnston return 0;
1610f4f56ff4SMark Johnston }
1611f4f56ff4SMark Johnston
1612f4f56ff4SMark Johnston static int
qat_crypto_bank_init(struct qat_softc * sc,struct qat_crypto_bank * qcb)1613f4f56ff4SMark Johnston qat_crypto_bank_init(struct qat_softc *sc, struct qat_crypto_bank *qcb)
1614f4f56ff4SMark Johnston {
1615f4f56ff4SMark Johnston mtx_init(&qcb->qcb_bank_mtx, "qcb bank", NULL, MTX_DEF);
1616f4f56ff4SMark Johnston
1617f4f56ff4SMark Johnston return qat_crypto_setup_ring(sc, qcb);
1618f4f56ff4SMark Johnston }
1619f4f56ff4SMark Johnston
1620f4f56ff4SMark Johnston static void
qat_crypto_bank_deinit(struct qat_softc * sc,struct qat_crypto_bank * qcb)1621f4f56ff4SMark Johnston qat_crypto_bank_deinit(struct qat_softc *sc, struct qat_crypto_bank *qcb)
1622f4f56ff4SMark Johnston {
1623f4f56ff4SMark Johnston struct qat_dmamem *qdm;
1624f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1625f4f56ff4SMark Johnston int i, j;
1626f4f56ff4SMark Johnston
1627f4f56ff4SMark Johnston for (i = 0; i < QAT_NSYMCOOKIE; i++) {
1628f4f56ff4SMark Johnston qdm = &qcb->qcb_symck_dmamems[i];
1629f4f56ff4SMark Johnston qsc = qcb->qcb_symck_free[i];
1630f4f56ff4SMark Johnston for (j = 0; j < QAT_SYM_DMA_COUNT; j++) {
1631f4f56ff4SMark Johnston bus_dmamap_destroy(qsc->qsc_dma[j].qsd_dma_tag,
1632f4f56ff4SMark Johnston qsc->qsc_dma[j].qsd_dmamap);
1633f4f56ff4SMark Johnston bus_dma_tag_destroy(qsc->qsc_dma[j].qsd_dma_tag);
1634f4f56ff4SMark Johnston }
1635f4f56ff4SMark Johnston qat_free_dmamem(sc, qdm);
1636f4f56ff4SMark Johnston }
1637f4f56ff4SMark Johnston qat_free_dmamem(sc, &qcb->qcb_sym_tx->qr_dma);
1638f4f56ff4SMark Johnston qat_free_dmamem(sc, &qcb->qcb_sym_rx->qr_dma);
1639f4f56ff4SMark Johnston
1640f4f56ff4SMark Johnston mtx_destroy(&qcb->qcb_bank_mtx);
1641f4f56ff4SMark Johnston }
1642f4f56ff4SMark Johnston
1643f4f56ff4SMark Johnston static int
qat_crypto_init(struct qat_softc * sc)1644f4f56ff4SMark Johnston qat_crypto_init(struct qat_softc *sc)
1645f4f56ff4SMark Johnston {
1646f4f56ff4SMark Johnston struct qat_crypto *qcy = &sc->sc_crypto;
1647f4f56ff4SMark Johnston struct sysctl_ctx_list *ctx;
1648f4f56ff4SMark Johnston struct sysctl_oid *oid;
1649f4f56ff4SMark Johnston struct sysctl_oid_list *children;
1650f4f56ff4SMark Johnston int bank, error, num_banks;
1651f4f56ff4SMark Johnston
1652f4f56ff4SMark Johnston qcy->qcy_sc = sc;
1653f4f56ff4SMark Johnston
1654f4f56ff4SMark Johnston if (sc->sc_hw.qhw_init_arb != NULL)
1655f4f56ff4SMark Johnston num_banks = imin(mp_ncpus, sc->sc_hw.qhw_num_banks);
1656f4f56ff4SMark Johnston else
1657f4f56ff4SMark Johnston num_banks = sc->sc_ae_num;
1658f4f56ff4SMark Johnston
1659f4f56ff4SMark Johnston qcy->qcy_num_banks = num_banks;
1660f4f56ff4SMark Johnston
1661f4f56ff4SMark Johnston qcy->qcy_banks =
1662f4f56ff4SMark Johnston qat_alloc_mem(sizeof(struct qat_crypto_bank) * num_banks);
1663f4f56ff4SMark Johnston
1664f4f56ff4SMark Johnston for (bank = 0; bank < num_banks; bank++) {
1665f4f56ff4SMark Johnston struct qat_crypto_bank *qcb = &qcy->qcy_banks[bank];
1666f4f56ff4SMark Johnston qcb->qcb_bank = bank;
1667f4f56ff4SMark Johnston error = qat_crypto_bank_init(sc, qcb);
1668f4f56ff4SMark Johnston if (error)
1669f4f56ff4SMark Johnston return error;
1670f4f56ff4SMark Johnston }
1671f4f56ff4SMark Johnston
1672f4f56ff4SMark Johnston mtx_init(&qcy->qcy_crypto_mtx, "qcy crypto", NULL, MTX_DEF);
1673f4f56ff4SMark Johnston
1674f4f56ff4SMark Johnston ctx = device_get_sysctl_ctx(sc->sc_dev);
1675f4f56ff4SMark Johnston oid = device_get_sysctl_tree(sc->sc_dev);
1676f4f56ff4SMark Johnston children = SYSCTL_CHILDREN(oid);
1677f4f56ff4SMark Johnston oid = SYSCTL_ADD_NODE(ctx, children, OID_AUTO, "stats",
1678f4f56ff4SMark Johnston CTLFLAG_RD | CTLFLAG_MPSAFE, NULL, "statistics");
1679f4f56ff4SMark Johnston children = SYSCTL_CHILDREN(oid);
1680f4f56ff4SMark Johnston
1681f4f56ff4SMark Johnston sc->sc_gcm_aad_restarts = counter_u64_alloc(M_WAITOK);
1682f4f56ff4SMark Johnston SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "gcm_aad_restarts",
1683f4f56ff4SMark Johnston CTLFLAG_RD, &sc->sc_gcm_aad_restarts,
1684f4f56ff4SMark Johnston "GCM requests deferred due to AAD size change");
1685f4f56ff4SMark Johnston sc->sc_gcm_aad_updates = counter_u64_alloc(M_WAITOK);
1686f4f56ff4SMark Johnston SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "gcm_aad_updates",
1687f4f56ff4SMark Johnston CTLFLAG_RD, &sc->sc_gcm_aad_updates,
1688f4f56ff4SMark Johnston "GCM requests that required session state update");
1689f4f56ff4SMark Johnston sc->sc_ring_full_restarts = counter_u64_alloc(M_WAITOK);
1690f4f56ff4SMark Johnston SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "ring_full",
1691f4f56ff4SMark Johnston CTLFLAG_RD, &sc->sc_ring_full_restarts,
1692f4f56ff4SMark Johnston "Requests deferred due to in-flight max reached");
1693f4f56ff4SMark Johnston sc->sc_sym_alloc_failures = counter_u64_alloc(M_WAITOK);
1694f4f56ff4SMark Johnston SYSCTL_ADD_COUNTER_U64(ctx, children, OID_AUTO, "sym_alloc_failures",
1695f4f56ff4SMark Johnston CTLFLAG_RD, &sc->sc_sym_alloc_failures,
1696f4f56ff4SMark Johnston "Request allocation failures");
1697f4f56ff4SMark Johnston
1698f4f56ff4SMark Johnston return 0;
1699f4f56ff4SMark Johnston }
1700f4f56ff4SMark Johnston
1701f4f56ff4SMark Johnston static void
qat_crypto_deinit(struct qat_softc * sc)1702f4f56ff4SMark Johnston qat_crypto_deinit(struct qat_softc *sc)
1703f4f56ff4SMark Johnston {
1704f4f56ff4SMark Johnston struct qat_crypto *qcy = &sc->sc_crypto;
1705f4f56ff4SMark Johnston struct qat_crypto_bank *qcb;
1706f4f56ff4SMark Johnston int bank;
1707f4f56ff4SMark Johnston
1708f4f56ff4SMark Johnston counter_u64_free(sc->sc_sym_alloc_failures);
1709f4f56ff4SMark Johnston counter_u64_free(sc->sc_ring_full_restarts);
1710f4f56ff4SMark Johnston counter_u64_free(sc->sc_gcm_aad_updates);
1711f4f56ff4SMark Johnston counter_u64_free(sc->sc_gcm_aad_restarts);
1712f4f56ff4SMark Johnston
1713f4f56ff4SMark Johnston if (qcy->qcy_banks != NULL) {
1714f4f56ff4SMark Johnston for (bank = 0; bank < qcy->qcy_num_banks; bank++) {
1715f4f56ff4SMark Johnston qcb = &qcy->qcy_banks[bank];
1716f4f56ff4SMark Johnston qat_crypto_bank_deinit(sc, qcb);
1717f4f56ff4SMark Johnston }
1718f4f56ff4SMark Johnston qat_free_mem(qcy->qcy_banks);
1719f4f56ff4SMark Johnston mtx_destroy(&qcy->qcy_crypto_mtx);
1720f4f56ff4SMark Johnston }
1721f4f56ff4SMark Johnston }
1722f4f56ff4SMark Johnston
1723f4f56ff4SMark Johnston static int
qat_crypto_start(struct qat_softc * sc)1724f4f56ff4SMark Johnston qat_crypto_start(struct qat_softc *sc)
1725f4f56ff4SMark Johnston {
1726f4f56ff4SMark Johnston struct qat_crypto *qcy;
1727f4f56ff4SMark Johnston
1728f4f56ff4SMark Johnston qcy = &sc->sc_crypto;
1729f4f56ff4SMark Johnston qcy->qcy_cid = crypto_get_driverid(sc->sc_dev,
1730f4f56ff4SMark Johnston sizeof(struct qat_session), CRYPTOCAP_F_HARDWARE);
1731f4f56ff4SMark Johnston if (qcy->qcy_cid < 0) {
1732f4f56ff4SMark Johnston device_printf(sc->sc_dev,
1733f4f56ff4SMark Johnston "could not get opencrypto driver id\n");
1734f4f56ff4SMark Johnston return ENOENT;
1735f4f56ff4SMark Johnston }
1736f4f56ff4SMark Johnston
1737f4f56ff4SMark Johnston return 0;
1738f4f56ff4SMark Johnston }
1739f4f56ff4SMark Johnston
1740f4f56ff4SMark Johnston static void
qat_crypto_stop(struct qat_softc * sc)1741f4f56ff4SMark Johnston qat_crypto_stop(struct qat_softc *sc)
1742f4f56ff4SMark Johnston {
1743f4f56ff4SMark Johnston struct qat_crypto *qcy;
1744f4f56ff4SMark Johnston
1745f4f56ff4SMark Johnston qcy = &sc->sc_crypto;
1746f4f56ff4SMark Johnston if (qcy->qcy_cid >= 0)
1747f4f56ff4SMark Johnston (void)crypto_unregister_all(qcy->qcy_cid);
1748f4f56ff4SMark Johnston }
1749f4f56ff4SMark Johnston
1750f4f56ff4SMark Johnston static void
qat_crypto_sym_dma_unload(struct qat_sym_cookie * qsc,enum qat_sym_dma i)1751f4f56ff4SMark Johnston qat_crypto_sym_dma_unload(struct qat_sym_cookie *qsc, enum qat_sym_dma i)
1752f4f56ff4SMark Johnston {
1753f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_dma[i].qsd_dma_tag, qsc->qsc_dma[i].qsd_dmamap,
1754f4f56ff4SMark Johnston BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1755f4f56ff4SMark Johnston bus_dmamap_unload(qsc->qsc_dma[i].qsd_dma_tag,
1756f4f56ff4SMark Johnston qsc->qsc_dma[i].qsd_dmamap);
1757f4f56ff4SMark Johnston }
1758f4f56ff4SMark Johnston
1759f4f56ff4SMark Johnston static int
qat_crypto_sym_rxintr(struct qat_softc * sc,void * arg,void * msg)1760f4f56ff4SMark Johnston qat_crypto_sym_rxintr(struct qat_softc *sc, void *arg, void *msg)
1761f4f56ff4SMark Johnston {
1762f4f56ff4SMark Johnston char icv[QAT_SYM_HASH_BUFFER_LEN];
1763f4f56ff4SMark Johnston struct qat_crypto_bank *qcb = arg;
1764f4f56ff4SMark Johnston struct qat_crypto *qcy;
1765f4f56ff4SMark Johnston struct qat_session *qs;
1766f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
1767f4f56ff4SMark Johnston struct qat_sym_bulk_cookie *qsbc;
1768f4f56ff4SMark Johnston struct cryptop *crp;
1769f4f56ff4SMark Johnston int error;
1770f4f56ff4SMark Johnston uint16_t auth_sz;
1771f4f56ff4SMark Johnston bool blocked;
1772f4f56ff4SMark Johnston
1773f4f56ff4SMark Johnston qsc = *(void **)((uintptr_t)msg + sc->sc_hw.qhw_crypto_opaque_offset);
1774f4f56ff4SMark Johnston
1775f4f56ff4SMark Johnston qsbc = &qsc->qsc_bulk_cookie;
1776f4f56ff4SMark Johnston qcy = qsbc->qsbc_crypto;
1777f4f56ff4SMark Johnston qs = qsbc->qsbc_session;
1778f4f56ff4SMark Johnston crp = qsbc->qsbc_cb_tag;
1779f4f56ff4SMark Johnston
1780f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_self_dma_tag, qsc->qsc_self_dmamap,
1781f4f56ff4SMark Johnston BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1782f4f56ff4SMark Johnston
1783f4f56ff4SMark Johnston if (crp->crp_aad != NULL)
1784f4f56ff4SMark Johnston qat_crypto_sym_dma_unload(qsc, QAT_SYM_DMA_AADBUF);
1785f4f56ff4SMark Johnston qat_crypto_sym_dma_unload(qsc, QAT_SYM_DMA_BUF);
1786f4f56ff4SMark Johnston if (CRYPTO_HAS_OUTPUT_BUFFER(crp))
1787f4f56ff4SMark Johnston qat_crypto_sym_dma_unload(qsc, QAT_SYM_DMA_OBUF);
1788f4f56ff4SMark Johnston
1789f4f56ff4SMark Johnston error = 0;
1790f4f56ff4SMark Johnston if ((auth_sz = qs->qs_auth_mlen) != 0) {
1791f4f56ff4SMark Johnston if ((crp->crp_op & CRYPTO_OP_VERIFY_DIGEST) != 0) {
1792f4f56ff4SMark Johnston crypto_copydata(crp, crp->crp_digest_start,
1793f4f56ff4SMark Johnston auth_sz, icv);
1794f4f56ff4SMark Johnston if (timingsafe_bcmp(icv, qsc->qsc_auth_res,
1795f4f56ff4SMark Johnston auth_sz) != 0) {
1796f4f56ff4SMark Johnston error = EBADMSG;
1797f4f56ff4SMark Johnston }
1798f4f56ff4SMark Johnston } else {
1799f4f56ff4SMark Johnston crypto_copyback(crp, crp->crp_digest_start,
1800f4f56ff4SMark Johnston auth_sz, qsc->qsc_auth_res);
1801f4f56ff4SMark Johnston }
1802f4f56ff4SMark Johnston }
1803f4f56ff4SMark Johnston
1804f4f56ff4SMark Johnston qat_crypto_free_sym_cookie(qcb, qsc);
1805f4f56ff4SMark Johnston
1806f4f56ff4SMark Johnston blocked = false;
1807f4f56ff4SMark Johnston mtx_lock(&qs->qs_session_mtx);
1808f4f56ff4SMark Johnston MPASS(qs->qs_status & QAT_SESSION_STATUS_ACTIVE);
1809f4f56ff4SMark Johnston qs->qs_inflight--;
1810f4f56ff4SMark Johnston if (__predict_false(qs->qs_need_wakeup && qs->qs_inflight == 0)) {
1811f4f56ff4SMark Johnston blocked = true;
1812f4f56ff4SMark Johnston qs->qs_need_wakeup = false;
1813f4f56ff4SMark Johnston }
1814f4f56ff4SMark Johnston mtx_unlock(&qs->qs_session_mtx);
1815f4f56ff4SMark Johnston
1816f4f56ff4SMark Johnston crp->crp_etype = error;
1817f4f56ff4SMark Johnston crypto_done(crp);
1818f4f56ff4SMark Johnston
1819f4f56ff4SMark Johnston if (blocked)
1820f4f56ff4SMark Johnston crypto_unblock(qcy->qcy_cid, CRYPTO_SYMQ);
1821f4f56ff4SMark Johnston
1822f4f56ff4SMark Johnston return 1;
1823f4f56ff4SMark Johnston }
1824f4f56ff4SMark Johnston
1825f4f56ff4SMark Johnston static int
qat_probesession(device_t dev,const struct crypto_session_params * csp)1826f4f56ff4SMark Johnston qat_probesession(device_t dev, const struct crypto_session_params *csp)
1827f4f56ff4SMark Johnston {
1828f4f56ff4SMark Johnston if ((csp->csp_flags & ~(CSP_F_SEPARATE_OUTPUT | CSP_F_SEPARATE_AAD)) !=
1829f4f56ff4SMark Johnston 0)
1830f4f56ff4SMark Johnston return EINVAL;
1831f4f56ff4SMark Johnston
1832f4f56ff4SMark Johnston if (csp->csp_cipher_alg == CRYPTO_AES_XTS &&
1833f4f56ff4SMark Johnston qat_lookup(dev)->qatp_chip == QAT_CHIP_C2XXX) {
1834f4f56ff4SMark Johnston /*
1835f4f56ff4SMark Johnston * AES-XTS is not supported by the NanoQAT.
1836f4f56ff4SMark Johnston */
1837f4f56ff4SMark Johnston return EINVAL;
1838f4f56ff4SMark Johnston }
1839f4f56ff4SMark Johnston
1840f4f56ff4SMark Johnston switch (csp->csp_mode) {
1841f4f56ff4SMark Johnston case CSP_MODE_CIPHER:
1842f4f56ff4SMark Johnston switch (csp->csp_cipher_alg) {
1843f4f56ff4SMark Johnston case CRYPTO_AES_CBC:
1844f4f56ff4SMark Johnston case CRYPTO_AES_ICM:
1845f4f56ff4SMark Johnston if (csp->csp_ivlen != AES_BLOCK_LEN)
1846f4f56ff4SMark Johnston return EINVAL;
1847f4f56ff4SMark Johnston break;
1848f4f56ff4SMark Johnston case CRYPTO_AES_XTS:
1849f4f56ff4SMark Johnston if (csp->csp_ivlen != AES_XTS_IV_LEN)
1850f4f56ff4SMark Johnston return EINVAL;
1851f4f56ff4SMark Johnston break;
1852f4f56ff4SMark Johnston default:
1853f4f56ff4SMark Johnston return EINVAL;
1854f4f56ff4SMark Johnston }
1855f4f56ff4SMark Johnston break;
1856f4f56ff4SMark Johnston case CSP_MODE_DIGEST:
1857f4f56ff4SMark Johnston switch (csp->csp_auth_alg) {
1858f4f56ff4SMark Johnston case CRYPTO_SHA1:
1859f4f56ff4SMark Johnston case CRYPTO_SHA1_HMAC:
1860f4f56ff4SMark Johnston case CRYPTO_SHA2_256:
1861f4f56ff4SMark Johnston case CRYPTO_SHA2_256_HMAC:
1862f4f56ff4SMark Johnston case CRYPTO_SHA2_384:
1863f4f56ff4SMark Johnston case CRYPTO_SHA2_384_HMAC:
1864f4f56ff4SMark Johnston case CRYPTO_SHA2_512:
1865f4f56ff4SMark Johnston case CRYPTO_SHA2_512_HMAC:
1866f4f56ff4SMark Johnston break;
1867f4f56ff4SMark Johnston case CRYPTO_AES_NIST_GMAC:
1868f4f56ff4SMark Johnston if (csp->csp_ivlen != AES_GCM_IV_LEN)
1869f4f56ff4SMark Johnston return EINVAL;
1870f4f56ff4SMark Johnston break;
1871f4f56ff4SMark Johnston default:
1872f4f56ff4SMark Johnston return EINVAL;
1873f4f56ff4SMark Johnston }
1874f4f56ff4SMark Johnston break;
1875f4f56ff4SMark Johnston case CSP_MODE_AEAD:
1876f4f56ff4SMark Johnston switch (csp->csp_cipher_alg) {
1877f4f56ff4SMark Johnston case CRYPTO_AES_NIST_GCM_16:
1878f4f56ff4SMark Johnston break;
1879f4f56ff4SMark Johnston default:
1880f4f56ff4SMark Johnston return EINVAL;
1881f4f56ff4SMark Johnston }
1882f4f56ff4SMark Johnston break;
1883f4f56ff4SMark Johnston case CSP_MODE_ETA:
1884f4f56ff4SMark Johnston switch (csp->csp_auth_alg) {
1885f4f56ff4SMark Johnston case CRYPTO_SHA1_HMAC:
1886f4f56ff4SMark Johnston case CRYPTO_SHA2_256_HMAC:
1887f4f56ff4SMark Johnston case CRYPTO_SHA2_384_HMAC:
1888f4f56ff4SMark Johnston case CRYPTO_SHA2_512_HMAC:
1889f4f56ff4SMark Johnston switch (csp->csp_cipher_alg) {
1890f4f56ff4SMark Johnston case CRYPTO_AES_CBC:
1891f4f56ff4SMark Johnston case CRYPTO_AES_ICM:
1892f4f56ff4SMark Johnston if (csp->csp_ivlen != AES_BLOCK_LEN)
1893f4f56ff4SMark Johnston return EINVAL;
1894f4f56ff4SMark Johnston break;
1895f4f56ff4SMark Johnston case CRYPTO_AES_XTS:
1896f4f56ff4SMark Johnston if (csp->csp_ivlen != AES_XTS_IV_LEN)
1897f4f56ff4SMark Johnston return EINVAL;
1898f4f56ff4SMark Johnston break;
1899f4f56ff4SMark Johnston default:
1900f4f56ff4SMark Johnston return EINVAL;
1901f4f56ff4SMark Johnston }
1902f4f56ff4SMark Johnston break;
1903f4f56ff4SMark Johnston default:
1904f4f56ff4SMark Johnston return EINVAL;
1905f4f56ff4SMark Johnston }
1906f4f56ff4SMark Johnston break;
1907f4f56ff4SMark Johnston default:
1908f4f56ff4SMark Johnston return EINVAL;
1909f4f56ff4SMark Johnston }
1910f4f56ff4SMark Johnston
1911f4f56ff4SMark Johnston return CRYPTODEV_PROBE_HARDWARE;
1912f4f56ff4SMark Johnston }
1913f4f56ff4SMark Johnston
1914f4f56ff4SMark Johnston static int
qat_newsession(device_t dev,crypto_session_t cses,const struct crypto_session_params * csp)1915f4f56ff4SMark Johnston qat_newsession(device_t dev, crypto_session_t cses,
1916f4f56ff4SMark Johnston const struct crypto_session_params *csp)
1917f4f56ff4SMark Johnston {
1918f4f56ff4SMark Johnston struct qat_crypto *qcy;
1919f4f56ff4SMark Johnston struct qat_dmamem *qdm;
1920f4f56ff4SMark Johnston struct qat_session *qs;
1921f4f56ff4SMark Johnston struct qat_softc *sc;
1922f4f56ff4SMark Johnston struct qat_crypto_desc *ddesc, *edesc;
1923f4f56ff4SMark Johnston int error, slices;
1924f4f56ff4SMark Johnston
1925f4f56ff4SMark Johnston sc = device_get_softc(dev);
1926f4f56ff4SMark Johnston qs = crypto_get_driver_session(cses);
1927f4f56ff4SMark Johnston qcy = &sc->sc_crypto;
1928f4f56ff4SMark Johnston
1929f4f56ff4SMark Johnston qdm = &qs->qs_desc_mem;
1930f4f56ff4SMark Johnston error = qat_alloc_dmamem(sc, qdm, QAT_MAXSEG,
1931f4f56ff4SMark Johnston sizeof(struct qat_crypto_desc) * 2, QAT_OPTIMAL_ALIGN);
1932f4f56ff4SMark Johnston if (error != 0)
1933f4f56ff4SMark Johnston return error;
1934f4f56ff4SMark Johnston
1935f4f56ff4SMark Johnston mtx_init(&qs->qs_session_mtx, "qs session", NULL, MTX_DEF);
1936f4f56ff4SMark Johnston qs->qs_aad_length = -1;
1937f4f56ff4SMark Johnston
1938f4f56ff4SMark Johnston qs->qs_dec_desc = ddesc = qdm->qdm_dma_vaddr;
1939f4f56ff4SMark Johnston qs->qs_enc_desc = edesc = ddesc + 1;
1940f4f56ff4SMark Johnston
1941f4f56ff4SMark Johnston ddesc->qcd_desc_paddr = qdm->qdm_dma_seg.ds_addr;
1942f4f56ff4SMark Johnston ddesc->qcd_hash_state_paddr = ddesc->qcd_desc_paddr +
1943f4f56ff4SMark Johnston offsetof(struct qat_crypto_desc, qcd_hash_state_prefix_buf);
1944f4f56ff4SMark Johnston edesc->qcd_desc_paddr = qdm->qdm_dma_seg.ds_addr +
1945f4f56ff4SMark Johnston sizeof(struct qat_crypto_desc);
1946f4f56ff4SMark Johnston edesc->qcd_hash_state_paddr = edesc->qcd_desc_paddr +
1947f4f56ff4SMark Johnston offsetof(struct qat_crypto_desc, qcd_hash_state_prefix_buf);
1948f4f56ff4SMark Johnston
1949f4f56ff4SMark Johnston qs->qs_status = QAT_SESSION_STATUS_ACTIVE;
1950f4f56ff4SMark Johnston qs->qs_inflight = 0;
1951f4f56ff4SMark Johnston
1952f4f56ff4SMark Johnston qs->qs_cipher_key = csp->csp_cipher_key;
1953f4f56ff4SMark Johnston qs->qs_cipher_klen = csp->csp_cipher_klen;
1954f4f56ff4SMark Johnston qs->qs_auth_key = csp->csp_auth_key;
1955f4f56ff4SMark Johnston qs->qs_auth_klen = csp->csp_auth_klen;
1956f4f56ff4SMark Johnston
1957f4f56ff4SMark Johnston switch (csp->csp_cipher_alg) {
1958f4f56ff4SMark Johnston case CRYPTO_AES_CBC:
1959f4f56ff4SMark Johnston qs->qs_cipher_algo = qat_aes_cipher_algo(csp->csp_cipher_klen);
1960f4f56ff4SMark Johnston qs->qs_cipher_mode = HW_CIPHER_CBC_MODE;
1961f4f56ff4SMark Johnston break;
1962f4f56ff4SMark Johnston case CRYPTO_AES_ICM:
1963f4f56ff4SMark Johnston qs->qs_cipher_algo = qat_aes_cipher_algo(csp->csp_cipher_klen);
1964f4f56ff4SMark Johnston qs->qs_cipher_mode = HW_CIPHER_CTR_MODE;
1965f4f56ff4SMark Johnston break;
1966f4f56ff4SMark Johnston case CRYPTO_AES_XTS:
1967f4f56ff4SMark Johnston qs->qs_cipher_algo =
1968f4f56ff4SMark Johnston qat_aes_cipher_algo(csp->csp_cipher_klen / 2);
1969f4f56ff4SMark Johnston qs->qs_cipher_mode = HW_CIPHER_XTS_MODE;
1970f4f56ff4SMark Johnston break;
1971f4f56ff4SMark Johnston case CRYPTO_AES_NIST_GCM_16:
1972f4f56ff4SMark Johnston qs->qs_cipher_algo = qat_aes_cipher_algo(csp->csp_cipher_klen);
1973f4f56ff4SMark Johnston qs->qs_cipher_mode = HW_CIPHER_CTR_MODE;
1974f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_GALOIS_128;
1975f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
1976f4f56ff4SMark Johnston break;
1977f4f56ff4SMark Johnston case 0:
1978f4f56ff4SMark Johnston break;
1979f4f56ff4SMark Johnston default:
1980f4f56ff4SMark Johnston panic("%s: unhandled cipher algorithm %d", __func__,
1981f4f56ff4SMark Johnston csp->csp_cipher_alg);
1982f4f56ff4SMark Johnston }
1983f4f56ff4SMark Johnston
1984f4f56ff4SMark Johnston switch (csp->csp_auth_alg) {
1985f4f56ff4SMark Johnston case CRYPTO_SHA1_HMAC:
1986f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA1;
1987f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
1988f4f56ff4SMark Johnston break;
1989f4f56ff4SMark Johnston case CRYPTO_SHA1:
1990f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA1;
1991f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE0;
1992f4f56ff4SMark Johnston break;
1993f4f56ff4SMark Johnston case CRYPTO_SHA2_256_HMAC:
1994f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA256;
1995f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
1996f4f56ff4SMark Johnston break;
1997f4f56ff4SMark Johnston case CRYPTO_SHA2_256:
1998f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA256;
1999f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE0;
2000f4f56ff4SMark Johnston break;
2001f4f56ff4SMark Johnston case CRYPTO_SHA2_384_HMAC:
2002f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA384;
2003f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
2004f4f56ff4SMark Johnston break;
2005f4f56ff4SMark Johnston case CRYPTO_SHA2_384:
2006f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA384;
2007f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE0;
2008f4f56ff4SMark Johnston break;
2009f4f56ff4SMark Johnston case CRYPTO_SHA2_512_HMAC:
2010f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA512;
2011f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
2012f4f56ff4SMark Johnston break;
2013f4f56ff4SMark Johnston case CRYPTO_SHA2_512:
2014f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_SHA512;
2015f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE0;
2016f4f56ff4SMark Johnston break;
2017f4f56ff4SMark Johnston case CRYPTO_AES_NIST_GMAC:
2018f4f56ff4SMark Johnston qs->qs_cipher_algo = qat_aes_cipher_algo(csp->csp_auth_klen);
2019f4f56ff4SMark Johnston qs->qs_cipher_mode = HW_CIPHER_CTR_MODE;
2020f4f56ff4SMark Johnston qs->qs_auth_algo = HW_AUTH_ALGO_GALOIS_128;
2021f4f56ff4SMark Johnston qs->qs_auth_mode = HW_AUTH_MODE1;
2022f4f56ff4SMark Johnston
2023f4f56ff4SMark Johnston qs->qs_cipher_key = qs->qs_auth_key;
2024f4f56ff4SMark Johnston qs->qs_cipher_klen = qs->qs_auth_klen;
2025f4f56ff4SMark Johnston break;
2026f4f56ff4SMark Johnston case 0:
2027f4f56ff4SMark Johnston break;
2028f4f56ff4SMark Johnston default:
2029f4f56ff4SMark Johnston panic("%s: unhandled auth algorithm %d", __func__,
2030f4f56ff4SMark Johnston csp->csp_auth_alg);
2031f4f56ff4SMark Johnston }
2032f4f56ff4SMark Johnston
2033f4f56ff4SMark Johnston slices = 0;
2034f4f56ff4SMark Johnston switch (csp->csp_mode) {
2035f4f56ff4SMark Johnston case CSP_MODE_AEAD:
2036f4f56ff4SMark Johnston case CSP_MODE_ETA:
2037f4f56ff4SMark Johnston /* auth then decrypt */
2038f4f56ff4SMark Johnston ddesc->qcd_slices[0] = FW_SLICE_AUTH;
2039f4f56ff4SMark Johnston ddesc->qcd_slices[1] = FW_SLICE_CIPHER;
2040f4f56ff4SMark Johnston ddesc->qcd_cipher_dir = HW_CIPHER_DECRYPT;
2041f4f56ff4SMark Johnston ddesc->qcd_cmd_id = FW_LA_CMD_HASH_CIPHER;
2042f4f56ff4SMark Johnston /* encrypt then auth */
2043f4f56ff4SMark Johnston edesc->qcd_slices[0] = FW_SLICE_CIPHER;
2044f4f56ff4SMark Johnston edesc->qcd_slices[1] = FW_SLICE_AUTH;
2045f4f56ff4SMark Johnston edesc->qcd_cipher_dir = HW_CIPHER_ENCRYPT;
2046f4f56ff4SMark Johnston edesc->qcd_cmd_id = FW_LA_CMD_CIPHER_HASH;
2047f4f56ff4SMark Johnston slices = 2;
2048f4f56ff4SMark Johnston break;
2049f4f56ff4SMark Johnston case CSP_MODE_CIPHER:
2050f4f56ff4SMark Johnston /* decrypt */
2051f4f56ff4SMark Johnston ddesc->qcd_slices[0] = FW_SLICE_CIPHER;
2052f4f56ff4SMark Johnston ddesc->qcd_cipher_dir = HW_CIPHER_DECRYPT;
2053f4f56ff4SMark Johnston ddesc->qcd_cmd_id = FW_LA_CMD_CIPHER;
2054f4f56ff4SMark Johnston /* encrypt */
2055f4f56ff4SMark Johnston edesc->qcd_slices[0] = FW_SLICE_CIPHER;
2056f4f56ff4SMark Johnston edesc->qcd_cipher_dir = HW_CIPHER_ENCRYPT;
2057f4f56ff4SMark Johnston edesc->qcd_cmd_id = FW_LA_CMD_CIPHER;
2058f4f56ff4SMark Johnston slices = 1;
2059f4f56ff4SMark Johnston break;
2060f4f56ff4SMark Johnston case CSP_MODE_DIGEST:
2061f4f56ff4SMark Johnston if (qs->qs_auth_algo == HW_AUTH_ALGO_GALOIS_128) {
2062f4f56ff4SMark Johnston /* auth then decrypt */
2063f4f56ff4SMark Johnston ddesc->qcd_slices[0] = FW_SLICE_AUTH;
2064f4f56ff4SMark Johnston ddesc->qcd_slices[1] = FW_SLICE_CIPHER;
2065f4f56ff4SMark Johnston ddesc->qcd_cipher_dir = HW_CIPHER_DECRYPT;
2066f4f56ff4SMark Johnston ddesc->qcd_cmd_id = FW_LA_CMD_HASH_CIPHER;
2067f4f56ff4SMark Johnston /* encrypt then auth */
2068f4f56ff4SMark Johnston edesc->qcd_slices[0] = FW_SLICE_CIPHER;
2069f4f56ff4SMark Johnston edesc->qcd_slices[1] = FW_SLICE_AUTH;
2070f4f56ff4SMark Johnston edesc->qcd_cipher_dir = HW_CIPHER_ENCRYPT;
2071f4f56ff4SMark Johnston edesc->qcd_cmd_id = FW_LA_CMD_CIPHER_HASH;
2072f4f56ff4SMark Johnston slices = 2;
2073f4f56ff4SMark Johnston } else {
2074f4f56ff4SMark Johnston ddesc->qcd_slices[0] = FW_SLICE_AUTH;
2075f4f56ff4SMark Johnston ddesc->qcd_cmd_id = FW_LA_CMD_AUTH;
2076f4f56ff4SMark Johnston edesc->qcd_slices[0] = FW_SLICE_AUTH;
2077f4f56ff4SMark Johnston edesc->qcd_cmd_id = FW_LA_CMD_AUTH;
2078f4f56ff4SMark Johnston slices = 1;
2079f4f56ff4SMark Johnston }
2080f4f56ff4SMark Johnston break;
2081f4f56ff4SMark Johnston default:
2082f4f56ff4SMark Johnston panic("%s: unhandled crypto algorithm %d, %d", __func__,
2083f4f56ff4SMark Johnston csp->csp_cipher_alg, csp->csp_auth_alg);
2084f4f56ff4SMark Johnston }
2085f4f56ff4SMark Johnston ddesc->qcd_slices[slices] = FW_SLICE_DRAM_WR;
2086f4f56ff4SMark Johnston edesc->qcd_slices[slices] = FW_SLICE_DRAM_WR;
2087f4f56ff4SMark Johnston
2088f4f56ff4SMark Johnston qcy->qcy_sc->sc_hw.qhw_crypto_setup_desc(qcy, qs, ddesc);
2089f4f56ff4SMark Johnston qcy->qcy_sc->sc_hw.qhw_crypto_setup_desc(qcy, qs, edesc);
2090f4f56ff4SMark Johnston
2091f4f56ff4SMark Johnston if (csp->csp_auth_mlen != 0)
2092f4f56ff4SMark Johnston qs->qs_auth_mlen = csp->csp_auth_mlen;
2093f4f56ff4SMark Johnston else
2094f4f56ff4SMark Johnston qs->qs_auth_mlen = edesc->qcd_auth_sz;
2095f4f56ff4SMark Johnston
2096f4f56ff4SMark Johnston /* Compute the GMAC by specifying a null cipher payload. */
2097f4f56ff4SMark Johnston if (csp->csp_auth_alg == CRYPTO_AES_NIST_GMAC)
2098f4f56ff4SMark Johnston ddesc->qcd_cmd_id = edesc->qcd_cmd_id = FW_LA_CMD_AUTH;
2099f4f56ff4SMark Johnston
2100f4f56ff4SMark Johnston return 0;
2101f4f56ff4SMark Johnston }
2102f4f56ff4SMark Johnston
2103f4f56ff4SMark Johnston static void
qat_crypto_clear_desc(struct qat_crypto_desc * desc)2104f4f56ff4SMark Johnston qat_crypto_clear_desc(struct qat_crypto_desc *desc)
2105f4f56ff4SMark Johnston {
2106f4f56ff4SMark Johnston explicit_bzero(desc->qcd_content_desc, sizeof(desc->qcd_content_desc));
2107f4f56ff4SMark Johnston explicit_bzero(desc->qcd_hash_state_prefix_buf,
2108f4f56ff4SMark Johnston sizeof(desc->qcd_hash_state_prefix_buf));
2109f4f56ff4SMark Johnston explicit_bzero(desc->qcd_req_cache, sizeof(desc->qcd_req_cache));
2110f4f56ff4SMark Johnston }
2111f4f56ff4SMark Johnston
2112f4f56ff4SMark Johnston static void
qat_freesession(device_t dev,crypto_session_t cses)2113f4f56ff4SMark Johnston qat_freesession(device_t dev, crypto_session_t cses)
2114f4f56ff4SMark Johnston {
2115f4f56ff4SMark Johnston struct qat_session *qs;
2116f4f56ff4SMark Johnston
2117f4f56ff4SMark Johnston qs = crypto_get_driver_session(cses);
2118f4f56ff4SMark Johnston KASSERT(qs->qs_inflight == 0,
2119f4f56ff4SMark Johnston ("%s: session %p has requests in flight", __func__, qs));
2120f4f56ff4SMark Johnston
2121f4f56ff4SMark Johnston qat_crypto_clear_desc(qs->qs_enc_desc);
2122f4f56ff4SMark Johnston qat_crypto_clear_desc(qs->qs_dec_desc);
2123f4f56ff4SMark Johnston qat_free_dmamem(device_get_softc(dev), &qs->qs_desc_mem);
2124f4f56ff4SMark Johnston mtx_destroy(&qs->qs_session_mtx);
2125f4f56ff4SMark Johnston }
2126f4f56ff4SMark Johnston
2127f4f56ff4SMark Johnston static int
qat_process(device_t dev,struct cryptop * crp,int hint)2128f4f56ff4SMark Johnston qat_process(device_t dev, struct cryptop *crp, int hint)
2129f4f56ff4SMark Johnston {
2130f4f56ff4SMark Johnston struct qat_crypto *qcy;
2131f4f56ff4SMark Johnston struct qat_crypto_bank *qcb;
2132f4f56ff4SMark Johnston struct qat_crypto_desc const *desc;
2133f4f56ff4SMark Johnston struct qat_session *qs;
2134f4f56ff4SMark Johnston struct qat_softc *sc;
2135f4f56ff4SMark Johnston struct qat_sym_cookie *qsc;
2136f4f56ff4SMark Johnston struct qat_sym_bulk_cookie *qsbc;
2137f4f56ff4SMark Johnston int error;
2138f4f56ff4SMark Johnston
2139f4f56ff4SMark Johnston sc = device_get_softc(dev);
2140f4f56ff4SMark Johnston qcy = &sc->sc_crypto;
2141f4f56ff4SMark Johnston qs = crypto_get_driver_session(crp->crp_session);
2142f4f56ff4SMark Johnston qsc = NULL;
2143f4f56ff4SMark Johnston
2144f4f56ff4SMark Johnston if (__predict_false(crypto_buffer_len(&crp->crp_buf) > QAT_MAXLEN)) {
2145f4f56ff4SMark Johnston error = E2BIG;
2146f4f56ff4SMark Johnston goto fail1;
2147f4f56ff4SMark Johnston }
2148f4f56ff4SMark Johnston
2149f4f56ff4SMark Johnston mtx_lock(&qs->qs_session_mtx);
2150f4f56ff4SMark Johnston if (qs->qs_auth_algo == HW_AUTH_ALGO_GALOIS_128) {
2151f4f56ff4SMark Johnston if (crp->crp_aad_length > QAT_GCM_AAD_SIZE_MAX) {
2152f4f56ff4SMark Johnston error = E2BIG;
2153f4f56ff4SMark Johnston mtx_unlock(&qs->qs_session_mtx);
2154f4f56ff4SMark Johnston goto fail1;
2155f4f56ff4SMark Johnston }
2156f4f56ff4SMark Johnston
2157f4f56ff4SMark Johnston /*
2158f4f56ff4SMark Johnston * The firmware interface for GCM annoyingly requires the AAD
2159f4f56ff4SMark Johnston * size to be stored in the session's content descriptor, which
2160f4f56ff4SMark Johnston * is not really meant to be updated after session
2161f4f56ff4SMark Johnston * initialization. For IPSec the AAD size is fixed so this is
2162f4f56ff4SMark Johnston * not much of a problem in practice, but we have to catch AAD
2163f4f56ff4SMark Johnston * size updates here so that the device code can safely update
2164f4f56ff4SMark Johnston * the session's recorded AAD size.
2165f4f56ff4SMark Johnston */
2166f4f56ff4SMark Johnston if (__predict_false(crp->crp_aad_length != qs->qs_aad_length)) {
2167f4f56ff4SMark Johnston if (qs->qs_inflight == 0) {
2168f4f56ff4SMark Johnston if (qs->qs_aad_length != -1) {
2169f4f56ff4SMark Johnston counter_u64_add(sc->sc_gcm_aad_updates,
2170f4f56ff4SMark Johnston 1);
2171f4f56ff4SMark Johnston }
2172f4f56ff4SMark Johnston qs->qs_aad_length = crp->crp_aad_length;
2173f4f56ff4SMark Johnston } else {
2174f4f56ff4SMark Johnston qs->qs_need_wakeup = true;
2175f4f56ff4SMark Johnston mtx_unlock(&qs->qs_session_mtx);
2176f4f56ff4SMark Johnston counter_u64_add(sc->sc_gcm_aad_restarts, 1);
2177f4f56ff4SMark Johnston error = ERESTART;
2178f4f56ff4SMark Johnston goto fail1;
2179f4f56ff4SMark Johnston }
2180f4f56ff4SMark Johnston }
2181f4f56ff4SMark Johnston }
2182f4f56ff4SMark Johnston qs->qs_inflight++;
2183f4f56ff4SMark Johnston mtx_unlock(&qs->qs_session_mtx);
2184f4f56ff4SMark Johnston
2185f4f56ff4SMark Johnston qcb = qat_crypto_select_bank(qcy);
2186f4f56ff4SMark Johnston
2187f4f56ff4SMark Johnston qsc = qat_crypto_alloc_sym_cookie(qcb);
2188f4f56ff4SMark Johnston if (qsc == NULL) {
2189f4f56ff4SMark Johnston counter_u64_add(sc->sc_sym_alloc_failures, 1);
2190f4f56ff4SMark Johnston error = ENOBUFS;
2191f4f56ff4SMark Johnston goto fail2;
2192f4f56ff4SMark Johnston }
2193f4f56ff4SMark Johnston
2194f4f56ff4SMark Johnston if (CRYPTO_OP_IS_ENCRYPT(crp->crp_op))
2195f4f56ff4SMark Johnston desc = qs->qs_enc_desc;
2196f4f56ff4SMark Johnston else
2197f4f56ff4SMark Johnston desc = qs->qs_dec_desc;
2198f4f56ff4SMark Johnston
2199f4f56ff4SMark Johnston error = qat_crypto_load(qs, qsc, desc, crp);
2200f4f56ff4SMark Johnston if (error != 0)
2201f4f56ff4SMark Johnston goto fail2;
2202f4f56ff4SMark Johnston
2203f4f56ff4SMark Johnston qsbc = &qsc->qsc_bulk_cookie;
2204f4f56ff4SMark Johnston qsbc->qsbc_crypto = qcy;
2205f4f56ff4SMark Johnston qsbc->qsbc_session = qs;
2206f4f56ff4SMark Johnston qsbc->qsbc_cb_tag = crp;
2207f4f56ff4SMark Johnston
2208f4f56ff4SMark Johnston sc->sc_hw.qhw_crypto_setup_req_params(qcb, qs, desc, qsc, crp);
2209f4f56ff4SMark Johnston
2210f4f56ff4SMark Johnston if (crp->crp_aad != NULL) {
2211f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_dma[QAT_SYM_DMA_AADBUF].qsd_dma_tag,
2212f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_AADBUF].qsd_dmamap,
2213f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2214f4f56ff4SMark Johnston }
2215f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_dma[QAT_SYM_DMA_BUF].qsd_dma_tag,
2216f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_BUF].qsd_dmamap,
2217f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2218f4f56ff4SMark Johnston if (CRYPTO_HAS_OUTPUT_BUFFER(crp)) {
2219f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_dma[QAT_SYM_DMA_OBUF].qsd_dma_tag,
2220f4f56ff4SMark Johnston qsc->qsc_dma[QAT_SYM_DMA_OBUF].qsd_dmamap,
2221f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2222f4f56ff4SMark Johnston }
2223f4f56ff4SMark Johnston bus_dmamap_sync(qsc->qsc_self_dma_tag, qsc->qsc_self_dmamap,
2224f4f56ff4SMark Johnston BUS_DMASYNC_PREWRITE | BUS_DMASYNC_PREREAD);
2225f4f56ff4SMark Johnston
2226f4f56ff4SMark Johnston error = qat_etr_put_msg(sc, qcb->qcb_sym_tx,
2227f4f56ff4SMark Johnston (uint32_t *)qsbc->qsbc_msg);
2228f4f56ff4SMark Johnston if (error)
2229f4f56ff4SMark Johnston goto fail2;
2230f4f56ff4SMark Johnston
2231f4f56ff4SMark Johnston return 0;
2232f4f56ff4SMark Johnston
2233f4f56ff4SMark Johnston fail2:
2234f4f56ff4SMark Johnston if (qsc)
2235f4f56ff4SMark Johnston qat_crypto_free_sym_cookie(qcb, qsc);
2236f4f56ff4SMark Johnston mtx_lock(&qs->qs_session_mtx);
2237f4f56ff4SMark Johnston qs->qs_inflight--;
2238f4f56ff4SMark Johnston mtx_unlock(&qs->qs_session_mtx);
2239f4f56ff4SMark Johnston fail1:
2240f4f56ff4SMark Johnston crp->crp_etype = error;
2241f4f56ff4SMark Johnston crypto_done(crp);
2242f4f56ff4SMark Johnston return 0;
2243f4f56ff4SMark Johnston }
2244f4f56ff4SMark Johnston
2245f4f56ff4SMark Johnston static device_method_t qat_methods[] = {
2246f4f56ff4SMark Johnston /* Device interface */
2247f4f56ff4SMark Johnston DEVMETHOD(device_probe, qat_probe),
2248f4f56ff4SMark Johnston DEVMETHOD(device_attach, qat_attach),
2249f4f56ff4SMark Johnston DEVMETHOD(device_detach, qat_detach),
2250f4f56ff4SMark Johnston
2251f4f56ff4SMark Johnston /* Cryptodev interface */
2252f4f56ff4SMark Johnston DEVMETHOD(cryptodev_probesession, qat_probesession),
2253f4f56ff4SMark Johnston DEVMETHOD(cryptodev_newsession, qat_newsession),
2254f4f56ff4SMark Johnston DEVMETHOD(cryptodev_freesession, qat_freesession),
2255f4f56ff4SMark Johnston DEVMETHOD(cryptodev_process, qat_process),
2256f4f56ff4SMark Johnston
2257f4f56ff4SMark Johnston DEVMETHOD_END
2258f4f56ff4SMark Johnston };
2259f4f56ff4SMark Johnston
2260f4f56ff4SMark Johnston static driver_t qat_driver = {
2261f4f56ff4SMark Johnston .name = "qat_c2xxx",
2262f4f56ff4SMark Johnston .methods = qat_methods,
2263f4f56ff4SMark Johnston .size = sizeof(struct qat_softc),
2264f4f56ff4SMark Johnston };
2265f4f56ff4SMark Johnston
2266f4f56ff4SMark Johnston DRIVER_MODULE(qat_c2xxx, pci, qat_driver, 0, 0);
2267f4f56ff4SMark Johnston MODULE_VERSION(qat_c2xxx, 1);
2268f4f56ff4SMark Johnston MODULE_DEPEND(qat_c2xxx, crypto, 1, 1, 1);
2269675e065bSMark Johnston MODULE_DEPEND(qat_c2xxx, firmware, 1, 1, 1);
2270f4f56ff4SMark Johnston MODULE_DEPEND(qat_c2xxx, pci, 1, 1, 1);
2271