1 /* SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
2 * Copyright 2008-2013 Freescale Semiconductor, Inc.
3 * Copyright 2019-2020 NXP
6 #ifndef __DESC_PDCP_H__
7 #define __DESC_PDCP_H__
13 * DOC: PDCP Shared Descriptor Constructors
15 * Shared descriptors for PDCP protocol.
19 * PDCP_NULL_MAX_FRAME_LEN - The maximum frame frame length that is supported by
22 #define PDCP_NULL_MAX_FRAME_LEN 0x00002FFF
25 * PDCP_MAC_I_LEN - The length of the MAC-I for PDCP protocol operation
27 #define PDCP_MAC_I_LEN 0x00000004
30 * PDCP_MAX_FRAME_LEN_STATUS - The status returned in FD status/command field in
31 * case the input frame is larger than
32 * PDCP_NULL_MAX_FRAME_LEN.
34 #define PDCP_MAX_FRAME_LEN_STATUS 0xF1
37 * PDCP_C_PLANE_SN_MASK - This mask is used in the PDCP descriptors for
38 * extracting the sequence number (SN) from the PDCP
39 * Control Plane header. For PDCP Control Plane, the SN
40 * is constant (5 bits) as opposed to PDCP Data Plane
43 #define PDCP_C_PLANE_SN_MASK 0x1F000000
44 #define PDCP_C_PLANE_SN_MASK_BE 0x0000001F
47 * PDCP_12BIT_SN_MASK - This mask is used in the PDCP descriptors for
48 * extracting the sequence number (SN) from the
49 * PDCP User Plane header.
51 #define PDCP_12BIT_SN_MASK 0xFF0F0000
52 #define PDCP_12BIT_SN_MASK_BE 0x00000FFF
55 * PDCP_U_PLANE_15BIT_SN_MASK - This mask is used in the PDCP descriptors for
56 * extracting the sequence number (SN) from the
57 * PDCP User Plane header. For PDCP Control Plane,
58 * the SN is constant (5 bits) as opposed to PDCP
59 * Data Plane (7/12/15 bits).
61 #define PDCP_U_PLANE_15BIT_SN_MASK 0xFF7F0000
62 #define PDCP_U_PLANE_15BIT_SN_MASK_BE 0x00007FFF
65 * PDCP_U_PLANE_18BIT_SN_MASK - This mask is used in the PDCP descriptors for
66 * extracting the sequence number (SN) from the
67 * PDCP User Plane header.
69 #define PDCP_U_PLANE_18BIT_SN_MASK 0xFFFF0300
70 #define PDCP_U_PLANE_18BIT_SN_MASK_BE 0x0003FFFF
73 * PDCP_BEARER_MASK - This mask is used masking out the bearer for PDCP
74 * processing with SNOW f9 in LTE.
76 * The value on which this mask is applied is formatted as below:
77 * Count-C (32 bit) | Bearer (5 bit) | Direction (1 bit) | 0 (26 bits)
79 * Applying this mask is done for creating the upper 64 bits of the IV needed
82 * The lower 32 bits of the mask are used for masking the direction for AES
85 #define PDCP_BEARER_MASK 0x00000004FFFFFFFFull
86 #define PDCP_BEARER_MASK_BE 0xFFFFFFFF04000000ull
89 * PDCP_DIR_MASK - This mask is used masking out the direction for PDCP
90 * processing with SNOW f9 in LTE.
92 * The value on which this mask is applied is formatted as below:
93 * Bearer (5 bit) | Direction (1 bit) | 0 (26 bits)
95 * Applying this mask is done for creating the lower 32 bits of the IV needed
98 * The upper 32 bits of the mask are used for masking the direction for AES
101 #define PDCP_DIR_MASK 0x00000000000000F8ull
102 #define PDCP_DIR_MASK_BE 0xF800000000000000ull
105 * PDCP_NULL_INT_MAC_I_VAL - The value of the PDCP PDU MAC-I in case NULL
109 #define PDCP_NULL_INT_MAC_I_VAL 0x00000000
112 * PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS - The status used to report ICV check
113 * failed in case of NULL integrity
114 * Control Plane processing.
116 #define PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS 0x0A
118 * PDCP_DPOVRD_HFN_OV_EN - Value to be used in the FD status/cmd field to
119 * indicate the HFN override mechanism is active for the
122 #define PDCP_DPOVRD_HFN_OV_EN 0x80000000
125 * PDCP_P4080REV2_HFN_OV_BUFLEN - The length in bytes of the supplementary space
126 * that must be provided by the user at the
127 * beginning of the input frame buffer for
130 * The format of the frame buffer is the following:
132 * |<---PDCP_P4080REV2_HFN_OV_BUFLEN-->|
133 * //===================================||============||==============\\
134 * || PDCP_DPOVRD_HFN_OV_EN | HFN value || PDCP Header|| PDCP Payload ||
135 * \\===================================||============||==============//
137 * If HFN override mechanism is not desired, then the MSB of the first 4 bytes
140 #define PDCP_P4080REV2_HFN_OV_BUFLEN 4
143 * enum cipher_type_pdcp - Type selectors for cipher types in PDCP protocol OP
145 * @PDCP_CIPHER_TYPE_NULL: NULL
146 * @PDCP_CIPHER_TYPE_SNOW: SNOW F8
147 * @PDCP_CIPHER_TYPE_AES: AES
148 * @PDCP_CIPHER_TYPE_ZUC: ZUCE
149 * @PDCP_CIPHER_TYPE_INVALID: invalid option
151 enum cipher_type_pdcp {
152 PDCP_CIPHER_TYPE_NULL,
153 PDCP_CIPHER_TYPE_SNOW,
154 PDCP_CIPHER_TYPE_AES,
155 PDCP_CIPHER_TYPE_ZUC,
156 PDCP_CIPHER_TYPE_INVALID
160 * enum auth_type_pdcp - Type selectors for integrity types in PDCP protocol OP
162 * @PDCP_AUTH_TYPE_NULL: NULL
163 * @PDCP_AUTH_TYPE_SNOW: SNOW F9
164 * @PDCP_AUTH_TYPE_AES: AES CMAC
165 * @PDCP_AUTH_TYPE_ZUC: ZUCA
166 * @PDCP_AUTH_TYPE_INVALID: invalid option
168 enum auth_type_pdcp {
173 PDCP_AUTH_TYPE_INVALID
177 * enum pdcp_dir - Type selectors for direction for PDCP protocol
178 * @PDCP_DIR_UPLINK: uplink direction
179 * @PDCP_DIR_DOWNLINK: downlink direction
180 * @PDCP_DIR_INVALID: invalid option
184 PDCP_DIR_DOWNLINK = 1,
189 * enum pdcp_plane - PDCP domain selectors
190 * @PDCP_CONTROL_PLANE: Control Plane
191 * @PDCP_DATA_PLANE: Data Plane
192 * @PDCP_SHORT_MAC: Short MAC
201 * enum pdcp_sn_size - Sequence Number Size selectors for PDCP protocol
202 * @PDCP_SN_SIZE_5: 5bit sequence number
203 * @PDCP_SN_SIZE_7: 7bit sequence number
204 * @PDCP_SN_SIZE_12: 12bit sequence number
205 * @PDCP_SN_SIZE_15: 15bit sequence number
206 * @PDCP_SN_SIZE_18: 18bit sequence number
211 PDCP_SN_SIZE_12 = 12,
212 PDCP_SN_SIZE_15 = 15,
217 * PDCP Control Plane Protocol Data Blocks
219 #define PDCP_C_PLANE_PDB_HFN_SHIFT 5
220 #define PDCP_C_PLANE_PDB_BEARER_SHIFT 27
221 #define PDCP_C_PLANE_PDB_DIR_SHIFT 26
222 #define PDCP_C_PLANE_PDB_HFN_THR_SHIFT 5
224 #define PDCP_U_PLANE_PDB_OPT_SHORT_SN 0x2
225 #define PDCP_U_PLANE_PDB_OPT_15B_SN 0x4
226 #define PDCP_U_PLANE_PDB_OPT_18B_SN 0x6
227 #define PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT 7
228 #define PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT 12
229 #define PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT 15
230 #define PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT 18
231 #define PDCP_U_PLANE_PDB_BEARER_SHIFT 27
232 #define PDCP_U_PLANE_PDB_DIR_SHIFT 26
233 #define PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT 7
234 #define PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT 12
235 #define PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT 15
236 #define PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT 18
243 uint32_t hfn_res; /* HyperFrame number,(27, 25 or 21 bits),
244 * left aligned & right-padded with zeros.
246 uint32_t bearer_dir_res;/* Bearer(5 bits), packet direction (1 bit),
247 * left aligned & right-padded with zeros.
249 uint32_t hfn_thr_res; /* HyperFrame number threshold (27, 25 or 21
250 * bits), left aligned & right-padded with
256 * PDCP internal PDB types
259 PDCP_PDB_TYPE_NO_PDB,
260 PDCP_PDB_TYPE_FULL_PDB,
261 PDCP_PDB_TYPE_REDUCED_PDB,
262 PDCP_PDB_TYPE_INVALID
266 * rta_inline_pdcp_query() - Provide indications if a key can be passed as
267 * immediate data or shall be referenced in a
269 * Return: 0 if data can be inlined or 1 if referenced.
272 rta_inline_pdcp_query(enum auth_type_pdcp auth_alg,
273 enum cipher_type_pdcp cipher_alg,
274 enum pdcp_sn_size sn_size,
278 * Shared Descriptors for some of the cases does not fit in the
279 * MAX_DESC_SIZE of the descriptor especially when non-protocol
280 * descriptors are formed as in 18bit cases and when HFN override
281 * is enabled as 2 extra words are added in the job descriptor.
282 * The cases which exceed are for RTA_SEC_ERA=8 and HFN override
283 * enabled and 18bit uplane and either of following Algo combinations.
289 * We cannot make inline for all cases, as this will impact performance
290 * due to extra memory accesses for the keys.
292 if ((rta_sec_era == RTA_SEC_ERA_8) && hfn_ovd &&
293 (sn_size == PDCP_SN_SIZE_18) &&
294 ((cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
295 auth_alg == PDCP_AUTH_TYPE_AES) ||
296 (cipher_alg == PDCP_CIPHER_TYPE_AES &&
297 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
298 (cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
299 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
300 (cipher_alg == PDCP_CIPHER_TYPE_ZUC &&
301 auth_alg == PDCP_AUTH_TYPE_SNOW))) {
310 * Function for appending the portion of a PDCP Control Plane shared descriptor
311 * which performs NULL encryption and integrity (i.e. copies the input frame
312 * to the output frame, appending 32 bits of zeros at the end (MAC-I for
316 pdcp_insert_cplane_null_op(struct program *p,
317 bool swap __maybe_unused,
318 struct alginfo *cipherdata __maybe_unused,
319 struct alginfo *authdata __maybe_unused,
321 enum pdcp_sn_size sn_size __maybe_unused,
322 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
325 REFERENCE(move_cmd_read_descbuf);
326 REFERENCE(move_cmd_write_descbuf);
328 if (rta_sec_era > RTA_SEC_ERA_2) {
329 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
330 if (dir == OP_TYPE_ENCAP_PROTOCOL)
331 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
334 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
337 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
338 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
340 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
341 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
343 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
345 MATHB(p, VSEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4,
347 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
349 MATHB(p, VSEQOUTSZ, SUB, ONE, MATH0, 4, 0);
352 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
355 * Since MOVELEN is available only starting with
356 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
357 * command dynamically by writing the length from M1 by
358 * OR-ing the command in the M1 register and MOVE the
359 * result into the descriptor buffer. Care must be taken
360 * wrt. the location of the command because of SEC
361 * pipelining. The actual MOVEs are written at the end
362 * of the descriptor due to calculations needed on the
363 * offset in the descriptor for the MOVE command.
365 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
367 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
370 MATHB(p, VSEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
372 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
374 if (rta_sec_era > RTA_SEC_ERA_2) {
375 if (dir == OP_TYPE_ENCAP_PROTOCOL)
376 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
378 MATHB(p, VSEQOUTSZ, ADD, ZERO, MATH0, 4, 0);
380 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
381 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
383 if (rta_sec_era > RTA_SEC_ERA_2) {
384 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
386 SET_LABEL(p, local_offset);
388 /* Shut off automatic Info FIFO entries */
389 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
390 /* Placeholder for MOVE command with length from M1 register */
391 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
392 /* Enable automatic Info FIFO entries */
393 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
396 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
397 MATHB(p, MATH1, XOR, MATH1, MATH0, 8, 0);
398 MOVE(p, MATH0, 0, OFIFO, 0, 4, IMMED);
401 if (rta_sec_era < RTA_SEC_ERA_3) {
402 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
403 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
410 insert_copy_frame_op(struct program *p,
411 struct alginfo *cipherdata __maybe_unused,
412 unsigned int dir __maybe_unused)
415 REFERENCE(move_cmd_read_descbuf);
416 REFERENCE(move_cmd_write_descbuf);
418 if (rta_sec_era > RTA_SEC_ERA_2) {
419 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
420 MATHB(p, SEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
422 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
423 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
424 MATHB(p, SEQINSZ, ADD, ONE, VSEQOUTSZ, 4, 0);
425 MATHB(p, VSEQOUTSZ, SUB, ONE, VSEQOUTSZ, 4, 0);
426 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
427 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
430 * Since MOVELEN is available only starting with
431 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
432 * command dynamically by writing the length from M1 by
433 * OR-ing the command in the M1 register and MOVE the
434 * result into the descriptor buffer. Care must be taken
435 * wrt. the location of the command because of SEC
436 * pipelining. The actual MOVEs are written at the end
437 * of the descriptor due to calculations needed on the
438 * offset in the descriptor for the MOVE command.
440 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
442 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
445 MATHB(p, SEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
447 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
449 if (rta_sec_era > RTA_SEC_ERA_2)
450 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
452 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
453 if (rta_sec_era > RTA_SEC_ERA_2) {
454 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
456 SET_LABEL(p, local_offset);
458 /* Shut off automatic Info FIFO entries */
459 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
461 /* Placeholder for MOVE command with length from M0 register */
462 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
464 /* Enable automatic Info FIFO entries */
465 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
468 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
470 if (rta_sec_era < RTA_SEC_ERA_3) {
471 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
472 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
478 pdcp_insert_cplane_int_only_op(struct program *p,
479 bool swap __maybe_unused,
480 struct alginfo *cipherdata __maybe_unused,
481 struct alginfo *authdata, unsigned int dir,
482 enum pdcp_sn_size sn_size,
483 unsigned char era_2_sw_hfn_ovrd)
485 uint32_t offset = 0, length = 0, sn_mask = 0;
487 /* 12 bit SN is only supported for protocol offload case */
488 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_12) {
489 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
490 authdata->keylen, INLINE_KEY(authdata));
492 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
493 (uint16_t)authdata->algtype);
497 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
502 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
503 PDCP_C_PLANE_SN_MASK_BE;
505 case PDCP_SN_SIZE_18:
508 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
509 PDCP_U_PLANE_18BIT_SN_MASK_BE;
512 case PDCP_SN_SIZE_12:
513 case PDCP_SN_SIZE_15:
514 pr_err("Invalid sn_size for %s\n", __func__);
519 REFERENCE(move_cmd_read_descbuf);
520 REFERENCE(move_cmd_write_descbuf);
522 switch (authdata->algtype) {
523 case PDCP_AUTH_TYPE_SNOW:
524 /* Insert Auth Key */
525 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
526 authdata->keylen, INLINE_KEY(authdata));
527 SEQLOAD(p, MATH0, offset, length, 0);
528 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
530 if (rta_sec_era > RTA_SEC_ERA_2 ||
531 (rta_sec_era == RTA_SEC_ERA_2 &&
532 era_2_sw_hfn_ovrd == 0)) {
533 SEQINPTR(p, 0, length, RTO);
535 SEQINPTR(p, 0, 5, RTO);
536 SEQFIFOLOAD(p, SKIP, 4, 0);
540 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
542 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
544 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
546 MATHB(p, MATH2, AND, PDCP_BEARER_MASK, MATH2, 8,
548 MOVEB(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
549 MATHB(p, MATH3, AND, PDCP_DIR_MASK, MATH3, 8, IMMED2);
550 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
551 MOVEB(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
553 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
555 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
557 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
558 MATHB(p, MATH2, AND, PDCP_BEARER_MASK_BE, MATH2, 8,
561 MOVE(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
562 MATHB(p, MATH3, AND, PDCP_DIR_MASK_BE, MATH3, 8,
564 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
565 MOVE(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
568 if (dir == OP_TYPE_DECAP_PROTOCOL) {
569 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
572 if (rta_sec_era > RTA_SEC_ERA_2) {
573 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
576 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
578 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
583 if (rta_sec_era > RTA_SEC_ERA_2) {
584 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
585 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
587 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
588 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
591 * Since MOVELEN is available only starting with
592 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
593 * command dynamically by writing the length from M1 by
594 * OR-ing the command in the M1 register and MOVE the
595 * result into the descriptor buffer. Care must be taken
596 * wrt. the location of the command because of SEC
597 * pipelining. The actual MOVEs are written at the end
598 * of the descriptor due to calculations needed on the
599 * offset in the descriptor for the MOVE command.
601 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
603 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
604 8, WAITCOMP | IMMED);
607 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
608 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9, OP_ALG_AAI_F9,
610 dir == OP_TYPE_ENCAP_PROTOCOL ?
611 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
614 if (rta_sec_era > RTA_SEC_ERA_2) {
615 SEQFIFOLOAD(p, MSGINSNOOP, 0,
616 VLF | LAST1 | LAST2 | FLUSH1);
617 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
619 SEQFIFOLOAD(p, MSGINSNOOP, 0,
620 VLF | LAST1 | LAST2 | FLUSH1);
621 SET_LABEL(p, local_offset);
623 /* Shut off automatic Info FIFO entries */
624 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
626 * Placeholder for MOVE command with length from M1
629 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
630 /* Enable automatic Info FIFO entries */
631 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
634 if (dir == OP_TYPE_DECAP_PROTOCOL)
635 SEQFIFOLOAD(p, ICV2, 4, LAST2);
637 SEQSTORE(p, CONTEXT2, 0, 4, 0);
641 case PDCP_AUTH_TYPE_AES:
642 /* Insert Auth Key */
643 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
644 authdata->keylen, INLINE_KEY(authdata));
645 SEQLOAD(p, MATH0, offset, length, 0);
646 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
647 if (rta_sec_era > RTA_SEC_ERA_2 ||
648 (rta_sec_era == RTA_SEC_ERA_2 &&
649 era_2_sw_hfn_ovrd == 0)) {
650 SEQINPTR(p, 0, length, RTO);
652 SEQINPTR(p, 0, 5, RTO);
653 SEQFIFOLOAD(p, SKIP, 4, 0);
657 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
659 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
661 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
662 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
663 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
665 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
667 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
669 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
670 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
671 MOVE(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
674 if (dir == OP_TYPE_DECAP_PROTOCOL) {
675 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
678 if (rta_sec_era > RTA_SEC_ERA_2) {
679 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
682 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
684 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
689 if (rta_sec_era > RTA_SEC_ERA_2) {
690 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
691 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
693 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
694 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
697 * Since MOVELEN is available only starting with
698 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
699 * command dynamically by writing the length from M1 by
700 * OR-ing the command in the M1 register and MOVE the
701 * result into the descriptor buffer. Care must be taken
702 * wrt. the location of the command because of SEC
703 * pipelining. The actual MOVEs are written at the end
704 * of the descriptor due to calculations needed on the
705 * offset in the descriptor for the MOVE command.
707 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
709 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
710 8, WAITCOMP | IMMED);
712 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
713 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
716 dir == OP_TYPE_ENCAP_PROTOCOL ?
717 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
720 if (rta_sec_era > RTA_SEC_ERA_2) {
721 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
722 SEQFIFOLOAD(p, MSGINSNOOP, 0,
723 VLF | LAST1 | LAST2 | FLUSH1);
725 SEQFIFOLOAD(p, MSGINSNOOP, 0,
726 VLF | LAST1 | LAST2 | FLUSH1);
727 SET_LABEL(p, local_offset);
729 /* Shut off automatic Info FIFO entries */
730 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
733 * Placeholder for MOVE command with length from
736 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
738 /* Enable automatic Info FIFO entries */
739 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
742 if (dir == OP_TYPE_DECAP_PROTOCOL)
743 SEQFIFOLOAD(p, ICV1, 4, LAST1 | FLUSH1);
745 SEQSTORE(p, CONTEXT1, 0, 4, 0);
749 case PDCP_AUTH_TYPE_ZUC:
750 if (rta_sec_era < RTA_SEC_ERA_5) {
751 pr_err("Invalid era for selected algorithm\n");
754 /* Insert Auth Key */
755 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
756 authdata->keylen, INLINE_KEY(authdata));
757 SEQLOAD(p, MATH0, offset, length, 0);
758 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
759 SEQINPTR(p, 0, length, RTO);
761 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
763 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
765 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
766 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
767 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
770 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
772 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
774 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
775 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
776 MOVE(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
778 if (dir == OP_TYPE_DECAP_PROTOCOL)
779 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
782 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
784 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
785 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
786 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
787 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
790 dir == OP_TYPE_ENCAP_PROTOCOL ?
791 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
793 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
794 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
796 if (dir == OP_TYPE_DECAP_PROTOCOL)
797 SEQFIFOLOAD(p, ICV2, 4, LAST2);
799 SEQSTORE(p, CONTEXT2, 0, 4, 0);
804 pr_err("%s: Invalid integrity algorithm selected: %d\n",
805 "pdcp_insert_cplane_int_only_op", authdata->algtype);
809 if (rta_sec_era < RTA_SEC_ERA_3) {
810 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
811 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
818 pdcp_insert_cplane_enc_only_op(struct program *p,
819 bool swap __maybe_unused,
820 struct alginfo *cipherdata,
821 struct alginfo *authdata __maybe_unused,
823 enum pdcp_sn_size sn_size,
824 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
826 uint32_t offset = 0, length = 0, sn_mask = 0;
827 /* Insert Cipher Key */
828 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
829 cipherdata->keylen, INLINE_KEY(cipherdata));
831 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18 &&
832 !(rta_sec_era == RTA_SEC_ERA_8 &&
833 authdata->algtype == 0))
834 || (rta_sec_era == RTA_SEC_ERA_10)) {
835 if (sn_size == PDCP_SN_SIZE_5)
836 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
837 (uint16_t)cipherdata->algtype << 8);
839 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
840 (uint16_t)cipherdata->algtype << 8);
843 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
848 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
849 PDCP_C_PLANE_SN_MASK_BE;
851 case PDCP_SN_SIZE_18:
854 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
855 PDCP_U_PLANE_18BIT_SN_MASK_BE;
857 case PDCP_SN_SIZE_12:
860 sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
861 PDCP_12BIT_SN_MASK_BE;
864 case PDCP_SN_SIZE_15:
865 pr_err("Invalid sn_size for %s\n", __func__);
869 SEQLOAD(p, MATH0, offset, length, 0);
870 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
871 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
872 SEQSTORE(p, MATH0, offset, length, 0);
873 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
874 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
875 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
877 switch (cipherdata->algtype) {
878 case PDCP_CIPHER_TYPE_SNOW:
879 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
881 if (rta_sec_era > RTA_SEC_ERA_2) {
882 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
884 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
885 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
888 if (dir == OP_TYPE_ENCAP_PROTOCOL)
889 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
892 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
894 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
895 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
897 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
898 dir == OP_TYPE_ENCAP_PROTOCOL ?
902 case PDCP_CIPHER_TYPE_AES:
903 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
905 if (rta_sec_era > RTA_SEC_ERA_2) {
906 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
908 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
909 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
912 if (dir == OP_TYPE_ENCAP_PROTOCOL)
913 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
916 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
919 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
920 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
924 dir == OP_TYPE_ENCAP_PROTOCOL ?
928 case PDCP_CIPHER_TYPE_ZUC:
929 if (rta_sec_era < RTA_SEC_ERA_5) {
930 pr_err("Invalid era for selected algorithm\n");
934 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
935 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
936 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
937 if (dir == OP_TYPE_ENCAP_PROTOCOL)
938 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
941 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
944 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
945 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
949 dir == OP_TYPE_ENCAP_PROTOCOL ?
954 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
955 "pdcp_insert_cplane_enc_only_op", cipherdata->algtype);
959 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
960 SEQFIFOLOAD(p, MSG1, 0, VLF);
961 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
962 LAST1 | FLUSH1 | IMMED);
964 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
965 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
966 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
967 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS,
968 HALT_STATUS, ALL_FALSE, MATH_Z);
975 pdcp_insert_uplane_snow_snow_op(struct program *p,
976 bool swap __maybe_unused,
977 struct alginfo *cipherdata,
978 struct alginfo *authdata,
980 enum pdcp_sn_size sn_size,
981 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
983 uint32_t offset = 0, length = 0, sn_mask = 0;
985 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
986 cipherdata->keylen, INLINE_KEY(cipherdata));
987 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
988 INLINE_KEY(authdata));
990 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
993 if (sn_size == PDCP_SN_SIZE_5)
994 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
996 pclid = OP_PCLID_LTE_PDCP_USER_RN;
998 PROTOCOL(p, dir, pclid,
999 ((uint16_t)cipherdata->algtype << 8) |
1000 (uint16_t)authdata->algtype);
1004 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1006 case PDCP_SN_SIZE_5:
1009 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1010 PDCP_C_PLANE_SN_MASK_BE;
1012 case PDCP_SN_SIZE_18:
1015 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1016 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1018 case PDCP_SN_SIZE_7:
1019 case PDCP_SN_SIZE_12:
1020 case PDCP_SN_SIZE_15:
1021 pr_err("Invalid sn_size for %s\n", __func__);
1025 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1026 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1028 SEQLOAD(p, MATH0, offset, length, 0);
1029 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1030 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1031 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1033 SEQSTORE(p, MATH0, offset, length, 0);
1034 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1035 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1036 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1037 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
1038 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
1039 if (swap == false) {
1040 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
1042 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
1045 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
1047 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
1050 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1052 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1053 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1054 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1055 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1057 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1058 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
1061 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1062 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1064 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1066 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1068 OP_ALG_AS_INITFINAL,
1069 dir == OP_TYPE_ENCAP_PROTOCOL ?
1070 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1072 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1074 OP_ALG_AS_INITFINAL,
1076 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1078 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1079 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1080 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1082 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1083 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1084 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1086 if (rta_sec_era >= RTA_SEC_ERA_6)
1087 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1089 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1091 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1093 if (rta_sec_era <= RTA_SEC_ERA_2) {
1094 /* Shut off automatic Info FIFO entries */
1095 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1096 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1098 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1106 pdcp_insert_uplane_zuc_zuc_op(struct program *p,
1107 bool swap __maybe_unused,
1108 struct alginfo *cipherdata,
1109 struct alginfo *authdata,
1111 enum pdcp_sn_size sn_size,
1112 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1114 uint32_t offset = 0, length = 0, sn_mask = 0;
1117 REFERENCE(pkeyjump);
1119 if (rta_sec_era < RTA_SEC_ERA_5) {
1120 pr_err("Invalid era for selected algorithm\n");
1124 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1125 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1126 cipherdata->keylen, INLINE_KEY(cipherdata));
1127 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1128 INLINE_KEY(authdata));
1130 SET_LABEL(p, keyjump);
1131 PATCH_JUMP(p, pkeyjump, keyjump);
1133 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
1136 if (sn_size == PDCP_SN_SIZE_5)
1137 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1139 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1141 PROTOCOL(p, dir, pclid,
1142 ((uint16_t)cipherdata->algtype << 8) |
1143 (uint16_t)authdata->algtype);
1147 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1149 case PDCP_SN_SIZE_5:
1152 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1153 PDCP_C_PLANE_SN_MASK_BE;
1155 case PDCP_SN_SIZE_18:
1158 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1159 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1161 case PDCP_SN_SIZE_7:
1162 case PDCP_SN_SIZE_12:
1163 case PDCP_SN_SIZE_15:
1164 pr_err("Invalid sn_size for %s\n", __func__);
1168 SEQLOAD(p, MATH0, offset, length, 0);
1169 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1170 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1171 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1172 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1174 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1175 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1176 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1178 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1180 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1181 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1183 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1185 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1186 SEQSTORE(p, MATH0, offset, length, 0);
1188 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1189 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1190 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1192 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1193 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1196 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1198 OP_ALG_AS_INITFINAL,
1199 dir == OP_TYPE_ENCAP_PROTOCOL ?
1200 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1203 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
1205 OP_ALG_AS_INITFINAL,
1207 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1209 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1210 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1213 MOVEB(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1215 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1216 NFIFOENTRY_DEST_CLASS2 |
1217 NFIFOENTRY_DTYPE_ICV |
1218 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1219 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1222 /* Reset ZUCA mode and done interrupt */
1223 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
1224 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
1230 pdcp_insert_uplane_aes_aes_op(struct program *p,
1231 bool swap __maybe_unused,
1232 struct alginfo *cipherdata,
1233 struct alginfo *authdata,
1235 enum pdcp_sn_size sn_size,
1236 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1238 uint32_t offset = 0, length = 0, sn_mask = 0;
1240 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18)) {
1241 /* Insert Auth Key */
1242 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1243 authdata->keylen, INLINE_KEY(authdata));
1245 /* Insert Cipher Key */
1246 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1247 cipherdata->keylen, INLINE_KEY(cipherdata));
1249 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1250 ((uint16_t)cipherdata->algtype << 8) |
1251 (uint16_t)authdata->algtype);
1255 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1257 case PDCP_SN_SIZE_18:
1260 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1261 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1265 pr_err("Invalid sn_size for %s\n", __func__);
1269 SEQLOAD(p, MATH0, offset, length, 0);
1270 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1271 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1273 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1274 MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED);
1275 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1276 SEQSTORE(p, MATH0, offset, length, 0);
1278 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1279 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1280 authdata->keylen, INLINE_KEY(authdata));
1281 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1282 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
1284 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1285 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1287 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1289 OP_ALG_AS_INITFINAL,
1292 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1293 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1295 LOAD(p, CLRW_RESET_CLS1_CHA |
1303 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1304 cipherdata->keylen, INLINE_KEY(cipherdata));
1306 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1307 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
1309 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1311 OP_ALG_AS_INITFINAL,
1315 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1317 SEQFIFOLOAD(p, SKIP, length, 0);
1319 SEQFIFOLOAD(p, MSG1, 0, VLF);
1320 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1322 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1323 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
1325 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1326 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1328 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1329 cipherdata->keylen, INLINE_KEY(cipherdata));
1331 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1333 OP_ALG_AS_INITFINAL,
1337 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1338 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1340 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1342 LOAD(p, CLRW_RESET_CLS1_CHA |
1350 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1351 authdata->keylen, INLINE_KEY(authdata));
1353 SEQINPTR(p, 0, 0, SOP);
1355 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1357 OP_ALG_AS_INITFINAL,
1361 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1363 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1365 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1367 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1368 NFIFOENTRY_DEST_CLASS1 |
1369 NFIFOENTRY_DTYPE_ICV |
1371 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1372 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1379 pdcp_insert_cplane_acc_op(struct program *p,
1380 bool swap __maybe_unused,
1381 struct alginfo *cipherdata,
1382 struct alginfo *authdata,
1384 enum pdcp_sn_size sn_size,
1385 unsigned char era_2_hfn_ovrd __maybe_unused)
1387 /* Insert Auth Key */
1388 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1389 INLINE_KEY(authdata));
1391 /* Insert Cipher Key */
1392 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1393 cipherdata->keylen, INLINE_KEY(cipherdata));
1395 if (sn_size == PDCP_SN_SIZE_5)
1396 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL,
1397 (uint16_t)cipherdata->algtype);
1399 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1400 ((uint16_t)cipherdata->algtype << 8) |
1401 (uint16_t)authdata->algtype);
1407 pdcp_insert_cplane_snow_aes_op(struct program *p,
1408 bool swap __maybe_unused,
1409 struct alginfo *cipherdata,
1410 struct alginfo *authdata,
1412 enum pdcp_sn_size sn_size,
1413 unsigned char era_2_sw_hfn_ovrd)
1415 uint32_t offset = 0, length = 0, sn_mask = 0;
1417 LABEL(back_to_sd_offset);
1419 LABEL(local_offset);
1420 LABEL(jump_to_beginning);
1421 LABEL(fifo_load_mac_i_offset);
1422 REFERENCE(seqin_ptr_read);
1423 REFERENCE(seqin_ptr_write);
1424 REFERENCE(seq_out_read);
1425 REFERENCE(jump_back_to_sd_cmd);
1426 REFERENCE(move_mac_i_to_desc_buf);
1428 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1429 (rta_sec_era == RTA_SEC_ERA_10)) {
1430 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1431 cipherdata->keylen, INLINE_KEY(cipherdata));
1432 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1433 authdata->keylen, INLINE_KEY(authdata));
1435 if (sn_size == PDCP_SN_SIZE_5)
1436 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
1437 ((uint16_t)cipherdata->algtype << 8) |
1438 (uint16_t)authdata->algtype);
1440 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1441 ((uint16_t)cipherdata->algtype << 8) |
1442 (uint16_t)authdata->algtype);
1446 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1448 case PDCP_SN_SIZE_5:
1451 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1452 PDCP_C_PLANE_SN_MASK_BE;
1454 case PDCP_SN_SIZE_18:
1457 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1458 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1460 case PDCP_SN_SIZE_7:
1461 case PDCP_SN_SIZE_12:
1462 case PDCP_SN_SIZE_15:
1463 pr_err("Invalid sn_size for %s\n", __func__);
1468 SEQLOAD(p, MATH0, offset, length, 0);
1469 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1470 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1471 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1472 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
1473 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1474 SEQSTORE(p, MATH0, offset, length, 0);
1475 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1476 if (rta_sec_era > RTA_SEC_ERA_2 ||
1477 (rta_sec_era == RTA_SEC_ERA_2 &&
1478 era_2_sw_hfn_ovrd == 0)) {
1479 SEQINPTR(p, 0, length, RTO);
1481 SEQINPTR(p, 0, 5, RTO);
1482 SEQFIFOLOAD(p, SKIP, 4, 0);
1484 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1485 authdata->keylen, INLINE_KEY(authdata));
1486 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1488 if (rta_sec_era > RTA_SEC_ERA_2) {
1489 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1490 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
1491 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1494 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1495 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1498 * Note: Although the calculations below might seem a
1499 * little off, the logic is the following:
1501 * - SEQ IN PTR RTO below needs the full length of the
1502 * frame; in case of P4080_REV_2_HFN_OV_WORKAROUND,
1503 * this means the length of the frame to be processed
1504 * + 4 bytes (the HFN override flag and value).
1505 * The length of the frame to be processed minus 1
1506 * byte is in the VSIL register (because
1507 * VSIL = SIL + 3, due to 1 byte, the header being
1508 * already written by the SEQ STORE above). So for
1509 * calculating the length to use in RTO, I add one
1510 * to the VSIL value in order to obtain the total
1511 * frame length. This helps in case of P4080 which
1512 * can have the value 0 as an operand in a MATH
1513 * command only as SRC1 When the HFN override
1514 * workaround is not enabled, the length of the
1515 * frame is given by the SIL register; the
1516 * calculation is similar to the one in the SEC 4.2
1517 * and SEC 5.3 cases.
1519 if (era_2_sw_hfn_ovrd)
1520 MATHB(p, VSEQOUTSZ, ADD, ONE, MATH1, 4,
1523 MATHB(p, SEQINSZ, ADD, MATH3, MATH1, 4,
1527 * Placeholder for filling the length in
1528 * SEQIN PTR RTO below
1530 seqin_ptr_read = MOVE(p, DESCBUF, 0, MATH1, 0, 6, IMMED);
1531 seqin_ptr_write = MOVE(p, MATH1, 0, DESCBUF, 0, 8,
1533 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1535 OP_ALG_AS_INITFINAL,
1538 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1539 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1540 if (rta_sec_era <= RTA_SEC_ERA_3)
1541 LOAD(p, CLRW_CLR_C1KEY |
1548 LOAD(p, CLRW_RESET_CLS1_CHA |
1556 if (rta_sec_era <= RTA_SEC_ERA_3)
1557 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1559 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1560 cipherdata->keylen, INLINE_KEY(cipherdata));
1561 SET_LABEL(p, local_offset);
1562 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1563 SEQINPTR(p, 0, 0, RTO);
1565 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
1566 SEQFIFOLOAD(p, SKIP, 5, 0);
1567 MATHB(p, SEQINSZ, ADD, ONE, SEQINSZ, 4, 0);
1570 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1571 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1573 OP_ALG_AS_INITFINAL,
1576 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1578 if (rta_sec_era > RTA_SEC_ERA_2 ||
1579 (rta_sec_era == RTA_SEC_ERA_2 &&
1580 era_2_sw_hfn_ovrd == 0))
1581 SEQFIFOLOAD(p, SKIP, length, 0);
1583 SEQFIFOLOAD(p, MSG1, 0, VLF);
1584 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1585 PATCH_MOVE(p, seqin_ptr_read, local_offset);
1586 PATCH_MOVE(p, seqin_ptr_write, local_offset);
1588 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1590 if (rta_sec_era >= RTA_SEC_ERA_5)
1591 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1593 if (rta_sec_era > RTA_SEC_ERA_2)
1594 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1596 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1598 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1600 * TODO: To be changed when proper support is added in RTA (can't load a
1601 * command that is also written by RTA (or patch it for that matter).
1602 * Change when proper RTA support is added.
1605 WORD(p, 0x168B0004);
1607 WORD(p, 0x16880404);
1609 jump_back_to_sd_cmd = JUMP(p, 0, LOCAL_JUMP, ALL_TRUE, 0);
1611 * Placeholder for command reading the SEQ OUT command in
1612 * JD. Done for rereading the decrypted data and performing
1613 * the integrity check
1616 * TODO: RTA currently doesn't support patching of length of a MOVE command
1617 * Thus, it is inserted as a raw word, as per PS setting.
1620 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 20,
1623 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 16,
1626 MATHB(p, MATH1, XOR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 4,
1628 /* Placeholder for overwriting the SEQ IN with SEQ OUT */
1630 * TODO: RTA currently doesn't support patching of length of a MOVE command
1631 * Thus, it is inserted as a raw word, as per PS setting.
1634 MOVE(p, MATH1, 0, DESCBUF, 0, 24, IMMED);
1636 MOVE(p, MATH1, 0, DESCBUF, 0, 20, IMMED);
1638 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1639 cipherdata->keylen, INLINE_KEY(cipherdata));
1641 if (rta_sec_era >= RTA_SEC_ERA_4)
1642 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1644 MOVE(p, CONTEXT1, 0, MATH3, 0, 8, IMMED);
1646 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1648 OP_ALG_AS_INITFINAL,
1651 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1652 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1654 if (rta_sec_era <= RTA_SEC_ERA_3)
1655 move_mac_i_to_desc_buf = MOVE(p, OFIFO, 0, DESCBUF, 0,
1656 4, WAITCOMP | IMMED);
1658 MOVE(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1660 if (rta_sec_era <= RTA_SEC_ERA_3)
1661 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1663 LOAD(p, CLRW_RESET_CLS1_CHA |
1671 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1672 authdata->keylen, INLINE_KEY(authdata));
1674 * Placeholder for jump in SD for executing the new SEQ IN PTR
1675 * command (which is actually the old SEQ OUT PTR command
1676 * copied over from JD.
1678 SET_LABEL(p, jump_to_beginning);
1679 JUMP(p, 1 - jump_to_beginning, LOCAL_JUMP, ALL_TRUE, 0);
1680 SET_LABEL(p, back_to_sd_offset);
1681 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1683 OP_ALG_AS_INITFINAL,
1687 /* Read the # of bytes written in the output buffer + 1 (HDR) */
1688 MATHI(p, VSEQOUTSZ, ADD, length, VSEQINSZ, 4, IMMED2);
1690 if (rta_sec_era <= RTA_SEC_ERA_3)
1691 MOVE(p, MATH3, 0, IFIFOAB1, 0, 8, IMMED);
1693 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1695 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd)
1696 SEQFIFOLOAD(p, SKIP, 4, 0);
1698 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1700 if (rta_sec_era >= RTA_SEC_ERA_4) {
1701 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1702 NFIFOENTRY_DEST_CLASS1 |
1703 NFIFOENTRY_DTYPE_ICV |
1705 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1706 MOVE(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1708 SET_LABEL(p, fifo_load_mac_i_offset);
1709 FIFOLOAD(p, ICV1, fifo_load_mac_i_offset, 4,
1710 LAST1 | FLUSH1 | IMMED);
1713 SET_LABEL(p, end_desc);
1716 PATCH_MOVE(p, seq_out_read, end_desc + 1);
1717 PATCH_JUMP(p, jump_back_to_sd_cmd,
1718 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1720 if (rta_sec_era <= RTA_SEC_ERA_3)
1721 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1722 fifo_load_mac_i_offset + 1);
1724 PATCH_MOVE(p, seq_out_read, end_desc + 2);
1725 PATCH_JUMP(p, jump_back_to_sd_cmd,
1726 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1728 if (rta_sec_era <= RTA_SEC_ERA_3)
1729 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1730 fifo_load_mac_i_offset + 1);
1738 pdcp_insert_cplane_aes_snow_op(struct program *p,
1739 bool swap __maybe_unused,
1740 struct alginfo *cipherdata,
1741 struct alginfo *authdata,
1743 enum pdcp_sn_size sn_size,
1744 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1746 uint32_t offset = 0, length = 0, sn_mask = 0;
1748 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1749 cipherdata->keylen, INLINE_KEY(cipherdata));
1750 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1751 INLINE_KEY(authdata));
1753 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1754 (rta_sec_era == RTA_SEC_ERA_10)) {
1757 if (sn_size == PDCP_SN_SIZE_5)
1758 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1760 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1762 PROTOCOL(p, dir, pclid,
1763 ((uint16_t)cipherdata->algtype << 8) |
1764 (uint16_t)authdata->algtype);
1768 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1770 case PDCP_SN_SIZE_5:
1773 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1774 PDCP_C_PLANE_SN_MASK_BE;
1776 case PDCP_SN_SIZE_18:
1779 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1780 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1782 case PDCP_SN_SIZE_7:
1783 case PDCP_SN_SIZE_12:
1784 case PDCP_SN_SIZE_15:
1785 pr_err("Invalid sn_size for %s\n", __func__);
1790 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1791 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1793 SEQLOAD(p, MATH0, offset, length, 0);
1794 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1795 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1796 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1798 SEQSTORE(p, MATH0, offset, length, 0);
1799 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1800 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1801 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1802 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
1803 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
1804 if (swap == false) {
1805 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2, 4,
1807 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3, 4,
1810 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
1812 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
1815 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1816 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1817 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1818 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1819 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1821 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4, IMMED2);
1823 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
1824 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
1827 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1828 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1830 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1832 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1834 OP_ALG_AS_INITFINAL,
1835 dir == OP_TYPE_ENCAP_PROTOCOL ?
1836 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1838 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1840 OP_ALG_AS_INITFINAL,
1842 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1844 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1845 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1846 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1848 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1849 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1850 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1852 if (rta_sec_era >= RTA_SEC_ERA_6)
1853 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1855 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1857 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1859 if (rta_sec_era <= RTA_SEC_ERA_2) {
1860 /* Shut off automatic Info FIFO entries */
1861 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1862 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1864 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1872 pdcp_insert_cplane_snow_zuc_op(struct program *p,
1873 bool swap __maybe_unused,
1874 struct alginfo *cipherdata,
1875 struct alginfo *authdata,
1877 enum pdcp_sn_size sn_size,
1878 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1880 uint32_t offset = 0, length = 0, sn_mask = 0;
1883 REFERENCE(pkeyjump);
1885 if (rta_sec_era < RTA_SEC_ERA_5) {
1886 pr_err("Invalid era for selected algorithm\n");
1890 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1891 (rta_sec_era == RTA_SEC_ERA_10)) {
1893 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1894 cipherdata->keylen, INLINE_KEY(cipherdata));
1895 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1896 INLINE_KEY(authdata));
1898 if (sn_size == PDCP_SN_SIZE_5)
1899 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1901 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1903 PROTOCOL(p, dir, pclid,
1904 ((uint16_t)cipherdata->algtype << 8) |
1905 (uint16_t)authdata->algtype);
1908 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1910 case PDCP_SN_SIZE_5:
1913 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1914 PDCP_C_PLANE_SN_MASK_BE;
1916 case PDCP_SN_SIZE_18:
1919 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1920 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1922 case PDCP_SN_SIZE_7:
1923 case PDCP_SN_SIZE_12:
1924 case PDCP_SN_SIZE_15:
1925 pr_err("Invalid sn_size for %s\n", __func__);
1930 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1931 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1932 cipherdata->keylen, INLINE_KEY(cipherdata));
1933 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1934 INLINE_KEY(authdata));
1936 SET_LABEL(p, keyjump);
1937 SEQLOAD(p, MATH0, offset, length, 0);
1938 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1939 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1940 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1942 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1943 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1944 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1945 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1946 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1948 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1949 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1951 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1953 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1954 SEQSTORE(p, MATH0, offset, length, 0);
1956 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1957 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1958 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1960 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1961 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1964 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1966 OP_ALG_AS_INITFINAL,
1967 dir == OP_TYPE_ENCAP_PROTOCOL ?
1968 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1971 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1973 OP_ALG_AS_INITFINAL,
1975 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1976 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1977 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1980 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1981 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1982 NFIFOENTRY_DEST_CLASS2 |
1983 NFIFOENTRY_DTYPE_ICV |
1984 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1985 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1988 /* Reset ZUCA mode and done interrupt */
1989 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
1990 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
1992 PATCH_JUMP(p, pkeyjump, keyjump);
1997 pdcp_insert_cplane_aes_zuc_op(struct program *p,
1998 bool swap __maybe_unused,
1999 struct alginfo *cipherdata,
2000 struct alginfo *authdata,
2002 enum pdcp_sn_size sn_size,
2003 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2005 uint32_t offset = 0, length = 0, sn_mask = 0;
2007 REFERENCE(pkeyjump);
2009 if (rta_sec_era < RTA_SEC_ERA_5) {
2010 pr_err("Invalid era for selected algorithm\n");
2014 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2015 (rta_sec_era == RTA_SEC_ERA_10)) {
2017 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2018 cipherdata->keylen, INLINE_KEY(cipherdata));
2019 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2020 INLINE_KEY(authdata));
2022 if (sn_size == PDCP_SN_SIZE_5)
2023 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2025 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2027 PROTOCOL(p, dir, pclid,
2028 ((uint16_t)cipherdata->algtype << 8) |
2029 (uint16_t)authdata->algtype);
2033 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2035 case PDCP_SN_SIZE_5:
2038 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2039 PDCP_C_PLANE_SN_MASK_BE;
2041 case PDCP_SN_SIZE_18:
2044 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2045 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2047 case PDCP_SN_SIZE_7:
2048 case PDCP_SN_SIZE_12:
2049 case PDCP_SN_SIZE_15:
2050 pr_err("Invalid sn_size for %s\n", __func__);
2054 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2055 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2056 cipherdata->keylen, INLINE_KEY(cipherdata));
2057 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2058 INLINE_KEY(authdata));
2060 SET_LABEL(p, keyjump);
2062 SEQLOAD(p, MATH0, offset, length, 0);
2063 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2064 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2065 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2067 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2068 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2069 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2070 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
2071 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
2073 if (dir == OP_TYPE_ENCAP_PROTOCOL)
2074 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2076 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2078 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2079 SEQSTORE(p, MATH0, offset, length, 0);
2081 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2082 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2083 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2085 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2086 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
2089 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
2091 OP_ALG_AS_INITFINAL,
2092 dir == OP_TYPE_ENCAP_PROTOCOL ?
2093 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2096 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2098 OP_ALG_AS_INITFINAL,
2100 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2102 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2103 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2106 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
2108 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2109 NFIFOENTRY_DEST_CLASS2 |
2110 NFIFOENTRY_DTYPE_ICV |
2111 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2112 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
2115 /* Reset ZUCA mode and done interrupt */
2116 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
2117 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
2119 PATCH_JUMP(p, pkeyjump, keyjump);
2125 pdcp_insert_cplane_zuc_snow_op(struct program *p,
2126 bool swap __maybe_unused,
2127 struct alginfo *cipherdata,
2128 struct alginfo *authdata,
2130 enum pdcp_sn_size sn_size,
2131 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2133 uint32_t offset = 0, length = 0, sn_mask = 0;
2135 REFERENCE(pkeyjump);
2137 if (rta_sec_era < RTA_SEC_ERA_5) {
2138 pr_err("Invalid era for selected algorithm\n");
2142 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2143 (rta_sec_era == RTA_SEC_ERA_10)) {
2145 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2146 cipherdata->keylen, INLINE_KEY(cipherdata));
2147 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2148 INLINE_KEY(authdata));
2150 if (sn_size == PDCP_SN_SIZE_5)
2151 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2153 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2155 PROTOCOL(p, dir, pclid,
2156 ((uint16_t)cipherdata->algtype << 8) |
2157 (uint16_t)authdata->algtype);
2161 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2163 case PDCP_SN_SIZE_5:
2166 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2167 PDCP_C_PLANE_SN_MASK_BE;
2169 case PDCP_SN_SIZE_18:
2172 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2173 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2175 case PDCP_SN_SIZE_7:
2176 case PDCP_SN_SIZE_12:
2177 case PDCP_SN_SIZE_15:
2178 pr_err("Invalid sn_size for %s\n", __func__);
2182 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2183 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2184 cipherdata->keylen, INLINE_KEY(cipherdata));
2185 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2186 INLINE_KEY(authdata));
2188 SET_LABEL(p, keyjump);
2189 SEQLOAD(p, MATH0, offset, length, 0);
2190 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2191 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2192 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2194 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2195 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2196 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
2197 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
2198 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
2199 if (swap == false) {
2200 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2,
2202 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3,
2205 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
2207 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
2210 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
2211 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
2212 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
2214 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2215 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2216 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2218 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2219 MATHB(p, VSEQOUTSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2222 SEQSTORE(p, MATH0, offset, length, 0);
2224 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2225 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2226 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2228 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2229 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
2232 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
2234 OP_ALG_AS_INITFINAL,
2235 dir == OP_TYPE_ENCAP_PROTOCOL ?
2236 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2239 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2241 OP_ALG_AS_INITFINAL,
2243 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2245 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2246 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2248 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
2249 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
2251 if (rta_sec_era >= RTA_SEC_ERA_6)
2253 * For SEC ERA 6, there's a problem with the OFIFO
2254 * pointer, and thus it needs to be reset here before
2257 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
2259 /* Put ICV to M0 before sending it to C2 for comparison. */
2260 MOVEB(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
2262 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2263 NFIFOENTRY_DEST_CLASS2 |
2264 NFIFOENTRY_DTYPE_ICV |
2265 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2266 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, IMMED);
2269 PATCH_JUMP(p, pkeyjump, keyjump);
2274 pdcp_insert_cplane_zuc_aes_op(struct program *p,
2275 bool swap __maybe_unused,
2276 struct alginfo *cipherdata,
2277 struct alginfo *authdata,
2279 enum pdcp_sn_size sn_size,
2280 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2282 uint32_t offset = 0, length = 0, sn_mask = 0;
2283 if (rta_sec_era < RTA_SEC_ERA_5) {
2284 pr_err("Invalid era for selected algorithm\n");
2288 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2289 (rta_sec_era == RTA_SEC_ERA_10)) {
2292 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2293 cipherdata->keylen, INLINE_KEY(cipherdata));
2294 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
2295 authdata->keylen, INLINE_KEY(authdata));
2297 if (sn_size == PDCP_SN_SIZE_5)
2298 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2300 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2302 PROTOCOL(p, dir, pclid,
2303 ((uint16_t)cipherdata->algtype << 8) |
2304 (uint16_t)authdata->algtype);
2307 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2309 case PDCP_SN_SIZE_5:
2312 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2313 PDCP_C_PLANE_SN_MASK_BE;
2315 case PDCP_SN_SIZE_18:
2318 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2319 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2321 case PDCP_SN_SIZE_7:
2322 case PDCP_SN_SIZE_12:
2323 case PDCP_SN_SIZE_15:
2324 pr_err("Invalid sn_size for %s\n", __func__);
2328 SEQLOAD(p, MATH0, offset, length, 0);
2329 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2330 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2332 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2333 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
2334 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2335 SEQSTORE(p, MATH0, offset, length, 0);
2336 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2337 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2338 authdata->keylen, INLINE_KEY(authdata));
2339 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
2340 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
2342 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2343 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2345 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2347 OP_ALG_AS_INITFINAL,
2350 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2351 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
2352 LOAD(p, CLRW_RESET_CLS1_CHA |
2360 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2361 cipherdata->keylen, INLINE_KEY(cipherdata));
2363 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2364 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
2366 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2368 OP_ALG_AS_INITFINAL,
2371 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2373 SEQFIFOLOAD(p, SKIP, length, 0);
2375 SEQFIFOLOAD(p, MSG1, 0, VLF);
2376 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2378 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2380 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2382 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2384 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2386 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2387 cipherdata->keylen, INLINE_KEY(cipherdata));
2389 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2391 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2393 OP_ALG_AS_INITFINAL,
2396 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2397 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2399 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
2401 LOAD(p, CLRW_RESET_CLS1_CHA |
2409 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2410 authdata->keylen, INLINE_KEY(authdata));
2412 SEQINPTR(p, 0, 0, SOP);
2414 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2416 OP_ALG_AS_INITFINAL,
2420 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2422 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
2424 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2426 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2427 NFIFOENTRY_DEST_CLASS1 |
2428 NFIFOENTRY_DTYPE_ICV |
2430 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
2431 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
2438 pdcp_insert_uplane_no_int_op(struct program *p,
2439 bool swap __maybe_unused,
2440 struct alginfo *cipherdata,
2442 enum pdcp_sn_size sn_size)
2447 /* Insert Cipher Key */
2448 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2449 cipherdata->keylen, INLINE_KEY(cipherdata));
2451 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_15) ||
2452 (rta_sec_era >= RTA_SEC_ERA_10)) {
2453 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER,
2454 (uint16_t)cipherdata->algtype);
2458 if (sn_size == PDCP_SN_SIZE_15) {
2459 SEQLOAD(p, MATH0, 6, 2, 0);
2460 sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
2461 PDCP_U_PLANE_15BIT_SN_MASK_BE;
2462 } else { /* SN Size == PDCP_SN_SIZE_18 */
2463 SEQLOAD(p, MATH0, 5, 3, 0);
2464 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2465 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2467 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2468 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2470 if (sn_size == PDCP_SN_SIZE_15)
2471 SEQSTORE(p, MATH0, 6, 2, 0);
2472 else /* SN Size == PDCP_SN_SIZE_18 */
2473 SEQSTORE(p, MATH0, 5, 3, 0);
2475 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2476 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
2477 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2479 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
2480 MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
2482 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2484 op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
2485 switch (cipherdata->algtype) {
2486 case PDCP_CIPHER_TYPE_SNOW:
2487 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
2488 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
2490 OP_ALG_AS_INITFINAL,
2495 case PDCP_CIPHER_TYPE_AES:
2496 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
2497 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2499 OP_ALG_AS_INITFINAL,
2504 case PDCP_CIPHER_TYPE_ZUC:
2505 if (rta_sec_era < RTA_SEC_ERA_5) {
2506 pr_err("Invalid era for selected algorithm\n");
2509 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
2510 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
2512 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2514 OP_ALG_AS_INITFINAL,
2520 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
2521 "pdcp_insert_uplane_15bit_op", cipherdata->algtype);
2525 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2531 * Function for inserting the snippet of code responsible for creating
2532 * the HFN override code via either DPOVRD or via the input frame.
2535 insert_hfn_ov_op(struct program *p,
2537 enum pdb_type_e pdb_type,
2538 unsigned char era_2_sw_hfn_ovrd)
2540 uint32_t imm = PDCP_DPOVRD_HFN_OV_EN;
2541 uint16_t hfn_pdb_offset;
2543 REFERENCE(pkeyjump);
2545 if (rta_sec_era == RTA_SEC_ERA_2 && !era_2_sw_hfn_ovrd)
2549 case PDCP_PDB_TYPE_NO_PDB:
2551 * If there is no PDB, then HFN override mechanism does not
2552 * make any sense, thus in this case the function will
2553 * return the pointer to the current position in the
2558 case PDCP_PDB_TYPE_REDUCED_PDB:
2562 case PDCP_PDB_TYPE_FULL_PDB:
2570 if (rta_sec_era > RTA_SEC_ERA_2) {
2571 MATHB(p, DPOVRD, AND, imm, NONE, 8, IFB | IMMED2);
2573 SEQLOAD(p, MATH0, 4, 4, 0);
2574 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2575 MATHB(p, MATH0, AND, imm, NONE, 8, IFB | IMMED2);
2576 SEQSTORE(p, MATH0, 4, 4, 0);
2579 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, MATH_Z);
2581 if (rta_sec_era > RTA_SEC_ERA_2)
2582 MATHI(p, DPOVRD, LSHIFT, shift, MATH0, 4, IMMED2);
2584 MATHB(p, MATH0, LSHIFT, shift, MATH0, 4, IMMED2);
2586 MATHB(p, MATH0, SHLD, MATH0, MATH0, 8, 0);
2587 MOVE(p, MATH0, 0, DESCBUF, hfn_pdb_offset, 4, IMMED);
2589 if (rta_sec_era >= RTA_SEC_ERA_8)
2591 * For ERA8, DPOVRD could be handled by the PROTOCOL command
2592 * itself. For now, this is not done. Thus, clear DPOVRD here
2593 * to alleviate any side-effects.
2595 MATHB(p, DPOVRD, AND, ZERO, DPOVRD, 4, STL);
2597 SET_LABEL(p, keyjump);
2598 PATCH_JUMP(p, pkeyjump, keyjump);
2603 * PDCP Control PDB creation function
2605 static inline enum pdb_type_e
2606 cnstr_pdcp_c_plane_pdb(struct program *p,
2608 enum pdcp_sn_size sn_size,
2609 unsigned char bearer,
2610 unsigned char direction,
2611 uint32_t hfn_threshold,
2612 struct alginfo *cipherdata,
2613 struct alginfo *authdata)
2615 struct pdcp_pdb pdb;
2617 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2619 PDCP_PDB_TYPE_NO_PDB, /* NULL */
2620 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2621 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2622 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2625 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2626 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2627 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2628 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2631 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2632 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2633 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2634 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2637 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2638 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2639 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2640 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2644 if (rta_sec_era >= RTA_SEC_ERA_8) {
2645 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2647 /* To support 12-bit seq numbers, we use u-plane opt in pdb.
2648 * SEC supports 5-bit only with c-plane opt in pdb.
2650 if (sn_size == PDCP_SN_SIZE_12) {
2651 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2652 pdb.bearer_dir_res = (uint32_t)
2653 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2654 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2657 hfn_threshold << PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2660 /* This means 5-bit c-plane.
2661 * Here we use c-plane opt in pdb
2664 /* This is a HW issue. Bit 2 should be set to zero,
2665 * but it does not work this way. Override here.
2667 pdb.opt_res.rsvd = 0x00000002;
2669 /* Copy relevant information from user to PDB */
2670 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2671 pdb.bearer_dir_res = (uint32_t)
2672 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2673 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2675 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2678 /* copy PDB in descriptor*/
2679 __rta_out32(p, pdb.opt_res.opt);
2680 __rta_out32(p, pdb.hfn_res);
2681 __rta_out32(p, pdb.bearer_dir_res);
2682 __rta_out32(p, pdb.hfn_thr_res);
2684 return PDCP_PDB_TYPE_FULL_PDB;
2687 switch (pdb_mask[cipherdata->algtype][authdata->algtype]) {
2688 case PDCP_PDB_TYPE_NO_PDB:
2691 case PDCP_PDB_TYPE_REDUCED_PDB:
2692 __rta_out32(p, (hfn << PDCP_C_PLANE_PDB_HFN_SHIFT));
2694 (uint32_t)((bearer <<
2695 PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2697 PDCP_C_PLANE_PDB_DIR_SHIFT)));
2700 case PDCP_PDB_TYPE_FULL_PDB:
2701 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2703 /* This is a HW issue. Bit 2 should be set to zero,
2704 * but it does not work this way. Override here.
2706 pdb.opt_res.rsvd = 0x00000002;
2708 /* Copy relevant information from user to PDB */
2709 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2710 pdb.bearer_dir_res = (uint32_t)
2711 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2712 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2714 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2716 /* copy PDB in descriptor*/
2717 __rta_out32(p, pdb.opt_res.opt);
2718 __rta_out32(p, pdb.hfn_res);
2719 __rta_out32(p, pdb.bearer_dir_res);
2720 __rta_out32(p, pdb.hfn_thr_res);
2725 return PDCP_PDB_TYPE_INVALID;
2728 return pdb_mask[cipherdata->algtype][authdata->algtype];
2732 * PDCP UPlane PDB creation function
2734 static inline enum pdb_type_e
2735 cnstr_pdcp_u_plane_pdb(struct program *p,
2736 enum pdcp_sn_size sn_size,
2737 uint32_t hfn, unsigned short bearer,
2738 unsigned short direction,
2739 uint32_t hfn_threshold,
2740 struct alginfo *cipherdata,
2741 struct alginfo *authdata)
2743 struct pdcp_pdb pdb;
2744 enum pdb_type_e pdb_type = PDCP_PDB_TYPE_FULL_PDB;
2746 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2748 PDCP_PDB_TYPE_NO_PDB, /* NULL */
2749 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2750 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2751 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2754 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2755 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2756 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2757 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2760 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2761 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2762 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2763 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2766 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2767 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2768 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2769 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2773 /* Read options from user */
2774 /* Depending on sequence number length, the HFN and HFN threshold
2775 * have different lengths.
2777 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2780 case PDCP_SN_SIZE_7:
2781 pdb.opt_res.opt |= PDCP_U_PLANE_PDB_OPT_SHORT_SN;
2782 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT;
2784 hfn_threshold<<PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT;
2787 case PDCP_SN_SIZE_12:
2788 pdb.opt_res.opt &= (uint32_t)(~PDCP_U_PLANE_PDB_OPT_SHORT_SN);
2789 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2791 hfn_threshold<<PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2794 case PDCP_SN_SIZE_15:
2795 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_15B_SN);
2796 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT;
2798 hfn_threshold<<PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT;
2801 case PDCP_SN_SIZE_18:
2802 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_18B_SN);
2803 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT;
2805 hfn_threshold<<PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT;
2807 if (rta_sec_era <= RTA_SEC_ERA_8) {
2808 if (cipherdata && authdata)
2809 pdb_type = pdb_mask[cipherdata->algtype]
2810 [authdata->algtype];
2815 pr_err("Invalid Sequence Number Size setting in PDB\n");
2819 pdb.bearer_dir_res = (uint32_t)
2820 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2821 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2824 case PDCP_PDB_TYPE_NO_PDB:
2827 case PDCP_PDB_TYPE_REDUCED_PDB:
2828 __rta_out32(p, pdb.hfn_res);
2829 __rta_out32(p, pdb.bearer_dir_res);
2832 case PDCP_PDB_TYPE_FULL_PDB:
2833 /* copy PDB in descriptor*/
2834 __rta_out32(p, pdb.opt_res.opt);
2835 __rta_out32(p, pdb.hfn_res);
2836 __rta_out32(p, pdb.bearer_dir_res);
2837 __rta_out32(p, pdb.hfn_thr_res);
2842 return PDCP_PDB_TYPE_INVALID;
2848 * cnstr_shdsc_pdcp_c_plane_encap - Function for creating a PDCP Control Plane
2849 * encapsulation descriptor.
2850 * @descbuf: pointer to buffer for descriptor construction
2851 * @ps: if 36/40bit addressing is desired, this parameter must be true
2852 * @swap: must be true when core endianness doesn't match SEC endianness
2853 * @hfn: starting Hyper Frame Number to be used together with the SN from the
2855 * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid
2856 * @bearer: radio bearer ID
2857 * @direction: the direction of the PDCP frame (UL/DL)
2858 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
2859 * keys should be renegotiated at the earliest convenience.
2860 * @cipherdata: pointer to block cipher transform definitions
2861 * Valid algorithm values are those from cipher_type_pdcp enum.
2862 * @authdata: pointer to authentication transform definitions
2863 * Valid algorithm values are those from auth_type_pdcp enum.
2864 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
2865 * this descriptor. Note: Can only be used for
2867 * Return: size of descriptor written in words or negative number on error.
2868 * Once the function returns, the value of this parameter can be used
2869 * for reclaiming the space that wasn't used for the descriptor.
2871 * Note: descbuf must be large enough to contain a full 256 byte long
2872 * descriptor; after the function returns, by subtracting the actual number of
2873 * bytes used, the user can reuse the remaining buffer space for other purposes.
2876 cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf,
2880 enum pdcp_sn_size sn_size,
2881 unsigned char bearer,
2882 unsigned char direction,
2883 uint32_t hfn_threshold,
2884 struct alginfo *cipherdata,
2885 struct alginfo *authdata,
2886 unsigned char era_2_sw_hfn_ovrd)
2889 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
2890 (struct program*, bool swap, struct alginfo *,
2891 struct alginfo *, unsigned int, enum pdcp_sn_size,
2892 unsigned char __maybe_unused) = {
2894 pdcp_insert_cplane_null_op, /* NULL */
2895 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
2896 pdcp_insert_cplane_int_only_op, /* AES CMAC */
2897 pdcp_insert_cplane_int_only_op /* ZUC-I */
2900 pdcp_insert_cplane_enc_only_op, /* NULL */
2901 pdcp_insert_cplane_acc_op, /* SNOW f9 */
2902 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
2903 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
2906 pdcp_insert_cplane_enc_only_op, /* NULL */
2907 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
2908 pdcp_insert_cplane_acc_op, /* AES CMAC */
2909 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
2912 pdcp_insert_cplane_enc_only_op, /* NULL */
2913 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
2914 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
2915 pdcp_insert_cplane_acc_op /* ZUC-I */
2918 static enum rta_share_type
2919 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2921 SHR_WAIT, /* NULL */
2922 SHR_ALWAYS, /* SNOW f9 */
2923 SHR_ALWAYS, /* AES CMAC */
2924 SHR_ALWAYS /* ZUC-I */
2927 SHR_ALWAYS, /* NULL */
2928 SHR_ALWAYS, /* SNOW f9 */
2929 SHR_WAIT, /* AES CMAC */
2930 SHR_WAIT /* ZUC-I */
2933 SHR_ALWAYS, /* NULL */
2934 SHR_ALWAYS, /* SNOW f9 */
2935 SHR_ALWAYS, /* AES CMAC */
2936 SHR_WAIT /* ZUC-I */
2939 SHR_ALWAYS, /* NULL */
2940 SHR_WAIT, /* SNOW f9 */
2941 SHR_WAIT, /* AES CMAC */
2942 SHR_ALWAYS /* ZUC-I */
2945 enum pdb_type_e pdb_type;
2947 struct program *p = &prg;
2951 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
2952 pr_err("Cannot select SW HFN override for other era than 2");
2956 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
2957 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
2961 PROGRAM_CNTXT_INIT(p, descbuf, 0);
2963 PROGRAM_SET_BSWAP(p);
2965 PROGRAM_SET_36BIT_ADDR(p);
2967 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
2969 pdb_type = cnstr_pdcp_c_plane_pdb(p,
2978 SET_LABEL(p, pdb_end);
2980 err = insert_hfn_ov_op(p, sn_size, pdb_type,
2985 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
2989 OP_TYPE_ENCAP_PROTOCOL,
2995 PATCH_HDR(p, 0, pdb_end);
2997 return PROGRAM_FINALIZE(p);
3001 * cnstr_shdsc_pdcp_c_plane_decap - Function for creating a PDCP Control Plane
3002 * decapsulation descriptor.
3003 * @descbuf: pointer to buffer for descriptor construction
3004 * @ps: if 36/40bit addressing is desired, this parameter must be true
3005 * @swap: must be true when core endianness doesn't match SEC endianness
3006 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3008 * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid
3009 * @bearer: radio bearer ID
3010 * @direction: the direction of the PDCP frame (UL/DL)
3011 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3012 * keys should be renegotiated at the earliest convenience.
3013 * @cipherdata: pointer to block cipher transform definitions
3014 * Valid algorithm values are those from cipher_type_pdcp enum.
3015 * @authdata: pointer to authentication transform definitions
3016 * Valid algorithm values are those from auth_type_pdcp enum.
3017 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3018 * this descriptor. Note: Can only be used for
3021 * Return: size of descriptor written in words or negative number on error.
3022 * Once the function returns, the value of this parameter can be used
3023 * for reclaiming the space that wasn't used for the descriptor.
3025 * Note: descbuf must be large enough to contain a full 256 byte long
3026 * descriptor; after the function returns, by subtracting the actual number of
3027 * bytes used, the user can reuse the remaining buffer space for other purposes.
3030 cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf,
3034 enum pdcp_sn_size sn_size,
3035 unsigned char bearer,
3036 unsigned char direction,
3037 uint32_t hfn_threshold,
3038 struct alginfo *cipherdata,
3039 struct alginfo *authdata,
3040 unsigned char era_2_sw_hfn_ovrd)
3043 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3044 (struct program*, bool swap, struct alginfo *,
3045 struct alginfo *, unsigned int, enum pdcp_sn_size,
3048 pdcp_insert_cplane_null_op, /* NULL */
3049 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
3050 pdcp_insert_cplane_int_only_op, /* AES CMAC */
3051 pdcp_insert_cplane_int_only_op /* ZUC-I */
3054 pdcp_insert_cplane_enc_only_op, /* NULL */
3055 pdcp_insert_cplane_acc_op, /* SNOW f9 */
3056 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
3057 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
3060 pdcp_insert_cplane_enc_only_op, /* NULL */
3061 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
3062 pdcp_insert_cplane_acc_op, /* AES CMAC */
3063 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
3066 pdcp_insert_cplane_enc_only_op, /* NULL */
3067 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
3068 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
3069 pdcp_insert_cplane_acc_op /* ZUC-I */
3072 static enum rta_share_type
3073 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3075 SHR_WAIT, /* NULL */
3076 SHR_ALWAYS, /* SNOW f9 */
3077 SHR_ALWAYS, /* AES CMAC */
3078 SHR_ALWAYS /* ZUC-I */
3081 SHR_ALWAYS, /* NULL */
3082 SHR_ALWAYS, /* SNOW f9 */
3083 SHR_WAIT, /* AES CMAC */
3084 SHR_WAIT /* ZUC-I */
3087 SHR_ALWAYS, /* NULL */
3088 SHR_ALWAYS, /* SNOW f9 */
3089 SHR_ALWAYS, /* AES CMAC */
3090 SHR_WAIT /* ZUC-I */
3093 SHR_ALWAYS, /* NULL */
3094 SHR_WAIT, /* SNOW f9 */
3095 SHR_WAIT, /* AES CMAC */
3096 SHR_ALWAYS /* ZUC-I */
3099 enum pdb_type_e pdb_type;
3101 struct program *p = &prg;
3105 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3106 pr_err("Cannot select SW HFN override for other era than 2");
3110 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
3111 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
3115 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3117 PROGRAM_SET_BSWAP(p);
3119 PROGRAM_SET_36BIT_ADDR(p);
3121 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3123 pdb_type = cnstr_pdcp_c_plane_pdb(p,
3132 SET_LABEL(p, pdb_end);
3134 err = insert_hfn_ov_op(p, sn_size, pdb_type,
3139 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3143 OP_TYPE_DECAP_PROTOCOL,
3149 PATCH_HDR(p, 0, pdb_end);
3151 return PROGRAM_FINALIZE(p);
3155 pdcp_insert_uplane_with_int_op(struct program *p,
3156 bool swap __maybe_unused,
3157 struct alginfo *cipherdata,
3158 struct alginfo *authdata,
3159 enum pdcp_sn_size sn_size,
3160 unsigned char era_2_sw_hfn_ovrd,
3164 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3165 (struct program*, bool swap, struct alginfo *,
3166 struct alginfo *, unsigned int, enum pdcp_sn_size,
3167 unsigned char __maybe_unused) = {
3169 pdcp_insert_cplane_null_op, /* NULL */
3170 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
3171 pdcp_insert_cplane_int_only_op, /* AES CMAC */
3172 pdcp_insert_cplane_int_only_op /* ZUC-I */
3175 pdcp_insert_cplane_enc_only_op, /* NULL */
3176 pdcp_insert_uplane_snow_snow_op, /* SNOW f9 */
3177 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
3178 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
3181 pdcp_insert_cplane_enc_only_op, /* NULL */
3182 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
3183 pdcp_insert_uplane_aes_aes_op, /* AES CMAC */
3184 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
3187 pdcp_insert_cplane_enc_only_op, /* NULL */
3188 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
3189 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
3190 pdcp_insert_uplane_zuc_zuc_op /* ZUC-I */
3195 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3210 * cnstr_shdsc_pdcp_u_plane_encap - Function for creating a PDCP User Plane
3211 * encapsulation descriptor.
3212 * @descbuf: pointer to buffer for descriptor construction
3213 * @ps: if 36/40bit addressing is desired, this parameter must be true
3214 * @swap: must be true when core endianness doesn't match SEC endianness
3215 * @sn_size: selects Sequence Number Size: 7/12/15 bits
3216 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3218 * @bearer: radio bearer ID
3219 * @direction: the direction of the PDCP frame (UL/DL)
3220 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3221 * keys should be renegotiated at the earliest convenience.
3222 * @cipherdata: pointer to block cipher transform definitions
3223 * Valid algorithm values are those from cipher_type_pdcp enum.
3224 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3225 * this descriptor. Note: Can only be used for
3228 * Return: size of descriptor written in words or negative number on error.
3229 * Once the function returns, the value of this parameter can be used
3230 * for reclaiming the space that wasn't used for the descriptor.
3232 * Note: descbuf must be large enough to contain a full 256 byte long
3233 * descriptor; after the function returns, by subtracting the actual number of
3234 * bytes used, the user can reuse the remaining buffer space for other purposes.
3237 cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf,
3240 enum pdcp_sn_size sn_size,
3242 unsigned short bearer,
3243 unsigned short direction,
3244 uint32_t hfn_threshold,
3245 struct alginfo *cipherdata,
3246 struct alginfo *authdata,
3247 unsigned char era_2_sw_hfn_ovrd)
3250 struct program *p = &prg;
3252 enum pdb_type_e pdb_type;
3253 static enum rta_share_type
3254 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3256 SHR_WAIT, /* NULL */
3257 SHR_ALWAYS, /* SNOW f9 */
3258 SHR_ALWAYS, /* AES CMAC */
3259 SHR_ALWAYS /* ZUC-I */
3262 SHR_ALWAYS, /* NULL */
3263 SHR_ALWAYS, /* SNOW f9 */
3264 SHR_WAIT, /* AES CMAC */
3265 SHR_WAIT /* ZUC-I */
3268 SHR_ALWAYS, /* NULL */
3269 SHR_ALWAYS, /* SNOW f9 */
3270 SHR_ALWAYS, /* AES CMAC */
3271 SHR_WAIT /* ZUC-I */
3274 SHR_ALWAYS, /* NULL */
3275 SHR_WAIT, /* SNOW f9 */
3276 SHR_WAIT, /* AES CMAC */
3277 SHR_ALWAYS /* ZUC-I */
3282 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3283 pr_err("Cannot select SW HFN ovrd for other era than 2");
3287 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3288 pr_err("Cannot use u-plane auth with era < 8");
3292 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3294 PROGRAM_SET_BSWAP(p);
3296 PROGRAM_SET_36BIT_ADDR(p);
3299 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3301 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3302 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn,
3303 bearer, direction, hfn_threshold,
3304 cipherdata, authdata);
3305 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3306 pr_err("Error creating PDCP UPlane PDB\n");
3309 SET_LABEL(p, pdb_end);
3311 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3316 case PDCP_SN_SIZE_7:
3317 case PDCP_SN_SIZE_12:
3318 switch (cipherdata->algtype) {
3319 case PDCP_CIPHER_TYPE_ZUC:
3320 if (rta_sec_era < RTA_SEC_ERA_5) {
3321 pr_err("Invalid era for selected algorithm\n");
3325 case PDCP_CIPHER_TYPE_AES:
3326 case PDCP_CIPHER_TYPE_SNOW:
3327 case PDCP_CIPHER_TYPE_NULL:
3328 if (rta_sec_era == RTA_SEC_ERA_8 &&
3329 authdata && authdata->algtype == 0){
3330 err = pdcp_insert_uplane_with_int_op(p, swap,
3331 cipherdata, authdata,
3332 sn_size, era_2_sw_hfn_ovrd,
3333 OP_TYPE_ENCAP_PROTOCOL);
3339 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3340 pr_err("PDB type must be FULL for PROTO desc\n");
3344 /* Insert auth key if requested */
3345 if (authdata && authdata->algtype) {
3346 KEY(p, KEY2, authdata->key_enc_flags,
3347 (uint64_t)authdata->key, authdata->keylen,
3348 INLINE_KEY(authdata));
3350 /* Insert Cipher Key */
3351 KEY(p, KEY1, cipherdata->key_enc_flags,
3352 (uint64_t)cipherdata->key, cipherdata->keylen,
3353 INLINE_KEY(cipherdata));
3356 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3357 OP_PCLID_LTE_PDCP_USER_RN,
3358 ((uint16_t)cipherdata->algtype << 8) |
3359 (uint16_t)authdata->algtype);
3361 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3362 OP_PCLID_LTE_PDCP_USER,
3363 (uint16_t)cipherdata->algtype);
3366 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3367 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3368 cipherdata->algtype);
3373 case PDCP_SN_SIZE_15:
3374 case PDCP_SN_SIZE_18:
3376 err = pdcp_insert_uplane_with_int_op(p, swap,
3377 cipherdata, authdata,
3378 sn_size, era_2_sw_hfn_ovrd,
3379 OP_TYPE_ENCAP_PROTOCOL);
3386 switch (cipherdata->algtype) {
3387 case PDCP_CIPHER_TYPE_NULL:
3388 insert_copy_frame_op(p,
3390 OP_TYPE_ENCAP_PROTOCOL);
3394 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3395 OP_TYPE_ENCAP_PROTOCOL, sn_size);
3402 case PDCP_SN_SIZE_5:
3404 pr_err("Invalid SN size selected\n");
3408 PATCH_HDR(p, 0, pdb_end);
3409 return PROGRAM_FINALIZE(p);
3413 * cnstr_shdsc_pdcp_u_plane_decap - Function for creating a PDCP User Plane
3414 * decapsulation descriptor.
3415 * @descbuf: pointer to buffer for descriptor construction
3416 * @ps: if 36/40bit addressing is desired, this parameter must be true
3417 * @swap: must be true when core endianness doesn't match SEC endianness
3418 * @sn_size: selects Sequence Number Size: 7/12/15 bits
3419 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3421 * @bearer: radio bearer ID
3422 * @direction: the direction of the PDCP frame (UL/DL)
3423 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3424 * keys should be renegotiated at the earliest convenience.
3425 * @cipherdata: pointer to block cipher transform definitions
3426 * Valid algorithm values are those from cipher_type_pdcp enum.
3427 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3428 * this descriptor. Note: Can only be used for
3431 * Return: size of descriptor written in words or negative number on error.
3432 * Once the function returns, the value of this parameter can be used
3433 * for reclaiming the space that wasn't used for the descriptor.
3435 * Note: descbuf must be large enough to contain a full 256 byte long
3436 * descriptor; after the function returns, by subtracting the actual number of
3437 * bytes used, the user can reuse the remaining buffer space for other purposes.
3440 cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf,
3443 enum pdcp_sn_size sn_size,
3445 unsigned short bearer,
3446 unsigned short direction,
3447 uint32_t hfn_threshold,
3448 struct alginfo *cipherdata,
3449 struct alginfo *authdata,
3450 unsigned char era_2_sw_hfn_ovrd)
3453 struct program *p = &prg;
3455 enum pdb_type_e pdb_type;
3456 static enum rta_share_type
3457 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3459 SHR_WAIT, /* NULL */
3460 SHR_ALWAYS, /* SNOW f9 */
3461 SHR_ALWAYS, /* AES CMAC */
3462 SHR_ALWAYS /* ZUC-I */
3465 SHR_ALWAYS, /* NULL */
3466 SHR_ALWAYS, /* SNOW f9 */
3467 SHR_WAIT, /* AES CMAC */
3468 SHR_WAIT /* ZUC-I */
3471 SHR_ALWAYS, /* NULL */
3472 SHR_ALWAYS, /* SNOW f9 */
3473 SHR_ALWAYS, /* AES CMAC */
3474 SHR_WAIT /* ZUC-I */
3477 SHR_ALWAYS, /* NULL */
3478 SHR_WAIT, /* SNOW f9 */
3479 SHR_WAIT, /* AES CMAC */
3480 SHR_ALWAYS /* ZUC-I */
3486 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3487 pr_err("Cannot select SW HFN override for other era than 2");
3491 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3492 pr_err("Cannot use u-plane auth with era < 8");
3496 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3498 PROGRAM_SET_BSWAP(p);
3500 PROGRAM_SET_36BIT_ADDR(p);
3502 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3504 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3506 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer,
3507 direction, hfn_threshold,
3508 cipherdata, authdata);
3509 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3510 pr_err("Error creating PDCP UPlane PDB\n");
3513 SET_LABEL(p, pdb_end);
3515 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3520 case PDCP_SN_SIZE_7:
3521 case PDCP_SN_SIZE_12:
3522 switch (cipherdata->algtype) {
3523 case PDCP_CIPHER_TYPE_ZUC:
3524 if (rta_sec_era < RTA_SEC_ERA_5) {
3525 pr_err("Invalid era for selected algorithm\n");
3529 case PDCP_CIPHER_TYPE_AES:
3530 case PDCP_CIPHER_TYPE_SNOW:
3531 case PDCP_CIPHER_TYPE_NULL:
3532 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3533 pr_err("PDB type must be FULL for PROTO desc\n");
3537 /* Insert auth key if requested */
3538 if (authdata && authdata->algtype)
3539 KEY(p, KEY2, authdata->key_enc_flags,
3540 (uint64_t)authdata->key, authdata->keylen,
3541 INLINE_KEY(authdata));
3542 else if (authdata && authdata->algtype == 0) {
3543 err = pdcp_insert_uplane_with_int_op(p, swap,
3544 cipherdata, authdata,
3545 sn_size, era_2_sw_hfn_ovrd,
3546 OP_TYPE_DECAP_PROTOCOL);
3552 /* Insert Cipher Key */
3553 KEY(p, KEY1, cipherdata->key_enc_flags,
3554 cipherdata->key, cipherdata->keylen,
3555 INLINE_KEY(cipherdata));
3557 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3558 OP_PCLID_LTE_PDCP_USER_RN,
3559 ((uint16_t)cipherdata->algtype << 8) |
3560 (uint16_t)authdata->algtype);
3562 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3563 OP_PCLID_LTE_PDCP_USER,
3564 (uint16_t)cipherdata->algtype);
3567 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3568 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3569 cipherdata->algtype);
3574 case PDCP_SN_SIZE_15:
3575 case PDCP_SN_SIZE_18:
3577 err = pdcp_insert_uplane_with_int_op(p, swap,
3578 cipherdata, authdata,
3579 sn_size, era_2_sw_hfn_ovrd,
3580 OP_TYPE_DECAP_PROTOCOL);
3587 switch (cipherdata->algtype) {
3588 case PDCP_CIPHER_TYPE_NULL:
3589 insert_copy_frame_op(p,
3591 OP_TYPE_DECAP_PROTOCOL);
3595 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3596 OP_TYPE_DECAP_PROTOCOL, sn_size);
3603 case PDCP_SN_SIZE_5:
3605 pr_err("Invalid SN size selected\n");
3609 PATCH_HDR(p, 0, pdb_end);
3610 return PROGRAM_FINALIZE(p);
3614 * cnstr_shdsc_pdcp_short_mac - Function for creating a PDCP Short MAC
3616 * @descbuf: pointer to buffer for descriptor construction
3617 * @ps: if 36/40bit addressing is desired, this parameter must be true
3618 * @swap: must be true when core endianness doesn't match SEC endianness
3619 * @authdata: pointer to authentication transform definitions
3620 * Valid algorithm values are those from auth_type_pdcp enum.
3622 * Return: size of descriptor written in words or negative number on error.
3623 * Once the function returns, the value of this parameter can be used
3624 * for reclaiming the space that wasn't used for the descriptor.
3626 * Note: descbuf must be large enough to contain a full 256 byte long
3627 * descriptor; after the function returns, by subtracting the actual number of
3628 * bytes used, the user can reuse the remaining buffer space for other purposes.
3631 cnstr_shdsc_pdcp_short_mac(uint32_t *descbuf,
3634 struct alginfo *authdata)
3637 struct program *p = &prg;
3638 uint32_t iv[3] = {0, 0, 0};
3639 LABEL(local_offset);
3640 REFERENCE(move_cmd_read_descbuf);
3641 REFERENCE(move_cmd_write_descbuf);
3643 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3645 PROGRAM_SET_BSWAP(p);
3647 PROGRAM_SET_36BIT_ADDR(p);
3649 SHR_HDR(p, SHR_ALWAYS, 1, 0);
3651 if (rta_sec_era > RTA_SEC_ERA_2) {
3652 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
3653 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
3655 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4, 0);
3656 MATHB(p, MATH1, SUB, ONE, MATH1, 4, 0);
3657 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
3658 MOVE(p, MATH1, 0, MATH0, 0, 8, IMMED);
3661 * Since MOVELEN is available only starting with
3662 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
3663 * command dynamically by writing the length from M1 by
3664 * OR-ing the command in the M1 register and MOVE the
3665 * result into the descriptor buffer. Care must be taken
3666 * wrt. the location of the command because of SEC
3667 * pipelining. The actual MOVEs are written at the end
3668 * of the descriptor due to calculations needed on the
3669 * offset in the descriptor for the MOVE command.
3671 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
3673 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
3676 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
3678 switch (authdata->algtype) {
3679 case PDCP_AUTH_TYPE_NULL:
3680 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3681 if (rta_sec_era > RTA_SEC_ERA_2) {
3682 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3684 SET_LABEL(p, local_offset);
3686 /* Shut off automatic Info FIFO entries */
3687 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3689 /* Placeholder for MOVE command with length from M1
3692 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3694 /* Enable automatic Info FIFO entries */
3695 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3698 LOAD(p, (uintptr_t)iv, MATH0, 0, 8, IMMED | COPY);
3699 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | LAST2 | FLUSH1);
3700 SEQSTORE(p, MATH0, 0, 4, 0);
3704 case PDCP_AUTH_TYPE_SNOW:
3706 iv[1] = swap ? swab32(0x04000000) : 0x04000000;
3707 iv[2] = swap ? swab32(0xF8000000) : 0xF8000000;
3709 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3710 authdata->keylen, INLINE_KEY(authdata));
3711 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3712 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
3714 OP_ALG_AS_INITFINAL,
3717 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3719 if (rta_sec_era > RTA_SEC_ERA_2) {
3720 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3722 SET_LABEL(p, local_offset);
3725 /* Shut off automatic Info FIFO entries */
3726 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3728 /* Placeholder for MOVE command with length from M1
3731 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3733 /* Enable automatic Info FIFO entries */
3734 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3736 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3737 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3741 case PDCP_AUTH_TYPE_AES:
3743 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3744 iv[2] = 0x00000000; /* unused */
3746 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
3747 authdata->keylen, INLINE_KEY(authdata));
3748 LOAD(p, (uintptr_t)&iv, MATH0, 0, 8, IMMED | COPY);
3749 MOVE(p, MATH0, 0, IFIFOAB1, 0, 8, IMMED);
3750 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
3752 OP_ALG_AS_INITFINAL,
3755 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3757 if (rta_sec_era > RTA_SEC_ERA_2) {
3758 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
3760 SET_LABEL(p, local_offset);
3762 /* Shut off automatic Info FIFO entries */
3763 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3765 /* Placeholder for MOVE command with length from M1
3768 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
3770 /* Enable automatic Info FIFO entries */
3771 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3773 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3774 SEQSTORE(p, CONTEXT1, 0, 4, 0);
3778 case PDCP_AUTH_TYPE_ZUC:
3779 if (rta_sec_era < RTA_SEC_ERA_5) {
3780 pr_err("Invalid era for selected algorithm\n");
3784 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3785 iv[2] = 0x00000000; /* unused */
3787 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3788 authdata->keylen, INLINE_KEY(authdata));
3789 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3790 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
3792 OP_ALG_AS_INITFINAL,
3795 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3796 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3797 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3798 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3803 pr_err("%s: Invalid integrity algorithm selected: %d\n",
3804 "cnstr_shdsc_pdcp_short_mac", authdata->algtype);
3809 if (rta_sec_era < RTA_SEC_ERA_3) {
3810 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
3811 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
3814 return PROGRAM_FINALIZE(p);
3817 #endif /* __DESC_PDCP_H__ */