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