summaryrefslogtreecommitdiffstats
path: root/drivers/net/ethernet/marvell/octeontx2/nic/cn10k_ipsec.h
blob: 9965df0faa3e7d7c5c91f6f270c8b9a885668658 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
/* SPDX-License-Identifier: GPL-2.0 */
/* Marvell IPSEC offload driver
 *
 * Copyright (C) 2024 Marvell.
 */

#ifndef CN10K_IPSEC_H
#define CN10K_IPSEC_H

#include <linux/types.h>

DECLARE_STATIC_KEY_FALSE(cn10k_ipsec_sa_enabled);

/* CPT instruction size in bytes */
#define CN10K_CPT_INST_SIZE	64

/* CPT instruction (CPT_INST_S) queue length */
#define CN10K_CPT_INST_QLEN	8200

/* CPT instruction queue size passed to HW is in units of
 * 40*CPT_INST_S messages.
 */
#define CN10K_CPT_SIZE_DIV40 (CN10K_CPT_INST_QLEN / 40)

/* CPT needs 320 free entries */
#define CN10K_CPT_INST_QLEN_EXTRA_BYTES	(320 * CN10K_CPT_INST_SIZE)
#define CN10K_CPT_EXTRA_SIZE_DIV40	(320 / 40)

/* CPT instruction queue length in bytes */
#define CN10K_CPT_INST_QLEN_BYTES					\
		((CN10K_CPT_SIZE_DIV40 * 40 * CN10K_CPT_INST_SIZE) +	\
		CN10K_CPT_INST_QLEN_EXTRA_BYTES)

/* CPT instruction group queue length in bytes */
#define CN10K_CPT_INST_GRP_QLEN_BYTES					\
		((CN10K_CPT_SIZE_DIV40 + CN10K_CPT_EXTRA_SIZE_DIV40) * 16)

/* CPT FC length in bytes */
#define CN10K_CPT_Q_FC_LEN 128

/* Default CPT engine group for ipsec offload */
#define CN10K_DEF_CPT_IPSEC_EGRP 1

/* CN10K CPT LF registers */
#define CPT_LFBASE			(BLKTYPE_CPT << RVU_FUNC_BLKADDR_SHIFT)
#define CN10K_CPT_LF_CTL		(CPT_LFBASE | 0x10)
#define CN10K_CPT_LF_INPROG		(CPT_LFBASE | 0x40)
#define CN10K_CPT_LF_Q_BASE		(CPT_LFBASE | 0xf0)
#define CN10K_CPT_LF_Q_SIZE		(CPT_LFBASE | 0x100)
#define CN10K_CPT_LF_Q_INST_PTR		(CPT_LFBASE | 0x110)
#define CN10K_CPT_LF_Q_GRP_PTR		(CPT_LFBASE | 0x120)
#define CN10K_CPT_LF_NQX(a)		(CPT_LFBASE | 0x400 | (a) << 3)
#define CN10K_CPT_LF_CTX_FLUSH		(CPT_LFBASE | 0x510)

/* IPSEC Instruction opcodes */
#define CN10K_IPSEC_MAJOR_OP_WRITE_SA 0x01UL
#define CN10K_IPSEC_MINOR_OP_WRITE_SA 0x09UL
#define CN10K_IPSEC_MAJOR_OP_OUTB_IPSEC 0x2AUL

enum cn10k_cpt_comp_e {
	CN10K_CPT_COMP_E_NOTDONE = 0x00,
	CN10K_CPT_COMP_E_GOOD = 0x01,
	CN10K_CPT_COMP_E_FAULT = 0x02,
	CN10K_CPT_COMP_E_HWERR = 0x04,
	CN10K_CPT_COMP_E_INSTERR = 0x05,
	CN10K_CPT_COMP_E_WARN = 0x06,
	CN10K_CPT_COMP_E_MASK = 0x3F
};

struct cn10k_cpt_inst_queue {
	u8 *vaddr;
	u8 *real_vaddr;
	dma_addr_t dma_addr;
	dma_addr_t real_dma_addr;
	u32 size;
};

enum cn10k_cpt_hw_state_e {
	CN10K_CPT_HW_UNAVAILABLE,
	CN10K_CPT_HW_AVAILABLE,
	CN10K_CPT_HW_IN_USE
};

struct cn10k_ipsec {
	/* Outbound CPT */
	u64 io_addr;
	atomic_t cpt_state;
	struct cn10k_cpt_inst_queue iq;

	/* SA info */
	u32 sa_size;
	u32 outb_sa_count;
	struct work_struct sa_work;
	struct workqueue_struct *sa_workq;
};

/* CN10K IPSEC Security Association (SA) */
/* SA direction */
#define CN10K_IPSEC_SA_DIR_INB			0
#define CN10K_IPSEC_SA_DIR_OUTB			1
/* SA protocol */
#define CN10K_IPSEC_SA_IPSEC_PROTO_AH		0
#define CN10K_IPSEC_SA_IPSEC_PROTO_ESP		1
/* SA Encryption Type */
#define CN10K_IPSEC_SA_ENCAP_TYPE_AES_GCM	5
/* SA IPSEC mode Transport/Tunnel */
#define CN10K_IPSEC_SA_IPSEC_MODE_TRANSPORT	0
#define CN10K_IPSEC_SA_IPSEC_MODE_TUNNEL	1
/* SA AES Key Length */
#define CN10K_IPSEC_SA_AES_KEY_LEN_128		1
#define CN10K_IPSEC_SA_AES_KEY_LEN_192		2
#define CN10K_IPSEC_SA_AES_KEY_LEN_256		3
/* IV Source */
#define CN10K_IPSEC_SA_IV_SRC_COUNTER		0
#define CN10K_IPSEC_SA_IV_SRC_PACKET		3

struct cn10k_tx_sa_s {
	u64 esn_en		: 1; /* W0 */
	u64 rsvd_w0_1_8		: 8;
	u64 hw_ctx_off		: 7;
	u64 ctx_id		: 16;
	u64 rsvd_w0_32_47	: 16;
	u64 ctx_push_size	: 7;
	u64 rsvd_w0_55		: 1;
	u64 ctx_hdr_size	: 2;
	u64 aop_valid		: 1;
	u64 rsvd_w0_59		: 1;
	u64 ctx_size		: 4;
	u64 w1;			/* W1 */
	u64 sa_valid		: 1; /* W2 */
	u64 sa_dir		: 1;
	u64 rsvd_w2_2_3		: 2;
	u64 ipsec_mode		: 1;
	u64 ipsec_protocol	: 1;
	u64 aes_key_len		: 2;
	u64 enc_type		: 3;
	u64 rsvd_w2_11_19	: 9;
	u64 iv_src		: 2;
	u64 rsvd_w2_22_31	: 10;
	u64 rsvd_w2_32_63	: 32;
	u64 w3;			/* W3 */
	u8 cipher_key[32];	/* W4 - W7 */
	u32 rsvd_w8_0_31;	/* W8 : IV */
	u32 iv_gcm_salt;
	u64 rsvd_w9_w30[22];	/* W9 - W30 */
	u64 hw_ctx[6];		/* W31 - W36 */
};

/* CPT instruction parameter-1 */
#define CN10K_IPSEC_INST_PARAM1_DIS_L4_CSUM		0x1
#define CN10K_IPSEC_INST_PARAM1_DIS_L3_CSUM		0x2
#define CN10K_IPSEC_INST_PARAM1_CRYPTO_MODE		0x20
#define CN10K_IPSEC_INST_PARAM1_IV_OFFSET_SHIFT		8

/* CPT instruction parameter-2 */
#define CN10K_IPSEC_INST_PARAM2_ENC_DATA_OFFSET_SHIFT	0
#define CN10K_IPSEC_INST_PARAM2_AUTH_DATA_OFFSET_SHIFT	8

/* CPT Instruction Structure */
struct cpt_inst_s {
	u64 nixtxl		: 3; /* W0 */
	u64 doneint		: 1;
	u64 rsvd_w0_4_15	: 12;
	u64 dat_offset		: 8;
	u64 ext_param1		: 8;
	u64 nixtx_offset	: 20;
	u64 rsvd_w0_52_63	: 12;
	u64 res_addr;		/* W1 */
	u64 tag			: 32; /* W2 */
	u64 tt			: 2;
	u64 grp			: 10;
	u64 rsvd_w2_44_47	: 4;
	u64 rvu_pf_func		: 16;
	u64 qord		: 1; /* W3 */
	u64 rsvd_w3_1_2		: 2;
	u64 wqe_ptr		: 61;
	u64 dlen		: 16; /* W4 */
	u64 param2		: 16;
	u64 param1		: 16;
	u64 opcode_major	: 8;
	u64 opcode_minor	: 8;
	u64 dptr;		/* W5 */
	u64 rptr;		/* W6 */
	u64 cptr		: 60; /* W7 */
	u64 ctx_val		: 1;
	u64 egrp		: 3;
};

/* CPT Instruction Result Structure */
struct cpt_res_s {
	u64 compcode		: 7; /* W0 */
	u64 doneint		: 1;
	u64 uc_compcode		: 8;
	u64 uc_info		: 48;
	u64 esn;		/* W1 */
};

/* CPT SG structure */
struct cpt_sg_s {
	u64 seg1_size	: 16;
	u64 seg2_size	: 16;
	u64 seg3_size	: 16;
	u64 segs	: 2;
	u64 rsvd_63_50	: 14;
};

/* CPT LF_INPROG Register */
#define CPT_LF_INPROG_INFLIGHT	GENMASK_ULL(8, 0)
#define CPT_LF_INPROG_GRB_CNT	GENMASK_ULL(39, 32)
#define CPT_LF_INPROG_GWB_CNT	GENMASK_ULL(47, 40)

/* CPT LF_Q_GRP_PTR Register */
#define CPT_LF_Q_GRP_PTR_DQ_PTR	GENMASK_ULL(14, 0)
#define CPT_LF_Q_GRP_PTR_NQ_PTR	GENMASK_ULL(46, 32)

/* CPT LF_Q_SIZE Register */
#define CPT_LF_Q_BASE_ADDR GENMASK_ULL(52, 7)

/* CPT LF_Q_SIZE Register */
#define CPT_LF_Q_SIZE_DIV40 GENMASK_ULL(14, 0)

/* CPT LF CTX Flush Register */
#define CPT_LF_CTX_FLUSH GENMASK_ULL(45, 0)

#ifdef CONFIG_XFRM_OFFLOAD
int cn10k_ipsec_init(struct net_device *netdev);
void cn10k_ipsec_clean(struct otx2_nic *pf);
int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable);
bool otx2_sqe_add_sg_ipsec(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
			   struct sk_buff *skb, int num_segs, int *offset);
bool cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq,
			  struct otx2_snd_queue *sq, struct sk_buff *skb,
			  int num_segs, int size);
#else
static inline __maybe_unused int cn10k_ipsec_init(struct net_device *netdev)
{
	return 0;
}

static inline __maybe_unused void cn10k_ipsec_clean(struct otx2_nic *pf)
{
}

static inline __maybe_unused
int cn10k_ipsec_ethtool_init(struct net_device *netdev, bool enable)
{
	return 0;
}

static inline bool __maybe_unused
otx2_sqe_add_sg_ipsec(struct otx2_nic *pfvf, struct otx2_snd_queue *sq,
		      struct sk_buff *skb, int num_segs, int *offset)
{
	return true;
}

static inline bool __maybe_unused
cn10k_ipsec_transmit(struct otx2_nic *pf, struct netdev_queue *txq,
		     struct otx2_snd_queue *sq, struct sk_buff *skb,
		     int num_segs, int size)
{
	return true;
}
#endif
#endif // CN10K_IPSEC_H