File: ionic_crypto.h

package info (click to toggle)
dpdk 25.11-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 127,892 kB
  • sloc: ansic: 2,358,479; python: 16,426; sh: 4,474; makefile: 1,713; awk: 70
file content (361 lines) | stat: -rw-r--r-- 9,424 bytes parent folder | download
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
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright 2021-2024 Advanced Micro Devices, Inc.
 */

#ifndef _IONIC_CRYPTO_H_
#define _IONIC_CRYPTO_H_

#include <stdint.h>
#include <stdbool.h>
#include <inttypes.h>

#include <rte_common.h>
#include <rte_dev.h>
#include <rte_cryptodev.h>
#include <cryptodev_pmd.h>
#include <rte_log.h>
#include <rte_bitmap.h>

#include "ionic_common.h"
#include "ionic_crypto_if.h"
#include "ionic_regs.h"

/* Devargs */
/* NONE */

#define IOCPT_MAX_RING_DESC		32768
#define IOCPT_MIN_RING_DESC		16
#define IOCPT_ADMINQ_LENGTH		16	/* must be a power of two */

#define IOCPT_CRYPTOQ_WAIT		10	/* 1s */

extern int iocpt_logtype;
#define RTE_LOGTYPE_IOCPT iocpt_logtype

#define IOCPT_PRINT(level, ...)						\
	RTE_LOG_LINE_PREFIX(level, IOCPT, "%s(): ", __func__, __VA_ARGS__)

#define IOCPT_PRINT_CALL() IOCPT_PRINT(DEBUG, " >>")

const struct rte_cryptodev_capabilities *iocpt_get_caps(uint64_t flags);

static inline void iocpt_struct_size_checks(void)
{
	RTE_BUILD_BUG_ON(sizeof(struct ionic_doorbell) != 8);
	RTE_BUILD_BUG_ON(sizeof(struct ionic_intr) != 32);
	RTE_BUILD_BUG_ON(sizeof(struct ionic_intr_status) != 8);

	RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_regs) != 4096);
	RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_info_regs) != 2048);
	RTE_BUILD_BUG_ON(sizeof(union iocpt_dev_cmd_regs) != 2048);

	RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_admin_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_nop_comp) != 16);

	/* Device commands */
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_identify_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_dev_reset_comp) != 16);

	/* LIF commands */
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_identify_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_init_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_reset_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_getattr_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_lif_setattr_comp) != 16);

	/* Queue commands */
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_identify_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_cmd) != 64);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_init_comp) != 16);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_q_control_cmd) != 64);

	/* Crypto */
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_desc) != 32);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_sg_desc) != 256);
	RTE_BUILD_BUG_ON(sizeof(struct iocpt_crypto_comp) != 16);
}

struct iocpt_dev_bars {
	struct ionic_dev_bar bar[IONIC_BARS_MAX];
	uint32_t num_bars;
};

/* Queue watchdog */
#define IOCPT_Q_WDOG_SESS_IDX		0
#define IOCPT_Q_WDOG_KEY_LEN		16
#define IOCPT_Q_WDOG_IV_LEN		12
#define IOCPT_Q_WDOG_PLD_LEN		4
#define IOCPT_Q_WDOG_TAG_LEN		16
#define IOCPT_Q_WDOG_OP_TYPE		RTE_CRYPTO_OP_TYPE_UNDEFINED

struct iocpt_qtype_info {
	uint8_t	 version;
	uint8_t	 supported;
	uint64_t features;
	uint16_t desc_sz;
	uint16_t comp_sz;
	uint16_t sg_desc_sz;
	uint16_t max_sg_elems;
	uint16_t sg_desc_stride;
};

#define IOCPT_Q_F_INITED	BIT(0)
#define IOCPT_Q_F_DEFERRED	BIT(1)
#define IOCPT_Q_F_SG		BIT(2)

#define Q_NEXT_TO_POST(_q, _n)	(((_q)->head_idx + (_n)) & ((_q)->size_mask))
#define Q_NEXT_TO_SRVC(_q, _n)	(((_q)->tail_idx + (_n)) & ((_q)->size_mask))

#define IOCPT_INFO_SZ(_q)	((_q)->num_segs * sizeof(void *))
#define IOCPT_INFO_IDX(_q, _i)	((_i) * (_q)->num_segs)
#define IOCPT_INFO_PTR(_q, _i)	(&(_q)->info[IOCPT_INFO_IDX((_q), _i)])

struct iocpt_queue {
	uint16_t num_descs;
	uint16_t num_segs;
	uint16_t head_idx;
	uint16_t tail_idx;
	uint16_t size_mask;
	uint8_t type;
	uint8_t hw_type;
	void *base;
	void *sg_base;
	struct ionic_doorbell __iomem *db;
	void **info;

	uint32_t index;
	uint32_t hw_index;
	rte_iova_t base_pa;
	rte_iova_t sg_base_pa;
};

struct iocpt_cq {
	uint16_t tail_idx;
	uint16_t num_descs;
	uint16_t size_mask;
	bool done_color;
	void *base;
	rte_iova_t base_pa;
};

#define IOCPT_COMMON_FIELDS				\
	struct iocpt_queue q;				\
	struct iocpt_cq cq;				\
	struct iocpt_dev *dev;				\
	const struct rte_memzone *base_z;		\
	void *base;					\
	rte_iova_t base_pa

struct iocpt_common_q {
	IOCPT_COMMON_FIELDS;
};

struct iocpt_admin_q {
	IOCPT_COMMON_FIELDS;

	uint16_t flags;
};

struct iocpt_crypto_q {
	/* cacheline0, cacheline1 */
	IOCPT_COMMON_FIELDS;

	/* cacheline2 */
	uint64_t last_wdog_cycles;
	uint16_t flags;

	/* cacheline3 */
	struct rte_cryptodev_stats stats;

	uint64_t enqueued_wdogs;
	uint64_t dequeued_wdogs;
	uint8_t wdog_iv[IOCPT_Q_WDOG_IV_LEN];
	uint8_t wdog_pld[IOCPT_Q_WDOG_PLD_LEN];
	uint8_t wdog_tag[IOCPT_Q_WDOG_TAG_LEN];
};

#define IOCPT_S_F_INITED	BIT(0)

struct iocpt_session_priv {
	struct iocpt_dev *dev;

	uint32_t index;

	uint16_t iv_offset;
	uint16_t iv_length;
	uint16_t digest_length;
	uint16_t aad_length;

	uint8_t flags;
	uint8_t op;
	uint8_t type;

	uint16_t key_len;
	uint8_t key[IOCPT_SESS_KEY_LEN_MAX_SYMM];
};

static inline uint32_t
iocpt_session_size(void)
{
	return sizeof(struct iocpt_session_priv);
}

#define IOCPT_DEV_F_INITED		BIT(0)
#define IOCPT_DEV_F_UP			BIT(1)
#define IOCPT_DEV_F_FW_RESET		BIT(2)

/* Combined dev / LIF object */
struct iocpt_dev {
	const char *name;
	char fw_version[IOCPT_FWVERS_BUFLEN];
	struct iocpt_dev_bars bars;
	struct iocpt_identity ident;

	const struct iocpt_dev_intf *intf;
	void *bus_dev;
	struct rte_cryptodev *crypto_dev;

	union iocpt_dev_info_regs __iomem *dev_info;
	union iocpt_dev_cmd_regs __iomem *dev_cmd;

	struct ionic_doorbell __iomem *db_pages;
	struct ionic_intr __iomem *intr_ctrl;

	uint32_t max_qps;
	uint32_t max_sessions;
	uint16_t state;
	uint8_t driver_id;
	uint8_t socket_id;

	rte_spinlock_t adminq_lock;
	rte_spinlock_t adminq_service_lock;

	struct iocpt_admin_q *adminq;
	struct iocpt_crypto_q **cryptoqs;

	struct rte_bitmap  *sess_bm;	/* SET bit indicates index is free */

	uint64_t features;
	uint32_t hw_features;

	uint32_t info_sz;
	struct iocpt_lif_info *info;
	rte_iova_t info_pa;
	const struct rte_memzone *info_z;

	struct iocpt_qtype_info qtype_info[IOCPT_QTYPE_MAX];
	uint8_t qtype_ver[IOCPT_QTYPE_MAX];

	struct rte_cryptodev_stats stats_base;
};

struct iocpt_dev_intf {
	int  (*setup_bars)(struct iocpt_dev *dev);
	void (*unmap_bars)(struct iocpt_dev *dev);
};

static inline int
iocpt_setup_bars(struct iocpt_dev *dev)
{
	if (dev->intf->setup_bars == NULL)
		return -EINVAL;

	return dev->intf->setup_bars(dev);
}

/** iocpt_admin_ctx - Admin command context.
 * @pending_work:	Flag that indicates a completion.
 * @cmd:		Admin command (64B) to be copied to the queue.
 * @comp:		Admin completion (16B) copied from the queue.
 */
struct iocpt_admin_ctx {
	bool pending_work;
	union iocpt_adminq_cmd cmd;
	union iocpt_adminq_comp comp;
};

int iocpt_probe(void *bus_dev, struct rte_device *rte_dev,
	struct iocpt_dev_bars *bars, const struct iocpt_dev_intf *intf,
	uint8_t driver_id, uint8_t socket_id);
int iocpt_remove(struct rte_device *rte_dev);

void iocpt_configure(struct iocpt_dev *dev);
int iocpt_assign_ops(struct rte_cryptodev *cdev);
int iocpt_start(struct iocpt_dev *dev);
void iocpt_stop(struct iocpt_dev *dev);
void iocpt_deinit(struct iocpt_dev *dev);

int iocpt_dev_identify(struct iocpt_dev *dev);
int iocpt_dev_init(struct iocpt_dev *dev, rte_iova_t info_pa);
int iocpt_dev_adminq_init(struct iocpt_dev *dev);
void iocpt_dev_reset(struct iocpt_dev *dev);

int iocpt_adminq_post_wait(struct iocpt_dev *dev, struct iocpt_admin_ctx *ctx);

int iocpt_cryptoq_alloc(struct iocpt_dev *dev, uint32_t socket_id,
	uint32_t index, uint16_t ndescs);
void iocpt_cryptoq_free(struct iocpt_crypto_q *cptq);

int iocpt_session_init(struct iocpt_session_priv *priv);
int iocpt_session_update(struct iocpt_session_priv *priv);
void iocpt_session_deinit(struct iocpt_session_priv *priv);

struct ionic_doorbell __iomem *iocpt_db_map(struct iocpt_dev *dev,
	struct iocpt_queue *q);

typedef bool (*iocpt_cq_cb)(struct iocpt_cq *cq, uint16_t cq_desc_index,
		void *cb_arg);
uint32_t iocpt_cq_service(struct iocpt_cq *cq, uint32_t work_to_do,
	iocpt_cq_cb cb, void *cb_arg);

void iocpt_get_stats(const struct iocpt_dev *dev,
	struct rte_cryptodev_stats *stats);
void iocpt_reset_stats(struct iocpt_dev *dev);

static inline uint16_t
iocpt_q_space_avail(struct iocpt_queue *q)
{
	uint16_t avail = q->tail_idx;

	if (q->head_idx >= avail)
		avail += q->num_descs - q->head_idx - 1;
	else
		avail -= q->head_idx + 1;

	return avail;
}

static inline void
iocpt_q_flush(struct iocpt_queue *q)
{
	uint64_t val = IONIC_DBELL_QID(q->hw_index) | q->head_idx;

#if defined(RTE_LIBRTE_IONIC_PMD_BARRIER_ERRATA)
	/* On some devices the standard 'dmb' barrier is insufficient */
	asm volatile("dsb st" : : : "memory");
	rte_write64_relaxed(rte_cpu_to_le_64(val), q->db);
#else
	rte_write64(rte_cpu_to_le_64(val), q->db);
#endif
}

static inline bool
iocpt_is_embedded(void)
{
#if defined(RTE_LIBRTE_IONIC_PMD_EMBEDDED)
	return true;
#else
	return false;
#endif
}

#endif /* _IONIC_CRYPTO_H_ */