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