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_7BIT_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_7BIT_SN_MASK 0x7F000000
52 #define PDCP_7BIT_SN_MASK_BE 0x0000007F
55 * PDCP_12BIT_SN_MASK - This mask is used in the PDCP descriptors for
56 * extracting the sequence number (SN) from the
57 * PDCP User Plane header.
59 #define PDCP_12BIT_SN_MASK 0xFF0F0000
60 #define PDCP_12BIT_SN_MASK_BE 0x00000FFF
63 * PDCP_U_PLANE_15BIT_SN_MASK - This mask is used in the PDCP descriptors for
64 * extracting the sequence number (SN) from the
65 * PDCP User Plane header. For PDCP Control Plane,
66 * the SN is constant (5 bits) as opposed to PDCP
67 * Data Plane (7/12/15 bits).
69 #define PDCP_U_PLANE_15BIT_SN_MASK 0xFF7F0000
70 #define PDCP_U_PLANE_15BIT_SN_MASK_BE 0x00007FFF
73 * PDCP_U_PLANE_18BIT_SN_MASK - This mask is used in the PDCP descriptors for
74 * extracting the sequence number (SN) from the
75 * PDCP User Plane header.
77 #define PDCP_U_PLANE_18BIT_SN_MASK 0xFFFF0300
78 #define PDCP_U_PLANE_18BIT_SN_MASK_BE 0x0003FFFF
81 * PDCP_BEARER_MASK - This mask is used masking out the bearer for PDCP
82 * processing with SNOW f9 in LTE.
84 * The value on which this mask is applied is formatted as below:
85 * Count-C (32 bit) | Bearer (5 bit) | Direction (1 bit) | 0 (26 bits)
87 * Applying this mask is done for creating the upper 64 bits of the IV needed
90 * The lower 32 bits of the mask are used for masking the direction for AES
93 #define PDCP_BEARER_MASK 0x00000004FFFFFFFFull
94 #define PDCP_BEARER_MASK_BE 0xFFFFFFFF04000000ull
97 * PDCP_DIR_MASK - This mask is used masking out the direction for PDCP
98 * processing with SNOW f9 in LTE.
100 * The value on which this mask is applied is formatted as below:
101 * Bearer (5 bit) | Direction (1 bit) | 0 (26 bits)
103 * Applying this mask is done for creating the lower 32 bits of the IV needed
106 * The upper 32 bits of the mask are used for masking the direction for AES
109 #define PDCP_DIR_MASK 0x00000000000000F8ull
110 #define PDCP_DIR_MASK_BE 0xF800000000000000ull
113 * PDCP_NULL_INT_MAC_I_VAL - The value of the PDCP PDU MAC-I in case NULL
117 #define PDCP_NULL_INT_MAC_I_VAL 0x00000000
120 * PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS - The status used to report ICV check
121 * failed in case of NULL integrity
122 * Control Plane processing.
124 #define PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS 0x0A
126 * PDCP_DPOVRD_HFN_OV_EN - Value to be used in the FD status/cmd field to
127 * indicate the HFN override mechanism is active for the
130 #define PDCP_DPOVRD_HFN_OV_EN 0x80000000
133 * PDCP_P4080REV2_HFN_OV_BUFLEN - The length in bytes of the supplementary space
134 * that must be provided by the user at the
135 * beginning of the input frame buffer for
138 * The format of the frame buffer is the following:
140 * |<---PDCP_P4080REV2_HFN_OV_BUFLEN-->|
141 * //===================================||============||==============\\
142 * || PDCP_DPOVRD_HFN_OV_EN | HFN value || PDCP Header|| PDCP Payload ||
143 * \\===================================||============||==============//
145 * If HFN override mechanism is not desired, then the MSB of the first 4 bytes
148 #define PDCP_P4080REV2_HFN_OV_BUFLEN 4
151 * enum cipher_type_pdcp - Type selectors for cipher types in PDCP protocol OP
153 * @PDCP_CIPHER_TYPE_NULL: NULL
154 * @PDCP_CIPHER_TYPE_SNOW: SNOW F8
155 * @PDCP_CIPHER_TYPE_AES: AES
156 * @PDCP_CIPHER_TYPE_ZUC: ZUCE
157 * @PDCP_CIPHER_TYPE_INVALID: invalid option
159 enum cipher_type_pdcp {
160 PDCP_CIPHER_TYPE_NULL,
161 PDCP_CIPHER_TYPE_SNOW,
162 PDCP_CIPHER_TYPE_AES,
163 PDCP_CIPHER_TYPE_ZUC,
164 PDCP_CIPHER_TYPE_INVALID
168 * enum auth_type_pdcp - Type selectors for integrity types in PDCP protocol OP
170 * @PDCP_AUTH_TYPE_NULL: NULL
171 * @PDCP_AUTH_TYPE_SNOW: SNOW F9
172 * @PDCP_AUTH_TYPE_AES: AES CMAC
173 * @PDCP_AUTH_TYPE_ZUC: ZUCA
174 * @PDCP_AUTH_TYPE_INVALID: invalid option
176 enum auth_type_pdcp {
181 PDCP_AUTH_TYPE_INVALID
185 * enum pdcp_dir - Type selectors for direction for PDCP protocol
186 * @PDCP_DIR_UPLINK: uplink direction
187 * @PDCP_DIR_DOWNLINK: downlink direction
188 * @PDCP_DIR_INVALID: invalid option
192 PDCP_DIR_DOWNLINK = 1,
197 * enum pdcp_plane - PDCP domain selectors
198 * @PDCP_CONTROL_PLANE: Control Plane
199 * @PDCP_DATA_PLANE: Data Plane
200 * @PDCP_SHORT_MAC: Short MAC
209 * enum pdcp_sn_size - Sequence Number Size selectors for PDCP protocol
210 * @PDCP_SN_SIZE_5: 5bit sequence number
211 * @PDCP_SN_SIZE_7: 7bit sequence number
212 * @PDCP_SN_SIZE_12: 12bit sequence number
213 * @PDCP_SN_SIZE_15: 15bit sequence number
214 * @PDCP_SN_SIZE_18: 18bit sequence number
219 PDCP_SN_SIZE_12 = 12,
220 PDCP_SN_SIZE_15 = 15,
225 * PDCP Control Plane Protocol Data Blocks
227 #define PDCP_C_PLANE_PDB_HFN_SHIFT 5
228 #define PDCP_C_PLANE_PDB_BEARER_SHIFT 27
229 #define PDCP_C_PLANE_PDB_DIR_SHIFT 26
230 #define PDCP_C_PLANE_PDB_HFN_THR_SHIFT 5
232 #define PDCP_U_PLANE_PDB_OPT_SHORT_SN 0x2
233 #define PDCP_U_PLANE_PDB_OPT_15B_SN 0x4
234 #define PDCP_U_PLANE_PDB_OPT_18B_SN 0x6
235 #define PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT 7
236 #define PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT 12
237 #define PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT 15
238 #define PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT 18
239 #define PDCP_U_PLANE_PDB_BEARER_SHIFT 27
240 #define PDCP_U_PLANE_PDB_DIR_SHIFT 26
241 #define PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT 7
242 #define PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT 12
243 #define PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT 15
244 #define PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT 18
251 uint32_t hfn_res; /* HyperFrame number,(27, 25 or 21 bits),
252 * left aligned & right-padded with zeros.
254 uint32_t bearer_dir_res;/* Bearer(5 bits), packet direction (1 bit),
255 * left aligned & right-padded with zeros.
257 uint32_t hfn_thr_res; /* HyperFrame number threshold (27, 25 or 21
258 * bits), left aligned & right-padded with
264 * PDCP internal PDB types
267 PDCP_PDB_TYPE_NO_PDB,
268 PDCP_PDB_TYPE_FULL_PDB,
269 PDCP_PDB_TYPE_REDUCED_PDB,
270 PDCP_PDB_TYPE_INVALID
273 #define REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET 4
274 #define FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET 8
277 * rta_inline_pdcp_query() - Provide indications if a key can be passed as
278 * immediate data or shall be referenced in a
280 * Return: 0 if data can be inlined or 1 if referenced.
283 rta_inline_pdcp_query(enum auth_type_pdcp auth_alg,
284 enum cipher_type_pdcp cipher_alg,
285 enum pdcp_sn_size sn_size,
289 * Shared Descriptors for some of the cases does not fit in the
290 * MAX_DESC_SIZE of the descriptor especially when non-protocol
291 * descriptors are formed as in 18bit cases and when HFN override
292 * is enabled as 2 extra words are added in the job descriptor.
293 * The cases which exceed are for RTA_SEC_ERA=8 and HFN override
294 * enabled and 18bit uplane and either of following Algo combinations.
300 * We cannot make inline for all cases, as this will impact performance
301 * due to extra memory accesses for the keys.
303 if ((rta_sec_era == RTA_SEC_ERA_8) && hfn_ovd &&
304 (sn_size == PDCP_SN_SIZE_18) &&
305 ((cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
306 auth_alg == PDCP_AUTH_TYPE_AES) ||
307 (cipher_alg == PDCP_CIPHER_TYPE_AES &&
308 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
309 (cipher_alg == PDCP_CIPHER_TYPE_SNOW &&
310 auth_alg == PDCP_AUTH_TYPE_SNOW) ||
311 (cipher_alg == PDCP_CIPHER_TYPE_ZUC &&
312 auth_alg == PDCP_AUTH_TYPE_SNOW))) {
321 * Function for appending the portion of a PDCP Control Plane shared descriptor
322 * which performs NULL encryption and integrity (i.e. copies the input frame
323 * to the output frame, appending 32 bits of zeros at the end (MAC-I for
327 pdcp_insert_cplane_null_op(struct program *p,
328 bool swap __maybe_unused,
329 struct alginfo *cipherdata __maybe_unused,
330 struct alginfo *authdata __maybe_unused,
332 enum pdcp_sn_size sn_size __maybe_unused,
333 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
336 REFERENCE(move_cmd_read_descbuf);
337 REFERENCE(move_cmd_write_descbuf);
339 if (rta_sec_era > RTA_SEC_ERA_2) {
340 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
341 if (dir == OP_TYPE_ENCAP_PROTOCOL)
342 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
345 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
348 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
349 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
351 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
352 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
354 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
356 MATHB(p, VSEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4,
358 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
360 MATHB(p, VSEQOUTSZ, SUB, ONE, MATH0, 4, 0);
363 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
366 * Since MOVELEN is available only starting with
367 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
368 * command dynamically by writing the length from M1 by
369 * OR-ing the command in the M1 register and MOVE the
370 * result into the descriptor buffer. Care must be taken
371 * wrt. the location of the command because of SEC
372 * pipelining. The actual MOVEs are written at the end
373 * of the descriptor due to calculations needed on the
374 * offset in the descriptor for the MOVE command.
376 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
378 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
381 MATHB(p, VSEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
383 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
385 if (rta_sec_era > RTA_SEC_ERA_2) {
386 if (dir == OP_TYPE_ENCAP_PROTOCOL)
387 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
389 MATHB(p, VSEQOUTSZ, ADD, ZERO, MATH0, 4, 0);
391 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
392 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
394 if (rta_sec_era > RTA_SEC_ERA_2) {
395 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
397 SET_LABEL(p, local_offset);
399 /* Shut off automatic Info FIFO entries */
400 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
401 /* Placeholder for MOVE command with length from M1 register */
402 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
403 /* Enable automatic Info FIFO entries */
404 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
407 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
408 MATHB(p, MATH1, XOR, MATH1, MATH0, 8, 0);
409 MOVE(p, MATH0, 0, OFIFO, 0, 4, IMMED);
412 if (rta_sec_era < RTA_SEC_ERA_3) {
413 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
414 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
421 insert_copy_frame_op(struct program *p,
422 struct alginfo *cipherdata __maybe_unused,
423 unsigned int dir __maybe_unused)
426 REFERENCE(move_cmd_read_descbuf);
427 REFERENCE(move_cmd_write_descbuf);
429 if (rta_sec_era > RTA_SEC_ERA_2) {
430 MATHB(p, SEQINSZ, ADD, ZERO, VSEQINSZ, 4, 0);
431 MATHB(p, SEQINSZ, ADD, ZERO, VSEQOUTSZ, 4, 0);
433 MATHB(p, SEQINSZ, ADD, ONE, VSEQINSZ, 4, 0);
434 MATHB(p, VSEQINSZ, SUB, ONE, VSEQINSZ, 4, 0);
435 MATHB(p, SEQINSZ, ADD, ONE, VSEQOUTSZ, 4, 0);
436 MATHB(p, VSEQOUTSZ, SUB, ONE, VSEQOUTSZ, 4, 0);
437 MATHB(p, VSEQINSZ, SUB, ONE, MATH0, 4, 0);
438 MATHB(p, MATH0, ADD, ONE, MATH0, 4, 0);
441 * Since MOVELEN is available only starting with
442 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
443 * command dynamically by writing the length from M1 by
444 * OR-ing the command in the M1 register and MOVE the
445 * result into the descriptor buffer. Care must be taken
446 * wrt. the location of the command because of SEC
447 * pipelining. The actual MOVEs are written at the end
448 * of the descriptor due to calculations needed on the
449 * offset in the descriptor for the MOVE command.
451 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
453 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
456 MATHB(p, SEQINSZ, SUB, PDCP_NULL_MAX_FRAME_LEN, NONE, 4,
458 JUMP(p, PDCP_MAX_FRAME_LEN_STATUS, HALT_STATUS, ALL_FALSE, MATH_N);
460 if (rta_sec_era > RTA_SEC_ERA_2)
461 MATHB(p, VSEQINSZ, ADD, ZERO, MATH0, 4, 0);
463 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
464 if (rta_sec_era > RTA_SEC_ERA_2) {
465 MOVE(p, AB1, 0, OFIFO, 0, MATH0, 0);
467 SET_LABEL(p, local_offset);
469 /* Shut off automatic Info FIFO entries */
470 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
472 /* Placeholder for MOVE command with length from M0 register */
473 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
475 /* Enable automatic Info FIFO entries */
476 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
479 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
481 if (rta_sec_era < RTA_SEC_ERA_3) {
482 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
483 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
489 pdcp_insert_cplane_int_only_op(struct program *p,
490 bool swap __maybe_unused,
491 struct alginfo *cipherdata __maybe_unused,
492 struct alginfo *authdata, unsigned int dir,
493 enum pdcp_sn_size sn_size,
494 unsigned char era_2_sw_hfn_ovrd)
496 uint32_t offset = 0, length = 0, sn_mask = 0;
498 /* 12 bit SN is only supported for protocol offload case */
499 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_12) {
500 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
501 authdata->keylen, INLINE_KEY(authdata));
503 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
504 (uint16_t)authdata->algtype);
508 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
513 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
514 PDCP_C_PLANE_SN_MASK_BE;
516 case PDCP_SN_SIZE_18:
519 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
520 PDCP_U_PLANE_18BIT_SN_MASK_BE;
523 case PDCP_SN_SIZE_12:
524 case PDCP_SN_SIZE_15:
525 pr_err("Invalid sn_size for %s\n", __func__);
530 REFERENCE(move_cmd_read_descbuf);
531 REFERENCE(move_cmd_write_descbuf);
533 switch (authdata->algtype) {
534 case PDCP_AUTH_TYPE_SNOW:
535 /* Insert Auth Key */
536 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
537 authdata->keylen, INLINE_KEY(authdata));
538 SEQLOAD(p, MATH0, offset, length, 0);
539 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
541 if (rta_sec_era > RTA_SEC_ERA_2 ||
542 (rta_sec_era == RTA_SEC_ERA_2 &&
543 era_2_sw_hfn_ovrd == 0)) {
544 SEQINPTR(p, 0, length, RTO);
546 SEQINPTR(p, 0, 5, RTO);
547 SEQFIFOLOAD(p, SKIP, 4, 0);
551 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
553 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
555 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
557 MATHB(p, MATH2, AND, PDCP_BEARER_MASK, MATH2, 8,
559 MOVEB(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
560 MATHB(p, MATH3, AND, PDCP_DIR_MASK, MATH3, 8, IMMED2);
561 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
562 MOVEB(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
564 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
566 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
568 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
569 MATHB(p, MATH2, AND, PDCP_BEARER_MASK_BE, MATH2, 8,
572 MOVE(p, DESCBUF, 0x0C, MATH3, 0, 4, WAITCOMP | IMMED);
573 MATHB(p, MATH3, AND, PDCP_DIR_MASK_BE, MATH3, 8,
575 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
576 MOVE(p, MATH2, 0, CONTEXT2, 0, 0x0C, WAITCOMP | IMMED);
579 if (dir == OP_TYPE_DECAP_PROTOCOL) {
580 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
583 if (rta_sec_era > RTA_SEC_ERA_2) {
584 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
587 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
589 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
594 if (rta_sec_era > RTA_SEC_ERA_2) {
595 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
596 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
598 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
599 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
602 * Since MOVELEN is available only starting with
603 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
604 * command dynamically by writing the length from M1 by
605 * OR-ing the command in the M1 register and MOVE the
606 * result into the descriptor buffer. Care must be taken
607 * wrt. the location of the command because of SEC
608 * pipelining. The actual MOVEs are written at the end
609 * of the descriptor due to calculations needed on the
610 * offset in the descriptor for the MOVE command.
612 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
614 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
615 8, WAITCOMP | IMMED);
618 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
619 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9, OP_ALG_AAI_F9,
621 dir == OP_TYPE_ENCAP_PROTOCOL ?
622 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
625 if (rta_sec_era > RTA_SEC_ERA_2) {
626 SEQFIFOLOAD(p, MSGINSNOOP, 0,
627 VLF | LAST1 | LAST2 | FLUSH1);
628 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
630 SEQFIFOLOAD(p, MSGINSNOOP, 0,
631 VLF | LAST1 | LAST2 | FLUSH1);
632 SET_LABEL(p, local_offset);
634 /* Shut off automatic Info FIFO entries */
635 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
637 * Placeholder for MOVE command with length from M1
640 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
641 /* Enable automatic Info FIFO entries */
642 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
645 if (dir == OP_TYPE_DECAP_PROTOCOL)
646 SEQFIFOLOAD(p, ICV2, 4, LAST2);
648 SEQSTORE(p, CONTEXT2, 0, 4, 0);
652 case PDCP_AUTH_TYPE_AES:
653 /* Insert Auth Key */
654 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
655 authdata->keylen, INLINE_KEY(authdata));
656 SEQLOAD(p, MATH0, offset, length, 0);
657 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
658 if (rta_sec_era > RTA_SEC_ERA_2 ||
659 (rta_sec_era == RTA_SEC_ERA_2 &&
660 era_2_sw_hfn_ovrd == 0)) {
661 SEQINPTR(p, 0, length, RTO);
663 SEQINPTR(p, 0, 5, RTO);
664 SEQFIFOLOAD(p, SKIP, 4, 0);
668 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
670 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
672 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
673 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
674 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
676 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
678 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
680 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
681 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
682 MOVE(p, MATH2, 0, IFIFOAB1, 0, 8, IMMED);
685 if (dir == OP_TYPE_DECAP_PROTOCOL) {
686 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
689 if (rta_sec_era > RTA_SEC_ERA_2) {
690 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4,
693 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4,
695 MATHB(p, MATH1, SUB, ONE, MATH1, 4,
700 if (rta_sec_era > RTA_SEC_ERA_2) {
701 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
702 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
704 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
705 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
708 * Since MOVELEN is available only starting with
709 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
710 * command dynamically by writing the length from M1 by
711 * OR-ing the command in the M1 register and MOVE the
712 * result into the descriptor buffer. Care must be taken
713 * wrt. the location of the command because of SEC
714 * pipelining. The actual MOVEs are written at the end
715 * of the descriptor due to calculations needed on the
716 * offset in the descriptor for the MOVE command.
718 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH1, 0, 6,
720 move_cmd_write_descbuf = MOVE(p, MATH1, 0, DESCBUF, 0,
721 8, WAITCOMP | IMMED);
723 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
724 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
727 dir == OP_TYPE_ENCAP_PROTOCOL ?
728 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
731 if (rta_sec_era > RTA_SEC_ERA_2) {
732 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
733 SEQFIFOLOAD(p, MSGINSNOOP, 0,
734 VLF | LAST1 | LAST2 | FLUSH1);
736 SEQFIFOLOAD(p, MSGINSNOOP, 0,
737 VLF | LAST1 | LAST2 | FLUSH1);
738 SET_LABEL(p, local_offset);
740 /* Shut off automatic Info FIFO entries */
741 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
744 * Placeholder for MOVE command with length from
747 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
749 /* Enable automatic Info FIFO entries */
750 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
753 if (dir == OP_TYPE_DECAP_PROTOCOL)
754 SEQFIFOLOAD(p, ICV1, 4, LAST1 | FLUSH1);
756 SEQSTORE(p, CONTEXT1, 0, 4, 0);
760 case PDCP_AUTH_TYPE_ZUC:
761 if (rta_sec_era < RTA_SEC_ERA_5) {
762 pr_err("Invalid era for selected algorithm\n");
765 /* Insert Auth Key */
766 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
767 authdata->keylen, INLINE_KEY(authdata));
768 SEQLOAD(p, MATH0, offset, length, 0);
769 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
770 SEQINPTR(p, 0, length, RTO);
772 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
774 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
776 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
777 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
778 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
781 MATHB(p, MATH0, AND, sn_mask, MATH1, 8,
783 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
785 MOVE(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
786 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
787 MOVE(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
789 if (dir == OP_TYPE_DECAP_PROTOCOL)
790 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4,
793 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
795 MATHB(p, MATH1, SUB, ZERO, VSEQINSZ, 4, 0);
796 MATHB(p, MATH1, SUB, ZERO, VSEQOUTSZ, 4, 0);
797 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
798 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
801 dir == OP_TYPE_ENCAP_PROTOCOL ?
802 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
804 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
805 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
807 if (dir == OP_TYPE_DECAP_PROTOCOL)
808 SEQFIFOLOAD(p, ICV2, 4, LAST2);
810 SEQSTORE(p, CONTEXT2, 0, 4, 0);
815 pr_err("%s: Invalid integrity algorithm selected: %d\n",
816 "pdcp_insert_cplane_int_only_op", authdata->algtype);
820 if (rta_sec_era < RTA_SEC_ERA_3) {
821 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
822 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
829 pdcp_insert_cplane_enc_only_op(struct program *p,
830 bool swap __maybe_unused,
831 struct alginfo *cipherdata,
832 struct alginfo *authdata __maybe_unused,
834 enum pdcp_sn_size sn_size,
835 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
837 uint32_t offset = 0, length = 0, sn_mask = 0;
838 /* Insert Cipher Key */
839 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
840 cipherdata->keylen, INLINE_KEY(cipherdata));
842 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18 &&
843 !(rta_sec_era == RTA_SEC_ERA_8 &&
844 authdata->algtype == 0))
845 || (rta_sec_era == RTA_SEC_ERA_10)) {
846 if (sn_size == PDCP_SN_SIZE_5)
847 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
848 (uint16_t)cipherdata->algtype << 8);
850 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
851 (uint16_t)cipherdata->algtype << 8);
854 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
859 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
860 PDCP_C_PLANE_SN_MASK_BE;
862 case PDCP_SN_SIZE_18:
865 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
866 PDCP_U_PLANE_18BIT_SN_MASK_BE;
868 case PDCP_SN_SIZE_12:
871 sn_mask = (swap == false) ? PDCP_12BIT_SN_MASK :
872 PDCP_12BIT_SN_MASK_BE;
875 case PDCP_SN_SIZE_15:
876 pr_err("Invalid sn_size for %s\n", __func__);
880 SEQLOAD(p, MATH0, offset, length, 0);
881 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
882 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
883 SEQSTORE(p, MATH0, offset, length, 0);
884 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
885 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
886 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
888 switch (cipherdata->algtype) {
889 case PDCP_CIPHER_TYPE_SNOW:
890 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
892 if (rta_sec_era > RTA_SEC_ERA_2) {
893 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
895 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
896 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
899 if (dir == OP_TYPE_ENCAP_PROTOCOL)
900 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
903 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
905 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
906 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
908 OP_ALG_AS_INITFINAL, ICV_CHECK_DISABLE,
909 dir == OP_TYPE_ENCAP_PROTOCOL ?
913 case PDCP_CIPHER_TYPE_AES:
914 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
916 if (rta_sec_era > RTA_SEC_ERA_2) {
917 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
919 MATHB(p, SEQINSZ, SUB, ONE, MATH1, 4, 0);
920 MATHB(p, MATH1, ADD, ONE, VSEQINSZ, 4, 0);
923 if (dir == OP_TYPE_ENCAP_PROTOCOL)
924 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
927 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
930 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
931 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
935 dir == OP_TYPE_ENCAP_PROTOCOL ?
939 case PDCP_CIPHER_TYPE_ZUC:
940 if (rta_sec_era < RTA_SEC_ERA_5) {
941 pr_err("Invalid era for selected algorithm\n");
945 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
946 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
947 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
948 if (dir == OP_TYPE_ENCAP_PROTOCOL)
949 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
952 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4,
955 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
956 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
960 dir == OP_TYPE_ENCAP_PROTOCOL ?
965 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
966 "pdcp_insert_cplane_enc_only_op", cipherdata->algtype);
970 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
971 SEQFIFOLOAD(p, MSG1, 0, VLF);
972 FIFOLOAD(p, MSG1, PDCP_NULL_INT_MAC_I_VAL, 4,
973 LAST1 | FLUSH1 | IMMED);
975 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
976 MOVE(p, OFIFO, 0, MATH1, 4, PDCP_MAC_I_LEN, WAITCOMP | IMMED);
977 MATHB(p, MATH1, XOR, PDCP_NULL_INT_MAC_I_VAL, NONE, 4, IMMED2);
978 JUMP(p, PDCP_NULL_INT_ICV_CHECK_FAILED_STATUS,
979 HALT_STATUS, ALL_FALSE, MATH_Z);
986 pdcp_insert_uplane_snow_snow_op(struct program *p,
987 bool swap __maybe_unused,
988 struct alginfo *cipherdata,
989 struct alginfo *authdata,
991 enum pdcp_sn_size sn_size,
992 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
994 uint32_t offset = 0, length = 0, sn_mask = 0;
996 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
997 cipherdata->keylen, INLINE_KEY(cipherdata));
998 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
999 INLINE_KEY(authdata));
1001 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
1004 if (sn_size == PDCP_SN_SIZE_5)
1005 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1007 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1009 PROTOCOL(p, dir, pclid,
1010 ((uint16_t)cipherdata->algtype << 8) |
1011 (uint16_t)authdata->algtype);
1015 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1017 case PDCP_SN_SIZE_5:
1020 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1021 PDCP_C_PLANE_SN_MASK_BE;
1023 case PDCP_SN_SIZE_18:
1026 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1027 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1029 case PDCP_SN_SIZE_7:
1030 case PDCP_SN_SIZE_12:
1031 case PDCP_SN_SIZE_15:
1032 pr_err("Invalid sn_size for %s\n", __func__);
1036 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1037 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1039 SEQLOAD(p, MATH0, offset, length, 0);
1040 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1041 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1042 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1044 SEQSTORE(p, MATH0, offset, length, 0);
1045 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1046 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1047 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1048 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
1049 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, WAITCOMP | IMMED);
1050 if (swap == false) {
1051 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK),
1053 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK),
1056 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE),
1058 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE),
1061 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1063 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1064 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1065 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1066 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1068 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1069 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQINSZ, 4, IMMED2);
1072 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1073 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1075 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1077 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1079 OP_ALG_AS_INITFINAL,
1080 dir == OP_TYPE_ENCAP_PROTOCOL ?
1081 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1083 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1085 OP_ALG_AS_INITFINAL,
1087 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1089 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1090 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1091 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1093 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1094 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1095 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1097 if (rta_sec_era >= RTA_SEC_ERA_6)
1098 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1100 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1102 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1104 if (rta_sec_era <= RTA_SEC_ERA_2) {
1105 /* Shut off automatic Info FIFO entries */
1106 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1107 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1109 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1117 pdcp_insert_uplane_zuc_zuc_op(struct program *p,
1118 bool swap __maybe_unused,
1119 struct alginfo *cipherdata,
1120 struct alginfo *authdata,
1122 enum pdcp_sn_size sn_size,
1123 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1125 uint32_t offset = 0, length = 0, sn_mask = 0;
1128 REFERENCE(pkeyjump);
1130 if (rta_sec_era < RTA_SEC_ERA_5) {
1131 pr_err("Invalid era for selected algorithm\n");
1135 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1136 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1137 cipherdata->keylen, INLINE_KEY(cipherdata));
1138 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1139 INLINE_KEY(authdata));
1141 SET_LABEL(p, keyjump);
1142 PATCH_JUMP(p, pkeyjump, keyjump);
1144 if (rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) {
1147 if (sn_size == PDCP_SN_SIZE_5)
1148 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1150 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1152 PROTOCOL(p, dir, pclid,
1153 ((uint16_t)cipherdata->algtype << 8) |
1154 (uint16_t)authdata->algtype);
1158 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1160 case PDCP_SN_SIZE_5:
1163 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1164 PDCP_C_PLANE_SN_MASK_BE;
1166 case PDCP_SN_SIZE_18:
1169 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1170 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1172 case PDCP_SN_SIZE_7:
1173 case PDCP_SN_SIZE_12:
1174 case PDCP_SN_SIZE_15:
1175 pr_err("Invalid sn_size for %s\n", __func__);
1179 SEQLOAD(p, MATH0, offset, length, 0);
1180 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1181 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1182 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1183 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1185 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
1186 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1187 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1189 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1191 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1192 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1194 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1196 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1197 SEQSTORE(p, MATH0, offset, length, 0);
1199 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1200 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1201 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1203 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1204 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1207 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1209 OP_ALG_AS_INITFINAL,
1210 dir == OP_TYPE_ENCAP_PROTOCOL ?
1211 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1214 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
1216 OP_ALG_AS_INITFINAL,
1218 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1220 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1221 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1224 MOVEB(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1226 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1227 NFIFOENTRY_DEST_CLASS2 |
1228 NFIFOENTRY_DTYPE_ICV |
1229 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1230 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1233 /* Reset ZUCA mode and done interrupt */
1234 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
1235 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
1241 pdcp_insert_uplane_aes_aes_op(struct program *p,
1242 bool swap __maybe_unused,
1243 struct alginfo *cipherdata,
1244 struct alginfo *authdata,
1246 enum pdcp_sn_size sn_size,
1247 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1249 uint32_t offset = 0, length = 0, sn_mask = 0;
1251 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18)) {
1252 /* Insert Auth Key */
1253 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1254 authdata->keylen, INLINE_KEY(authdata));
1256 /* Insert Cipher Key */
1257 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1258 cipherdata->keylen, INLINE_KEY(cipherdata));
1260 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1261 ((uint16_t)cipherdata->algtype << 8) |
1262 (uint16_t)authdata->algtype);
1266 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1268 case PDCP_SN_SIZE_18:
1271 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1272 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1276 pr_err("Invalid sn_size for %s\n", __func__);
1280 SEQLOAD(p, MATH0, offset, length, 0);
1281 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1282 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1284 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1285 MOVEB(p, DESCBUF, 8, MATH2, 0, 0x08, WAITCOMP | IMMED);
1286 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1287 SEQSTORE(p, MATH0, offset, length, 0);
1289 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1290 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1291 authdata->keylen, INLINE_KEY(authdata));
1292 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1293 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
1295 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1296 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1298 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1300 OP_ALG_AS_INITFINAL,
1303 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1304 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1306 LOAD(p, CLRW_RESET_CLS1_CHA |
1314 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1315 cipherdata->keylen, INLINE_KEY(cipherdata));
1317 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1318 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
1320 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1322 OP_ALG_AS_INITFINAL,
1326 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1328 SEQFIFOLOAD(p, SKIP, length, 0);
1330 SEQFIFOLOAD(p, MSG1, 0, VLF);
1331 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1333 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
1334 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, IMMED);
1336 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1337 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1339 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1340 cipherdata->keylen, INLINE_KEY(cipherdata));
1342 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1344 OP_ALG_AS_INITFINAL,
1348 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1349 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1351 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1353 LOAD(p, CLRW_RESET_CLS1_CHA |
1361 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1362 authdata->keylen, INLINE_KEY(authdata));
1364 SEQINPTR(p, 0, 0, SOP);
1366 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1368 OP_ALG_AS_INITFINAL,
1372 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1374 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1376 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1378 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1379 NFIFOENTRY_DEST_CLASS1 |
1380 NFIFOENTRY_DTYPE_ICV |
1382 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1383 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1390 pdcp_insert_cplane_acc_op(struct program *p,
1391 bool swap __maybe_unused,
1392 struct alginfo *cipherdata,
1393 struct alginfo *authdata,
1395 enum pdcp_sn_size sn_size,
1396 unsigned char era_2_hfn_ovrd __maybe_unused)
1398 /* Insert Auth Key */
1399 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1400 INLINE_KEY(authdata));
1402 /* Insert Cipher Key */
1403 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1404 cipherdata->keylen, INLINE_KEY(cipherdata));
1406 if (sn_size == PDCP_SN_SIZE_5)
1407 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL,
1408 (uint16_t)cipherdata->algtype);
1410 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1411 ((uint16_t)cipherdata->algtype << 8) |
1412 (uint16_t)authdata->algtype);
1418 pdcp_insert_cplane_snow_aes_op(struct program *p,
1419 bool swap __maybe_unused,
1420 struct alginfo *cipherdata,
1421 struct alginfo *authdata,
1423 enum pdcp_sn_size sn_size,
1424 unsigned char era_2_sw_hfn_ovrd)
1426 uint32_t offset = 0, length = 0, sn_mask = 0;
1428 LABEL(back_to_sd_offset);
1430 LABEL(local_offset);
1431 LABEL(jump_to_beginning);
1432 LABEL(fifo_load_mac_i_offset);
1433 REFERENCE(seqin_ptr_read);
1434 REFERENCE(seqin_ptr_write);
1435 REFERENCE(seq_out_read);
1436 REFERENCE(jump_back_to_sd_cmd);
1437 REFERENCE(move_mac_i_to_desc_buf);
1439 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1440 (rta_sec_era == RTA_SEC_ERA_10)) {
1441 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1442 cipherdata->keylen, INLINE_KEY(cipherdata));
1443 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
1444 authdata->keylen, INLINE_KEY(authdata));
1446 if (sn_size == PDCP_SN_SIZE_5)
1447 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_CTRL_MIXED,
1448 ((uint16_t)cipherdata->algtype << 8) |
1449 (uint16_t)authdata->algtype);
1451 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER_RN,
1452 ((uint16_t)cipherdata->algtype << 8) |
1453 (uint16_t)authdata->algtype);
1457 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1459 case PDCP_SN_SIZE_5:
1462 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1463 PDCP_C_PLANE_SN_MASK_BE;
1465 case PDCP_SN_SIZE_18:
1468 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1469 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1471 case PDCP_SN_SIZE_7:
1472 case PDCP_SN_SIZE_12:
1473 case PDCP_SN_SIZE_15:
1474 pr_err("Invalid sn_size for %s\n", __func__);
1479 SEQLOAD(p, MATH0, offset, length, 0);
1480 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1481 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1482 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1483 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
1484 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1485 SEQSTORE(p, MATH0, offset, length, 0);
1486 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1487 if (rta_sec_era > RTA_SEC_ERA_2 ||
1488 (rta_sec_era == RTA_SEC_ERA_2 &&
1489 era_2_sw_hfn_ovrd == 0)) {
1490 SEQINPTR(p, 0, length, RTO);
1492 SEQINPTR(p, 0, 5, RTO);
1493 SEQFIFOLOAD(p, SKIP, 4, 0);
1495 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1496 authdata->keylen, INLINE_KEY(authdata));
1497 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
1499 if (rta_sec_era > RTA_SEC_ERA_2) {
1500 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1501 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
1502 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1505 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1506 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN - 1, VSEQOUTSZ,
1509 * Note: Although the calculations below might seem a
1510 * little off, the logic is the following:
1512 * - SEQ IN PTR RTO below needs the full length of the
1513 * frame; in case of P4080_REV_2_HFN_OV_WORKAROUND,
1514 * this means the length of the frame to be processed
1515 * + 4 bytes (the HFN override flag and value).
1516 * The length of the frame to be processed minus 1
1517 * byte is in the VSIL register (because
1518 * VSIL = SIL + 3, due to 1 byte, the header being
1519 * already written by the SEQ STORE above). So for
1520 * calculating the length to use in RTO, I add one
1521 * to the VSIL value in order to obtain the total
1522 * frame length. This helps in case of P4080 which
1523 * can have the value 0 as an operand in a MATH
1524 * command only as SRC1 When the HFN override
1525 * workaround is not enabled, the length of the
1526 * frame is given by the SIL register; the
1527 * calculation is similar to the one in the SEC 4.2
1528 * and SEC 5.3 cases.
1530 if (era_2_sw_hfn_ovrd)
1531 MATHB(p, VSEQOUTSZ, ADD, ONE, MATH1, 4,
1534 MATHB(p, SEQINSZ, ADD, MATH3, MATH1, 4,
1538 * Placeholder for filling the length in
1539 * SEQIN PTR RTO below
1541 seqin_ptr_read = MOVE(p, DESCBUF, 0, MATH1, 0, 6, IMMED);
1542 seqin_ptr_write = MOVE(p, MATH1, 0, DESCBUF, 0, 8,
1544 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1546 OP_ALG_AS_INITFINAL,
1549 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1550 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
1551 if (rta_sec_era <= RTA_SEC_ERA_3)
1552 LOAD(p, CLRW_CLR_C1KEY |
1559 LOAD(p, CLRW_RESET_CLS1_CHA |
1567 if (rta_sec_era <= RTA_SEC_ERA_3)
1568 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1570 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1571 cipherdata->keylen, INLINE_KEY(cipherdata));
1572 SET_LABEL(p, local_offset);
1573 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1574 SEQINPTR(p, 0, 0, RTO);
1576 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
1577 SEQFIFOLOAD(p, SKIP, 5, 0);
1578 MATHB(p, SEQINSZ, ADD, ONE, SEQINSZ, 4, 0);
1581 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1582 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1584 OP_ALG_AS_INITFINAL,
1587 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1589 if (rta_sec_era > RTA_SEC_ERA_2 ||
1590 (rta_sec_era == RTA_SEC_ERA_2 &&
1591 era_2_sw_hfn_ovrd == 0))
1592 SEQFIFOLOAD(p, SKIP, length, 0);
1594 SEQFIFOLOAD(p, MSG1, 0, VLF);
1595 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1596 PATCH_MOVE(p, seqin_ptr_read, local_offset);
1597 PATCH_MOVE(p, seqin_ptr_write, local_offset);
1599 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1601 if (rta_sec_era >= RTA_SEC_ERA_5)
1602 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1604 if (rta_sec_era > RTA_SEC_ERA_2)
1605 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1607 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
1609 MATHI(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1611 * TODO: To be changed when proper support is added in RTA (can't load a
1612 * command that is also written by RTA (or patch it for that matter).
1613 * Change when proper RTA support is added.
1616 WORD(p, 0x168B0004);
1618 WORD(p, 0x16880404);
1620 jump_back_to_sd_cmd = JUMP(p, 0, LOCAL_JUMP, ALL_TRUE, 0);
1622 * Placeholder for command reading the SEQ OUT command in
1623 * JD. Done for rereading the decrypted data and performing
1624 * the integrity check
1627 * TODO: RTA currently doesn't support patching of length of a MOVE command
1628 * Thus, it is inserted as a raw word, as per PS setting.
1631 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 20,
1634 seq_out_read = MOVE(p, DESCBUF, 0, MATH1, 0, 16,
1637 MATHB(p, MATH1, XOR, CMD_SEQ_IN_PTR ^ CMD_SEQ_OUT_PTR, MATH1, 4,
1639 /* Placeholder for overwriting the SEQ IN with SEQ OUT */
1641 * TODO: RTA currently doesn't support patching of length of a MOVE command
1642 * Thus, it is inserted as a raw word, as per PS setting.
1645 MOVE(p, MATH1, 0, DESCBUF, 0, 24, IMMED);
1647 MOVE(p, MATH1, 0, DESCBUF, 0, 20, IMMED);
1649 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1650 cipherdata->keylen, INLINE_KEY(cipherdata));
1652 if (rta_sec_era >= RTA_SEC_ERA_4)
1653 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
1655 MOVE(p, CONTEXT1, 0, MATH3, 0, 8, IMMED);
1657 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1659 OP_ALG_AS_INITFINAL,
1662 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1663 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1665 if (rta_sec_era <= RTA_SEC_ERA_3)
1666 move_mac_i_to_desc_buf = MOVE(p, OFIFO, 0, DESCBUF, 0,
1667 4, WAITCOMP | IMMED);
1669 MOVE(p, OFIFO, 0, MATH3, 0, 4, IMMED);
1671 if (rta_sec_era <= RTA_SEC_ERA_3)
1672 LOAD(p, CCTRL_RESET_CHA_ALL, CCTRL, 0, 4, IMMED);
1674 LOAD(p, CLRW_RESET_CLS1_CHA |
1682 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
1683 authdata->keylen, INLINE_KEY(authdata));
1685 * Placeholder for jump in SD for executing the new SEQ IN PTR
1686 * command (which is actually the old SEQ OUT PTR command
1687 * copied over from JD.
1689 SET_LABEL(p, jump_to_beginning);
1690 JUMP(p, 1 - jump_to_beginning, LOCAL_JUMP, ALL_TRUE, 0);
1691 SET_LABEL(p, back_to_sd_offset);
1692 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1694 OP_ALG_AS_INITFINAL,
1698 /* Read the # of bytes written in the output buffer + 1 (HDR) */
1699 MATHI(p, VSEQOUTSZ, ADD, length, VSEQINSZ, 4, IMMED2);
1701 if (rta_sec_era <= RTA_SEC_ERA_3)
1702 MOVE(p, MATH3, 0, IFIFOAB1, 0, 8, IMMED);
1704 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
1706 if (rta_sec_era == RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd)
1707 SEQFIFOLOAD(p, SKIP, 4, 0);
1709 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
1711 if (rta_sec_era >= RTA_SEC_ERA_4) {
1712 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1713 NFIFOENTRY_DEST_CLASS1 |
1714 NFIFOENTRY_DTYPE_ICV |
1716 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
1717 MOVE(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
1719 SET_LABEL(p, fifo_load_mac_i_offset);
1720 FIFOLOAD(p, ICV1, fifo_load_mac_i_offset, 4,
1721 LAST1 | FLUSH1 | IMMED);
1724 SET_LABEL(p, end_desc);
1727 PATCH_MOVE(p, seq_out_read, end_desc + 1);
1728 PATCH_JUMP(p, jump_back_to_sd_cmd,
1729 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1731 if (rta_sec_era <= RTA_SEC_ERA_3)
1732 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1733 fifo_load_mac_i_offset + 1);
1735 PATCH_MOVE(p, seq_out_read, end_desc + 2);
1736 PATCH_JUMP(p, jump_back_to_sd_cmd,
1737 back_to_sd_offset + jump_back_to_sd_cmd - 5);
1739 if (rta_sec_era <= RTA_SEC_ERA_3)
1740 PATCH_MOVE(p, move_mac_i_to_desc_buf,
1741 fifo_load_mac_i_offset + 1);
1749 pdcp_insert_cplane_aes_snow_op(struct program *p,
1750 bool swap __maybe_unused,
1751 struct alginfo *cipherdata,
1752 struct alginfo *authdata,
1754 enum pdcp_sn_size sn_size,
1755 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1757 uint32_t offset = 0, length = 0, sn_mask = 0;
1759 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1760 cipherdata->keylen, INLINE_KEY(cipherdata));
1761 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1762 INLINE_KEY(authdata));
1764 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1765 (rta_sec_era == RTA_SEC_ERA_10)) {
1768 if (sn_size == PDCP_SN_SIZE_5)
1769 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1771 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1773 PROTOCOL(p, dir, pclid,
1774 ((uint16_t)cipherdata->algtype << 8) |
1775 (uint16_t)authdata->algtype);
1779 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1781 case PDCP_SN_SIZE_5:
1784 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1785 PDCP_C_PLANE_SN_MASK_BE;
1787 case PDCP_SN_SIZE_18:
1790 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1791 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1793 case PDCP_SN_SIZE_7:
1794 case PDCP_SN_SIZE_12:
1795 case PDCP_SN_SIZE_15:
1796 pr_err("Invalid sn_size for %s\n", __func__);
1801 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1802 MATHB(p, SEQINSZ, SUB, length, VSEQINSZ, 4, IMMED2);
1804 SEQLOAD(p, MATH0, offset, length, 0);
1805 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1806 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1807 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1809 SEQSTORE(p, MATH0, offset, length, 0);
1810 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1811 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1812 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
1813 MOVEB(p, MATH1, 0, CONTEXT1, 16, 8, IMMED);
1814 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
1815 if (swap == false) {
1816 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2, 4,
1818 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3, 4,
1821 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
1823 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
1826 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
1827 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
1828 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
1829 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1830 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1832 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, MATH1, 4, IMMED2);
1834 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
1835 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
1838 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1839 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1841 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1843 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
1845 OP_ALG_AS_INITFINAL,
1846 dir == OP_TYPE_ENCAP_PROTOCOL ?
1847 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1849 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
1851 OP_ALG_AS_INITFINAL,
1853 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1855 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1856 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1857 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1859 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
1860 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
1861 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
1863 if (rta_sec_era >= RTA_SEC_ERA_6)
1864 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
1866 MOVE(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
1868 NFIFOADD(p, IFIFO, ICV2, 4, LAST2);
1870 if (rta_sec_era <= RTA_SEC_ERA_2) {
1871 /* Shut off automatic Info FIFO entries */
1872 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
1873 MOVE(p, MATH0, 0, IFIFOAB2, 0, 4, WAITCOMP | IMMED);
1875 MOVE(p, MATH0, 0, IFIFO, 0, 4, WAITCOMP | IMMED);
1883 pdcp_insert_cplane_snow_zuc_op(struct program *p,
1884 bool swap __maybe_unused,
1885 struct alginfo *cipherdata,
1886 struct alginfo *authdata,
1888 enum pdcp_sn_size sn_size,
1889 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
1891 uint32_t offset = 0, length = 0, sn_mask = 0;
1894 REFERENCE(pkeyjump);
1896 if (rta_sec_era < RTA_SEC_ERA_5) {
1897 pr_err("Invalid era for selected algorithm\n");
1901 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
1902 (rta_sec_era == RTA_SEC_ERA_10)) {
1904 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1905 cipherdata->keylen, INLINE_KEY(cipherdata));
1906 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1907 INLINE_KEY(authdata));
1909 if (sn_size == PDCP_SN_SIZE_5)
1910 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
1912 pclid = OP_PCLID_LTE_PDCP_USER_RN;
1914 PROTOCOL(p, dir, pclid,
1915 ((uint16_t)cipherdata->algtype << 8) |
1916 (uint16_t)authdata->algtype);
1919 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
1921 case PDCP_SN_SIZE_5:
1924 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
1925 PDCP_C_PLANE_SN_MASK_BE;
1927 case PDCP_SN_SIZE_18:
1930 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
1931 PDCP_U_PLANE_18BIT_SN_MASK_BE;
1933 case PDCP_SN_SIZE_7:
1934 case PDCP_SN_SIZE_12:
1935 case PDCP_SN_SIZE_15:
1936 pr_err("Invalid sn_size for %s\n", __func__);
1941 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
1942 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
1943 cipherdata->keylen, INLINE_KEY(cipherdata));
1944 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
1945 INLINE_KEY(authdata));
1947 SET_LABEL(p, keyjump);
1948 SEQLOAD(p, MATH0, offset, length, 0);
1949 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
1950 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
1951 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
1953 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
1954 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
1955 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
1956 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
1957 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
1959 if (dir == OP_TYPE_ENCAP_PROTOCOL)
1960 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1962 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
1964 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
1965 SEQSTORE(p, MATH0, offset, length, 0);
1967 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1968 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
1969 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
1971 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
1972 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
1975 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
1977 OP_ALG_AS_INITFINAL,
1978 dir == OP_TYPE_ENCAP_PROTOCOL ?
1979 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
1982 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
1984 OP_ALG_AS_INITFINAL,
1986 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
1987 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
1988 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
1991 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
1992 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
1993 NFIFOENTRY_DEST_CLASS2 |
1994 NFIFOENTRY_DTYPE_ICV |
1995 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
1996 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
1999 /* Reset ZUCA mode and done interrupt */
2000 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
2001 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
2003 PATCH_JUMP(p, pkeyjump, keyjump);
2008 pdcp_insert_cplane_aes_zuc_op(struct program *p,
2009 bool swap __maybe_unused,
2010 struct alginfo *cipherdata,
2011 struct alginfo *authdata,
2013 enum pdcp_sn_size sn_size,
2014 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2016 uint32_t offset = 0, length = 0, sn_mask = 0;
2018 REFERENCE(pkeyjump);
2020 if (rta_sec_era < RTA_SEC_ERA_5) {
2021 pr_err("Invalid era for selected algorithm\n");
2025 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2026 (rta_sec_era == RTA_SEC_ERA_10)) {
2028 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2029 cipherdata->keylen, INLINE_KEY(cipherdata));
2030 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2031 INLINE_KEY(authdata));
2033 if (sn_size == PDCP_SN_SIZE_5)
2034 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2036 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2038 PROTOCOL(p, dir, pclid,
2039 ((uint16_t)cipherdata->algtype << 8) |
2040 (uint16_t)authdata->algtype);
2044 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2046 case PDCP_SN_SIZE_5:
2049 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2050 PDCP_C_PLANE_SN_MASK_BE;
2052 case PDCP_SN_SIZE_18:
2055 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2056 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2058 case PDCP_SN_SIZE_7:
2059 case PDCP_SN_SIZE_12:
2060 case PDCP_SN_SIZE_15:
2061 pr_err("Invalid sn_size for %s\n", __func__);
2065 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2066 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2067 cipherdata->keylen, INLINE_KEY(cipherdata));
2068 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2069 INLINE_KEY(authdata));
2071 SET_LABEL(p, keyjump);
2073 SEQLOAD(p, MATH0, offset, length, 0);
2074 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2075 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2076 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2078 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2079 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2080 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2081 MOVEB(p, MATH2, 0, CONTEXT1, 16, 8, IMMED);
2082 MOVEB(p, MATH2, 0, CONTEXT2, 0, 8, WAITCOMP | IMMED);
2084 if (dir == OP_TYPE_ENCAP_PROTOCOL)
2085 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2087 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2089 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2090 SEQSTORE(p, MATH0, offset, length, 0);
2092 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2093 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2094 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2096 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2097 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST1 | FLUSH1);
2100 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
2102 OP_ALG_AS_INITFINAL,
2103 dir == OP_TYPE_ENCAP_PROTOCOL ?
2104 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2107 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2109 OP_ALG_AS_INITFINAL,
2111 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2113 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2114 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2117 MOVE(p, OFIFO, 0, MATH0, 0, 4, IMMED);
2119 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2120 NFIFOENTRY_DEST_CLASS2 |
2121 NFIFOENTRY_DTYPE_ICV |
2122 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2123 MOVE(p, MATH0, 0, ALTSOURCE, 0, 4, WAITCOMP | IMMED);
2126 /* Reset ZUCA mode and done interrupt */
2127 LOAD(p, CLRW_CLR_C2MODE, CLRW, 0, 4, IMMED);
2128 LOAD(p, CIRQ_ZADI, ICTRL, 0, 4, IMMED);
2130 PATCH_JUMP(p, pkeyjump, keyjump);
2136 pdcp_insert_cplane_zuc_snow_op(struct program *p,
2137 bool swap __maybe_unused,
2138 struct alginfo *cipherdata,
2139 struct alginfo *authdata,
2141 enum pdcp_sn_size sn_size,
2142 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2144 uint32_t offset = 0, length = 0, sn_mask = 0;
2146 REFERENCE(pkeyjump);
2148 if (rta_sec_era < RTA_SEC_ERA_5) {
2149 pr_err("Invalid era for selected algorithm\n");
2153 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2154 (rta_sec_era == RTA_SEC_ERA_10)) {
2156 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2157 cipherdata->keylen, INLINE_KEY(cipherdata));
2158 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2159 INLINE_KEY(authdata));
2161 if (sn_size == PDCP_SN_SIZE_5)
2162 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2164 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2166 PROTOCOL(p, dir, pclid,
2167 ((uint16_t)cipherdata->algtype << 8) |
2168 (uint16_t)authdata->algtype);
2172 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2174 case PDCP_SN_SIZE_5:
2177 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2178 PDCP_C_PLANE_SN_MASK_BE;
2180 case PDCP_SN_SIZE_18:
2183 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2184 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2186 case PDCP_SN_SIZE_7:
2187 case PDCP_SN_SIZE_12:
2188 case PDCP_SN_SIZE_15:
2189 pr_err("Invalid sn_size for %s\n", __func__);
2193 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, SHRD | SELF | BOTH);
2194 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2195 cipherdata->keylen, INLINE_KEY(cipherdata));
2196 KEY(p, KEY2, authdata->key_enc_flags, authdata->key, authdata->keylen,
2197 INLINE_KEY(authdata));
2199 SET_LABEL(p, keyjump);
2200 SEQLOAD(p, MATH0, offset, length, 0);
2201 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2202 MOVEB(p, MATH0, offset, IFIFOAB2, 0, length, IMMED);
2203 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2205 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2206 MOVEB(p, DESCBUF, 4, MATH2, 0, 8, WAITCOMP | IMMED);
2207 MATHB(p, MATH1, OR, MATH2, MATH1, 8, 0);
2208 MOVEB(p, MATH1, 0, CONTEXT1, 0, 8, IMMED);
2209 MOVEB(p, MATH1, 0, CONTEXT2, 0, 4, IMMED);
2210 if (swap == false) {
2211 MATHB(p, MATH1, AND, upper_32_bits(PDCP_BEARER_MASK), MATH2,
2213 MATHB(p, MATH1, AND, lower_32_bits(PDCP_DIR_MASK), MATH3,
2216 MATHB(p, MATH1, AND, lower_32_bits(PDCP_BEARER_MASK_BE), MATH2,
2218 MATHB(p, MATH1, AND, upper_32_bits(PDCP_DIR_MASK_BE), MATH3,
2221 MATHB(p, MATH3, SHLD, MATH3, MATH3, 8, 0);
2222 MOVEB(p, MATH2, 4, OFIFO, 0, 12, IMMED);
2223 MOVE(p, OFIFO, 0, CONTEXT2, 4, 12, IMMED);
2225 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2226 MATHB(p, SEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2227 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2229 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2230 MATHB(p, VSEQOUTSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2233 SEQSTORE(p, MATH0, offset, length, 0);
2235 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2236 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2237 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST2);
2239 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2240 SEQFIFOLOAD(p, MSGOUTSNOOP, 0, VLF | LAST2);
2243 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
2245 OP_ALG_AS_INITFINAL,
2246 dir == OP_TYPE_ENCAP_PROTOCOL ?
2247 ICV_CHECK_DISABLE : ICV_CHECK_ENABLE,
2250 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2252 OP_ALG_AS_INITFINAL,
2254 dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC);
2256 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2257 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2259 SEQFIFOLOAD(p, MSG1, 4, LAST1 | FLUSH1);
2260 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CLASS1 | NOP | NIFP);
2262 if (rta_sec_era >= RTA_SEC_ERA_6)
2264 * For SEC ERA 6, there's a problem with the OFIFO
2265 * pointer, and thus it needs to be reset here before
2268 LOAD(p, 0, DCTRL, 0, LDLEN_RST_CHA_OFIFO_PTR, IMMED);
2270 /* Put ICV to M0 before sending it to C2 for comparison. */
2271 MOVEB(p, OFIFO, 0, MATH0, 0, 4, WAITCOMP | IMMED);
2273 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2274 NFIFOENTRY_DEST_CLASS2 |
2275 NFIFOENTRY_DTYPE_ICV |
2276 NFIFOENTRY_LC2 | 4, NFIFO_SZL, 0, 4, IMMED);
2277 MOVEB(p, MATH0, 0, ALTSOURCE, 0, 4, IMMED);
2280 PATCH_JUMP(p, pkeyjump, keyjump);
2285 pdcp_insert_cplane_zuc_aes_op(struct program *p,
2286 bool swap __maybe_unused,
2287 struct alginfo *cipherdata,
2288 struct alginfo *authdata,
2290 enum pdcp_sn_size sn_size,
2291 unsigned char era_2_sw_hfn_ovrd __maybe_unused)
2293 uint32_t offset = 0, length = 0, sn_mask = 0;
2294 if (rta_sec_era < RTA_SEC_ERA_5) {
2295 pr_err("Invalid era for selected algorithm\n");
2299 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size != PDCP_SN_SIZE_18) ||
2300 (rta_sec_era == RTA_SEC_ERA_10)) {
2303 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2304 cipherdata->keylen, INLINE_KEY(cipherdata));
2305 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
2306 authdata->keylen, INLINE_KEY(authdata));
2308 if (sn_size == PDCP_SN_SIZE_5)
2309 pclid = OP_PCLID_LTE_PDCP_CTRL_MIXED;
2311 pclid = OP_PCLID_LTE_PDCP_USER_RN;
2313 PROTOCOL(p, dir, pclid,
2314 ((uint16_t)cipherdata->algtype << 8) |
2315 (uint16_t)authdata->algtype);
2318 /* Non-proto is supported only for 5bit cplane and 18bit uplane */
2320 case PDCP_SN_SIZE_5:
2323 sn_mask = (swap == false) ? PDCP_C_PLANE_SN_MASK :
2324 PDCP_C_PLANE_SN_MASK_BE;
2326 case PDCP_SN_SIZE_18:
2329 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2330 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2332 case PDCP_SN_SIZE_7:
2333 case PDCP_SN_SIZE_12:
2334 case PDCP_SN_SIZE_15:
2335 pr_err("Invalid sn_size for %s\n", __func__);
2339 SEQLOAD(p, MATH0, offset, length, 0);
2340 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2341 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2343 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2344 MOVEB(p, DESCBUF, 4, MATH2, 0, 0x08, WAITCOMP | IMMED);
2345 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2346 SEQSTORE(p, MATH0, offset, length, 0);
2347 if (dir == OP_TYPE_ENCAP_PROTOCOL) {
2348 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2349 authdata->keylen, INLINE_KEY(authdata));
2350 MOVEB(p, MATH2, 0, IFIFOAB1, 0, 0x08, IMMED);
2351 MOVEB(p, MATH0, offset, IFIFOAB1, 0, length, IMMED);
2353 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2354 MATHB(p, VSEQINSZ, ADD, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2356 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2358 OP_ALG_AS_INITFINAL,
2361 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2362 MOVEB(p, CONTEXT1, 0, MATH3, 0, 4, WAITCOMP | IMMED);
2363 LOAD(p, CLRW_RESET_CLS1_CHA |
2371 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2372 cipherdata->keylen, INLINE_KEY(cipherdata));
2374 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2375 SEQINPTR(p, 0, PDCP_NULL_MAX_FRAME_LEN, RTO);
2377 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2379 OP_ALG_AS_INITFINAL,
2382 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2384 SEQFIFOLOAD(p, SKIP, length, 0);
2386 SEQFIFOLOAD(p, MSG1, 0, VLF);
2387 MOVEB(p, MATH3, 0, IFIFOAB1, 0, 4, LAST1 | FLUSH1 | IMMED);
2389 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, IMMED);
2391 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2393 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2395 MATHB(p, SEQINSZ, SUB, PDCP_MAC_I_LEN, VSEQOUTSZ, 4, IMMED2);
2397 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2398 cipherdata->keylen, INLINE_KEY(cipherdata));
2400 MOVE(p, CONTEXT1, 0, CONTEXT2, 0, 8, IMMED);
2402 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2404 OP_ALG_AS_INITFINAL,
2407 SEQFIFOSTORE(p, MSG, 0, 0, VLF | CONT);
2408 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2410 MOVEB(p, OFIFO, 0, MATH3, 0, 4, IMMED);
2412 LOAD(p, CLRW_RESET_CLS1_CHA |
2420 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
2421 authdata->keylen, INLINE_KEY(authdata));
2423 SEQINPTR(p, 0, 0, SOP);
2425 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2427 OP_ALG_AS_INITFINAL,
2431 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
2433 MOVE(p, CONTEXT2, 0, IFIFOAB1, 0, 8, IMMED);
2435 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2437 LOAD(p, NFIFOENTRY_STYPE_ALTSOURCE |
2438 NFIFOENTRY_DEST_CLASS1 |
2439 NFIFOENTRY_DTYPE_ICV |
2441 NFIFOENTRY_FC1 | 4, NFIFO_SZL, 0, 4, IMMED);
2442 MOVEB(p, MATH3, 0, ALTSOURCE, 0, 4, IMMED);
2449 pdcp_insert_uplane_no_int_op(struct program *p,
2450 bool swap __maybe_unused,
2451 struct alginfo *cipherdata,
2453 enum pdcp_sn_size sn_size)
2458 /* Insert Cipher Key */
2459 KEY(p, KEY1, cipherdata->key_enc_flags, cipherdata->key,
2460 cipherdata->keylen, INLINE_KEY(cipherdata));
2462 if ((rta_sec_era >= RTA_SEC_ERA_8 && sn_size == PDCP_SN_SIZE_15) ||
2463 (rta_sec_era >= RTA_SEC_ERA_10)) {
2464 PROTOCOL(p, dir, OP_PCLID_LTE_PDCP_USER,
2465 (uint16_t)cipherdata->algtype);
2469 if (sn_size == PDCP_SN_SIZE_15) {
2470 SEQLOAD(p, MATH0, 6, 2, 0);
2471 sn_mask = (swap == false) ? PDCP_U_PLANE_15BIT_SN_MASK :
2472 PDCP_U_PLANE_15BIT_SN_MASK_BE;
2473 } else { /* SN Size == PDCP_SN_SIZE_18 */
2474 SEQLOAD(p, MATH0, 5, 3, 0);
2475 sn_mask = (swap == false) ? PDCP_U_PLANE_18BIT_SN_MASK :
2476 PDCP_U_PLANE_18BIT_SN_MASK_BE;
2478 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2479 MATHB(p, MATH0, AND, sn_mask, MATH1, 8, IFB | IMMED2);
2481 if (sn_size == PDCP_SN_SIZE_15)
2482 SEQSTORE(p, MATH0, 6, 2, 0);
2483 else /* SN Size == PDCP_SN_SIZE_18 */
2484 SEQSTORE(p, MATH0, 5, 3, 0);
2486 MATHB(p, MATH1, SHLD, MATH1, MATH1, 8, 0);
2487 MOVEB(p, DESCBUF, 8, MATH2, 0, 8, WAITCOMP | IMMED);
2488 MATHB(p, MATH1, OR, MATH2, MATH2, 8, 0);
2490 MATHB(p, SEQINSZ, SUB, MATH3, VSEQINSZ, 4, 0);
2491 MATHB(p, SEQINSZ, SUB, MATH3, VSEQOUTSZ, 4, 0);
2493 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
2495 op = dir == OP_TYPE_ENCAP_PROTOCOL ? DIR_ENC : DIR_DEC;
2496 switch (cipherdata->algtype) {
2497 case PDCP_CIPHER_TYPE_SNOW:
2498 MOVEB(p, MATH2, 0, CONTEXT1, 0, 8, WAITCOMP | IMMED);
2499 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F8,
2501 OP_ALG_AS_INITFINAL,
2506 case PDCP_CIPHER_TYPE_AES:
2507 MOVEB(p, MATH2, 0, CONTEXT1, 0x10, 0x10, WAITCOMP | IMMED);
2508 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
2510 OP_ALG_AS_INITFINAL,
2515 case PDCP_CIPHER_TYPE_ZUC:
2516 if (rta_sec_era < RTA_SEC_ERA_5) {
2517 pr_err("Invalid era for selected algorithm\n");
2520 MOVEB(p, MATH2, 0, CONTEXT1, 0, 0x08, IMMED);
2521 MOVEB(p, MATH2, 0, CONTEXT1, 0x08, 0x08, WAITCOMP | IMMED);
2523 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCE,
2525 OP_ALG_AS_INITFINAL,
2531 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
2532 "pdcp_insert_uplane_15bit_op", cipherdata->algtype);
2536 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | FLUSH1);
2542 * Function for inserting the snippet of code responsible for creating
2543 * the HFN override code via either DPOVRD or via the input frame.
2546 insert_hfn_ov_op(struct program *p,
2548 enum pdb_type_e pdb_type,
2549 unsigned char era_2_sw_hfn_ovrd)
2551 uint32_t imm = PDCP_DPOVRD_HFN_OV_EN;
2552 uint16_t hfn_pdb_offset;
2554 REFERENCE(pkeyjump);
2556 if (rta_sec_era == RTA_SEC_ERA_2 && !era_2_sw_hfn_ovrd)
2560 case PDCP_PDB_TYPE_NO_PDB:
2562 * If there is no PDB, then HFN override mechanism does not
2563 * make any sense, thus in this case the function will
2564 * return the pointer to the current position in the
2569 case PDCP_PDB_TYPE_REDUCED_PDB:
2570 hfn_pdb_offset = REDUCED_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
2573 case PDCP_PDB_TYPE_FULL_PDB:
2574 hfn_pdb_offset = FULL_PDB_DESCBUF_HFN_BEARER_DIR_OFFSET;
2581 if (rta_sec_era > RTA_SEC_ERA_2) {
2582 MATHB(p, DPOVRD, AND, imm, NONE, 8, IFB | IMMED2);
2584 SEQLOAD(p, MATH0, 4, 4, 0);
2585 JUMP(p, 1, LOCAL_JUMP, ALL_TRUE, CALM);
2586 MATHB(p, MATH0, AND, imm, NONE, 8, IFB | IMMED2);
2587 SEQSTORE(p, MATH0, 4, 4, 0);
2590 pkeyjump = JUMP(p, keyjump, LOCAL_JUMP, ALL_TRUE, MATH_Z);
2592 if (rta_sec_era > RTA_SEC_ERA_2)
2593 MATHI(p, DPOVRD, LSHIFT, shift, MATH0, 4, IMMED2);
2595 MATHB(p, MATH0, LSHIFT, shift, MATH0, 4, IMMED2);
2597 MATHB(p, MATH0, SHLD, MATH0, MATH0, 8, 0);
2598 MOVE(p, MATH0, 0, DESCBUF, hfn_pdb_offset, 4, IMMED);
2600 if (rta_sec_era >= RTA_SEC_ERA_8)
2602 * For ERA8, DPOVRD could be handled by the PROTOCOL command
2603 * itself. For now, this is not done. Thus, clear DPOVRD here
2604 * to alleviate any side-effects.
2606 MATHB(p, DPOVRD, AND, ZERO, DPOVRD, 4, STL);
2608 SET_LABEL(p, keyjump);
2609 PATCH_JUMP(p, pkeyjump, keyjump);
2614 * PDCP Control PDB creation function
2616 static inline enum pdb_type_e
2617 cnstr_pdcp_c_plane_pdb(struct program *p,
2619 enum pdcp_sn_size sn_size,
2620 unsigned char bearer,
2621 unsigned char direction,
2622 uint32_t hfn_threshold,
2623 struct alginfo *cipherdata,
2624 struct alginfo *authdata)
2626 struct pdcp_pdb pdb;
2628 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2630 PDCP_PDB_TYPE_NO_PDB, /* NULL */
2631 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2632 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2633 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2636 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2637 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2638 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2639 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2642 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2643 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2644 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2645 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2648 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2649 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2650 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2651 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2655 if (rta_sec_era >= RTA_SEC_ERA_8) {
2656 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2658 /* To support 12-bit seq numbers, we use u-plane opt in pdb.
2659 * SEC supports 5-bit only with c-plane opt in pdb.
2661 if (sn_size == PDCP_SN_SIZE_12) {
2662 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2663 pdb.bearer_dir_res = (uint32_t)
2664 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2665 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2668 hfn_threshold << PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2671 /* This means 5-bit c-plane.
2672 * Here we use c-plane opt in pdb
2675 /* This is a HW issue. Bit 2 should be set to zero,
2676 * but it does not work this way. Override here.
2678 pdb.opt_res.rsvd = 0x00000002;
2680 /* Copy relevant information from user to PDB */
2681 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2682 pdb.bearer_dir_res = (uint32_t)
2683 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2684 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2686 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2689 /* copy PDB in descriptor*/
2690 __rta_out32(p, pdb.opt_res.opt);
2691 __rta_out32(p, pdb.hfn_res);
2692 __rta_out32(p, pdb.bearer_dir_res);
2693 __rta_out32(p, pdb.hfn_thr_res);
2695 return PDCP_PDB_TYPE_FULL_PDB;
2698 switch (pdb_mask[cipherdata->algtype][authdata->algtype]) {
2699 case PDCP_PDB_TYPE_NO_PDB:
2702 case PDCP_PDB_TYPE_REDUCED_PDB:
2703 __rta_out32(p, (hfn << PDCP_C_PLANE_PDB_HFN_SHIFT));
2705 (uint32_t)((bearer <<
2706 PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2708 PDCP_C_PLANE_PDB_DIR_SHIFT)));
2711 case PDCP_PDB_TYPE_FULL_PDB:
2712 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2714 /* This is a HW issue. Bit 2 should be set to zero,
2715 * but it does not work this way. Override here.
2717 pdb.opt_res.rsvd = 0x00000002;
2719 /* Copy relevant information from user to PDB */
2720 pdb.hfn_res = hfn << PDCP_C_PLANE_PDB_HFN_SHIFT;
2721 pdb.bearer_dir_res = (uint32_t)
2722 ((bearer << PDCP_C_PLANE_PDB_BEARER_SHIFT) |
2723 (direction << PDCP_C_PLANE_PDB_DIR_SHIFT));
2725 hfn_threshold << PDCP_C_PLANE_PDB_HFN_THR_SHIFT;
2727 /* copy PDB in descriptor*/
2728 __rta_out32(p, pdb.opt_res.opt);
2729 __rta_out32(p, pdb.hfn_res);
2730 __rta_out32(p, pdb.bearer_dir_res);
2731 __rta_out32(p, pdb.hfn_thr_res);
2736 return PDCP_PDB_TYPE_INVALID;
2739 return pdb_mask[cipherdata->algtype][authdata->algtype];
2743 * PDCP UPlane PDB creation function
2745 static inline enum pdb_type_e
2746 cnstr_pdcp_u_plane_pdb(struct program *p,
2747 enum pdcp_sn_size sn_size,
2748 uint32_t hfn, unsigned short bearer,
2749 unsigned short direction,
2750 uint32_t hfn_threshold,
2751 struct alginfo *cipherdata,
2752 struct alginfo *authdata)
2754 struct pdcp_pdb pdb;
2755 enum pdb_type_e pdb_type = PDCP_PDB_TYPE_FULL_PDB;
2757 pdb_mask[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2759 PDCP_PDB_TYPE_NO_PDB, /* NULL */
2760 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2761 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2762 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2765 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2766 PDCP_PDB_TYPE_FULL_PDB, /* SNOW f9 */
2767 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2768 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2771 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2772 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2773 PDCP_PDB_TYPE_FULL_PDB, /* AES CMAC */
2774 PDCP_PDB_TYPE_REDUCED_PDB /* ZUC-I */
2777 PDCP_PDB_TYPE_FULL_PDB, /* NULL */
2778 PDCP_PDB_TYPE_REDUCED_PDB, /* SNOW f9 */
2779 PDCP_PDB_TYPE_REDUCED_PDB, /* AES CMAC */
2780 PDCP_PDB_TYPE_FULL_PDB /* ZUC-I */
2784 /* Read options from user */
2785 /* Depending on sequence number length, the HFN and HFN threshold
2786 * have different lengths.
2788 memset(&pdb, 0x00, sizeof(struct pdcp_pdb));
2791 case PDCP_SN_SIZE_7:
2792 pdb.opt_res.opt |= PDCP_U_PLANE_PDB_OPT_SHORT_SN;
2793 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_SHORT_SN_HFN_SHIFT;
2795 hfn_threshold<<PDCP_U_PLANE_PDB_SHORT_SN_HFN_THR_SHIFT;
2798 case PDCP_SN_SIZE_12:
2799 pdb.opt_res.opt &= (uint32_t)(~PDCP_U_PLANE_PDB_OPT_SHORT_SN);
2800 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_LONG_SN_HFN_SHIFT;
2802 hfn_threshold<<PDCP_U_PLANE_PDB_LONG_SN_HFN_THR_SHIFT;
2805 case PDCP_SN_SIZE_15:
2806 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_15B_SN);
2807 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_15BIT_SN_HFN_SHIFT;
2809 hfn_threshold<<PDCP_U_PLANE_PDB_15BIT_SN_HFN_THR_SHIFT;
2812 case PDCP_SN_SIZE_18:
2813 pdb.opt_res.opt = (uint32_t)(PDCP_U_PLANE_PDB_OPT_18B_SN);
2814 pdb.hfn_res = hfn << PDCP_U_PLANE_PDB_18BIT_SN_HFN_SHIFT;
2816 hfn_threshold<<PDCP_U_PLANE_PDB_18BIT_SN_HFN_THR_SHIFT;
2818 if (rta_sec_era <= RTA_SEC_ERA_8) {
2819 if (cipherdata && authdata)
2820 pdb_type = pdb_mask[cipherdata->algtype]
2821 [authdata->algtype];
2826 pr_err("Invalid Sequence Number Size setting in PDB\n");
2830 pdb.bearer_dir_res = (uint32_t)
2831 ((bearer << PDCP_U_PLANE_PDB_BEARER_SHIFT) |
2832 (direction << PDCP_U_PLANE_PDB_DIR_SHIFT));
2835 case PDCP_PDB_TYPE_NO_PDB:
2838 case PDCP_PDB_TYPE_REDUCED_PDB:
2839 __rta_out32(p, pdb.hfn_res);
2840 __rta_out32(p, pdb.bearer_dir_res);
2843 case PDCP_PDB_TYPE_FULL_PDB:
2844 /* copy PDB in descriptor*/
2845 __rta_out32(p, pdb.opt_res.opt);
2846 __rta_out32(p, pdb.hfn_res);
2847 __rta_out32(p, pdb.bearer_dir_res);
2848 __rta_out32(p, pdb.hfn_thr_res);
2853 return PDCP_PDB_TYPE_INVALID;
2859 * cnstr_shdsc_pdcp_c_plane_encap - Function for creating a PDCP Control Plane
2860 * encapsulation descriptor.
2861 * @descbuf: pointer to buffer for descriptor construction
2862 * @ps: if 36/40bit addressing is desired, this parameter must be true
2863 * @swap: must be true when core endianness doesn't match SEC endianness
2864 * @hfn: starting Hyper Frame Number to be used together with the SN from the
2866 * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid
2867 * @bearer: radio bearer ID
2868 * @direction: the direction of the PDCP frame (UL/DL)
2869 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
2870 * keys should be renegotiated at the earliest convenience.
2871 * @cipherdata: pointer to block cipher transform definitions
2872 * Valid algorithm values are those from cipher_type_pdcp enum.
2873 * @authdata: pointer to authentication transform definitions
2874 * Valid algorithm values are those from auth_type_pdcp enum.
2875 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
2876 * this descriptor. Note: Can only be used for
2878 * Return: size of descriptor written in words or negative number on error.
2879 * Once the function returns, the value of this parameter can be used
2880 * for reclaiming the space that wasn't used for the descriptor.
2882 * Note: descbuf must be large enough to contain a full 256 byte long
2883 * descriptor; after the function returns, by subtracting the actual number of
2884 * bytes used, the user can reuse the remaining buffer space for other purposes.
2887 cnstr_shdsc_pdcp_c_plane_encap(uint32_t *descbuf,
2891 enum pdcp_sn_size sn_size,
2892 unsigned char bearer,
2893 unsigned char direction,
2894 uint32_t hfn_threshold,
2895 struct alginfo *cipherdata,
2896 struct alginfo *authdata,
2897 unsigned char era_2_sw_hfn_ovrd)
2900 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
2901 (struct program*, bool swap, struct alginfo *,
2902 struct alginfo *, unsigned int, enum pdcp_sn_size,
2903 unsigned char __maybe_unused) = {
2905 pdcp_insert_cplane_null_op, /* NULL */
2906 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
2907 pdcp_insert_cplane_int_only_op, /* AES CMAC */
2908 pdcp_insert_cplane_int_only_op /* ZUC-I */
2911 pdcp_insert_cplane_enc_only_op, /* NULL */
2912 pdcp_insert_cplane_acc_op, /* SNOW f9 */
2913 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
2914 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
2917 pdcp_insert_cplane_enc_only_op, /* NULL */
2918 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
2919 pdcp_insert_cplane_acc_op, /* AES CMAC */
2920 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
2923 pdcp_insert_cplane_enc_only_op, /* NULL */
2924 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
2925 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
2926 pdcp_insert_cplane_acc_op /* ZUC-I */
2929 static enum rta_share_type
2930 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
2932 SHR_WAIT, /* NULL */
2933 SHR_ALWAYS, /* SNOW f9 */
2934 SHR_ALWAYS, /* AES CMAC */
2935 SHR_ALWAYS /* ZUC-I */
2938 SHR_ALWAYS, /* NULL */
2939 SHR_ALWAYS, /* SNOW f9 */
2940 SHR_WAIT, /* AES CMAC */
2941 SHR_WAIT /* ZUC-I */
2944 SHR_ALWAYS, /* NULL */
2945 SHR_ALWAYS, /* SNOW f9 */
2946 SHR_ALWAYS, /* AES CMAC */
2947 SHR_WAIT /* ZUC-I */
2950 SHR_ALWAYS, /* NULL */
2951 SHR_WAIT, /* SNOW f9 */
2952 SHR_WAIT, /* AES CMAC */
2953 SHR_ALWAYS /* ZUC-I */
2956 enum pdb_type_e pdb_type;
2958 struct program *p = &prg;
2962 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
2963 pr_err("Cannot select SW HFN override for other era than 2");
2967 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
2968 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
2972 PROGRAM_CNTXT_INIT(p, descbuf, 0);
2974 PROGRAM_SET_BSWAP(p);
2976 PROGRAM_SET_36BIT_ADDR(p);
2978 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
2980 pdb_type = cnstr_pdcp_c_plane_pdb(p,
2989 SET_LABEL(p, pdb_end);
2991 err = insert_hfn_ov_op(p, sn_size, pdb_type,
2996 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3000 OP_TYPE_ENCAP_PROTOCOL,
3006 PATCH_HDR(p, 0, pdb_end);
3008 return PROGRAM_FINALIZE(p);
3012 * cnstr_shdsc_pdcp_c_plane_decap - Function for creating a PDCP Control Plane
3013 * decapsulation descriptor.
3014 * @descbuf: pointer to buffer for descriptor construction
3015 * @ps: if 36/40bit addressing is desired, this parameter must be true
3016 * @swap: must be true when core endianness doesn't match SEC endianness
3017 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3019 * @sn_size: size of sequence numbers, only 5/12 bit sequence numbers are valid
3020 * @bearer: radio bearer ID
3021 * @direction: the direction of the PDCP frame (UL/DL)
3022 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3023 * keys should be renegotiated at the earliest convenience.
3024 * @cipherdata: pointer to block cipher transform definitions
3025 * Valid algorithm values are those from cipher_type_pdcp enum.
3026 * @authdata: pointer to authentication transform definitions
3027 * Valid algorithm values are those from auth_type_pdcp enum.
3028 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3029 * this descriptor. Note: Can only be used for
3032 * Return: size of descriptor written in words or negative number on error.
3033 * Once the function returns, the value of this parameter can be used
3034 * for reclaiming the space that wasn't used for the descriptor.
3036 * Note: descbuf must be large enough to contain a full 256 byte long
3037 * descriptor; after the function returns, by subtracting the actual number of
3038 * bytes used, the user can reuse the remaining buffer space for other purposes.
3041 cnstr_shdsc_pdcp_c_plane_decap(uint32_t *descbuf,
3045 enum pdcp_sn_size sn_size,
3046 unsigned char bearer,
3047 unsigned char direction,
3048 uint32_t hfn_threshold,
3049 struct alginfo *cipherdata,
3050 struct alginfo *authdata,
3051 unsigned char era_2_sw_hfn_ovrd)
3054 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3055 (struct program*, bool swap, struct alginfo *,
3056 struct alginfo *, unsigned int, enum pdcp_sn_size,
3059 pdcp_insert_cplane_null_op, /* NULL */
3060 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
3061 pdcp_insert_cplane_int_only_op, /* AES CMAC */
3062 pdcp_insert_cplane_int_only_op /* ZUC-I */
3065 pdcp_insert_cplane_enc_only_op, /* NULL */
3066 pdcp_insert_cplane_acc_op, /* SNOW f9 */
3067 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
3068 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
3071 pdcp_insert_cplane_enc_only_op, /* NULL */
3072 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
3073 pdcp_insert_cplane_acc_op, /* AES CMAC */
3074 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
3077 pdcp_insert_cplane_enc_only_op, /* NULL */
3078 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
3079 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
3080 pdcp_insert_cplane_acc_op /* ZUC-I */
3083 static enum rta_share_type
3084 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3086 SHR_WAIT, /* NULL */
3087 SHR_ALWAYS, /* SNOW f9 */
3088 SHR_ALWAYS, /* AES CMAC */
3089 SHR_ALWAYS /* ZUC-I */
3092 SHR_ALWAYS, /* NULL */
3093 SHR_ALWAYS, /* SNOW f9 */
3094 SHR_WAIT, /* AES CMAC */
3095 SHR_WAIT /* ZUC-I */
3098 SHR_ALWAYS, /* NULL */
3099 SHR_ALWAYS, /* SNOW f9 */
3100 SHR_ALWAYS, /* AES CMAC */
3101 SHR_WAIT /* ZUC-I */
3104 SHR_ALWAYS, /* NULL */
3105 SHR_WAIT, /* SNOW f9 */
3106 SHR_WAIT, /* AES CMAC */
3107 SHR_ALWAYS /* ZUC-I */
3110 enum pdb_type_e pdb_type;
3112 struct program *p = &prg;
3116 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3117 pr_err("Cannot select SW HFN override for other era than 2");
3121 if (sn_size != PDCP_SN_SIZE_12 && sn_size != PDCP_SN_SIZE_5) {
3122 pr_err("C-plane supports only 5-bit and 12-bit sequence numbers\n");
3126 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3128 PROGRAM_SET_BSWAP(p);
3130 PROGRAM_SET_36BIT_ADDR(p);
3132 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3134 pdb_type = cnstr_pdcp_c_plane_pdb(p,
3143 SET_LABEL(p, pdb_end);
3145 err = insert_hfn_ov_op(p, sn_size, pdb_type,
3150 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3154 OP_TYPE_DECAP_PROTOCOL,
3160 PATCH_HDR(p, 0, pdb_end);
3162 return PROGRAM_FINALIZE(p);
3166 pdcp_insert_uplane_with_int_op(struct program *p,
3167 bool swap __maybe_unused,
3168 struct alginfo *cipherdata,
3169 struct alginfo *authdata,
3170 enum pdcp_sn_size sn_size,
3171 unsigned char era_2_sw_hfn_ovrd,
3175 (*pdcp_cp_fp[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID])
3176 (struct program*, bool swap, struct alginfo *,
3177 struct alginfo *, unsigned int, enum pdcp_sn_size,
3178 unsigned char __maybe_unused) = {
3180 pdcp_insert_cplane_null_op, /* NULL */
3181 pdcp_insert_cplane_int_only_op, /* SNOW f9 */
3182 pdcp_insert_cplane_int_only_op, /* AES CMAC */
3183 pdcp_insert_cplane_int_only_op /* ZUC-I */
3186 pdcp_insert_cplane_enc_only_op, /* NULL */
3187 pdcp_insert_uplane_snow_snow_op, /* SNOW f9 */
3188 pdcp_insert_cplane_snow_aes_op, /* AES CMAC */
3189 pdcp_insert_cplane_snow_zuc_op /* ZUC-I */
3192 pdcp_insert_cplane_enc_only_op, /* NULL */
3193 pdcp_insert_cplane_aes_snow_op, /* SNOW f9 */
3194 pdcp_insert_uplane_aes_aes_op, /* AES CMAC */
3195 pdcp_insert_cplane_aes_zuc_op /* ZUC-I */
3198 pdcp_insert_cplane_enc_only_op, /* NULL */
3199 pdcp_insert_cplane_zuc_snow_op, /* SNOW f9 */
3200 pdcp_insert_cplane_zuc_aes_op, /* AES CMAC */
3201 pdcp_insert_uplane_zuc_zuc_op /* ZUC-I */
3206 err = pdcp_cp_fp[cipherdata->algtype][authdata->algtype](p,
3221 * cnstr_shdsc_pdcp_u_plane_encap - Function for creating a PDCP User Plane
3222 * encapsulation descriptor.
3223 * @descbuf: pointer to buffer for descriptor construction
3224 * @ps: if 36/40bit addressing is desired, this parameter must be true
3225 * @swap: must be true when core endianness doesn't match SEC endianness
3226 * @sn_size: selects Sequence Number Size: 7/12/15 bits
3227 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3229 * @bearer: radio bearer ID
3230 * @direction: the direction of the PDCP frame (UL/DL)
3231 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3232 * keys should be renegotiated at the earliest convenience.
3233 * @cipherdata: pointer to block cipher transform definitions
3234 * Valid algorithm values are those from cipher_type_pdcp enum.
3235 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3236 * this descriptor. Note: Can only be used for
3239 * Return: size of descriptor written in words or negative number on error.
3240 * Once the function returns, the value of this parameter can be used
3241 * for reclaiming the space that wasn't used for the descriptor.
3243 * Note: descbuf must be large enough to contain a full 256 byte long
3244 * descriptor; after the function returns, by subtracting the actual number of
3245 * bytes used, the user can reuse the remaining buffer space for other purposes.
3248 cnstr_shdsc_pdcp_u_plane_encap(uint32_t *descbuf,
3251 enum pdcp_sn_size sn_size,
3253 unsigned short bearer,
3254 unsigned short direction,
3255 uint32_t hfn_threshold,
3256 struct alginfo *cipherdata,
3257 struct alginfo *authdata,
3258 unsigned char era_2_sw_hfn_ovrd)
3261 struct program *p = &prg;
3263 enum pdb_type_e pdb_type;
3264 static enum rta_share_type
3265 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3267 SHR_WAIT, /* NULL */
3268 SHR_ALWAYS, /* SNOW f9 */
3269 SHR_ALWAYS, /* AES CMAC */
3270 SHR_ALWAYS /* ZUC-I */
3273 SHR_ALWAYS, /* NULL */
3274 SHR_ALWAYS, /* SNOW f9 */
3275 SHR_WAIT, /* AES CMAC */
3276 SHR_WAIT /* ZUC-I */
3279 SHR_ALWAYS, /* NULL */
3280 SHR_ALWAYS, /* SNOW f9 */
3281 SHR_ALWAYS, /* AES CMAC */
3282 SHR_WAIT /* ZUC-I */
3285 SHR_ALWAYS, /* NULL */
3286 SHR_WAIT, /* SNOW f9 */
3287 SHR_WAIT, /* AES CMAC */
3288 SHR_WAIT /* ZUC-I */
3293 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3294 pr_err("Cannot select SW HFN ovrd for other era than 2");
3298 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3299 pr_err("Cannot use u-plane auth with era < 8");
3303 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3305 PROGRAM_SET_BSWAP(p);
3307 PROGRAM_SET_36BIT_ADDR(p);
3310 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3312 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3313 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn,
3314 bearer, direction, hfn_threshold,
3315 cipherdata, authdata);
3316 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3317 pr_err("Error creating PDCP UPlane PDB\n");
3320 SET_LABEL(p, pdb_end);
3322 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3327 case PDCP_SN_SIZE_7:
3328 case PDCP_SN_SIZE_12:
3329 switch (cipherdata->algtype) {
3330 case PDCP_CIPHER_TYPE_ZUC:
3331 if (rta_sec_era < RTA_SEC_ERA_5) {
3332 pr_err("Invalid era for selected algorithm\n");
3336 case PDCP_CIPHER_TYPE_AES:
3337 case PDCP_CIPHER_TYPE_SNOW:
3338 case PDCP_CIPHER_TYPE_NULL:
3339 if (rta_sec_era == RTA_SEC_ERA_8 &&
3340 authdata && authdata->algtype == 0){
3341 err = pdcp_insert_uplane_with_int_op(p, swap,
3342 cipherdata, authdata,
3343 sn_size, era_2_sw_hfn_ovrd,
3344 OP_TYPE_ENCAP_PROTOCOL);
3350 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3351 pr_err("PDB type must be FULL for PROTO desc\n");
3355 /* Insert auth key if requested */
3356 if (authdata && authdata->algtype) {
3357 KEY(p, KEY2, authdata->key_enc_flags,
3358 (uint64_t)authdata->key, authdata->keylen,
3359 INLINE_KEY(authdata));
3361 /* Insert Cipher Key */
3362 KEY(p, KEY1, cipherdata->key_enc_flags,
3363 (uint64_t)cipherdata->key, cipherdata->keylen,
3364 INLINE_KEY(cipherdata));
3367 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3368 OP_PCLID_LTE_PDCP_USER_RN,
3369 ((uint16_t)cipherdata->algtype << 8) |
3370 (uint16_t)authdata->algtype);
3372 PROTOCOL(p, OP_TYPE_ENCAP_PROTOCOL,
3373 OP_PCLID_LTE_PDCP_USER,
3374 (uint16_t)cipherdata->algtype);
3377 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3378 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3379 cipherdata->algtype);
3384 case PDCP_SN_SIZE_15:
3385 case PDCP_SN_SIZE_18:
3387 err = pdcp_insert_uplane_with_int_op(p, swap,
3388 cipherdata, authdata,
3389 sn_size, era_2_sw_hfn_ovrd,
3390 OP_TYPE_ENCAP_PROTOCOL);
3397 switch (cipherdata->algtype) {
3398 case PDCP_CIPHER_TYPE_NULL:
3399 insert_copy_frame_op(p,
3401 OP_TYPE_ENCAP_PROTOCOL);
3405 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3406 OP_TYPE_ENCAP_PROTOCOL, sn_size);
3413 case PDCP_SN_SIZE_5:
3415 pr_err("Invalid SN size selected\n");
3419 PATCH_HDR(p, 0, pdb_end);
3420 return PROGRAM_FINALIZE(p);
3424 * cnstr_shdsc_pdcp_u_plane_decap - Function for creating a PDCP User Plane
3425 * decapsulation descriptor.
3426 * @descbuf: pointer to buffer for descriptor construction
3427 * @ps: if 36/40bit addressing is desired, this parameter must be true
3428 * @swap: must be true when core endianness doesn't match SEC endianness
3429 * @sn_size: selects Sequence Number Size: 7/12/15 bits
3430 * @hfn: starting Hyper Frame Number to be used together with the SN from the
3432 * @bearer: radio bearer ID
3433 * @direction: the direction of the PDCP frame (UL/DL)
3434 * @hfn_threshold: HFN value that once reached triggers a warning from SEC that
3435 * keys should be renegotiated at the earliest convenience.
3436 * @cipherdata: pointer to block cipher transform definitions
3437 * Valid algorithm values are those from cipher_type_pdcp enum.
3438 * @era_2_sw_hfn_ovrd: if software HFN override mechanism is desired for
3439 * this descriptor. Note: Can only be used for
3442 * Return: size of descriptor written in words or negative number on error.
3443 * Once the function returns, the value of this parameter can be used
3444 * for reclaiming the space that wasn't used for the descriptor.
3446 * Note: descbuf must be large enough to contain a full 256 byte long
3447 * descriptor; after the function returns, by subtracting the actual number of
3448 * bytes used, the user can reuse the remaining buffer space for other purposes.
3451 cnstr_shdsc_pdcp_u_plane_decap(uint32_t *descbuf,
3454 enum pdcp_sn_size sn_size,
3456 unsigned short bearer,
3457 unsigned short direction,
3458 uint32_t hfn_threshold,
3459 struct alginfo *cipherdata,
3460 struct alginfo *authdata,
3461 unsigned char era_2_sw_hfn_ovrd)
3464 struct program *p = &prg;
3466 enum pdb_type_e pdb_type;
3467 static enum rta_share_type
3468 desc_share[PDCP_CIPHER_TYPE_INVALID][PDCP_AUTH_TYPE_INVALID] = {
3470 SHR_WAIT, /* NULL */
3471 SHR_ALWAYS, /* SNOW f9 */
3472 SHR_ALWAYS, /* AES CMAC */
3473 SHR_ALWAYS /* ZUC-I */
3476 SHR_ALWAYS, /* NULL */
3477 SHR_ALWAYS, /* SNOW f9 */
3478 SHR_WAIT, /* AES CMAC */
3479 SHR_WAIT /* ZUC-I */
3482 SHR_ALWAYS, /* NULL */
3483 SHR_ALWAYS, /* SNOW f9 */
3484 SHR_ALWAYS, /* AES CMAC */
3485 SHR_WAIT /* ZUC-I */
3488 SHR_ALWAYS, /* NULL */
3489 SHR_WAIT, /* SNOW f9 */
3490 SHR_WAIT, /* AES CMAC */
3491 SHR_WAIT /* ZUC-I */
3497 if (rta_sec_era != RTA_SEC_ERA_2 && era_2_sw_hfn_ovrd) {
3498 pr_err("Cannot select SW HFN override for other era than 2");
3502 if (authdata && !authdata->algtype && rta_sec_era < RTA_SEC_ERA_8) {
3503 pr_err("Cannot use u-plane auth with era < 8");
3507 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3509 PROGRAM_SET_BSWAP(p);
3511 PROGRAM_SET_36BIT_ADDR(p);
3513 SHR_HDR(p, desc_share[cipherdata->algtype][authdata->algtype], 0, 0);
3515 SHR_HDR(p, SHR_ALWAYS, 0, 0);
3517 pdb_type = cnstr_pdcp_u_plane_pdb(p, sn_size, hfn, bearer,
3518 direction, hfn_threshold,
3519 cipherdata, authdata);
3520 if (pdb_type == PDCP_PDB_TYPE_INVALID) {
3521 pr_err("Error creating PDCP UPlane PDB\n");
3524 SET_LABEL(p, pdb_end);
3526 err = insert_hfn_ov_op(p, sn_size, pdb_type, era_2_sw_hfn_ovrd);
3531 case PDCP_SN_SIZE_7:
3532 case PDCP_SN_SIZE_12:
3533 switch (cipherdata->algtype) {
3534 case PDCP_CIPHER_TYPE_ZUC:
3535 if (rta_sec_era < RTA_SEC_ERA_5) {
3536 pr_err("Invalid era for selected algorithm\n");
3540 case PDCP_CIPHER_TYPE_AES:
3541 case PDCP_CIPHER_TYPE_SNOW:
3542 case PDCP_CIPHER_TYPE_NULL:
3543 if (pdb_type != PDCP_PDB_TYPE_FULL_PDB) {
3544 pr_err("PDB type must be FULL for PROTO desc\n");
3548 /* Insert auth key if requested */
3549 if (authdata && authdata->algtype)
3550 KEY(p, KEY2, authdata->key_enc_flags,
3551 (uint64_t)authdata->key, authdata->keylen,
3552 INLINE_KEY(authdata));
3553 else if (authdata && authdata->algtype == 0) {
3554 err = pdcp_insert_uplane_with_int_op(p, swap,
3555 cipherdata, authdata,
3556 sn_size, era_2_sw_hfn_ovrd,
3557 OP_TYPE_DECAP_PROTOCOL);
3563 /* Insert Cipher Key */
3564 KEY(p, KEY1, cipherdata->key_enc_flags,
3565 cipherdata->key, cipherdata->keylen,
3566 INLINE_KEY(cipherdata));
3568 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3569 OP_PCLID_LTE_PDCP_USER_RN,
3570 ((uint16_t)cipherdata->algtype << 8) |
3571 (uint16_t)authdata->algtype);
3573 PROTOCOL(p, OP_TYPE_DECAP_PROTOCOL,
3574 OP_PCLID_LTE_PDCP_USER,
3575 (uint16_t)cipherdata->algtype);
3578 pr_err("%s: Invalid encrypt algorithm selected: %d\n",
3579 "cnstr_pcl_shdsc_pdcp_u_plane_decap",
3580 cipherdata->algtype);
3585 case PDCP_SN_SIZE_15:
3586 case PDCP_SN_SIZE_18:
3588 err = pdcp_insert_uplane_with_int_op(p, swap,
3589 cipherdata, authdata,
3590 sn_size, era_2_sw_hfn_ovrd,
3591 OP_TYPE_DECAP_PROTOCOL);
3598 switch (cipherdata->algtype) {
3599 case PDCP_CIPHER_TYPE_NULL:
3600 insert_copy_frame_op(p,
3602 OP_TYPE_DECAP_PROTOCOL);
3606 err = pdcp_insert_uplane_no_int_op(p, swap, cipherdata,
3607 OP_TYPE_DECAP_PROTOCOL, sn_size);
3614 case PDCP_SN_SIZE_5:
3616 pr_err("Invalid SN size selected\n");
3620 PATCH_HDR(p, 0, pdb_end);
3621 return PROGRAM_FINALIZE(p);
3625 * cnstr_shdsc_pdcp_short_mac - Function for creating a PDCP Short MAC
3627 * @descbuf: pointer to buffer for descriptor construction
3628 * @ps: if 36/40bit addressing is desired, this parameter must be true
3629 * @swap: must be true when core endianness doesn't match SEC endianness
3630 * @authdata: pointer to authentication transform definitions
3631 * Valid algorithm values are those from auth_type_pdcp enum.
3633 * Return: size of descriptor written in words or negative number on error.
3634 * Once the function returns, the value of this parameter can be used
3635 * for reclaiming the space that wasn't used for the descriptor.
3637 * Note: descbuf must be large enough to contain a full 256 byte long
3638 * descriptor; after the function returns, by subtracting the actual number of
3639 * bytes used, the user can reuse the remaining buffer space for other purposes.
3642 cnstr_shdsc_pdcp_short_mac(uint32_t *descbuf,
3645 struct alginfo *authdata)
3648 struct program *p = &prg;
3649 uint32_t iv[3] = {0, 0, 0};
3650 LABEL(local_offset);
3651 REFERENCE(move_cmd_read_descbuf);
3652 REFERENCE(move_cmd_write_descbuf);
3654 PROGRAM_CNTXT_INIT(p, descbuf, 0);
3656 PROGRAM_SET_BSWAP(p);
3658 PROGRAM_SET_36BIT_ADDR(p);
3660 SHR_HDR(p, SHR_ALWAYS, 1, 0);
3662 if (rta_sec_era > RTA_SEC_ERA_2) {
3663 MATHB(p, SEQINSZ, SUB, ZERO, VSEQINSZ, 4, 0);
3664 MATHB(p, SEQINSZ, SUB, ZERO, MATH1, 4, 0);
3666 MATHB(p, SEQINSZ, ADD, ONE, MATH1, 4, 0);
3667 MATHB(p, MATH1, SUB, ONE, MATH1, 4, 0);
3668 MATHB(p, ZERO, ADD, MATH1, VSEQINSZ, 4, 0);
3669 MOVE(p, MATH1, 0, MATH0, 0, 8, IMMED);
3672 * Since MOVELEN is available only starting with
3673 * SEC ERA 3, use poor man's MOVELEN: create a MOVE
3674 * command dynamically by writing the length from M1 by
3675 * OR-ing the command in the M1 register and MOVE the
3676 * result into the descriptor buffer. Care must be taken
3677 * wrt. the location of the command because of SEC
3678 * pipelining. The actual MOVEs are written at the end
3679 * of the descriptor due to calculations needed on the
3680 * offset in the descriptor for the MOVE command.
3682 move_cmd_read_descbuf = MOVE(p, DESCBUF, 0, MATH0, 0, 6,
3684 move_cmd_write_descbuf = MOVE(p, MATH0, 0, DESCBUF, 0, 8,
3687 MATHB(p, ZERO, ADD, MATH1, VSEQOUTSZ, 4, 0);
3689 switch (authdata->algtype) {
3690 case PDCP_AUTH_TYPE_NULL:
3691 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3692 if (rta_sec_era > RTA_SEC_ERA_2) {
3693 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3695 SET_LABEL(p, local_offset);
3697 /* Shut off automatic Info FIFO entries */
3698 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3700 /* Placeholder for MOVE command with length from M1
3703 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3705 /* Enable automatic Info FIFO entries */
3706 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3709 LOAD(p, (uintptr_t)iv, MATH0, 0, 8, IMMED | COPY);
3710 SEQFIFOLOAD(p, MSG1, 0, VLF | LAST1 | LAST2 | FLUSH1);
3711 SEQSTORE(p, MATH0, 0, 4, 0);
3715 case PDCP_AUTH_TYPE_SNOW:
3717 iv[1] = swap ? swab32(0x04000000) : 0x04000000;
3718 iv[2] = swap ? swab32(0xF8000000) : 0xF8000000;
3720 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3721 authdata->keylen, INLINE_KEY(authdata));
3722 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3723 ALG_OPERATION(p, OP_ALG_ALGSEL_SNOW_F9,
3725 OP_ALG_AS_INITFINAL,
3728 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3730 if (rta_sec_era > RTA_SEC_ERA_2) {
3731 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3733 SET_LABEL(p, local_offset);
3736 /* Shut off automatic Info FIFO entries */
3737 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3739 /* Placeholder for MOVE command with length from M1
3742 MOVE(p, IFIFOAB1, 0, OFIFO, 0, 0, IMMED);
3744 /* Enable automatic Info FIFO entries */
3745 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3747 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3748 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3752 case PDCP_AUTH_TYPE_AES:
3754 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3755 iv[2] = 0x00000000; /* unused */
3757 KEY(p, KEY1, authdata->key_enc_flags, authdata->key,
3758 authdata->keylen, INLINE_KEY(authdata));
3759 LOAD(p, (uintptr_t)&iv, MATH0, 0, 8, IMMED | COPY);
3760 MOVE(p, MATH0, 0, IFIFOAB1, 0, 8, IMMED);
3761 ALG_OPERATION(p, OP_ALG_ALGSEL_AES,
3763 OP_ALG_AS_INITFINAL,
3766 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3768 if (rta_sec_era > RTA_SEC_ERA_2) {
3769 MOVE(p, AB2, 0, OFIFO, 0, MATH1, 0);
3771 SET_LABEL(p, local_offset);
3773 /* Shut off automatic Info FIFO entries */
3774 LOAD(p, 0, DCTRL, LDOFF_DISABLE_AUTO_NFIFO, 0, IMMED);
3776 /* Placeholder for MOVE command with length from M1
3779 MOVE(p, IFIFOAB2, 0, OFIFO, 0, 0, IMMED);
3781 /* Enable automatic Info FIFO entries */
3782 LOAD(p, 0, DCTRL, LDOFF_ENABLE_AUTO_NFIFO, 0, IMMED);
3784 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3785 SEQSTORE(p, CONTEXT1, 0, 4, 0);
3789 case PDCP_AUTH_TYPE_ZUC:
3790 if (rta_sec_era < RTA_SEC_ERA_5) {
3791 pr_err("Invalid era for selected algorithm\n");
3795 iv[1] = swap ? swab32(0xFC000000) : 0xFC000000;
3796 iv[2] = 0x00000000; /* unused */
3798 KEY(p, KEY2, authdata->key_enc_flags, authdata->key,
3799 authdata->keylen, INLINE_KEY(authdata));
3800 LOAD(p, (uintptr_t)&iv, CONTEXT2, 0, 12, IMMED | COPY);
3801 ALG_OPERATION(p, OP_ALG_ALGSEL_ZUCA,
3803 OP_ALG_AS_INITFINAL,
3806 SEQFIFOSTORE(p, MSG, 0, 0, VLF);
3807 MOVE(p, AB1, 0, OFIFO, 0, MATH1, 0);
3808 SEQFIFOLOAD(p, MSGINSNOOP, 0, VLF | LAST1 | LAST2 | FLUSH1);
3809 SEQSTORE(p, CONTEXT2, 0, 4, 0);
3814 pr_err("%s: Invalid integrity algorithm selected: %d\n",
3815 "cnstr_shdsc_pdcp_short_mac", authdata->algtype);
3820 if (rta_sec_era < RTA_SEC_ERA_3) {
3821 PATCH_MOVE(p, move_cmd_read_descbuf, local_offset);
3822 PATCH_MOVE(p, move_cmd_write_descbuf, local_offset);
3825 return PROGRAM_FINALIZE(p);
3828 #endif /* __DESC_PDCP_H__ */