net/mlx5: support connection tracking between two ports
[dpdk.git] / drivers / common / dpaax / caamflib / desc / sdap.h
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__ */