xref: /dpdk/drivers/common/dpaax/caamflib/desc/sdap.h (revision 68a03efeed657e6e05f281479b33b51102797e15)
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright 2020 NXP
3  */
4 
5 #ifndef __DESC_SDAP_H__
6 #define __DESC_SDAP_H__
7 
8 #include "rta.h"
9 #include "common.h"
10 #include "pdcp.h"
11 
12 /* The file defines all the functions to do PDCP without protocol support in
13  * SEC
14  */
15 
16 /* Enable SDAP support */
17 #define SDAP_SUPPORT
18 #ifdef SDAP_SUPPORT
19 #define SDAP_BYTE_SIZE 1
20 #define SDAP_BITS_SIZE (SDAP_BYTE_SIZE * 8)
21 #endif
22 
23 static inline void key_loading_opti(struct program *p,
24 				    struct alginfo *cipherdata,
25 				    struct alginfo *authdata)
26 {
27 	LABEL(lbl_skip_key_loading_jump);
28 	REFERENCE(ref_skip_key_loading_jump);
29 
30 	/* Optimisation to bypass key loading (and decryption of the keys):
31 	 * Jump command testing:
32 	 * - SHRD: Descriptor is shared
33 	 * - SELF: The shared descriptor is in the same DECO
34 	 * - BOTH: The Class 1 and 2 CHA have finished
35 	 * -> If this is true, we jump and skip loading of the keys as they are
36 	 *    already loaded
37 	 */
38 	ref_skip_key_loading_jump =
39 		JUMP(p, lbl_skip_key_loading_jump, LOCAL_JUMP, ALL_TRUE,
40 		     SHRD | SELF | BOTH);
41 
42 	/* Load the keys */
43 	if (cipherdata) {
44 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
45 		    cipherdata->keylen, INLINE_KEY(cipherdata));
46 	}
47 
48 	if (authdata) {
49 		KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
50 		    authdata->keylen, INLINE_KEY(authdata));
51 	}
52 
53 	/* Save the place where we want the jump to go */
54 	SET_LABEL(p, lbl_skip_key_loading_jump);
55 	/* Update the jump command with the position where to jump */
56 	PATCH_JUMP(p, ref_skip_key_loading_jump, lbl_skip_key_loading_jump);
57 }
58 
59 static inline int pdcp_sdap_get_sn_parameters(enum pdcp_sn_size sn_size,
60 					      bool swap, uint32_t *offset,
61 					      uint32_t *length,
62 					      uint32_t *sn_mask)
63 {
64 	switch (sn_size) {
65 	case PDCP_SN_SIZE_5:
66 		*offset = 7;
67 		*length = 1;
68 		*sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
69 					     PDCP_C_PLANE_SN_MASK_BE;
70 		break;
71 	case PDCP_SN_SIZE_7:
72 		*offset = 7;
73 		*length = 1;
74 		*sn_mask = (swap == false) ? PDCP_7BIT_SN_MASK :
75 					     PDCP_7BIT_SN_MASK_BE;
76 		break;
77 	case PDCP_SN_SIZE_12:
78 		*offset = 6;
79 		*length = 2;
80 		*sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
81 					     PDCP_12BIT_SN_MASK_BE;
82 		break;
83 	case PDCP_SN_SIZE_15:
84 		*offset = 6;
85 		*length = 2;
86 		*sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
87 					     PDCP_U_PLANE_15BIT_SN_MASK_BE;
88 		break;
89 	case PDCP_SN_SIZE_18:
90 		*offset = 5;
91 		*length = 3;
92 		*sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
93 					     PDCP_U_PLANE_18BIT_SN_MASK_BE;
94 		break;
95 	default:
96 		pr_err("Invalid sn_size for %s\n", __func__);
97 		return -ENOTSUP;
98 	}
99 
100 #ifdef SDAP_SUPPORT
101 	*length += SDAP_BYTE_SIZE;
102 	*offset -= SDAP_BYTE_SIZE;
103 #endif
104 
105 	return 0;
106 }
107 
108 static inline int pdcp_sdap_insert_no_int_op(struct program *p,
109 					     bool swap __maybe_unused,
110 					     struct alginfo *cipherdata,
111 					     unsigned int dir,
112 					     enum pdcp_sn_size sn_size)
113 {
114 	int op;
115 	uint32_t sn_mask = 0;
116 	uint32_t length = 0;
117 	uint32_t offset = 0;
118 
119 	if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
120 					&sn_mask))
121 		return -ENOTSUP;
122 
123 	/* Load key */
124 	key_loading_opti(p, cipherdata, NULL);
125 
126 	SEQLOAD(p, MATH0, offset, length, 0);
127 	JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
128 #ifdef SDAP_SUPPORT
129 	rta_mathi(p, MATH0,
130 		  ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
131 		  SDAP_BITS_SIZE, MATH1, 8, 0);
132 	MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
133 #else
134 	MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
135 #endif
136 
137 	SEQSTORE(p, MATH0, offset, length, 0);
138 
139 	MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
140 	MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
141 	MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
142 
143 	MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
144 	MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
145 
146 	SEQFIFOSTORE(p, MSG, 0, 0, VLF);
147 
148 	op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
149 	switch (cipherdata->algtype) {
150 	case PDCP_CIPHER_TYPE_SNOW:
151 		/* Copy the IV */
152 		MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
153 		ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
154 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
155 		break;
156 
157 	case PDCP_CIPHER_TYPE_AES:
158 		/* The first 64 bits are 0 */
159 		MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
160 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
161 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
162 		break;
163 
164 	case PDCP_CIPHER_TYPE_ZUC:
165 		if (rta_sec_era < RTA_SEC_ERA_5) {
166 			pr_err("Invalid era for selected algorithm\n");
167 			return -ENOTSUP;
168 		}
169 		/* The LSB and MSB is the same for ZUC context */
170 		MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
171 		MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
172 
173 		ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
174 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, op);
175 		break;
176 
177 	default:
178 		pr_err("%s: Invalid encrypt algorithm selected: %d\n",
179 		       "pdcp_sdap_insert_15bit_op", cipherdata->algtype);
180 		return -EINVAL;
181 	}
182 
183 	SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
184 
185 	return 0;
186 }
187 
188 static inline int
189 pdcp_sdap_insert_enc_only_op(struct program *p, bool swap __maybe_unused,
190 			     struct alginfo *cipherdata,
191 			     struct alginfo *authdata __maybe_unused,
192 			     unsigned int dir, enum pdcp_sn_size sn_size,
193 			     unsigned char era_2_sw_hfn_ovrd __maybe_unused)
194 {
195 	uint32_t offset = 0, length = 0, sn_mask = 0;
196 
197 	if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
198 					&sn_mask))
199 		return -ENOTSUP;
200 
201 	/* Load key */
202 	key_loading_opti(p, cipherdata, NULL);
203 
204 	/* Load header */
205 	SEQLOAD(p, MATH0, offset, length, 0);
206 	JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
207 
208 #ifdef SDAP_SUPPORT
209 	rta_mathi(p, MATH0,
210 		  ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
211 		  SDAP_BITS_SIZE, MATH1, 8, 0);
212 	MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
213 #else
214 	MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
215 #endif
216 
217 	/* Word (32 bit) swap */
218 	MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
219 	/* Load words from PDB: word 02 (HFN) + word 03 (bearer_dir)*/
220 	MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
221 	/* Create basic IV */
222 	MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
223 
224 	/* Write header */
225 	SEQSTORE(p, MATH0, offset, length, 0);
226 
227 	if (rta_sec_era > RTA_SEC_ERA_2) {
228 		MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
229 	} else {
230 		MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
231 		MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
232 	}
233 
234 	if (dir == OP_TYPE_ENCAP_PROTOCOL)
235 		MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
236 	else
237 		MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
238 
239 	switch (cipherdata->algtype) {
240 	case PDCP_CIPHER_TYPE_SNOW:
241 		MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
242 		SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
243 		ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8, OP_ALG_AAI_F8,
244 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
245 			      dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
246 							      DIR_DEC);
247 		break;
248 
249 	case PDCP_CIPHER_TYPE_AES:
250 		MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, WAITCOMP | IMMED);
251 
252 		SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
253 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CTR,
254 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
255 			      dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
256 							      DIR_DEC);
257 		break;
258 
259 	case PDCP_CIPHER_TYPE_ZUC:
260 		if (rta_sec_era < RTA_SEC_ERA_5) {
261 			pr_err("Invalid era for selected algorithm\n");
262 			return -ENOTSUP;
263 		}
264 
265 		MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
266 		MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
267 
268 		SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
269 		ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE, OP_ALG_AAI_F8,
270 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
271 			      dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC :
272 							      DIR_DEC);
273 		break;
274 
275 	default:
276 		pr_err("%s: Invalid encrypt algorithm selected: %d\n",
277 		       "pdcp_sdap_insert_enc_only_op", cipherdata->algtype);
278 		return -EINVAL;
279 	}
280 
281 	if (dir == OP_TYPE_ENCAP_PROTOCOL) {
282 		SEQFIFOLOAD(p, MSG1, 0, VLF);
283 		FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
284 			 LAST1 | FLUSH1 | IMMED);
285 	} else {
286 		SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
287 		MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
288 		MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
289 		JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS, HALT_STATUS,
290 		     ALL_FALSE, MATH_Z);
291 	}
292 
293 	return 0;
294 }
295 
296 /*
297  * This function leverage the use of in/out snooping as SNOW and ZUC both
298  * have a class 1 and class 2 CHA. It also supports AES as cipher.
299  * Supported:
300  *  - cipher:
301  *      - AES-CTR
302  *      - SNOW F8
303  *      - ZUC F8
304  *  - authentication
305  *      - SNOW F8
306  *      - ZUC F8
307  */
308 static inline int
309 pdcp_sdap_insert_snoop_op(struct program *p, bool swap __maybe_unused,
310 			  struct alginfo *cipherdata, struct alginfo *authdata,
311 			  unsigned int dir, enum pdcp_sn_size sn_size,
312 			  unsigned char era_2_sw_hfn_ovrd __maybe_unused)
313 {
314 	uint32_t offset = 0, length = 0, sn_mask = 0;
315 	uint32_t int_op_alg = 0;
316 	uint32_t int_op_aai = 0;
317 	uint32_t cipher_op_alg = 0;
318 	uint32_t cipher_op_aai = 0;
319 
320 	if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
321 		if (rta_sec_era < RTA_SEC_ERA_5) {
322 			pr_err("Invalid era for selected algorithm\n");
323 			return -ENOTSUP;
324 		}
325 	}
326 
327 	if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
328 					&sn_mask))
329 		return -ENOTSUP;
330 
331 	if (dir == OP_TYPE_ENCAP_PROTOCOL)
332 		MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
333 
334 	key_loading_opti(p, cipherdata, authdata);
335 
336 	/* Load the PDCP header from the input data
337 	 * Note: SEQINSZ is decremented by length
338 	 */
339 	SEQLOAD(p, MATH0, offset, length, 0);
340 	/* Wait the SN is loaded */
341 	JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
342 
343 	/* Pass the PDCP header to integrity block */
344 	MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
345 
346 #ifdef SDAP_SUPPORT
347 	/* If SDAP is enabled, the least significant byte is the SDAP header
348 	 * Remove it by shifting the register
349 	 */
350 	rta_mathi(p, MATH0,
351 		  ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
352 		  SDAP_BITS_SIZE, MATH1, 8, 0);
353 	/* Mask the PDCP header to keep only the SN */
354 	MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
355 #else
356 	/* Mask the PDCP header to keep only the SN */
357 	MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
358 #endif
359 
360 	/* Do a byte swap, it places the SN in upper part of the MATH reg */
361 	MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
362 
363 	/* Load the HFN / Beare / Dir from the PDB
364 	 * CAAM word are 32bit hence loading 8 byte loads 2 words:
365 	 *  - The HFN at offset 8
366 	 *  - The Bearer / Dir at offset 12
367 	 */
368 	MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
369 	/* Create the 4 first byte of the ICV by oring the math registers */
370 	MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
371 
372 	/* Set the IV of class 1 CHA */
373 	if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
374 		MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
375 	} else {
376 		/* Set the IV for the confidentiality CHA */
377 		MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
378 	}
379 
380 	/* Set the IV of class 2 CHA */
381 	if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
382 		/* Set the IV for the integrity CHA */
383 		MOVEB(p, MATH1, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
384 	} else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
385 		MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
386 
387 		/* Generate the bottom snow IV for integrity
388 		 * Note: MATH1 lowest 32bits is as follow:
389 		 * | bearer (5) | Dir (1) | zero (26) |
390 		 * the resulting math regs will be:
391 		 *               MATH3                           MATH2
392 		 * | zero (5) | Dir (1) | zero (26) | | Bearer (5) | zero (27) |
393 		 */
394 		if (swap == false) {
395 			MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
396 			      MATH2, 4, IMMED2);
397 			MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
398 			      MATH3, 4, IMMED2);
399 		} else {
400 			MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
401 			      MATH2, 4, IMMED2);
402 			MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
403 			      MATH3, 4, IMMED2);
404 		}
405 		/* Word swap MATH3 reg */
406 		MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
407 
408 		/* Don't understand, seems to be doing a move of 12 byte
409 		 * (read MATH2 and overread MATH3)
410 		 */
411 		MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
412 
413 		/* Add the rest of the snow IV to the context */
414 		MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
415 	}
416 
417 	/* Set the variable size of data the register will write */
418 	if (dir == OP_TYPE_ENCAP_PROTOCOL) {
419 		/* We will add the interity data so add its length */
420 		MATHI(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
421 	} else {
422 		/* We will check the interity data so remove its length */
423 		MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
424 		/* Do not take the ICV in the out-snooping configuration */
425 		MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
426 	}
427 
428 	/* We write the PDCP header to output*/
429 	SEQSTORE(p, MATH0, offset, length, 0);
430 
431 	/* Definition of the flow of output data */
432 	if (dir == OP_TYPE_ENCAP_PROTOCOL) {
433 		/* We write data according to VSEQOUTSZ */
434 		SEQFIFOSTORE(p, MSG, 0, 0, VLF);
435 	} else {
436 		/* We write data according to VSEQOUTSZ */
437 		SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
438 	}
439 
440 	/* Get parameters for authentication */
441 	if (authdata->algtype == PDCP_AUTH_TYPE_ZUC) {
442 		int_op_alg = OP_ALG_ALGSEL_ZUCA;
443 		int_op_aai = OP_ALG_AAI_F9;
444 	} else if (authdata->algtype == PDCP_AUTH_TYPE_SNOW) {
445 		int_op_alg = OP_ALG_ALGSEL_SNOW_F9;
446 		int_op_aai = OP_ALG_AAI_F9;
447 	} else {
448 		pr_err("%s no support for auth alg: %d\n", __func__,
449 		       authdata->algtype);
450 		return -1;
451 	}
452 
453 	/* Get parameters for ciphering */
454 	if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
455 		cipher_op_alg = OP_ALG_ALGSEL_ZUCE;
456 		cipher_op_aai = OP_ALG_AAI_F8;
457 	} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
458 		cipher_op_alg = OP_ALG_ALGSEL_SNOW_F8;
459 		cipher_op_aai = OP_ALG_AAI_F8;
460 	} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
461 		cipher_op_alg = OP_ALG_ALGSEL_AES;
462 		cipher_op_aai = OP_ALG_AAI_CTR;
463 	} else {
464 		pr_err("%s no support for cipher alg: %d\n", __func__,
465 		       authdata->algtype);
466 		return -1;
467 	}
468 
469 	/* Configure the CHA, the class 2 CHA must be configured first or an
470 	 * error will be generated
471 	 */
472 
473 	/* Configure the class 2 CHA (integrity )*/
474 	ALG_OPERATION(p, int_op_alg, int_op_aai, OP_ALG_AS_INITFINAL,
475 		      dir == OP_TYPE_ENCAP_PROTOCOL ? ICV_CHECK_DISABLE :
476 						      ICV_CHECK_ENABLE,
477 		      DIR_ENC);
478 
479 	/* Configure class 1 CHA (confidentiality)*/
480 	ALG_OPERATION(p, cipher_op_alg, cipher_op_aai, OP_ALG_AS_INITFINAL,
481 		      ICV_CHECK_DISABLE,
482 		      dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
483 
484 	/* Definition of the flow of input data */
485 	if (dir == OP_TYPE_ENCAP_PROTOCOL) {
486 		/* We read data according to VSEQINSZ
487 		 * Note: we perform an in-snooping, eg the data will be read
488 		 * only once. they will be sent to both the integrity CHA and
489 		 * confidentiality CHA
490 		 */
491 		SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
492 
493 		/* When the integrity CHA is finished, send the ICV stored in
494 		 * the context to the confidentiality CHA for encryption
495 		 */
496 		MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
497 	} else {
498 		/* We read data according to VSEQINSZ
499 		 * Note: we perform an out-snooping, eg the data will be read
500 		 * only once. The will first be sent to the confidentiality
501 		 * CHA for decryption, then the CAAM will direct them to the
502 		 * integrity CHA to verify the ICV (which is at the end of the
503 		 * sequence)
504 		 */
505 		SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
506 
507 		/* Process the ICV by class 1 CHA */
508 		SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
509 
510 		/* Wait for class 1 CHA to finish, the ICV data are stalling in
511 		 * the output fifo
512 		 */
513 		JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
514 
515 		if (rta_sec_era >= RTA_SEC_ERA_6)
516 			LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
517 
518 		/* Save the content left in the Output FIFO (the ICV) to MATH0
519 		 */
520 		MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
521 
522 		/* Configure a NFIFO entry to take data from the altsource
523 		 * and send it to the class 2 CHA as an ICV
524 		 */
525 		NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
526 
527 		/* Move the content of MATH0 (OFIFO offset) to altsource
528 		 * Note: As configured by the altsource, this will send
529 		 * the
530 		 */
531 		if (rta_sec_era <= RTA_SEC_ERA_2) {
532 			/* Shut off automatic Info FIFO entries */
533 			LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
534 			MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
535 		} else {
536 			MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
537 		}
538 	}
539 
540 	if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
541 		/* Reset ZUCA mode and done interrupt
542 		 * Note: If it is not done, DECO generate an error: 200031ca
543 		 * -> ZUCA ICV failed
544 		 */
545 		LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
546 		LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
547 	}
548 
549 	return 0;
550 }
551 
552 /* Function used when the integrity algorithm is a class 1 CHA so outsnooping
553  * is not possible
554  * Supported:
555  *  - cipher:
556  *      - AES-CTR
557  *      - SNOW F8
558  *      - ZUC F8
559  *  - authentication
560  *      - AES-CMAC
561  */
562 static inline int pdcp_sdap_insert_no_snoop_op(
563 	struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
564 	struct alginfo *authdata, unsigned int dir, enum pdcp_sn_size sn_size,
565 	unsigned char era_2_sw_hfn_ovrd __maybe_unused)
566 {
567 	uint32_t offset = 0, length = 0, sn_mask = 0;
568 	uint32_t cipher_alg_op = 0;
569 	uint32_t cipher_alg_aai = 0;
570 
571 	if (authdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
572 		if (rta_sec_era < RTA_SEC_ERA_5) {
573 			pr_err("Invalid era for selected algorithm\n");
574 			return -ENOTSUP;
575 		}
576 	}
577 
578 	if (pdcp_sdap_get_sn_parameters(sn_size, swap, &offset, &length,
579 					&sn_mask))
580 		return -ENOTSUP;
581 
582 	SEQLOAD(p, MATH0, offset, length, 0);
583 	JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
584 
585 #ifdef SDAP_SUPPORT
586 	rta_mathi(p, MATH0,
587 		  ((swap == true) ? MATH_FUN_RSHIFT : MATH_FUN_LSHIFT),
588 		  SDAP_BITS_SIZE, MATH1, 8, 0);
589 	MATHB(p, MATH1, AND, sn_mask, MATH1, 8, IFB | IMMED2);
590 #else
591 	MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
592 #endif
593 
594 	MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
595 	MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED);
596 	MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
597 
598 	SEQSTORE(p, MATH0, offset, length, 0);
599 
600 	if (dir == OP_TYPE_ENCAP_PROTOCOL) {
601 		/* Load authentication key */
602 		KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
603 		    authdata->keylen, INLINE_KEY(authdata));
604 
605 		/* Set the iv for AES authentication */
606 		MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
607 
608 		/* Pass the header */
609 		MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
610 
611 		/* Configure variable size for I/O */
612 		MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
613 		MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
614 
615 		/* Perform the authentication */
616 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
617 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
618 
619 		/* Configure the read of data */
620 		SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
621 
622 		/* Save the ICV generated */
623 		MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
624 
625 		/* The CHA will be reused so we need to clear it */
626 		LOAD(p, CLRW_RESET_CLS1_CHA |
627 		     CLRW_CLR_C1KEY |
628 		     CLRW_CLR_C1CTX |
629 		     CLRW_CLR_C1ICV |
630 		     CLRW_CLR_C1DATAS |
631 		     CLRW_CLR_C1MODE,
632 		     CLRW, 0, 4, IMMED);
633 
634 		/* Load confidentiality key */
635 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
636 		    cipherdata->keylen, INLINE_KEY(cipherdata));
637 
638 		/* Load the IV for ciphering */
639 		if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
640 			MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
641 			cipher_alg_op = OP_ALG_ALGSEL_AES;
642 			cipher_alg_aai = OP_ALG_AAI_CTR;
643 		} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
644 			/* Set the IV for the confidentiality CHA */
645 			MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
646 			cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
647 			cipher_alg_aai = OP_ALG_AAI_F8;
648 		} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
649 			/* Set the IV for the confidentiality CHA */
650 			MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
651 			cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
652 			cipher_alg_aai = OP_ALG_AAI_F8;
653 		}
654 
655 		/* Rewind the pointer on input data to reread it */
656 		SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
657 
658 		/* Define the ciphering operation */
659 		ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
660 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_ENC);
661 
662 		/* Define the data to write */
663 		SEQFIFOSTORE(p, MSG, 0, 0, VLF);
664 
665 		/* Skip the header which does not need to be encrypted */
666 		SEQFIFOLOAD(p, SKIP, length, 0);
667 
668 		/* Read the rest of the data */
669 		SEQFIFOLOAD(p, MSG1, 0, VLF);
670 
671 		/* Send the ICV stored in MATH3 for encryption */
672 		MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
673 	} else {
674 		/* Load the IV for ciphering */
675 		if (cipherdata->algtype == PDCP_CIPHER_TYPE_AES) {
676 			MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
677 			cipher_alg_op = OP_ALG_ALGSEL_AES;
678 			cipher_alg_aai = OP_ALG_AAI_CTR;
679 		} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC) {
680 			/* Set the IV for the confidentiality CHA */
681 			MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
682 			cipher_alg_op = OP_ALG_ALGSEL_ZUCE;
683 			cipher_alg_aai = OP_ALG_AAI_F8;
684 		} else if (cipherdata->algtype == PDCP_CIPHER_TYPE_SNOW) {
685 			/* Set the IV for the confidentiality CHA */
686 			MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
687 			cipher_alg_op = OP_ALG_ALGSEL_SNOW_F8;
688 			cipher_alg_aai = OP_ALG_AAI_F8;
689 		}
690 		MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
691 
692 		/* Read all the data */
693 		MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
694 
695 		/* Do not write back the ICV */
696 		MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
697 
698 		/* Load the key for ciphering */
699 		KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
700 		    cipherdata->keylen, INLINE_KEY(cipherdata));
701 
702 		/* Write all the data */
703 		SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
704 
705 		/* Define the ciphering algorithm */
706 		ALG_OPERATION(p, cipher_alg_op, cipher_alg_aai,
707 			      OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE, DIR_DEC);
708 
709 		/* Read all the data */
710 		SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
711 
712 		/* Save the ICV which is stalling in output FIFO to MATH3 */
713 		MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
714 
715 		/* Reset class 1 CHA */
716 		LOAD(p, CLRW_RESET_CLS1_CHA |
717 		     CLRW_CLR_C1KEY |
718 		     CLRW_CLR_C1CTX |
719 		     CLRW_CLR_C1ICV |
720 		     CLRW_CLR_C1DATAS |
721 		     CLRW_CLR_C1MODE,
722 		     CLRW, 0, 4, IMMED);
723 
724 		/* Load the key for authentcation */
725 		KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
726 		    authdata->keylen, INLINE_KEY(authdata));
727 
728 		/* Start a new sequence */
729 		SEQINPTR(p, 0, 0, SOP);
730 
731 		/* Define the operation to verify the ICV */
732 		ALG_OPERATION(p, OP_ALG_ALGSEL_AES, OP_ALG_AAI_CMAC,
733 			      OP_ALG_AS_INITFINAL, ICV_CHECK_ENABLE, DIR_DEC);
734 
735 		/* Set the variable size input */
736 		MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
737 
738 		MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
739 
740 		SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
741 
742 		/* Define an NFIFO entry to load the ICV saved */
743 		LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
744 		     NFIFOENTRY_DEST_CLASS1 |
745 		     NFIFOENTRY_DTYPE_ICV |
746 		     NFIFOENTRY_LC1 |
747 		     NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
748 
749 		/* Load the ICV */
750 		MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
751 	}
752 
753 	return 0;
754 }
755 
756 static int pdcp_sdap_insert_with_int_op(
757 	struct program *p, bool swap __maybe_unused, struct alginfo *cipherdata,
758 	struct alginfo *authdata, enum pdcp_sn_size sn_size,
759 	unsigned char era_2_sw_hfn_ovrd, unsigned int dir)
760 {
761 	static int (
762 		*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])(
763 		struct program *, bool swap, struct alginfo *, struct alginfo *,
764 		unsigned int, enum pdcp_sn_size,
765 		unsigned char __maybe_unused) = {
766 		{
767 			/* NULL */
768 			pdcp_insert_cplane_null_op,     /* NULL */
769 			pdcp_insert_cplane_int_only_op, /* SNOW f9 */
770 			pdcp_insert_cplane_int_only_op, /* AES CMAC */
771 			pdcp_insert_cplane_int_only_op  /* ZUC-I */
772 		},
773 		{
774 			/* SNOW f8 */
775 			pdcp_sdap_insert_enc_only_op, /* NULL */
776 			pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
777 			pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
778 			pdcp_sdap_insert_snoop_op     /* ZUC-I */
779 		},
780 		{
781 			/* AES CTR */
782 			pdcp_sdap_insert_enc_only_op, /* NULL */
783 			pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
784 			pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
785 			pdcp_sdap_insert_snoop_op     /* ZUC-I */
786 		},
787 		{
788 			/* ZUC-E */
789 			pdcp_sdap_insert_enc_only_op, /* NULL */
790 			pdcp_sdap_insert_snoop_op,    /* SNOW f9 */
791 			pdcp_sdap_insert_no_snoop_op, /* AES CMAC */
792 			pdcp_sdap_insert_snoop_op     /* ZUC-I */
793 		},
794 	};
795 	int err;
796 
797 	err = pdcp_cp_fp[cipherdata->algtype]
798 			[authdata->algtype](p, swap, cipherdata, authdata, dir,
799 					    sn_size, era_2_sw_hfn_ovrd);
800 	if (err)
801 		return err;
802 
803 	return 0;
804 }
805 
806 static inline int
807 cnstr_shdsc_pdcp_sdap_u_plane(uint32_t *descbuf,
808 			       bool ps,
809 			       bool swap,
810 			       enum pdcp_sn_size sn_size,
811 			       uint32_t hfn,
812 			       unsigned short bearer,
813 			       unsigned short direction,
814 			       uint32_t hfn_threshold,
815 			       struct alginfo *cipherdata,
816 			       struct alginfo *authdata,
817 			       unsigned char era_2_sw_hfn_ovrd,
818 			       uint32_t caps_mode)
819 {
820 	struct program prg;
821 	struct program *p = &prg;
822 	int err;
823 	enum pdb_type_e pdb_type;
824 	static enum rta_share_type
825 		desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
826 			{
827 				/* NULL */
828 				SHR_WAIT,   /* NULL */
829 				SHR_ALWAYS, /* SNOW f9 */
830 				SHR_ALWAYS, /* AES CMAC */
831 				SHR_ALWAYS  /* ZUC-I */
832 			},
833 			{
834 				/* SNOW f8 */
835 				SHR_ALWAYS, /* NULL */
836 				SHR_ALWAYS, /* SNOW f9 */
837 				SHR_WAIT,   /* AES CMAC */
838 				SHR_WAIT    /* ZUC-I */
839 			},
840 			{
841 				/* AES CTR */
842 				SHR_ALWAYS, /* NULL */
843 				SHR_ALWAYS, /* SNOW f9 */
844 				SHR_ALWAYS, /* AES CMAC */
845 				SHR_WAIT    /* ZUC-I */
846 			},
847 			{
848 				/* ZUC-E */
849 				SHR_ALWAYS, /* NULL */
850 				SHR_WAIT,   /* SNOW f9 */
851 				SHR_WAIT,   /* AES CMAC */
852 				SHR_WAIT    /* ZUC-I */
853 			},
854 		};
855 
856 	LABEL(pdb_end);
857 
858 	/* Check HFN override for ERA 2 */
859 	if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
860 		pr_err("Cannot select SW HFN ovrd for other era than 2");
861 		return -EINVAL;
862 	}
863 
864 	/* Check the confidentiality algorithm is supported by the code */
865 	switch (cipherdata->algtype) {
866 	case PDCP_CIPHER_TYPE_NULL:
867 	case PDCP_CIPHER_TYPE_SNOW:
868 	case PDCP_CIPHER_TYPE_AES:
869 	case PDCP_CIPHER_TYPE_ZUC:
870 		break;
871 	default:
872 		pr_err("Cipher algorithm not supported: %d\n",
873 				cipherdata->algtype);
874 		return -ENOTSUP;
875 	}
876 
877 	/* Check the authentication algorithm is supported by the code */
878 	if (authdata) {
879 		switch (authdata->algtype) {
880 		case PDCP_AUTH_TYPE_NULL:
881 		case PDCP_AUTH_TYPE_SNOW:
882 		case PDCP_AUTH_TYPE_AES:
883 		case PDCP_AUTH_TYPE_ZUC:
884 			break;
885 		default:
886 			pr_err("Auth algorithm not supported: %d\n",
887 					authdata->algtype);
888 			return -ENOTSUP;
889 		}
890 	}
891 
892 	/* Check the Sequence Number size is supported by the code */
893 	switch (sn_size) {
894 	case PDCP_SN_SIZE_5:
895 	case PDCP_SN_SIZE_7:
896 	case PDCP_SN_SIZE_12:
897 	case PDCP_SN_SIZE_15:
898 	case PDCP_SN_SIZE_18:
899 		break;
900 	default:
901 		pr_err("SN size not supported: %d\n", sn_size);
902 		return -ENOTSUP;
903 	}
904 
905 	/* Check that we are not performing ZUC algo on old platforms */
906 	if (cipherdata->algtype == PDCP_CIPHER_TYPE_ZUC &&
907 			rta_sec_era < RTA_SEC_ERA_5) {
908 		pr_err("ZUC algorithm not supported for era: %d\n",
909 				rta_sec_era);
910 		return -ENOTSUP;
911 	}
912 
913 	/* Initialize the program */
914 	PROGRAM_CNTXT_INIT(p, descbuf, 0);
915 
916 	if (swap)
917 		PROGRAM_SET_BSWAP(p);
918 
919 	if (ps)
920 		PROGRAM_SET_36BIT_ADDR(p);
921 
922 	/* Select the shared descriptor sharing mode */
923 	if (authdata)
924 		SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype],
925 			0, 0);
926 	else
927 		SHR_HDR(p, SHR_ALWAYS, 0, 0);
928 
929 	/* Construct the PDB */
930 	pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer, direction,
931 					  hfn_threshold, cipherdata, authdata);
932 	if (pdb_type == PDCP_PDB_TYPE_INVALID) {
933 		pr_err("Error creating PDCP UPlane PDB\n");
934 		return -EINVAL;
935 	}
936 	SET_LABEL(p, pdb_end);
937 
938 	/* Inser the HFN override operation */
939 	err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
940 	if (err)
941 		return err;
942 
943 	/* Create the descriptor */
944 	if (!authdata) {
945 		if (cipherdata->algtype == PDCP_CIPHER_TYPE_NULL) {
946 			insert_copy_frame_op(p, cipherdata,
947 					     OP_TYPE_ENCAP_PROTOCOL);
948 		} else {
949 			err = pdcp_sdap_insert_no_int_op(p, swap, cipherdata,
950 							 caps_mode,
951 							 sn_size);
952 			if (err) {
953 				pr_err("Fail pdcp_sdap_insert_no_int_op\n");
954 				return err;
955 			}
956 		}
957 	} else {
958 		err = pdcp_sdap_insert_with_int_op(p, swap, cipherdata,
959 						   authdata, sn_size,
960 						   era_2_sw_hfn_ovrd,
961 						   caps_mode);
962 		if (err) {
963 			pr_err("Fail pdcp_sdap_insert_with_int_op\n");
964 			return err;
965 		}
966 	}
967 
968 	PATCH_HDR(p, 0, pdb_end);
969 
970 	return PROGRAM_FINALIZE(p);
971 }
972 
973 /**
974  * cnstr_shdsc_pdcp_sdap_u_plane_encap - Function for creating a PDCP-SDAP
975  *                                       User Plane encapsulation descriptor.
976  * @descbuf: pointer to buffer for descriptor construction
977  * @ps: if 36/40bit addressing is desired, this parameter must be true
978  * @swap: must be true when core endianness doesn't match SEC endianness
979  * @sn_size: selects Sequence Number Size: 7/12/15 bits
980  * @hfn: starting Hyper Frame Number to be used together with the SN from the
981  *       PDCP frames.
982  * @bearer: radio bearer ID
983  * @direction: the direction of the PDCP frame (UL/DL)
984  * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
985  *                 keys should be renegotiated at the earliest convenience.
986  * @cipherdata: pointer to block cipher transform definitions
987  *              Valid algorithm values are those from cipher_type_pdcp enum.
988  * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
989  *                     this descriptor. Note: Can only be used for
990  *                     SEC ERA 2.
991  *
992  * Return: size of descriptor written in words or negative number on error.
993  *         Once the function returns, the value of this parameter can be used
994  *         for reclaiming the space that wasn't used for the descriptor.
995  *
996  * Note: descbuf must be large enough to contain a full 256 byte long
997  * descriptor; after the function returns, by subtracting the actual number of
998  * bytes used, the user can reuse the remaining buffer space for other purposes.
999  */
1000 static inline int
1001 cnstr_shdsc_pdcp_sdap_u_plane_encap(uint32_t *descbuf,
1002 			       bool ps,
1003 			       bool swap,
1004 			       enum pdcp_sn_size sn_size,
1005 			       uint32_t hfn,
1006 			       unsigned short bearer,
1007 			       unsigned short direction,
1008 			       uint32_t hfn_threshold,
1009 			       struct alginfo *cipherdata,
1010 			       struct alginfo *authdata,
1011 			       unsigned char era_2_sw_hfn_ovrd)
1012 {
1013 	return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size,
1014 			hfn, bearer, direction, hfn_threshold, cipherdata,
1015 			authdata, era_2_sw_hfn_ovrd, OP_TYPE_ENCAP_PROTOCOL);
1016 }
1017 
1018 /**
1019  * cnstr_shdsc_pdcp_sdap_u_plane_decap - Function for creating a PDCP-SDAP
1020  *                                       User Plane decapsulation descriptor.
1021  * @descbuf: pointer to buffer for descriptor construction
1022  * @ps: if 36/40bit addressing is desired, this parameter must be true
1023  * @swap: must be true when core endianness doesn't match SEC endianness
1024  * @sn_size: selects Sequence Number Size: 7/12/15 bits
1025  * @hfn: starting Hyper Frame Number to be used together with the SN from the
1026  *       PDCP frames.
1027  * @bearer: radio bearer ID
1028  * @direction: the direction of the PDCP frame (UL/DL)
1029  * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
1030  *                 keys should be renegotiated at the earliest convenience.
1031  * @cipherdata: pointer to block cipher transform definitions
1032  *              Valid algorithm values are those from cipher_type_pdcp enum.
1033  * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
1034  *                     this descriptor. Note: Can only be used for
1035  *                     SEC ERA 2.
1036  *
1037  * Return: size of descriptor written in words or negative number on error.
1038  *         Once the function returns, the value of this parameter can be used
1039  *         for reclaiming the space that wasn't used for the descriptor.
1040  *
1041  * Note: descbuf must be large enough to contain a full 256 byte long
1042  * descriptor; after the function returns, by subtracting the actual number of
1043  * bytes used, the user can reuse the remaining buffer space for other purposes.
1044  */
1045 static inline int
1046 cnstr_shdsc_pdcp_sdap_u_plane_decap(uint32_t *descbuf,
1047 			       bool ps,
1048 			       bool swap,
1049 			       enum pdcp_sn_size sn_size,
1050 			       uint32_t hfn,
1051 			       unsigned short bearer,
1052 			       unsigned short direction,
1053 			       uint32_t hfn_threshold,
1054 			       struct alginfo *cipherdata,
1055 			       struct alginfo *authdata,
1056 			       unsigned char era_2_sw_hfn_ovrd)
1057 {
1058 	return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, hfn,
1059 			bearer, direction, hfn_threshold, cipherdata, authdata,
1060 			era_2_sw_hfn_ovrd, OP_TYPE_DECAP_PROTOCOL);
1061 }
1062 
1063 #endif /* __DESC_SDAP_H__ */
1064