Merge tag 'for-v6.2' of git://git.kernel.org/pub/scm/linux/kernel/git/sre/linux-power...
[linux-block.git] / drivers / isdn / hardware / mISDN / isdnhdlc.c
CommitLineData
74ba9207 1// SPDX-License-Identifier: GPL-2.0-or-later
1da177e4
LT
2/*
3 * isdnhdlc.c -- General purpose ISDN HDLC decoder.
4 *
6bd4bcd3 5 * Copyright (C)
c38fc3bc 6 * 2009 Karsten Keil <keil@b1-systems.de>
6bd4bcd3
KK
7 * 2002 Wolfgang Mües <wolfgang@iksw-muees.de>
8 * 2001 Frode Isaksen <fisaksen@bewan.com>
9 * 2001 Kai Germaschewski <kai.germaschewski@gmx.de>
1da177e4
LT
10 */
11
12#include <linux/module.h>
13#include <linux/init.h>
14#include <linux/crc-ccitt.h>
c38fc3bc 15#include <linux/bitrev.h>
99c2aa15 16#include "isdnhdlc.h"
1da177e4
LT
17
18/*-------------------------------------------------------------------*/
19
96de0e25 20MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
1da177e4
LT
21 "Frode Isaksen <fisaksen@bewan.com>, "
22 "Kai Germaschewski <kai.germaschewski@gmx.de>");
23MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
24MODULE_LICENSE("GPL");
25
26/*-------------------------------------------------------------------*/
27
1da177e4 28enum {
6bd4bcd3
KK
29 HDLC_FAST_IDLE, HDLC_GET_FLAG_B0, HDLC_GETFLAG_B1A6, HDLC_GETFLAG_B7,
30 HDLC_GET_DATA, HDLC_FAST_FLAG
1da177e4
LT
31};
32
33enum {
6bd4bcd3
KK
34 HDLC_SEND_DATA, HDLC_SEND_CRC1, HDLC_SEND_FAST_FLAG,
35 HDLC_SEND_FIRST_FLAG, HDLC_SEND_CRC2, HDLC_SEND_CLOSING_FLAG,
36 HDLC_SEND_IDLE1, HDLC_SEND_FAST_IDLE, HDLC_SENDFLAG_B0,
f3fad223 37 HDLC_SENDFLAG_B1A6, HDLC_SENDFLAG_B7, STOPPED, HDLC_SENDFLAG_ONE
1da177e4
LT
38};
39
c38fc3bc 40void isdnhdlc_rcv_init(struct isdnhdlc_vars *hdlc, u32 features)
1da177e4 41{
c38fc3bc 42 memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
1da177e4 43 hdlc->state = HDLC_GET_DATA;
c38fc3bc
KK
44 if (features & HDLC_56KBIT)
45 hdlc->do_adapt56 = 1;
46 if (features & HDLC_BITREVERSE)
47 hdlc->do_bitreverse = 1;
1da177e4 48}
6bd4bcd3 49EXPORT_SYMBOL(isdnhdlc_out_init);
1da177e4 50
c38fc3bc 51void isdnhdlc_out_init(struct isdnhdlc_vars *hdlc, u32 features)
1da177e4 52{
c38fc3bc
KK
53 memset(hdlc, 0, sizeof(struct isdnhdlc_vars));
54 if (features & HDLC_DCHANNEL) {
1da177e4
LT
55 hdlc->dchannel = 1;
56 hdlc->state = HDLC_SEND_FIRST_FLAG;
57 } else {
58 hdlc->dchannel = 0;
59 hdlc->state = HDLC_SEND_FAST_FLAG;
60 hdlc->ffvalue = 0x7e;
61 }
62 hdlc->cbin = 0x7e;
c38fc3bc 63 if (features & HDLC_56KBIT) {
1da177e4 64 hdlc->do_adapt56 = 1;
1da177e4 65 hdlc->state = HDLC_SENDFLAG_B0;
c38fc3bc 66 } else
1da177e4 67 hdlc->data_bits = 8;
c38fc3bc
KK
68 if (features & HDLC_BITREVERSE)
69 hdlc->do_bitreverse = 1;
1da177e4 70}
6bd4bcd3
KK
71EXPORT_SYMBOL(isdnhdlc_rcv_init);
72
73static int
74check_frame(struct isdnhdlc_vars *hdlc)
75{
76 int status;
77
475be4d8 78 if (hdlc->dstpos < 2) /* too small - framing error */
6bd4bcd3
KK
79 status = -HDLC_FRAMING_ERROR;
80 else if (hdlc->crc != 0xf0b8) /* crc error */
81 status = -HDLC_CRC_ERROR;
82 else {
83 /* remove CRC */
84 hdlc->dstpos -= 2;
85 /* good frame */
86 status = hdlc->dstpos;
87 }
88 return status;
89}
1da177e4
LT
90
91/*
92 isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
93
94 The source buffer is scanned for valid HDLC frames looking for
95 flags (01111110) to indicate the start of a frame. If the start of
96 the frame is found, the bit stuffing is removed (0 after 5 1's).
97 When a new flag is found, the complete frame has been received
98 and the CRC is checked.
99 If a valid frame is found, the function returns the frame length
100 excluding the CRC with the bit HDLC_END_OF_FRAME set.
101 If the beginning of a valid frame is found, the function returns
102 the length.
103 If a framing error is found (too many 1s and not a flag) the function
104 returns the length with the bit HDLC_FRAMING_ERROR set.
105 If a CRC error is found the function returns the length with the
106 bit HDLC_CRC_ERROR set.
107 If the frame length exceeds the destination buffer size, the function
108 returns the length with the bit HDLC_LENGTH_ERROR set.
109
110 src - source buffer
111 slen - source buffer length
112 count - number of bytes removed (decoded) from the source buffer
113 dst _ destination buffer
114 dsize - destination buffer size
115 returns - number of decoded bytes in the destination buffer and status
116 flag.
475be4d8 117*/
6bd4bcd3 118int isdnhdlc_decode(struct isdnhdlc_vars *hdlc, const u8 *src, int slen,
475be4d8 119 int *count, u8 *dst, int dsize)
1da177e4 120{
6bd4bcd3 121 int status = 0;
1da177e4 122
6bd4bcd3
KK
123 static const unsigned char fast_flag[] = {
124 0x00, 0x00, 0x00, 0x20, 0x30, 0x38, 0x3c, 0x3e, 0x3f
1da177e4
LT
125 };
126
6bd4bcd3
KK
127 static const unsigned char fast_flag_value[] = {
128 0x00, 0x7e, 0xfc, 0xf9, 0xf3, 0xe7, 0xcf, 0x9f, 0x3f
1da177e4
LT
129 };
130
6bd4bcd3
KK
131 static const unsigned char fast_abort[] = {
132 0x00, 0x00, 0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff
1da177e4
LT
133 };
134
475be4d8
JP
135#define handle_fast_flag(h) \
136 do { \
137 if (h->cbin == fast_flag[h->bit_shift]) { \
138 h->ffvalue = fast_flag_value[h->bit_shift]; \
139 h->state = HDLC_FAST_FLAG; \
140 h->ffbit_shift = h->bit_shift; \
141 h->bit_shift = 1; \
142 } else { \
143 h->state = HDLC_GET_DATA; \
144 h->data_received = 0; \
145 } \
6bd4bcd3
KK
146 } while (0)
147
475be4d8
JP
148#define handle_abort(h) \
149 do { \
150 h->shift_reg = fast_abort[h->ffbit_shift - 1]; \
151 h->hdlc_bits1 = h->ffbit_shift - 2; \
152 if (h->hdlc_bits1 < 0) \
153 h->hdlc_bits1 = 0; \
154 h->data_bits = h->ffbit_shift - 1; \
155 h->state = HDLC_GET_DATA; \
156 h->data_received = 0; \
6bd4bcd3
KK
157 } while (0)
158
1da177e4
LT
159 *count = slen;
160
6bd4bcd3
KK
161 while (slen > 0) {
162 if (hdlc->bit_shift == 0) {
c38fc3bc
KK
163 /* the code is for bitreverse streams */
164 if (hdlc->do_bitreverse == 0)
165 hdlc->cbin = bitrev8(*src++);
166 else
167 hdlc->cbin = *src++;
1da177e4
LT
168 slen--;
169 hdlc->bit_shift = 8;
6bd4bcd3
KK
170 if (hdlc->do_adapt56)
171 hdlc->bit_shift--;
1da177e4
LT
172 }
173
6bd4bcd3 174 switch (hdlc->state) {
1da177e4
LT
175 case STOPPED:
176 return 0;
177 case HDLC_FAST_IDLE:
6bd4bcd3 178 if (hdlc->cbin == 0xff) {
1da177e4
LT
179 hdlc->bit_shift = 0;
180 break;
181 }
182 hdlc->state = HDLC_GET_FLAG_B0;
183 hdlc->hdlc_bits1 = 0;
184 hdlc->bit_shift = 8;
185 break;
186 case HDLC_GET_FLAG_B0:
6bd4bcd3 187 if (!(hdlc->cbin & 0x80)) {
1da177e4
LT
188 hdlc->state = HDLC_GETFLAG_B1A6;
189 hdlc->hdlc_bits1 = 0;
190 } else {
6bd4bcd3
KK
191 if ((!hdlc->do_adapt56) &&
192 (++hdlc->hdlc_bits1 >= 8) &&
193 (hdlc->bit_shift == 1))
475be4d8 194 hdlc->state = HDLC_FAST_IDLE;
1da177e4 195 }
6bd4bcd3
KK
196 hdlc->cbin <<= 1;
197 hdlc->bit_shift--;
1da177e4
LT
198 break;
199 case HDLC_GETFLAG_B1A6:
6bd4bcd3 200 if (hdlc->cbin & 0x80) {
1da177e4 201 hdlc->hdlc_bits1++;
6bd4bcd3 202 if (hdlc->hdlc_bits1 == 6)
1da177e4 203 hdlc->state = HDLC_GETFLAG_B7;
6bd4bcd3 204 } else
1da177e4 205 hdlc->hdlc_bits1 = 0;
6bd4bcd3
KK
206 hdlc->cbin <<= 1;
207 hdlc->bit_shift--;
1da177e4
LT
208 break;
209 case HDLC_GETFLAG_B7:
6bd4bcd3 210 if (hdlc->cbin & 0x80) {
1da177e4
LT
211 hdlc->state = HDLC_GET_FLAG_B0;
212 } else {
213 hdlc->state = HDLC_GET_DATA;
214 hdlc->crc = 0xffff;
215 hdlc->shift_reg = 0;
216 hdlc->hdlc_bits1 = 0;
217 hdlc->data_bits = 0;
218 hdlc->data_received = 0;
219 }
6bd4bcd3
KK
220 hdlc->cbin <<= 1;
221 hdlc->bit_shift--;
1da177e4
LT
222 break;
223 case HDLC_GET_DATA:
6bd4bcd3 224 if (hdlc->cbin & 0x80) {
1da177e4 225 hdlc->hdlc_bits1++;
6bd4bcd3 226 switch (hdlc->hdlc_bits1) {
1da177e4
LT
227 case 6:
228 break;
229 case 7:
6bd4bcd3
KK
230 if (hdlc->data_received)
231 /* bad frame */
1da177e4 232 status = -HDLC_FRAMING_ERROR;
6bd4bcd3
KK
233 if (!hdlc->do_adapt56) {
234 if (hdlc->cbin == fast_abort
235 [hdlc->bit_shift + 1]) {
236 hdlc->state =
237 HDLC_FAST_IDLE;
238 hdlc->bit_shift = 1;
1da177e4
LT
239 break;
240 }
6bd4bcd3 241 } else
1da177e4 242 hdlc->state = HDLC_GET_FLAG_B0;
1da177e4
LT
243 break;
244 default:
6bd4bcd3 245 hdlc->shift_reg >>= 1;
1da177e4
LT
246 hdlc->shift_reg |= 0x80;
247 hdlc->data_bits++;
248 break;
249 }
250 } else {
6bd4bcd3 251 switch (hdlc->hdlc_bits1) {
1da177e4
LT
252 case 5:
253 break;
254 case 6:
6bd4bcd3
KK
255 if (hdlc->data_received)
256 status = check_frame(hdlc);
1da177e4
LT
257 hdlc->crc = 0xffff;
258 hdlc->shift_reg = 0;
259 hdlc->data_bits = 0;
6bd4bcd3
KK
260 if (!hdlc->do_adapt56)
261 handle_fast_flag(hdlc);
262 else {
1da177e4
LT
263 hdlc->state = HDLC_GET_DATA;
264 hdlc->data_received = 0;
265 }
266 break;
267 default:
6bd4bcd3 268 hdlc->shift_reg >>= 1;
1da177e4
LT
269 hdlc->data_bits++;
270 break;
271 }
272 hdlc->hdlc_bits1 = 0;
273 }
274 if (status) {
275 hdlc->dstpos = 0;
276 *count -= slen;
277 hdlc->cbin <<= 1;
278 hdlc->bit_shift--;
279 return status;
280 }
6bd4bcd3 281 if (hdlc->data_bits == 8) {
1da177e4
LT
282 hdlc->data_bits = 0;
283 hdlc->data_received = 1;
6bd4bcd3 284 hdlc->crc = crc_ccitt_byte(hdlc->crc,
475be4d8 285 hdlc->shift_reg);
1da177e4 286
6bd4bcd3
KK
287 /* good byte received */
288 if (hdlc->dstpos < dsize)
1da177e4 289 dst[hdlc->dstpos++] = hdlc->shift_reg;
6bd4bcd3
KK
290 else {
291 /* frame too long */
1da177e4
LT
292 status = -HDLC_LENGTH_ERROR;
293 hdlc->dstpos = 0;
294 }
295 }
296 hdlc->cbin <<= 1;
297 hdlc->bit_shift--;
298 break;
299 case HDLC_FAST_FLAG:
6bd4bcd3 300 if (hdlc->cbin == hdlc->ffvalue) {
1da177e4
LT
301 hdlc->bit_shift = 0;
302 break;
303 } else {
6bd4bcd3 304 if (hdlc->cbin == 0xff) {
1da177e4 305 hdlc->state = HDLC_FAST_IDLE;
6bd4bcd3
KK
306 hdlc->bit_shift = 0;
307 } else if (hdlc->ffbit_shift == 8) {
1da177e4
LT
308 hdlc->state = HDLC_GETFLAG_B7;
309 break;
6bd4bcd3
KK
310 } else
311 handle_abort(hdlc);
1da177e4
LT
312 }
313 break;
314 default:
315 break;
316 }
317 }
318 *count -= slen;
319 return 0;
320}
6bd4bcd3 321EXPORT_SYMBOL(isdnhdlc_decode);
1da177e4
LT
322/*
323 isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
324
325 The bit stream starts with a beginning flag (01111110). After
326 that each byte is added to the bit stream with bit stuffing added
327 (0 after 5 1's).
328 When the last byte has been removed from the source buffer, the
329 CRC (2 bytes is added) and the frame terminates with the ending flag.
330 For the dchannel, the idle character (all 1's) is also added at the end.
331 If this function is called with empty source buffer (slen=0), flags or
332 idle character will be generated.
333
334 src - source buffer
335 slen - source buffer length
336 count - number of bytes removed (encoded) from source buffer
337 dst _ destination buffer
338 dsize - destination buffer size
339 returns - number of encoded bytes in the destination buffer
340*/
6bd4bcd3 341int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const u8 *src, u16 slen,
475be4d8 342 int *count, u8 *dst, int dsize)
1da177e4
LT
343{
344 static const unsigned char xfast_flag_value[] = {
6bd4bcd3 345 0x7e, 0x3f, 0x9f, 0xcf, 0xe7, 0xf3, 0xf9, 0xfc, 0x7e
1da177e4
LT
346 };
347
348 int len = 0;
349
350 *count = slen;
351
f3fad223
KK
352 /* special handling for one byte frames */
353 if ((slen == 1) && (hdlc->state == HDLC_SEND_FAST_FLAG))
354 hdlc->state = HDLC_SENDFLAG_ONE;
1da177e4 355 while (dsize > 0) {
6bd4bcd3
KK
356 if (hdlc->bit_shift == 0) {
357 if (slen && !hdlc->do_closing) {
1da177e4
LT
358 hdlc->shift_reg = *src++;
359 slen--;
360 if (slen == 0)
6bd4bcd3
KK
361 /* closing sequence, CRC + flag(s) */
362 hdlc->do_closing = 1;
1da177e4
LT
363 hdlc->bit_shift = 8;
364 } else {
6bd4bcd3
KK
365 if (hdlc->state == HDLC_SEND_DATA) {
366 if (hdlc->data_received) {
1da177e4
LT
367 hdlc->state = HDLC_SEND_CRC1;
368 hdlc->crc ^= 0xffff;
369 hdlc->bit_shift = 8;
6bd4bcd3
KK
370 hdlc->shift_reg =
371 hdlc->crc & 0xff;
372 } else if (!hdlc->do_adapt56)
373 hdlc->state =
374 HDLC_SEND_FAST_FLAG;
375 else
376 hdlc->state =
377 HDLC_SENDFLAG_B0;
1da177e4
LT
378 }
379
380 }
381 }
382
6bd4bcd3 383 switch (hdlc->state) {
1da177e4
LT
384 case STOPPED:
385 while (dsize--)
386 *dst++ = 0xff;
1da177e4
LT
387 return dsize;
388 case HDLC_SEND_FAST_FLAG:
389 hdlc->do_closing = 0;
6bd4bcd3 390 if (slen == 0) {
c38fc3bc
KK
391 /* the code is for bitreverse streams */
392 if (hdlc->do_bitreverse == 0)
393 *dst++ = bitrev8(hdlc->ffvalue);
394 else
395 *dst++ = hdlc->ffvalue;
1da177e4
LT
396 len++;
397 dsize--;
398 break;
399 }
df561f66 400 fallthrough;
f3fad223 401 case HDLC_SENDFLAG_ONE:
6bd4bcd3
KK
402 if (hdlc->bit_shift == 8) {
403 hdlc->cbin = hdlc->ffvalue >>
404 (8 - hdlc->data_bits);
1da177e4
LT
405 hdlc->state = HDLC_SEND_DATA;
406 hdlc->crc = 0xffff;
407 hdlc->hdlc_bits1 = 0;
408 hdlc->data_received = 1;
409 }
410 break;
411 case HDLC_SENDFLAG_B0:
412 hdlc->do_closing = 0;
413 hdlc->cbin <<= 1;
414 hdlc->data_bits++;
415 hdlc->hdlc_bits1 = 0;
416 hdlc->state = HDLC_SENDFLAG_B1A6;
417 break;
418 case HDLC_SENDFLAG_B1A6:
419 hdlc->cbin <<= 1;
420 hdlc->data_bits++;
421 hdlc->cbin++;
6bd4bcd3 422 if (++hdlc->hdlc_bits1 == 6)
1da177e4
LT
423 hdlc->state = HDLC_SENDFLAG_B7;
424 break;
425 case HDLC_SENDFLAG_B7:
426 hdlc->cbin <<= 1;
427 hdlc->data_bits++;
6bd4bcd3 428 if (slen == 0) {
1da177e4
LT
429 hdlc->state = HDLC_SENDFLAG_B0;
430 break;
431 }
6bd4bcd3 432 if (hdlc->bit_shift == 8) {
1da177e4
LT
433 hdlc->state = HDLC_SEND_DATA;
434 hdlc->crc = 0xffff;
435 hdlc->hdlc_bits1 = 0;
436 hdlc->data_received = 1;
437 }
438 break;
439 case HDLC_SEND_FIRST_FLAG:
440 hdlc->data_received = 1;
6bd4bcd3 441 if (hdlc->data_bits == 8) {
1da177e4
LT
442 hdlc->state = HDLC_SEND_DATA;
443 hdlc->crc = 0xffff;
444 hdlc->hdlc_bits1 = 0;
445 break;
446 }
447 hdlc->cbin <<= 1;
448 hdlc->data_bits++;
6bd4bcd3 449 if (hdlc->shift_reg & 0x01)
1da177e4
LT
450 hdlc->cbin++;
451 hdlc->shift_reg >>= 1;
452 hdlc->bit_shift--;
6bd4bcd3 453 if (hdlc->bit_shift == 0) {
1da177e4
LT
454 hdlc->state = HDLC_SEND_DATA;
455 hdlc->crc = 0xffff;
456 hdlc->hdlc_bits1 = 0;
457 }
458 break;
459 case HDLC_SEND_DATA:
460 hdlc->cbin <<= 1;
461 hdlc->data_bits++;
6bd4bcd3 462 if (hdlc->hdlc_bits1 == 5) {
1da177e4
LT
463 hdlc->hdlc_bits1 = 0;
464 break;
465 }
6bd4bcd3
KK
466 if (hdlc->bit_shift == 8)
467 hdlc->crc = crc_ccitt_byte(hdlc->crc,
475be4d8 468 hdlc->shift_reg);
6bd4bcd3 469 if (hdlc->shift_reg & 0x01) {
1da177e4
LT
470 hdlc->hdlc_bits1++;
471 hdlc->cbin++;
472 hdlc->shift_reg >>= 1;
473 hdlc->bit_shift--;
474 } else {
475 hdlc->hdlc_bits1 = 0;
476 hdlc->shift_reg >>= 1;
477 hdlc->bit_shift--;
478 }
479 break;
480 case HDLC_SEND_CRC1:
481 hdlc->cbin <<= 1;
482 hdlc->data_bits++;
6bd4bcd3 483 if (hdlc->hdlc_bits1 == 5) {
1da177e4
LT
484 hdlc->hdlc_bits1 = 0;
485 break;
486 }
6bd4bcd3 487 if (hdlc->shift_reg & 0x01) {
1da177e4
LT
488 hdlc->hdlc_bits1++;
489 hdlc->cbin++;
490 hdlc->shift_reg >>= 1;
491 hdlc->bit_shift--;
492 } else {
493 hdlc->hdlc_bits1 = 0;
494 hdlc->shift_reg >>= 1;
495 hdlc->bit_shift--;
496 }
6bd4bcd3 497 if (hdlc->bit_shift == 0) {
1da177e4
LT
498 hdlc->shift_reg = (hdlc->crc >> 8);
499 hdlc->state = HDLC_SEND_CRC2;
500 hdlc->bit_shift = 8;
501 }
502 break;
503 case HDLC_SEND_CRC2:
504 hdlc->cbin <<= 1;
505 hdlc->data_bits++;
6bd4bcd3 506 if (hdlc->hdlc_bits1 == 5) {
1da177e4
LT
507 hdlc->hdlc_bits1 = 0;
508 break;
509 }
6bd4bcd3 510 if (hdlc->shift_reg & 0x01) {
1da177e4
LT
511 hdlc->hdlc_bits1++;
512 hdlc->cbin++;
513 hdlc->shift_reg >>= 1;
514 hdlc->bit_shift--;
515 } else {
516 hdlc->hdlc_bits1 = 0;
517 hdlc->shift_reg >>= 1;
518 hdlc->bit_shift--;
519 }
6bd4bcd3 520 if (hdlc->bit_shift == 0) {
1da177e4
LT
521 hdlc->shift_reg = 0x7e;
522 hdlc->state = HDLC_SEND_CLOSING_FLAG;
523 hdlc->bit_shift = 8;
524 }
525 break;
526 case HDLC_SEND_CLOSING_FLAG:
527 hdlc->cbin <<= 1;
528 hdlc->data_bits++;
6bd4bcd3 529 if (hdlc->hdlc_bits1 == 5) {
1da177e4
LT
530 hdlc->hdlc_bits1 = 0;
531 break;
532 }
6bd4bcd3 533 if (hdlc->shift_reg & 0x01)
1da177e4 534 hdlc->cbin++;
1da177e4
LT
535 hdlc->shift_reg >>= 1;
536 hdlc->bit_shift--;
6bd4bcd3
KK
537 if (hdlc->bit_shift == 0) {
538 hdlc->ffvalue =
539 xfast_flag_value[hdlc->data_bits];
540 if (hdlc->dchannel) {
1da177e4
LT
541 hdlc->ffvalue = 0x7e;
542 hdlc->state = HDLC_SEND_IDLE1;
543 hdlc->bit_shift = 8-hdlc->data_bits;
6bd4bcd3
KK
544 if (hdlc->bit_shift == 0)
545 hdlc->state =
546 HDLC_SEND_FAST_IDLE;
1da177e4 547 } else {
6bd4bcd3
KK
548 if (!hdlc->do_adapt56) {
549 hdlc->state =
550 HDLC_SEND_FAST_FLAG;
1da177e4
LT
551 hdlc->data_received = 0;
552 } else {
553 hdlc->state = HDLC_SENDFLAG_B0;
554 hdlc->data_received = 0;
555 }
6bd4bcd3
KK
556 /* Finished this frame, send flags */
557 if (dsize > 1)
558 dsize = 1;
1da177e4
LT
559 }
560 }
561 break;
562 case HDLC_SEND_IDLE1:
563 hdlc->do_closing = 0;
564 hdlc->cbin <<= 1;
565 hdlc->cbin++;
566 hdlc->data_bits++;
567 hdlc->bit_shift--;
6bd4bcd3 568 if (hdlc->bit_shift == 0) {
1da177e4
LT
569 hdlc->state = HDLC_SEND_FAST_IDLE;
570 hdlc->bit_shift = 0;
571 }
572 break;
573 case HDLC_SEND_FAST_IDLE:
574 hdlc->do_closing = 0;
575 hdlc->cbin = 0xff;
576 hdlc->data_bits = 8;
6bd4bcd3 577 if (hdlc->bit_shift == 8) {
1da177e4
LT
578 hdlc->cbin = 0x7e;
579 hdlc->state = HDLC_SEND_FIRST_FLAG;
580 } else {
c38fc3bc
KK
581 /* the code is for bitreverse streams */
582 if (hdlc->do_bitreverse == 0)
583 *dst++ = bitrev8(hdlc->cbin);
584 else
585 *dst++ = hdlc->cbin;
6bd4bcd3
KK
586 hdlc->bit_shift = 0;
587 hdlc->data_bits = 0;
1da177e4
LT
588 len++;
589 dsize = 0;
590 }
591 break;
592 default:
593 break;
594 }
6bd4bcd3
KK
595 if (hdlc->do_adapt56) {
596 if (hdlc->data_bits == 7) {
1da177e4
LT
597 hdlc->cbin <<= 1;
598 hdlc->cbin++;
599 hdlc->data_bits++;
600 }
601 }
6bd4bcd3 602 if (hdlc->data_bits == 8) {
c38fc3bc
KK
603 /* the code is for bitreverse streams */
604 if (hdlc->do_bitreverse == 0)
605 *dst++ = bitrev8(hdlc->cbin);
606 else
607 *dst++ = hdlc->cbin;
1da177e4
LT
608 hdlc->data_bits = 0;
609 len++;
610 dsize--;
611 }
612 }
613 *count -= slen;
614
615 return len;
616}
1da177e4 617EXPORT_SYMBOL(isdnhdlc_encode);