dpdk/drivers/common/dpaax/caamflib/desc/sdap.h
<<
>>
Prefs
   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
  23static 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
  59static 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
 108static 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
 188static inline int
 189pdcp_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 */
 308static inline int
 309pdcp_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 */
 562static 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
 756static 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
 806static inline int
 807cnstr_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 */
1000static inline int
1001cnstr_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 */
1045static inline int
1046cnstr_shdsc_pdcp_sdap_u_plane_decap(uint32_t *descbuf,
1047                               bool ps,
1048                               bool swap,
1049                               enum pdcp_sn_size sn_size,
1050                               uint32_t hfn,
1051                               unsigned short bearer,
1052                               unsigned short direction,
1053                               uint32_t hfn_threshold,
1054                               struct alginfo *cipherdata,
1055                               struct alginfo *authdata,
1056                               unsigned char era_2_sw_hfn_ovrd)
1057{
1058        return cnstr_shdsc_pdcp_sdap_u_plane(descbuf, ps, swap, sn_size, hfn,
1059                        bearer, direction, hfn_threshold, cipherdata, authdata,
1060                        era_2_sw_hfn_ovrd, OP_TYPE_DECAP_PROTOCOL);
1061}
1062
1063#endif /* __DESC_SDAP_H__ */
1064