Skip to content

Commit 31de3f5

Browse files
committed
Merge branch 'cxgb4-chcr-ktls-tx-ofld-support-on-T6-adapter'
Rohit Maheshwari says: ==================== cxgb4/chcr: ktls tx ofld support on T6 adapter This series of patches add support for kernel tls offload in Tx direction, over Chelsio T6 NICs. SKBs marked as decrypted will be treated as tls plain text packets and then offloaded to encrypt using network device (chelsio T6 adapter). This series is broken down as follows: Patch 1 defines a new macro and registers tls_dev_add and tls_dev_del callbacks. When tls_dev_add gets called we send a connection request to our hardware and to make HW understand about tls offload. Its a partial connection setup and only ipv4 part is done. Patch 2 handles the HW response of the connection request and then we request to update TCB and handle it's HW response as well. Also we save crypto key locally. Only supporting TLS_CIPHER_AES_GCM_128_KEY_SIZE. Patch 3 handles tls marked skbs (decrypted bit set) and sends it to ULD for crypto handling. This code has a minimal portion of tx handler, to handle only one complete record per skb. Patch 4 hanldes partial end part of records. Also added logic to handle multiple records in one single skb. It also adds support to send out tcp option(/s) if exists in skb. If a record is partial but has end part of a record, we'll fetch complete record and then only send it to HW to generate HASH on complete record. Patch 5 handles partial first or middle part of record, it uses AES_CTR to encrypt the partial record. If we are trying to send middle record, it's start should be 16 byte aligned, so we'll fetch few earlier bytes from the record and then send it to HW for encryption. Patch 6 enables ipv6 support and also includes ktls startistics. v1->v2: - mark tcb state to close in tls_dev_del. - u_ctx is now picked from adapter structure. - clear atid in case of failure. - corrected ULP_CRYPTO_KTLS_INLINE value. - optimized tcb update using control queue. - state machine handling when earlier states received. - chcr_write_cpl_set_tcb_ulp function is shifted to patch3. - un-necessary updating left variable. v2->v3: - add empty line after variable declaration. - local variable declaration in reverse christmas tree ordering. v3->v4: - replaced kfree_skb with dev_kfree_skb_any. - corrected error message reported by kbuild test robot <[email protected]> - mss calculation logic. - correct place for Alloc skb check. - Replaced atomic_t with atomic64_t - added few more statistics counters. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 9d2e4e1 + 62370a4 commit 31de3f5

File tree

17 files changed

+2506
-17
lines changed

17 files changed

+2506
-17
lines changed

drivers/crypto/chelsio/Kconfig

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,3 +42,14 @@ config CRYPTO_DEV_CHELSIO_TLS
4242

4343
To compile this driver as a module, choose M here: the module
4444
will be called chtls.
45+
46+
config CHELSIO_TLS_DEVICE
47+
bool "Chelsio Inline KTLS Offload"
48+
depends on CHELSIO_T4
49+
depends on TLS_DEVICE
50+
select CRYPTO_DEV_CHELSIO
51+
default y
52+
help
53+
This flag enables support for kernel tls offload over Chelsio T6
54+
crypto accelerator. CONFIG_CHELSIO_TLS_DEVICE flag can be enabled
55+
only if CONFIG_TLS and CONFIG_TLS_DEVICE flags are enabled.

drivers/crypto/chelsio/Makefile

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,8 @@ ccflags-y := -I $(srctree)/drivers/net/ethernet/chelsio/cxgb4
33

44
obj-$(CONFIG_CRYPTO_DEV_CHELSIO) += chcr.o
55
chcr-objs := chcr_core.o chcr_algo.o
6+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
7+
chcr-objs += chcr_ktls.o
8+
#endif
69
chcr-$(CONFIG_CHELSIO_IPSEC_INLINE) += chcr_ipsec.o
710
obj-$(CONFIG_CRYPTO_DEV_CHELSIO_TLS) += chtls/
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
/* SPDX-License-Identifier: GPL-2.0-only */
2+
/* Copyright (C) 2020 Chelsio Communications. All rights reserved. */
3+
4+
#ifndef __CHCR_COMMON_H__
5+
#define __CHCR_COMMON_H__
6+
7+
#include "cxgb4.h"
8+
9+
#define CHCR_MAX_SALT 4
10+
#define CHCR_KEYCTX_MAC_KEY_SIZE_128 0
11+
#define CHCR_KEYCTX_CIPHER_KEY_SIZE_128 0
12+
#define CHCR_SCMD_CIPHER_MODE_AES_GCM 2
13+
#define CHCR_SCMD_CIPHER_MODE_AES_CTR 3
14+
#define CHCR_CPL_TX_SEC_PDU_LEN_64BIT 2
15+
#define CHCR_SCMD_SEQ_NO_CTRL_64BIT 3
16+
#define CHCR_SCMD_PROTO_VERSION_TLS 0
17+
#define CHCR_SCMD_PROTO_VERSION_GENERIC 4
18+
#define CHCR_SCMD_AUTH_MODE_GHASH 4
19+
#define AES_BLOCK_LEN 16
20+
21+
enum chcr_state {
22+
CHCR_INIT = 0,
23+
CHCR_ATTACH,
24+
CHCR_DETACH,
25+
};
26+
27+
struct chcr_dev {
28+
spinlock_t lock_chcr_dev; /* chcr dev structure lock */
29+
enum chcr_state state;
30+
atomic_t inflight;
31+
int wqretry;
32+
struct delayed_work detach_work;
33+
struct completion detach_comp;
34+
unsigned char tx_channel_id;
35+
};
36+
37+
struct uld_ctx {
38+
struct list_head entry;
39+
struct cxgb4_lld_info lldi;
40+
struct chcr_dev dev;
41+
};
42+
43+
struct ktls_key_ctx {
44+
__be32 ctx_hdr;
45+
u8 salt[CHCR_MAX_SALT];
46+
__be64 iv_to_auth;
47+
unsigned char key[TLS_CIPHER_AES_GCM_128_KEY_SIZE +
48+
TLS_CIPHER_AES_GCM_256_TAG_SIZE];
49+
};
50+
51+
/* Crypto key context */
52+
#define KEY_CONTEXT_CTX_LEN_S 24
53+
#define KEY_CONTEXT_CTX_LEN_V(x) ((x) << KEY_CONTEXT_CTX_LEN_S)
54+
55+
#define KEY_CONTEXT_SALT_PRESENT_S 10
56+
#define KEY_CONTEXT_SALT_PRESENT_V(x) ((x) << KEY_CONTEXT_SALT_PRESENT_S)
57+
#define KEY_CONTEXT_SALT_PRESENT_F KEY_CONTEXT_SALT_PRESENT_V(1U)
58+
59+
#define KEY_CONTEXT_VALID_S 0
60+
#define KEY_CONTEXT_VALID_V(x) ((x) << KEY_CONTEXT_VALID_S)
61+
#define KEY_CONTEXT_VALID_F KEY_CONTEXT_VALID_V(1U)
62+
63+
#define KEY_CONTEXT_CK_SIZE_S 6
64+
#define KEY_CONTEXT_CK_SIZE_V(x) ((x) << KEY_CONTEXT_CK_SIZE_S)
65+
66+
#define KEY_CONTEXT_MK_SIZE_S 2
67+
#define KEY_CONTEXT_MK_SIZE_V(x) ((x) << KEY_CONTEXT_MK_SIZE_S)
68+
69+
#define KEY_CONTEXT_OPAD_PRESENT_S 11
70+
#define KEY_CONTEXT_OPAD_PRESENT_V(x) ((x) << KEY_CONTEXT_OPAD_PRESENT_S)
71+
#define KEY_CONTEXT_OPAD_PRESENT_F KEY_CONTEXT_OPAD_PRESENT_V(1U)
72+
73+
#define FILL_KEY_CTX_HDR(ck_size, mk_size, ctx_len) \
74+
htonl(KEY_CONTEXT_MK_SIZE_V(mk_size) | \
75+
KEY_CONTEXT_CK_SIZE_V(ck_size) | \
76+
KEY_CONTEXT_VALID_F | \
77+
KEY_CONTEXT_SALT_PRESENT_F | \
78+
KEY_CONTEXT_CTX_LEN_V((ctx_len)))
79+
80+
struct uld_ctx *assign_chcr_device(void);
81+
82+
static inline void *chcr_copy_to_txd(const void *src, const struct sge_txq *q,
83+
void *pos, int length)
84+
{
85+
int left = (void *)q->stat - pos;
86+
u64 *p;
87+
88+
if (likely(length <= left)) {
89+
memcpy(pos, src, length);
90+
pos += length;
91+
} else {
92+
memcpy(pos, src, left);
93+
memcpy(q->desc, src + left, length - left);
94+
pos = (void *)q->desc + (length - left);
95+
}
96+
/* 0-pad to multiple of 16 */
97+
p = PTR_ALIGN(pos, 8);
98+
if ((uintptr_t)p & 8) {
99+
*p = 0;
100+
return p + 1;
101+
}
102+
return p;
103+
}
104+
105+
static inline unsigned int chcr_txq_avail(const struct sge_txq *q)
106+
{
107+
return q->size - 1 - q->in_use;
108+
}
109+
110+
static inline void chcr_txq_advance(struct sge_txq *q, unsigned int n)
111+
{
112+
q->in_use += n;
113+
q->pidx += n;
114+
if (q->pidx >= q->size)
115+
q->pidx -= q->size;
116+
}
117+
118+
static inline void chcr_eth_txq_stop(struct sge_eth_txq *q)
119+
{
120+
netif_tx_stop_queue(q->txq);
121+
q->q.stops++;
122+
}
123+
124+
static inline unsigned int chcr_sgl_len(unsigned int n)
125+
{
126+
n--;
127+
return (3 * n) / 2 + (n & 1) + 2;
128+
}
129+
130+
static inline unsigned int chcr_flits_to_desc(unsigned int n)
131+
{
132+
WARN_ON(n > SGE_MAX_WR_LEN / 8);
133+
return DIV_ROUND_UP(n, 8);
134+
}
135+
#endif /* __CHCR_COMMON_H__ */

drivers/crypto/chelsio/chcr_core.c

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,17 @@
2828

2929
static struct chcr_driver_data drv_data;
3030

31-
typedef int (*chcr_handler_func)(struct chcr_dev *dev, unsigned char *input);
32-
static int cpl_fw6_pld_handler(struct chcr_dev *dev, unsigned char *input);
31+
typedef int (*chcr_handler_func)(struct adapter *adap, unsigned char *input);
32+
static int cpl_fw6_pld_handler(struct adapter *adap, unsigned char *input);
3333
static void *chcr_uld_add(const struct cxgb4_lld_info *lld);
3434
static int chcr_uld_state_change(void *handle, enum cxgb4_state state);
3535

3636
static chcr_handler_func work_handlers[NUM_CPL_CMDS] = {
3737
[CPL_FW6_PLD] = cpl_fw6_pld_handler,
38+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
39+
[CPL_ACT_OPEN_RPL] = chcr_ktls_cpl_act_open_rpl,
40+
[CPL_SET_TCB_RPL] = chcr_ktls_cpl_set_tcb_rpl,
41+
#endif
3842
};
3943

4044
static struct cxgb4_uld_info chcr_uld_info = {
@@ -45,9 +49,9 @@ static struct cxgb4_uld_info chcr_uld_info = {
4549
.add = chcr_uld_add,
4650
.state_change = chcr_uld_state_change,
4751
.rx_handler = chcr_uld_rx_handler,
48-
#ifdef CONFIG_CHELSIO_IPSEC_INLINE
52+
#if defined(CONFIG_CHELSIO_IPSEC_INLINE) || defined(CONFIG_CHELSIO_TLS_DEVICE)
4953
.tx_handler = chcr_uld_tx_handler,
50-
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */
54+
#endif /* CONFIG_CHELSIO_IPSEC_INLINE || CONFIG_CHELSIO_TLS_DEVICE */
5155
};
5256

5357
static void detach_work_fn(struct work_struct *work)
@@ -150,14 +154,13 @@ static int chcr_dev_move(struct uld_ctx *u_ctx)
150154
return 0;
151155
}
152156

153-
static int cpl_fw6_pld_handler(struct chcr_dev *dev,
157+
static int cpl_fw6_pld_handler(struct adapter *adap,
154158
unsigned char *input)
155159
{
156160
struct crypto_async_request *req;
157161
struct cpl_fw6_pld *fw6_pld;
158162
u32 ack_err_status = 0;
159163
int error_status = 0;
160-
struct adapter *adap = padap(dev);
161164

162165
fw6_pld = (struct cpl_fw6_pld *)input;
163166
req = (struct crypto_async_request *)(uintptr_t)be64_to_cpu(
@@ -205,6 +208,11 @@ static void *chcr_uld_add(const struct cxgb4_lld_info *lld)
205208
if (lld->crypto & ULP_CRYPTO_IPSEC_INLINE)
206209
chcr_add_xfrmops(lld);
207210
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */
211+
212+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
213+
if (lld->ulp_crypto & ULP_CRYPTO_KTLS_INLINE)
214+
chcr_enable_ktls(padap(&u_ctx->dev));
215+
#endif
208216
out:
209217
return u_ctx;
210218
}
@@ -214,26 +222,37 @@ int chcr_uld_rx_handler(void *handle, const __be64 *rsp,
214222
{
215223
struct uld_ctx *u_ctx = (struct uld_ctx *)handle;
216224
struct chcr_dev *dev = &u_ctx->dev;
225+
struct adapter *adap = padap(dev);
217226
const struct cpl_fw6_pld *rpl = (struct cpl_fw6_pld *)rsp;
218227

219-
if (rpl->opcode != CPL_FW6_PLD) {
220-
pr_err("Unsupported opcode\n");
228+
if (!work_handlers[rpl->opcode]) {
229+
pr_err("Unsupported opcode %d received\n", rpl->opcode);
221230
return 0;
222231
}
223232

224233
if (!pgl)
225-
work_handlers[rpl->opcode](dev, (unsigned char *)&rsp[1]);
234+
work_handlers[rpl->opcode](adap, (unsigned char *)&rsp[1]);
226235
else
227-
work_handlers[rpl->opcode](dev, pgl->va);
236+
work_handlers[rpl->opcode](adap, pgl->va);
228237
return 0;
229238
}
230239

231-
#ifdef CONFIG_CHELSIO_IPSEC_INLINE
240+
#if defined(CONFIG_CHELSIO_IPSEC_INLINE) || defined(CONFIG_CHELSIO_TLS_DEVICE)
232241
int chcr_uld_tx_handler(struct sk_buff *skb, struct net_device *dev)
233242
{
243+
/* In case if skb's decrypted bit is set, it's nic tls packet, else it's
244+
* ipsec packet.
245+
*/
246+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
247+
if (skb->decrypted)
248+
return chcr_ktls_xmit(skb, dev);
249+
#endif
250+
#ifdef CONFIG_CHELSIO_IPSEC_INLINE
234251
return chcr_ipsec_xmit(skb, dev);
252+
#endif
253+
return 0;
235254
}
236-
#endif /* CONFIG_CHELSIO_IPSEC_INLINE */
255+
#endif /* CONFIG_CHELSIO_IPSEC_INLINE || CONFIG_CHELSIO_TLS_DEVICE */
237256

238257
static void chcr_detach_device(struct uld_ctx *u_ctx)
239258
{
@@ -304,12 +323,20 @@ static void __exit chcr_crypto_exit(void)
304323
list_for_each_entry_safe(u_ctx, tmp, &drv_data.act_dev, entry) {
305324
adap = padap(&u_ctx->dev);
306325
memset(&adap->chcr_stats, 0, sizeof(adap->chcr_stats));
326+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
327+
if (u_ctx->lldi.ulp_crypto & ULP_CRYPTO_KTLS_INLINE)
328+
chcr_disable_ktls(adap);
329+
#endif
307330
list_del(&u_ctx->entry);
308331
kfree(u_ctx);
309332
}
310333
list_for_each_entry_safe(u_ctx, tmp, &drv_data.inact_dev, entry) {
311334
adap = padap(&u_ctx->dev);
312335
memset(&adap->chcr_stats, 0, sizeof(adap->chcr_stats));
336+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
337+
if (u_ctx->lldi.ulp_crypto & ULP_CRYPTO_KTLS_INLINE)
338+
chcr_disable_ktls(adap);
339+
#endif
313340
list_del(&u_ctx->entry);
314341
kfree(u_ctx);
315342
}

drivers/crypto/chelsio/chcr_core.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,4 +222,11 @@ int chcr_handle_resp(struct crypto_async_request *req, unsigned char *input,
222222
int err);
223223
int chcr_ipsec_xmit(struct sk_buff *skb, struct net_device *dev);
224224
void chcr_add_xfrmops(const struct cxgb4_lld_info *lld);
225+
#ifdef CONFIG_CHELSIO_TLS_DEVICE
226+
void chcr_enable_ktls(struct adapter *adap);
227+
void chcr_disable_ktls(struct adapter *adap);
228+
int chcr_ktls_cpl_act_open_rpl(struct adapter *adap, unsigned char *input);
229+
int chcr_ktls_cpl_set_tcb_rpl(struct adapter *adap, unsigned char *input);
230+
int chcr_ktls_xmit(struct sk_buff *skb, struct net_device *dev);
231+
#endif
225232
#endif /* __CHCR_CORE_H__ */

0 commit comments

Comments
 (0)