aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/crypto/caam_jr/caam_jr_pvt.h
blob: 9f1adabc7d8244213490200d844409bca2891d46 (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
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
/* SPDX-License-Identifier: BSD-3-Clause
 * Copyright 2017-2018 NXP
 */

#ifndef CAAM_JR_PVT_H
#define CAAM_JR_PVT_H

#include <hw/desc/ipsec.h>

/* NXP CAAM JR PMD device name */

#define CAAM_JR_ALG_UNSUPPORT	(-1)

/* Minimum job descriptor consists of a oneword job descriptor HEADER and
 * a pointer to the shared descriptor.
 */
#define MIN_JOB_DESC_SIZE	(CAAM_CMD_SZ + CAAM_PTR_SZ)
#define CAAM_JOB_DESC_SIZE	13

/* CTX_POOL_NUM_BUFS is set as per the ipsec-secgw application */
#define CTX_POOL_NUM_BUFS	32000
#define CTX_POOL_CACHE_SIZE	512

#define DIR_ENC                 1
#define DIR_DEC                 0

#define JR_MAX_NB_MAX_DIGEST	32

#define RTE_CAAM_JR_PMD_MAX_NB_SESSIONS 2048


/* Return codes for SEC user space driver APIs */
enum sec_return_code_e {
	SEC_SUCCESS = 0,	       /* Operation executed successfully.*/
	SEC_INVALID_INPUT_PARAM,       /* API received an invalid input
					* parameter
					*/
	SEC_OUT_OF_MEMORY,	       /* Memory allocation failed. */
	SEC_DESCRIPTOR_IN_FLIGHT,      /* API function indicates there are
					* descriptors in flight
					* for SEC to process.
					*/
	SEC_LAST_DESCRIPTOR_IN_FLIGHT, /* API function indicates there is one
					* last descriptor in flight
					* for SEC to process that.
					*/
	SEC_PROCESSING_ERROR,	       /* Indicates a SEC processing error
					* occurred on a Job Ring which requires
					* a SEC user space driver shutdown. Can
					* be returned from sec_poll_job_ring().
					* Then the only other API that can be
					* called after this error is
					* sec_release().
					*/
	SEC_DESC_PROCESSING_ERROR,     /* Indicates a SEC descriptor processing
					* error occurred on a Job Ring. Can be
					* returned from sec_poll_job_ring().
					* The driver was able to reset job ring
					* and job ring can be used like in a
					* normal case.
					*/
	SEC_JR_IS_FULL,			/* Job Ring is full. There is no more
					 * room in the JR for new descriptors.
					 * This can happen if the descriptor RX
					 * rate is higher than SEC's capacity.
					 */
	SEC_DRIVER_RELEASE_IN_PROGRESS, /* SEC driver shutdown is in progress,
					 * descriptors processing or polling is
					 * allowed.
					 */
	SEC_DRIVER_ALREADY_INITIALIZED, /* SEC driver is already initialized.*/
	SEC_DRIVER_NOT_INITIALIZED,	/* SEC driver is NOT initialized. */
	SEC_JOB_RING_RESET_IN_PROGRESS, /* Job ring is resetting due to a
					 * per-descriptor SEC processing error
					 * ::SEC_desc_PROCESSING_ERROR. Reset is
					 * finished when sec_poll_job_ring()
					 * return. Then the job ring can be used
					 * again.
					 */
	SEC_RESET_ENGINE_FAILED,	/* Resetting of SEC Engine by SEC Kernel
					 * Driver Failed
					 */
	SEC_ENABLE_IRQS_FAILED,		/* Enabling of IRQs in SEC Kernel Driver
					 * Failed
					 */
	SEC_DISABLE_IRQS_FAILED,	/* Disabling of IRQs in SEC Kernel
					 * Driver Failed
					 */
	/* END OF VALID VALUES */

	SEC_RETURN_CODE_MAX_VALUE,	/* Invalid value for return code. It is
					 * used to mark the end of the return
					 * code values. @note ALL new return
					 * code values MUST be added before
					 * ::SEC_RETURN_CODE_MAX_VALUE!
					 */
};

enum caam_jr_op_type {
	CAAM_JR_NONE,  /* No Cipher operations*/
	CAAM_JR_CIPHER,/* CIPHER operations */
	CAAM_JR_AUTH,  /* Authentication Operations */
	CAAM_JR_AEAD,  /* Authenticated Encryption with associated data */
	CAAM_JR_IPSEC, /* IPSEC protocol operations*/
	CAAM_JR_PDCP,  /* PDCP protocol operations*/
	CAAM_JR_PKC,   /* Public Key Cryptographic Operations */
	CAAM_JR_MAX
};

struct caam_jr_session {
	uint8_t dir;         /* Operation Direction */
	enum rte_crypto_cipher_algorithm cipher_alg; /* Cipher Algorithm*/
	enum rte_crypto_auth_algorithm auth_alg; /* Authentication Algorithm*/
	enum rte_crypto_aead_algorithm aead_alg; /* AEAD Algorithm*/
	enum rte_security_session_protocol proto_alg; /* Security Algorithm*/
	union {
		struct {
			uint8_t *data;	/* pointer to key data */
			size_t length;	/* key length in bytes */
		} aead_key;
		struct {
			struct {
				uint8_t *data;	/* pointer to key data */
				size_t length;	/* key length in bytes */
			} cipher_key;
			struct {
				uint8_t *data;	/* pointer to key data */
				size_t length;	/* key length in bytes */
			} auth_key;
		};
	};
	struct {
		uint16_t length;
		uint16_t offset;
	} iv;	/* Initialisation vector parameters */
	uint16_t auth_only_len; /* Length of data for Auth only */
	uint32_t digest_length;
	struct ipsec_encap_pdb encap_pdb;
	struct ip ip4_hdr;
	struct ipsec_decap_pdb decap_pdb;
	struct caam_jr_qp *qp;
	struct sec_cdb *cdb;	/* cmd block associated with qp */
	struct rte_mempool *ctx_pool; /* session mempool for caam_jr_op_ctx */
};

/*
 * 16-byte hardware scatter/gather table
 */

#define SEC4_SG_LEN_EXT		0x80000000	/* Entry points to table */
#define SEC4_SG_LEN_FIN		0x40000000	/* Last ent in table */
#define SEC4_SG_BPID_MASK	0x000000ff
#define SEC4_SG_BPID_SHIFT	16
#define SEC4_SG_LEN_MASK	0x3fffffff	/* Excludes EXT and FINAL */
#define SEC4_SG_OFFSET_MASK	0x00001fff

struct sec4_sg_entry {
	uint64_t ptr;
	uint32_t len;
	uint32_t bpid_offset;
};

#define MAX_SG_ENTRIES		16
#define SG_CACHELINE_0		0
#define SG_CACHELINE_1		4
#define SG_CACHELINE_2		8
#define SG_CACHELINE_3		12

/* Structure encompassing a job descriptor which is to be processed
 * by SEC. User should also initialise this structure with the callback
 * function pointer which will be called by driver after recieving proccessed
 * descriptor from SEC. User data is also passed in this data structure which
 * will be sent as an argument to the user callback function.
 */
struct job_descriptor {
	uint32_t desc[CAAM_JOB_DESC_SIZE];
};

struct caam_jr_op_ctx {
	struct job_descriptor jobdes;
	/* sg[0] output, sg[1] input, others are possible sub frames */
	struct sec4_sg_entry sg[MAX_SG_ENTRIES];
	struct rte_crypto_op *op;
	struct rte_mempool *ctx_pool; /* mempool pointer for caam_jr_op_ctx */
	int64_t vtop_offset;
	uint8_t digest[JR_MAX_NB_MAX_DIGEST];
};

/**
 * Checksum
 *
 * @param buffer calculate chksum for buffer
 * @param len    buffer length
 *
 * @return checksum value in host cpu order
 */
static inline uint16_t
calc_chksum(void *buffer, int len)
{
	uint16_t *buf = (uint16_t *)buffer;
	uint32_t sum = 0;
	uint16_t result;

	for (sum = 0; len > 1; len -= 2)
		sum += *buf++;

	if (len == 1)
		sum += *(unsigned char *)buf;

	sum = (sum >> 16) + (sum & 0xFFFF);
	sum += (sum >> 16);
	result = ~sum;

	return  result;
}
struct uio_job_ring {
	uint32_t jr_id;
	uint32_t uio_fd;
	void *register_base_addr;
	int map_size;
	int uio_minor_number;
};

int sec_cleanup(void);
int sec_configure(void);
struct uio_job_ring *config_job_ring(void);
void free_job_ring(uint32_t uio_fd);

/* For Dma memory allocation of specified length and alignment */
static inline void *
caam_jr_dma_mem_alloc(size_t align, size_t len)
{
	return rte_malloc("mem_alloc", len, align);
}

/* For freeing dma memory */
static inline void
caam_jr_dma_free(void *ptr)
{
	rte_free(ptr);
}

static inline rte_iova_t
caam_jr_mem_vtop(void *vaddr)
{
	const struct rte_memseg *ms;

	ms = rte_mem_virt2memseg(vaddr, NULL);
	if (ms)
		return ms->iova + RTE_PTR_DIFF(vaddr, ms->addr);
	return (size_t)NULL;
}

static inline void *
caam_jr_dma_ptov(rte_iova_t paddr)
{
	return rte_mem_iova2virt(paddr);
}

/* Virtual to physical address conversion */
static inline rte_iova_t caam_jr_dma_vtop(void *ptr)
{
	return caam_jr_mem_vtop(ptr);
}

/** @brief Request to SEC kernel driver to enable interrupts for
 *         descriptor finished processing
 *  Use UIO to communicate with SEC kernel driver: write command
 *  value that indicates an IRQ enable action into UIO file descriptor
 *  of this job ring.
 *
 * @param [in]  uio_fd     Job Ring UIO File descriptor
 * @retval 0 for success
 * @retval -1 value for error
 */
uint32_t caam_jr_enable_irqs(uint32_t uio_fd);

/** @brief Request to SEC kernel driver to disable interrupts for descriptor
 *  finished processing
 *  Use UIO to communicate with SEC kernel driver: write command
 *  value that indicates an IRQ disable action into UIO file descriptor
 *  of this job ring.
 *
 * @param [in]  uio_fd    UIO File descripto
 * @retval 0 for success
 * @retval -1 value for error
 *
 */
uint32_t caam_jr_disable_irqs(uint32_t uio_fd);

#endif