1 // SPDX-License-Identifier: GPL-2.0-or-later
7 * Copyright (C) Altera Corporation 1998-2001
8 * Copyright (C) 2010 NetUP Inc.
9 * Copyright (C) 2010 Igor M. Liplianin <liplianin@netup.ru>
12 #include <linux/kernel.h>
13 #include "altera-exprt.h"
17 #define DATA_BLOB_LENGTH 3
18 #define MATCH_DATA_LENGTH 8192
19 #define ALTERA_REQUEST_SIZE 1024
20 #define ALTERA_BUFFER_SIZE (MATCH_DATA_LENGTH + ALTERA_REQUEST_SIZE)
22 static u32
altera_bits_req(u32 n
)
24 u32 result
= SHORT_BITS
;
29 /* Look for the highest non-zero bit position */
30 while ((n
& (1 << (SHORT_BITS
- 1))) == 0) {
39 static u32
altera_read_packed(u8
*buffer
, u32 bits
, u32
*bits_avail
,
47 databyte
= buffer
[*in_index
];
48 result
|= (((databyte
>> (CHAR_BITS
- *bits_avail
))
49 & (0xff >> (CHAR_BITS
- *bits_avail
))) << shift
);
51 if (bits
<= *bits_avail
) {
52 result
&= (0xffff >> (SHORT_BITS
- (bits
+ shift
)));
59 *bits_avail
= CHAR_BITS
;
66 u32
altera_shrink(u8
*in
, u32 in_length
, u8
*out
, u32 out_length
, s32 version
)
68 u32 i
, j
, data_length
= 0L;
70 u32 match_data_length
= MATCH_DATA_LENGTH
;
71 u32 bits_avail
= CHAR_BITS
;
77 for (i
= 0; i
< out_length
; ++i
)
80 /* Read number of bytes in data. */
81 for (i
= 0; i
< sizeof(in_length
); ++i
) {
82 data_length
= data_length
| (
83 altera_read_packed(in
,
86 &in_index
) << (i
* CHAR_BITS
));
89 if (data_length
> out_length
) {
95 while (i
< data_length
) {
96 /* A 0 bit indicates literal data. */
97 if (altera_read_packed(in
, 1, &bits_avail
,
99 for (j
= 0; j
< DATA_BLOB_LENGTH
; ++j
) {
100 if (i
< data_length
) {
101 out
[i
] = (u8
)altera_read_packed(in
,
109 /* A 1 bit indicates offset/length to follow. */
110 offset
= altera_read_packed(in
, altera_bits_req((s16
)
111 (i
> match_data_length
?
112 match_data_length
: i
)),
115 length
= altera_read_packed(in
, CHAR_BITS
,
118 for (j
= 0; j
< length
; ++j
) {
119 if (i
< data_length
) {
120 out
[i
] = out
[i
- offset
];