0bf93efadcdd9fdf72c897b16a712c89f28052a6
[dpdk.git] / drivers / crypto / dpaa2_sec / hw / rta / sec_run_time_asm.h
1 /*
2  * Copyright 2008-2016 Freescale Semiconductor, Inc.
3  *
4  * SPDX-License-Identifier: BSD-3-Clause or GPL-2.0+
5  */
6
7 #ifndef __RTA_SEC_RUN_TIME_ASM_H__
8 #define __RTA_SEC_RUN_TIME_ASM_H__
9
10 #include "hw/desc.h"
11
12 /* hw/compat.h is not delivered in kernel */
13 #ifndef __KERNEL__
14 #include "hw/compat.h"
15 #endif
16
17 /**
18  * enum rta_sec_era - SEC HW block revisions supported by the RTA library
19  * @RTA_SEC_ERA_1: SEC Era 1
20  * @RTA_SEC_ERA_2: SEC Era 2
21  * @RTA_SEC_ERA_3: SEC Era 3
22  * @RTA_SEC_ERA_4: SEC Era 4
23  * @RTA_SEC_ERA_5: SEC Era 5
24  * @RTA_SEC_ERA_6: SEC Era 6
25  * @RTA_SEC_ERA_7: SEC Era 7
26  * @RTA_SEC_ERA_8: SEC Era 8
27  * @MAX_SEC_ERA: maximum SEC HW block revision supported by RTA library
28  */
29 enum rta_sec_era {
30         RTA_SEC_ERA_1,
31         RTA_SEC_ERA_2,
32         RTA_SEC_ERA_3,
33         RTA_SEC_ERA_4,
34         RTA_SEC_ERA_5,
35         RTA_SEC_ERA_6,
36         RTA_SEC_ERA_7,
37         RTA_SEC_ERA_8,
38         MAX_SEC_ERA = RTA_SEC_ERA_8
39 };
40
41 /**
42  * DEFAULT_SEC_ERA - the default value for the SEC era in case the user provides
43  * an unsupported value.
44  */
45 #define DEFAULT_SEC_ERA MAX_SEC_ERA
46
47 /**
48  * USER_SEC_ERA - translates the SEC Era from internal to user representation.
49  * @sec_era: SEC Era in internal (library) representation
50  */
51 #define USER_SEC_ERA(sec_era)   (sec_era + 1)
52
53 /**
54  * INTL_SEC_ERA - translates the SEC Era from user representation to internal.
55  * @sec_era: SEC Era in user representation
56  */
57 #define INTL_SEC_ERA(sec_era)   (sec_era - 1)
58
59 /**
60  * enum rta_jump_type - Types of action taken by JUMP command
61  * @LOCAL_JUMP: conditional jump to an offset within the descriptor buffer
62  * @FAR_JUMP: conditional jump to a location outside the descriptor buffer,
63  *            indicated by the POINTER field after the JUMP command.
64  * @HALT: conditional halt - stop the execution of the current descriptor and
65  *        writes PKHA / Math condition bits as status / error code.
66  * @HALT_STATUS: conditional halt with user-specified status - stop the
67  *               execution of the current descriptor and writes the value of
68  *               "LOCAL OFFSET" JUMP field as status / error code.
69  * @GOSUB: conditional subroutine call - similar to @LOCAL_JUMP, but also saves
70  *         return address in the Return Address register; subroutine calls
71  *         cannot be nested.
72  * @RETURN: conditional subroutine return - similar to @LOCAL_JUMP, but the
73  *          offset is taken from the Return Address register.
74  * @LOCAL_JUMP_INC: similar to @LOCAL_JUMP, but increment the register specified
75  *                  in "SRC_DST" JUMP field before evaluating the jump
76  *                  condition.
77  * @LOCAL_JUMP_DEC: similar to @LOCAL_JUMP, but decrement the register specified
78  *                  in "SRC_DST" JUMP field before evaluating the jump
79  *                  condition.
80  */
81 enum rta_jump_type {
82         LOCAL_JUMP,
83         FAR_JUMP,
84         HALT,
85         HALT_STATUS,
86         GOSUB,
87         RETURN,
88         LOCAL_JUMP_INC,
89         LOCAL_JUMP_DEC
90 };
91
92 /**
93  * enum rta_jump_cond - How test conditions are evaluated by JUMP command
94  * @ALL_TRUE: perform action if ALL selected conditions are true
95  * @ALL_FALSE: perform action if ALL selected conditions are false
96  * @ANY_TRUE: perform action if ANY of the selected conditions is true
97  * @ANY_FALSE: perform action if ANY of the selected conditions is false
98  */
99 enum rta_jump_cond {
100         ALL_TRUE,
101         ALL_FALSE,
102         ANY_TRUE,
103         ANY_FALSE
104 };
105
106 /**
107  * enum rta_share_type - Types of sharing for JOB_HDR and SHR_HDR commands
108  * @SHR_NEVER: nothing is shared; descriptors can execute in parallel (i.e. no
109  *             dependencies are allowed between them).
110  * @SHR_WAIT: shared descriptor and keys are shared once the descriptor sets
111  *            "OK to share" in DECO Control Register (DCTRL).
112  * @SHR_SERIAL: shared descriptor and keys are shared once the descriptor has
113  *              completed.
114  * @SHR_ALWAYS: shared descriptor is shared anytime after the descriptor is
115  *              loaded.
116  * @SHR_DEFER: valid only for JOB_HDR; sharing type is the one specified
117  *             in the shared descriptor associated with the job descriptor.
118  */
119 enum rta_share_type {
120         SHR_NEVER,
121         SHR_WAIT,
122         SHR_SERIAL,
123         SHR_ALWAYS,
124         SHR_DEFER
125 };
126
127 /**
128  * enum rta_data_type - Indicates how is the data provided and how to include it
129  *                      in the descriptor.
130  * @RTA_DATA_PTR: Data is in memory and accessed by reference; data address is a
131  *               physical (bus) address.
132  * @RTA_DATA_IMM: Data is inlined in descriptor and accessed as immediate data;
133  *               data address is a virtual address.
134  * @RTA_DATA_IMM_DMA: (AIOP only) Data is inlined in descriptor and accessed as
135  *                   immediate data; data address is a physical (bus) address
136  *                   in external memory and CDMA is programmed to transfer the
137  *                   data into descriptor buffer being built in Workspace Area.
138  */
139 enum rta_data_type {
140         RTA_DATA_PTR = 1,
141         RTA_DATA_IMM,
142         RTA_DATA_IMM_DMA
143 };
144
145 /* Registers definitions */
146 enum rta_regs {
147         /* CCB Registers */
148         CONTEXT1 = 1,
149         CONTEXT2,
150         KEY1,
151         KEY2,
152         KEY1SZ,
153         KEY2SZ,
154         ICV1SZ,
155         ICV2SZ,
156         DATA1SZ,
157         DATA2SZ,
158         ALTDS1,
159         IV1SZ,
160         AAD1SZ,
161         MODE1,
162         MODE2,
163         CCTRL,
164         DCTRL,
165         ICTRL,
166         CLRW,
167         CSTAT,
168         IFIFO,
169         NFIFO,
170         OFIFO,
171         PKASZ,
172         PKBSZ,
173         PKNSZ,
174         PKESZ,
175         /* DECO Registers */
176         MATH0,
177         MATH1,
178         MATH2,
179         MATH3,
180         DESCBUF,
181         JOBDESCBUF,
182         SHAREDESCBUF,
183         DPOVRD,
184         DJQDA,
185         DSTAT,
186         DPID,
187         DJQCTRL,
188         ALTSOURCE,
189         SEQINSZ,
190         SEQOUTSZ,
191         VSEQINSZ,
192         VSEQOUTSZ,
193         /* PKHA Registers */
194         PKA,
195         PKN,
196         PKA0,
197         PKA1,
198         PKA2,
199         PKA3,
200         PKB,
201         PKB0,
202         PKB1,
203         PKB2,
204         PKB3,
205         PKE,
206         /* Pseudo registers */
207         AB1,
208         AB2,
209         ABD,
210         IFIFOABD,
211         IFIFOAB1,
212         IFIFOAB2,
213         AFHA_SBOX,
214         MDHA_SPLIT_KEY,
215         JOBSRC,
216         ZERO,
217         ONE,
218         AAD1,
219         IV1,
220         IV2,
221         MSG1,
222         MSG2,
223         MSG,
224         MSG_CKSUM,
225         MSGOUTSNOOP,
226         MSGINSNOOP,
227         ICV1,
228         ICV2,
229         SKIP,
230         NONE,
231         RNGOFIFO,
232         RNG,
233         IDFNS,
234         ODFNS,
235         NFIFOSZ,
236         SZ,
237         PAD,
238         SAD1,
239         AAD2,
240         BIT_DATA,
241         NFIFO_SZL,
242         NFIFO_SZM,
243         NFIFO_L,
244         NFIFO_M,
245         SZL,
246         SZM,
247         JOBDESCBUF_EFF,
248         SHAREDESCBUF_EFF,
249         METADATA,
250         GTR,
251         STR,
252         OFIFO_SYNC,
253         MSGOUTSNOOP_ALT
254 };
255
256 /* Command flags */
257 #define FLUSH1          BIT(0)
258 #define LAST1           BIT(1)
259 #define LAST2           BIT(2)
260 #define IMMED           BIT(3)
261 #define SGF             BIT(4)
262 #define VLF             BIT(5)
263 #define EXT             BIT(6)
264 #define CONT            BIT(7)
265 #define SEQ             BIT(8)
266 #define AIDF            BIT(9)
267 #define FLUSH2          BIT(10)
268 #define CLASS1          BIT(11)
269 #define CLASS2          BIT(12)
270 #define BOTH            BIT(13)
271
272 /**
273  * DCOPY - (AIOP only) command param is pointer to external memory
274  *
275  * CDMA must be used to transfer the key via DMA into Workspace Area.
276  * Valid only in combination with IMMED flag.
277  */
278 #define DCOPY           BIT(30)
279
280 #define COPY            BIT(31) /* command param is pointer (not immediate)
281                                  * valid only in combination when IMMED
282                                  */
283
284 #define __COPY_MASK     (COPY | DCOPY)
285
286 /* SEQ IN/OUT PTR Command specific flags */
287 #define RBS             BIT(16)
288 #define INL             BIT(17)
289 #define PRE             BIT(18)
290 #define RTO             BIT(19)
291 #define RJD             BIT(20)
292 #define SOP             BIT(21)
293 #define RST             BIT(22)
294 #define EWS             BIT(23)
295
296 #define ENC             BIT(14) /* Encrypted Key */
297 #define EKT             BIT(15) /* AES CCM Encryption (default is
298                                  * AES ECB Encryption)
299                                  */
300 #define TK              BIT(16) /* Trusted Descriptor Key (default is
301                                  * Job Descriptor Key)
302                                  */
303 #define NWB             BIT(17) /* No Write Back Key */
304 #define PTS             BIT(18) /* Plaintext Store */
305
306 /* HEADER Command specific flags */
307 #define RIF             BIT(16)
308 #define DNR             BIT(17)
309 #define CIF             BIT(18)
310 #define PD              BIT(19)
311 #define RSMS            BIT(20)
312 #define TD              BIT(21)
313 #define MTD             BIT(22)
314 #define REO             BIT(23)
315 #define SHR             BIT(24)
316 #define SC              BIT(25)
317 /* Extended HEADER specific flags */
318 #define DSV             BIT(7)
319 #define DSEL_MASK       0x00000007      /* DECO Select */
320 #define FTD             BIT(8)
321
322 /* JUMP Command specific flags */
323 #define NIFP            BIT(20)
324 #define NIP             BIT(21)
325 #define NOP             BIT(22)
326 #define NCP             BIT(23)
327 #define CALM            BIT(24)
328
329 #define MATH_Z          BIT(25)
330 #define MATH_N          BIT(26)
331 #define MATH_NV         BIT(27)
332 #define MATH_C          BIT(28)
333 #define PK_0            BIT(29)
334 #define PK_GCD_1        BIT(30)
335 #define PK_PRIME        BIT(31)
336 #define SELF            BIT(0)
337 #define SHRD            BIT(1)
338 #define JQP             BIT(2)
339
340 /* NFIFOADD specific flags */
341 #define PAD_ZERO        BIT(16)
342 #define PAD_NONZERO     BIT(17)
343 #define PAD_INCREMENT   BIT(18)
344 #define PAD_RANDOM      BIT(19)
345 #define PAD_ZERO_N1     BIT(20)
346 #define PAD_NONZERO_0   BIT(21)
347 #define PAD_N1          BIT(23)
348 #define PAD_NONZERO_N   BIT(24)
349 #define OC              BIT(25)
350 #define BM              BIT(26)
351 #define PR              BIT(27)
352 #define PS              BIT(28)
353 #define BP              BIT(29)
354
355 /* MOVE Command specific flags */
356 #define WAITCOMP        BIT(16)
357 #define SIZE_WORD       BIT(17)
358 #define SIZE_BYTE       BIT(18)
359 #define SIZE_DWORD      BIT(19)
360
361 /* MATH command specific flags */
362 #define IFB         MATH_IFB
363 #define NFU         MATH_NFU
364 #define STL         MATH_STL
365 #define SSEL        MATH_SSEL
366 #define SWP         MATH_SWP
367 #define IMMED2      BIT(31)
368
369 /**
370  * struct program - descriptor buffer management structure
371  * @current_pc: current offset in descriptor
372  * @current_instruction: current instruction in descriptor
373  * @first_error_pc: offset of the first error in descriptor
374  * @start_pc: start offset in descriptor buffer
375  * @buffer: buffer carrying descriptor
376  * @shrhdr: shared descriptor header
377  * @jobhdr: job descriptor header
378  * @ps: pointer fields size; if ps is true, pointers will be 36bits in
379  *      length; if ps is false, pointers will be 32bits in length
380  * @bswap: if true, perform byte swap on a 4-byte boundary
381  */
382 struct program {
383         unsigned int current_pc;
384         unsigned int current_instruction;
385         unsigned int first_error_pc;
386         unsigned int start_pc;
387         uint32_t *buffer;
388         uint32_t *shrhdr;
389         uint32_t *jobhdr;
390         bool ps;
391         bool bswap;
392 };
393
394 static inline void
395 rta_program_cntxt_init(struct program *program,
396                        uint32_t *buffer, unsigned int offset)
397 {
398         program->current_pc = 0;
399         program->current_instruction = 0;
400         program->first_error_pc = 0;
401         program->start_pc = offset;
402         program->buffer = buffer;
403         program->shrhdr = NULL;
404         program->jobhdr = NULL;
405         program->ps = false;
406         program->bswap = false;
407 }
408
409 static inline int
410 rta_program_finalize(struct program *program)
411 {
412         /* Descriptor is usually not allowed to go beyond 64 words size */
413         if (program->current_pc > MAX_CAAM_DESCSIZE)
414                 pr_warn("Descriptor Size exceeded max limit of 64 words\n");
415
416         /* Descriptor is erroneous */
417         if (program->first_error_pc) {
418                 pr_err("Descriptor creation error\n");
419                 return -EINVAL;
420         }
421
422         /* Update descriptor length in shared and job descriptor headers */
423         if (program->shrhdr != NULL)
424                 *program->shrhdr |= program->bswap ?
425                                         swab32(program->current_pc) :
426                                         program->current_pc;
427         else if (program->jobhdr != NULL)
428                 *program->jobhdr |= program->bswap ?
429                                         swab32(program->current_pc) :
430                                         program->current_pc;
431
432         return (int)program->current_pc;
433 }
434
435 static inline unsigned int
436 rta_program_set_36bit_addr(struct program *program)
437 {
438         program->ps = true;
439         return program->current_pc;
440 }
441
442 static inline unsigned int
443 rta_program_set_bswap(struct program *program)
444 {
445         program->bswap = true;
446         return program->current_pc;
447 }
448
449 static inline void
450 __rta_out32(struct program *program, uint32_t val)
451 {
452         program->buffer[program->current_pc] = program->bswap ?
453                                                 swab32(val) : val;
454         program->current_pc++;
455 }
456
457 static inline void
458 __rta_out_be32(struct program *program, uint32_t val)
459 {
460         program->buffer[program->current_pc] = cpu_to_be32(val);
461         program->current_pc++;
462 }
463
464 static inline void
465 __rta_out_le32(struct program *program, uint32_t val)
466 {
467         program->buffer[program->current_pc] = cpu_to_le32(val);
468         program->current_pc++;
469 }
470
471 static inline void
472 __rta_out64(struct program *program, bool is_ext, uint64_t val)
473 {
474         if (is_ext) {
475                 /*
476                  * Since we are guaranteed only a 4-byte alignment in the
477                  * descriptor buffer, we have to do 2 x 32-bit (word) writes.
478                  * For the order of the 2 words to be correct, we need to
479                  * take into account the endianness of the CPU.
480                  */
481 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
482                 __rta_out32(program, program->bswap ? lower_32_bits(val) :
483                                                       upper_32_bits(val));
484
485                 __rta_out32(program, program->bswap ? upper_32_bits(val) :
486                                                       lower_32_bits(val));
487 #else
488                 __rta_out32(program, program->bswap ? upper_32_bits(val) :
489                                                       lower_32_bits(val));
490
491                 __rta_out32(program, program->bswap ? lower_32_bits(val) :
492                                                       upper_32_bits(val));
493 #endif
494         } else {
495                 __rta_out32(program, lower_32_bits(val));
496         }
497 }
498
499 static inline unsigned int
500 rta_word(struct program *program, uint32_t val)
501 {
502         unsigned int start_pc = program->current_pc;
503
504         __rta_out32(program, val);
505
506         return start_pc;
507 }
508
509 static inline unsigned int
510 rta_dword(struct program *program, uint64_t val)
511 {
512         unsigned int start_pc = program->current_pc;
513
514         __rta_out64(program, true, val);
515
516         return start_pc;
517 }
518
519 static inline uint32_t
520 inline_flags(enum rta_data_type data_type)
521 {
522         switch (data_type) {
523         case RTA_DATA_PTR:
524                 return 0;
525         case RTA_DATA_IMM:
526                 return IMMED | COPY;
527         case RTA_DATA_IMM_DMA:
528                 return IMMED | DCOPY;
529         default:
530                 /* warn and default to RTA_DATA_PTR */
531                 pr_warn("RTA: defaulting to RTA_DATA_PTR parameter type\n");
532                 return 0;
533         }
534 }
535
536 static inline unsigned int
537 rta_copy_data(struct program *program, uint8_t *data, unsigned int length)
538 {
539         unsigned int i;
540         unsigned int start_pc = program->current_pc;
541         uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
542
543         for (i = 0; i < length; i++)
544                 *tmp++ = data[i];
545         program->current_pc += (length + 3) / 4;
546
547         return start_pc;
548 }
549
550 #if defined(__EWL__) && defined(AIOP)
551 static inline void
552 __rta_dma_data(void *ws_dst, uint64_t ext_address, uint16_t size)
553 { cdma_read(ws_dst, ext_address, size); }
554 #else
555 static inline void
556 __rta_dma_data(void *ws_dst __maybe_unused,
557                uint64_t ext_address __maybe_unused,
558                uint16_t size __maybe_unused)
559 { pr_warn("RTA: DCOPY not supported, DMA will be skipped\n"); }
560 #endif /* defined(__EWL__) && defined(AIOP) */
561
562 static inline void
563 __rta_inline_data(struct program *program, uint64_t data,
564                   uint32_t copy_data, uint32_t length)
565 {
566         if (!copy_data) {
567                 __rta_out64(program, length > 4, data);
568         } else if (copy_data & COPY) {
569                 uint8_t *tmp = (uint8_t *)&program->buffer[program->current_pc];
570                 uint32_t i;
571
572                 for (i = 0; i < length; i++)
573                         *tmp++ = ((uint8_t *)(uintptr_t)data)[i];
574                 program->current_pc += ((length + 3) / 4);
575         } else if (copy_data & DCOPY) {
576                 __rta_dma_data(&program->buffer[program->current_pc], data,
577                                (uint16_t)length);
578                 program->current_pc += ((length + 3) / 4);
579         }
580 }
581
582 static inline unsigned int
583 rta_desc_len(uint32_t *buffer)
584 {
585         if ((*buffer & CMD_MASK) == CMD_DESC_HDR)
586                 return *buffer & HDR_DESCLEN_MASK;
587         else
588                 return *buffer & HDR_DESCLEN_SHR_MASK;
589 }
590
591 static inline unsigned int
592 rta_desc_bytes(uint32_t *buffer)
593 {
594         return (unsigned int)(rta_desc_len(buffer) * CAAM_CMD_SZ);
595 }
596
597 /**
598  * split_key_len - Compute MDHA split key length for a given algorithm
599  * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* or
600  *        OP_PCLID_DKP_* - MD5, SHA1, SHA224, SHA256, SHA384, SHA512.
601  *
602  * Return: MDHA split key length
603  */
604 static inline uint32_t
605 split_key_len(uint32_t hash)
606 {
607         /* Sizes for MDHA pads (*not* keys): MD5, SHA1, 224, 256, 384, 512 */
608         static const uint8_t mdpadlen[] = { 16, 20, 32, 32, 64, 64 };
609         uint32_t idx;
610
611         idx = (hash & OP_ALG_ALGSEL_SUBMASK) >> OP_ALG_ALGSEL_SHIFT;
612
613         return (uint32_t)(mdpadlen[idx] * 2);
614 }
615
616 /**
617  * split_key_pad_len - Compute MDHA split key pad length for a given algorithm
618  * @hash: Hashing algorithm selection, one of OP_ALG_ALGSEL_* - MD5, SHA1,
619  *        SHA224, SHA384, SHA512.
620  *
621  * Return: MDHA split key pad length
622  */
623 static inline uint32_t
624 split_key_pad_len(uint32_t hash)
625 {
626         return ALIGN(split_key_len(hash), 16);
627 }
628
629 static inline unsigned int
630 rta_set_label(struct program *program)
631 {
632         return program->current_pc + program->start_pc;
633 }
634
635 static inline int
636 rta_patch_move(struct program *program, int line, unsigned int new_ref)
637 {
638         uint32_t opcode;
639         bool bswap = program->bswap;
640
641         if (line < 0)
642                 return -EINVAL;
643
644         opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
645
646         opcode &= (uint32_t)~MOVE_OFFSET_MASK;
647         opcode |= (new_ref << (MOVE_OFFSET_SHIFT + 2)) & MOVE_OFFSET_MASK;
648         program->buffer[line] = bswap ? swab32(opcode) : opcode;
649
650         return 0;
651 }
652
653 static inline int
654 rta_patch_jmp(struct program *program, int line, unsigned int new_ref)
655 {
656         uint32_t opcode;
657         bool bswap = program->bswap;
658
659         if (line < 0)
660                 return -EINVAL;
661
662         opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
663
664         opcode &= (uint32_t)~JUMP_OFFSET_MASK;
665         opcode |= (new_ref - (line + program->start_pc)) & JUMP_OFFSET_MASK;
666         program->buffer[line] = bswap ? swab32(opcode) : opcode;
667
668         return 0;
669 }
670
671 static inline int
672 rta_patch_header(struct program *program, int line, unsigned int new_ref)
673 {
674         uint32_t opcode;
675         bool bswap = program->bswap;
676
677         if (line < 0)
678                 return -EINVAL;
679
680         opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
681
682         opcode &= (uint32_t)~HDR_START_IDX_MASK;
683         opcode |= (new_ref << HDR_START_IDX_SHIFT) & HDR_START_IDX_MASK;
684         program->buffer[line] = bswap ? swab32(opcode) : opcode;
685
686         return 0;
687 }
688
689 static inline int
690 rta_patch_load(struct program *program, int line, unsigned int new_ref)
691 {
692         uint32_t opcode;
693         bool bswap = program->bswap;
694
695         if (line < 0)
696                 return -EINVAL;
697
698         opcode = (bswap ? swab32(program->buffer[line]) :
699                          program->buffer[line]) & (uint32_t)~LDST_OFFSET_MASK;
700
701         if (opcode & (LDST_SRCDST_WORD_DESCBUF | LDST_CLASS_DECO))
702                 opcode |= (new_ref << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
703         else
704                 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
705                           LDST_OFFSET_MASK;
706
707         program->buffer[line] = bswap ? swab32(opcode) : opcode;
708
709         return 0;
710 }
711
712 static inline int
713 rta_patch_store(struct program *program, int line, unsigned int new_ref)
714 {
715         uint32_t opcode;
716         bool bswap = program->bswap;
717
718         if (line < 0)
719                 return -EINVAL;
720
721         opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
722
723         opcode &= (uint32_t)~LDST_OFFSET_MASK;
724
725         switch (opcode & LDST_SRCDST_MASK) {
726         case LDST_SRCDST_WORD_DESCBUF:
727         case LDST_SRCDST_WORD_DESCBUF_JOB:
728         case LDST_SRCDST_WORD_DESCBUF_SHARED:
729         case LDST_SRCDST_WORD_DESCBUF_JOB_WE:
730         case LDST_SRCDST_WORD_DESCBUF_SHARED_WE:
731                 opcode |= ((new_ref) << LDST_OFFSET_SHIFT) & LDST_OFFSET_MASK;
732                 break;
733         default:
734                 opcode |= (new_ref << (LDST_OFFSET_SHIFT + 2)) &
735                           LDST_OFFSET_MASK;
736         }
737
738         program->buffer[line] = bswap ? swab32(opcode) : opcode;
739
740         return 0;
741 }
742
743 static inline int
744 rta_patch_raw(struct program *program, int line, unsigned int mask,
745               unsigned int new_val)
746 {
747         uint32_t opcode;
748         bool bswap = program->bswap;
749
750         if (line < 0)
751                 return -EINVAL;
752
753         opcode = bswap ? swab32(program->buffer[line]) : program->buffer[line];
754
755         opcode &= (uint32_t)~mask;
756         opcode |= new_val & mask;
757         program->buffer[line] = bswap ? swab32(opcode) : opcode;
758
759         return 0;
760 }
761
762 static inline int
763 __rta_map_opcode(uint32_t name, const uint32_t (*map_table)[2],
764                  unsigned int num_of_entries, uint32_t *val)
765 {
766         unsigned int i;
767
768         for (i = 0; i < num_of_entries; i++)
769                 if (map_table[i][0] == name) {
770                         *val = map_table[i][1];
771                         return 0;
772                 }
773
774         return -EINVAL;
775 }
776
777 static inline void
778 __rta_map_flags(uint32_t flags, const uint32_t (*flags_table)[2],
779                 unsigned int num_of_entries, uint32_t *opcode)
780 {
781         unsigned int i;
782
783         for (i = 0; i < num_of_entries; i++) {
784                 if (flags_table[i][0] & flags)
785                         *opcode |= flags_table[i][1];
786         }
787 }
788
789 #endif /* __RTA_SEC_RUN_TIME_ASM_H__ */