ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / isdn / hisax / isdnhdlc.c
1 /*
2  * isdnhdlc.c  --  General purpose ISDN HDLC decoder.
3  *
4  *Copyright (C) 2002    Wolfgang Mües      <wolfgang@iksw-muees.de>
5  *              2001    Frode Isaksen      <fisaksen@bewan.com>
6  *              2001    Kai Germaschewski  <kai.germaschewski@gmx.de>
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License as published by
10  *      the Free Software Foundation; either version 2 of the License, or
11  *      (at your option) any later version.
12  *
13  *      This program is distributed in the hope that it will be useful,
14  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *      GNU General Public License for more details.
17  *
18  *      You should have received a copy of the GNU General Public License
19  *      along with this program; if not, write to the Free Software
20  *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21  */
22
23 #include <linux/module.h>
24 #include <linux/init.h>
25 #include "isdnhdlc.h"
26
27 /*-------------------------------------------------------------------*/
28
29 MODULE_AUTHOR("Wolfgang Mües <wolfgang@iksw-muees.de>, "
30               "Frode Isaksen <fisaksen@bewan.com>, "
31               "Kai Germaschewski <kai.germaschewski@gmx.de>");
32 MODULE_DESCRIPTION("General purpose ISDN HDLC decoder");
33 MODULE_LICENSE("GPL");
34
35 /*-------------------------------------------------------------------*/
36
37 /* bit swap table.
38  * Very handy for devices with different bit order,
39  * and neccessary for each transparent B-channel access for all
40  * devices which works with this HDLC decoder without bit reversal.
41  */
42 const unsigned char isdnhdlc_bit_rev_tab[256] = {
43         0x00,0x80,0x40,0xC0,0x20,0xA0,0x60,0xE0,0x10,0x90,0x50,0xD0,0x30,0xB0,0x70,0xF0,
44         0x08,0x88,0x48,0xC8,0x28,0xA8,0x68,0xE8,0x18,0x98,0x58,0xD8,0x38,0xB8,0x78,0xF8,
45         0x04,0x84,0x44,0xC4,0x24,0xA4,0x64,0xE4,0x14,0x94,0x54,0xD4,0x34,0xB4,0x74,0xF4,
46         0x0C,0x8C,0x4C,0xCC,0x2C,0xAC,0x6C,0xEC,0x1C,0x9C,0x5C,0xDC,0x3C,0xBC,0x7C,0xFC,
47         0x02,0x82,0x42,0xC2,0x22,0xA2,0x62,0xE2,0x12,0x92,0x52,0xD2,0x32,0xB2,0x72,0xF2,
48         0x0A,0x8A,0x4A,0xCA,0x2A,0xAA,0x6A,0xEA,0x1A,0x9A,0x5A,0xDA,0x3A,0xBA,0x7A,0xFA,
49         0x06,0x86,0x46,0xC6,0x26,0xA6,0x66,0xE6,0x16,0x96,0x56,0xD6,0x36,0xB6,0x76,0xF6,
50         0x0E,0x8E,0x4E,0xCE,0x2E,0xAE,0x6E,0xEE,0x1E,0x9E,0x5E,0xDE,0x3E,0xBE,0x7E,0xFE,
51         0x01,0x81,0x41,0xC1,0x21,0xA1,0x61,0xE1,0x11,0x91,0x51,0xD1,0x31,0xB1,0x71,0xF1,
52         0x09,0x89,0x49,0xC9,0x29,0xA9,0x69,0xE9,0x19,0x99,0x59,0xD9,0x39,0xB9,0x79,0xF9,
53         0x05,0x85,0x45,0xC5,0x25,0xA5,0x65,0xE5,0x15,0x95,0x55,0xD5,0x35,0xB5,0x75,0xF5,
54         0x0D,0x8D,0x4D,0xCD,0x2D,0xAD,0x6D,0xED,0x1D,0x9D,0x5D,0xDD,0x3D,0xBD,0x7D,0xFD,
55         0x03,0x83,0x43,0xC3,0x23,0xA3,0x63,0xE3,0x13,0x93,0x53,0xD3,0x33,0xB3,0x73,0xF3,
56         0x0B,0x8B,0x4B,0xCB,0x2B,0xAB,0x6B,0xEB,0x1B,0x9B,0x5B,0xDB,0x3B,0xBB,0x7B,0xFB,
57         0x07,0x87,0x47,0xC7,0x27,0xA7,0x67,0xE7,0x17,0x97,0x57,0xD7,0x37,0xB7,0x77,0xF7,
58         0x0F,0x8F,0x4F,0xCF,0x2F,0xAF,0x6F,0xEF,0x1F,0x9F,0x5F,0xDF,0x3F,0xBF,0x7F,0xFF
59 };
60
61 /* Table for CRC16. Internal used only. */
62 static const unsigned short int crc16_tab[] = {
63         0x0000,0x1189,0x2312,0x329b,0x4624,0x57ad,0x6536,0x74bf,
64         0x8c48,0x9dc1,0xaf5a,0xbed3,0xca6c,0xdbe5,0xe97e,0xf8f7,
65         0x1081,0x0108,0x3393,0x221a,0x56a5,0x472c,0x75b7,0x643e,
66         0x9cc9,0x8d40,0xbfdb,0xae52,0xdaed,0xcb64,0xf9ff,0xe876,
67         0x2102,0x308b,0x0210,0x1399,0x6726,0x76af,0x4434,0x55bd,
68         0xad4a,0xbcc3,0x8e58,0x9fd1,0xeb6e,0xfae7,0xc87c,0xd9f5,
69         0x3183,0x200a,0x1291,0x0318,0x77a7,0x662e,0x54b5,0x453c,
70         0xbdcb,0xac42,0x9ed9,0x8f50,0xfbef,0xea66,0xd8fd,0xc974,
71         0x4204,0x538d,0x6116,0x709f,0x0420,0x15a9,0x2732,0x36bb,
72         0xce4c,0xdfc5,0xed5e,0xfcd7,0x8868,0x99e1,0xab7a,0xbaf3,
73         0x5285,0x430c,0x7197,0x601e,0x14a1,0x0528,0x37b3,0x263a,
74         0xdecd,0xcf44,0xfddf,0xec56,0x98e9,0x8960,0xbbfb,0xaa72,
75         0x6306,0x728f,0x4014,0x519d,0x2522,0x34ab,0x0630,0x17b9,
76         0xef4e,0xfec7,0xcc5c,0xddd5,0xa96a,0xb8e3,0x8a78,0x9bf1,
77         0x7387,0x620e,0x5095,0x411c,0x35a3,0x242a,0x16b1,0x0738,
78         0xffcf,0xee46,0xdcdd,0xcd54,0xb9eb,0xa862,0x9af9,0x8b70,
79         0x8408,0x9581,0xa71a,0xb693,0xc22c,0xd3a5,0xe13e,0xf0b7,
80         0x0840,0x19c9,0x2b52,0x3adb,0x4e64,0x5fed,0x6d76,0x7cff,
81         0x9489,0x8500,0xb79b,0xa612,0xd2ad,0xc324,0xf1bf,0xe036,
82         0x18c1,0x0948,0x3bd3,0x2a5a,0x5ee5,0x4f6c,0x7df7,0x6c7e,
83         0xa50a,0xb483,0x8618,0x9791,0xe32e,0xf2a7,0xc03c,0xd1b5,
84         0x2942,0x38cb,0x0a50,0x1bd9,0x6f66,0x7eef,0x4c74,0x5dfd,
85         0xb58b,0xa402,0x9699,0x8710,0xf3af,0xe226,0xd0bd,0xc134,
86         0x39c3,0x284a,0x1ad1,0x0b58,0x7fe7,0x6e6e,0x5cf5,0x4d7c,
87         0xc60c,0xd785,0xe51e,0xf497,0x8028,0x91a1,0xa33a,0xb2b3,
88         0x4a44,0x5bcd,0x6956,0x78df,0x0c60,0x1de9,0x2f72,0x3efb,
89         0xd68d,0xc704,0xf59f,0xe416,0x90a9,0x8120,0xb3bb,0xa232,
90         0x5ac5,0x4b4c,0x79d7,0x685e,0x1ce1,0x0d68,0x3ff3,0x2e7a,
91         0xe70e,0xf687,0xc41c,0xd595,0xa12a,0xb0a3,0x8238,0x93b1,
92         0x6b46,0x7acf,0x4854,0x59dd,0x2d62,0x3ceb,0x0e70,0x1ff9,
93         0xf78f,0xe606,0xd49d,0xc514,0xb1ab,0xa022,0x92b9,0x8330,
94         0x7bc7,0x6a4e,0x58d5,0x495c,0x3de3,0x2c6a,0x1ef1,0x0f78
95 };
96
97
98 enum {
99         HDLC_FAST_IDLE,HDLC_GET_FLAG_B0,HDLC_GETFLAG_B1A6,HDLC_GETFLAG_B7,
100         HDLC_GET_DATA,HDLC_FAST_FLAG
101 };
102
103 enum {
104         HDLC_SEND_DATA,HDLC_SEND_CRC1,HDLC_SEND_FAST_FLAG,
105         HDLC_SEND_FIRST_FLAG,HDLC_SEND_CRC2,HDLC_SEND_CLOSING_FLAG,
106         HDLC_SEND_IDLE1,HDLC_SEND_FAST_IDLE,HDLC_SENDFLAG_B0,
107         HDLC_SENDFLAG_B1A6,HDLC_SENDFLAG_B7,STOPPED
108 };
109
110 void isdnhdlc_rcv_init (struct isdnhdlc_vars *hdlc, int do_adapt56)
111 {
112         hdlc->bit_shift = 0;
113         hdlc->hdlc_bits1 = 0;
114         hdlc->data_bits = 0;
115         hdlc->ffbit_shift = 0;
116         hdlc->data_received = 0;
117         hdlc->state = HDLC_GET_DATA;
118         hdlc->do_adapt56 = do_adapt56;
119         hdlc->dchannel = 0;
120         hdlc->crc = 0;
121         hdlc->cbin = 0;
122         hdlc->shift_reg = 0;
123         hdlc->ffvalue = 0;
124         hdlc->dstpos = 0;
125 }
126
127 void isdnhdlc_out_init (struct isdnhdlc_vars *hdlc, int is_d_channel, int do_adapt56)
128 {
129         hdlc->bit_shift = 0;
130         hdlc->hdlc_bits1 = 0;
131         hdlc->data_bits = 0;
132         hdlc->ffbit_shift = 0;
133         hdlc->data_received = 0;
134         hdlc->do_closing = 0;
135         hdlc->ffvalue = 0;
136         if (is_d_channel) {
137                 hdlc->dchannel = 1;
138                 hdlc->state = HDLC_SEND_FIRST_FLAG;
139         } else {
140                 hdlc->dchannel = 0;
141                 hdlc->state = HDLC_SEND_FAST_FLAG;
142                 hdlc->ffvalue = 0x7e;
143         }
144         hdlc->cbin = 0x7e;
145         hdlc->bit_shift = 0;
146         if(do_adapt56){
147                 hdlc->do_adapt56 = 1;
148                 hdlc->data_bits = 0;
149                 hdlc->state = HDLC_SENDFLAG_B0;
150         } else {
151                 hdlc->do_adapt56 = 0;
152                 hdlc->data_bits = 8;
153         }
154         hdlc->shift_reg = 0;
155 }
156
157 /*
158   isdnhdlc_decode - decodes HDLC frames from a transparent bit stream.
159
160   The source buffer is scanned for valid HDLC frames looking for
161   flags (01111110) to indicate the start of a frame. If the start of
162   the frame is found, the bit stuffing is removed (0 after 5 1's).
163   When a new flag is found, the complete frame has been received
164   and the CRC is checked.
165   If a valid frame is found, the function returns the frame length
166   excluding the CRC with the bit HDLC_END_OF_FRAME set.
167   If the beginning of a valid frame is found, the function returns
168   the length.
169   If a framing error is found (too many 1s and not a flag) the function
170   returns the length with the bit HDLC_FRAMING_ERROR set.
171   If a CRC error is found the function returns the length with the
172   bit HDLC_CRC_ERROR set.
173   If the frame length exceeds the destination buffer size, the function
174   returns the length with the bit HDLC_LENGTH_ERROR set.
175
176   src - source buffer
177   slen - source buffer length
178   count - number of bytes removed (decoded) from the source buffer
179   dst _ destination buffer
180   dsize - destination buffer size
181   returns - number of decoded bytes in the destination buffer and status
182   flag.
183  */
184 int isdnhdlc_decode (struct isdnhdlc_vars *hdlc, const unsigned char *src,
185                      int slen, int *count, unsigned char *dst, int dsize)
186 {
187         int status=0;
188
189         static const unsigned char fast_flag[]={
190                 0x00,0x00,0x00,0x20,0x30,0x38,0x3c,0x3e,0x3f
191         };
192
193         static const unsigned char fast_flag_value[]={
194                 0x00,0x7e,0xfc,0xf9,0xf3,0xe7,0xcf,0x9f,0x3f
195         };
196
197         static const unsigned char fast_abort[]={
198                 0x00,0x00,0x80,0xc0,0xe0,0xf0,0xf8,0xfc,0xfe,0xff
199         };
200
201         *count = slen;
202
203         while(slen > 0){
204                 if(hdlc->bit_shift==0){
205                         hdlc->cbin = *src++;
206                         slen--;
207                         hdlc->bit_shift = 8;
208                         if(hdlc->do_adapt56){
209                                 hdlc->bit_shift --;
210                         }
211                 }
212
213                 switch(hdlc->state){
214                 case STOPPED:
215                         return 0;
216                 case HDLC_FAST_IDLE:
217                         if(hdlc->cbin == 0xff){
218                                 hdlc->bit_shift = 0;
219                                 break;
220                         }
221                         hdlc->state = HDLC_GET_FLAG_B0;
222                         hdlc->hdlc_bits1 = 0;
223                         hdlc->bit_shift = 8;
224                         break;
225                 case HDLC_GET_FLAG_B0:
226                         if(!(hdlc->cbin & 0x80)) {
227                                 hdlc->state = HDLC_GETFLAG_B1A6;
228                                 hdlc->hdlc_bits1 = 0;
229                         } else {
230                                 if(!hdlc->do_adapt56){
231                                         if(++hdlc->hdlc_bits1 >=8 ) if(hdlc->bit_shift==1)
232                                                 hdlc->state = HDLC_FAST_IDLE;
233                                 }
234                         }
235                         hdlc->cbin<<=1;
236                         hdlc->bit_shift --;
237                         break;
238                 case HDLC_GETFLAG_B1A6:
239                         if(hdlc->cbin & 0x80){
240                                 hdlc->hdlc_bits1++;
241                                 if(hdlc->hdlc_bits1==6){
242                                         hdlc->state = HDLC_GETFLAG_B7;
243                                 }
244                         } else {
245                                 hdlc->hdlc_bits1 = 0;
246                         }
247                         hdlc->cbin<<=1;
248                         hdlc->bit_shift --;
249                         break;
250                 case HDLC_GETFLAG_B7:
251                         if(hdlc->cbin & 0x80) {
252                                 hdlc->state = HDLC_GET_FLAG_B0;
253                         } else {
254                                 hdlc->state = HDLC_GET_DATA;
255                                 hdlc->crc = 0xffff;
256                                 hdlc->shift_reg = 0;
257                                 hdlc->hdlc_bits1 = 0;
258                                 hdlc->data_bits = 0;
259                                 hdlc->data_received = 0;
260                         }
261                         hdlc->cbin<<=1;
262                         hdlc->bit_shift --;
263                         break;
264                 case HDLC_GET_DATA:
265                         if(hdlc->cbin & 0x80){
266                                 hdlc->hdlc_bits1++;
267                                 switch(hdlc->hdlc_bits1){
268                                 case 6:
269                                         break;
270                                 case 7:
271                                         if(hdlc->data_received) {
272                                                 // bad frame
273                                                 status = -HDLC_FRAMING_ERROR;
274                                         }
275                                         if(!hdlc->do_adapt56){
276                                                 if(hdlc->cbin==fast_abort[hdlc->bit_shift+1]){
277                                                         hdlc->state = HDLC_FAST_IDLE;
278                                                         hdlc->bit_shift=1;
279                                                         break;
280                                                 }
281                                         } else {
282                                                 hdlc->state = HDLC_GET_FLAG_B0;
283                                         }
284                                         break;
285                                 default:
286                                         hdlc->shift_reg>>=1;
287                                         hdlc->shift_reg |= 0x80;
288                                         hdlc->data_bits++;
289                                         break;
290                                 }
291                         } else {
292                                 switch(hdlc->hdlc_bits1){
293                                 case 5:
294                                         break;
295                                 case 6:
296                                         if(hdlc->data_received){
297                                                 if (hdlc->dstpos < 2) {
298                                                         status = -HDLC_FRAMING_ERROR;
299                                                 } else if (hdlc->crc != 0xf0b8){
300                                                         // crc error
301                                                         status = -HDLC_CRC_ERROR;
302                                                 } else {
303                                                         // remove CRC
304                                                         hdlc->dstpos -= 2;
305                                                         // good frame
306                                                         status = hdlc->dstpos;
307                                                 }
308                                         }
309                                         hdlc->crc = 0xffff;
310                                         hdlc->shift_reg = 0;
311                                         hdlc->data_bits = 0;
312                                         if(!hdlc->do_adapt56){
313                                                 if(hdlc->cbin==fast_flag[hdlc->bit_shift]){
314                                                         hdlc->ffvalue = fast_flag_value[hdlc->bit_shift];
315                                                         hdlc->state = HDLC_FAST_FLAG;
316                                                         hdlc->ffbit_shift = hdlc->bit_shift;
317                                                         hdlc->bit_shift = 1;
318                                                 } else {
319                                                         hdlc->state = HDLC_GET_DATA;
320                                                         hdlc->data_received = 0;
321                                                 }
322                                         } else {
323                                                 hdlc->state = HDLC_GET_DATA;
324                                                 hdlc->data_received = 0;
325                                         }
326                                         break;
327                                 default:
328                                         hdlc->shift_reg>>=1;
329                                         hdlc->data_bits++;
330                                         break;
331                                 }
332                                 hdlc->hdlc_bits1 = 0;
333                         }
334                         if (status) {
335                                 hdlc->dstpos = 0;
336                                 *count -= slen;
337                                 hdlc->cbin <<= 1;
338                                 hdlc->bit_shift--;
339                                 return status;
340                         }
341                         if(hdlc->data_bits==8){
342                                 unsigned cval;
343
344                                 hdlc->data_bits = 0;
345                                 hdlc->data_received = 1;
346                                 cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
347                                 hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
348                                 // good byte received
349                                 if (dsize--) {
350                                         dst[hdlc->dstpos++] = hdlc->shift_reg;
351                                 } else {
352                                         // frame too long
353                                         status = -HDLC_LENGTH_ERROR;
354                                         hdlc->dstpos = 0;
355                                 }
356                         }
357                         hdlc->cbin <<= 1;
358                         hdlc->bit_shift--;
359                         break;
360                 case HDLC_FAST_FLAG:
361                         if(hdlc->cbin==hdlc->ffvalue){
362                                 hdlc->bit_shift = 0;
363                                 break;
364                         } else {
365                                 if(hdlc->cbin == 0xff){
366                                         hdlc->state = HDLC_FAST_IDLE;
367                                         hdlc->bit_shift=0;
368                                 } else if(hdlc->ffbit_shift==8){
369                                         hdlc->state = HDLC_GETFLAG_B7;
370                                         break;
371                                 } else {
372                                         hdlc->shift_reg = fast_abort[hdlc->ffbit_shift-1];
373                                         hdlc->hdlc_bits1 = hdlc->ffbit_shift-2;
374                                         if(hdlc->hdlc_bits1<0)hdlc->hdlc_bits1 = 0;
375                                         hdlc->data_bits = hdlc->ffbit_shift-1;
376                                         hdlc->state = HDLC_GET_DATA;
377                                         hdlc->data_received = 0;
378                                 }
379                         }
380                         break;
381                 default:
382                         break;
383                 }
384         }
385         *count -= slen;
386         return 0;
387 }
388
389 /*
390   isdnhdlc_encode - encodes HDLC frames to a transparent bit stream.
391
392   The bit stream starts with a beginning flag (01111110). After
393   that each byte is added to the bit stream with bit stuffing added
394   (0 after 5 1's).
395   When the last byte has been removed from the source buffer, the
396   CRC (2 bytes is added) and the frame terminates with the ending flag.
397   For the dchannel, the idle character (all 1's) is also added at the end.
398   If this function is called with empty source buffer (slen=0), flags or
399   idle character will be generated.
400
401   src - source buffer
402   slen - source buffer length
403   count - number of bytes removed (encoded) from source buffer
404   dst _ destination buffer
405   dsize - destination buffer size
406   returns - number of encoded bytes in the destination buffer
407 */
408 int isdnhdlc_encode(struct isdnhdlc_vars *hdlc, const unsigned char *src,
409                 unsigned short slen, int *count,
410                 unsigned char *dst, int dsize)
411 {
412         static const unsigned char xfast_flag_value[] = {
413                 0x7e,0x3f,0x9f,0xcf,0xe7,0xf3,0xf9,0xfc,0x7e
414         };
415
416         int len = 0;
417
418         *count = slen;
419
420         while (dsize > 0) {
421                 if(hdlc->bit_shift==0){
422                         if(slen && !hdlc->do_closing){
423                                 hdlc->shift_reg = *src++;
424                                 slen--;
425                                 if (slen == 0)
426                                         hdlc->do_closing = 1;  /* closing sequence, CRC + flag(s) */
427                                 hdlc->bit_shift = 8;
428                         } else {
429                                 if(hdlc->state == HDLC_SEND_DATA){
430                                         if(hdlc->data_received){
431                                                 hdlc->state = HDLC_SEND_CRC1;
432                                                 hdlc->crc ^= 0xffff;
433                                                 hdlc->bit_shift = 8;
434                                                 hdlc->shift_reg = hdlc->crc & 0xff;
435                                         } else if(!hdlc->do_adapt56){
436                                                 hdlc->state = HDLC_SEND_FAST_FLAG;
437                                         } else {
438                                                 hdlc->state = HDLC_SENDFLAG_B0;
439                                         }
440                                 }
441
442                         }
443                 }
444
445                 switch(hdlc->state){
446                 case STOPPED:
447                         while (dsize--)
448                                 *dst++ = 0xff;
449
450                         return dsize;
451                 case HDLC_SEND_FAST_FLAG:
452                         hdlc->do_closing = 0;
453                         if(slen == 0){
454                                 *dst++ = hdlc->ffvalue;
455                                 len++;
456                                 dsize--;
457                                 break;
458                         }
459                         if(hdlc->bit_shift==8){
460                                 hdlc->cbin = hdlc->ffvalue>>(8-hdlc->data_bits);
461                                 hdlc->state = HDLC_SEND_DATA;
462                                 hdlc->crc = 0xffff;
463                                 hdlc->hdlc_bits1 = 0;
464                                 hdlc->data_received = 1;
465                         }
466                         break;
467                 case HDLC_SENDFLAG_B0:
468                         hdlc->do_closing = 0;
469                         hdlc->cbin <<= 1;
470                         hdlc->data_bits++;
471                         hdlc->hdlc_bits1 = 0;
472                         hdlc->state = HDLC_SENDFLAG_B1A6;
473                         break;
474                 case HDLC_SENDFLAG_B1A6:
475                         hdlc->cbin <<= 1;
476                         hdlc->data_bits++;
477                         hdlc->cbin++;
478                         if(++hdlc->hdlc_bits1 == 6)
479                                 hdlc->state = HDLC_SENDFLAG_B7;
480                         break;
481                 case HDLC_SENDFLAG_B7:
482                         hdlc->cbin <<= 1;
483                         hdlc->data_bits++;
484                         if(slen == 0){
485                                 hdlc->state = HDLC_SENDFLAG_B0;
486                                 break;
487                         }
488                         if(hdlc->bit_shift==8){
489                                 hdlc->state = HDLC_SEND_DATA;
490                                 hdlc->crc = 0xffff;
491                                 hdlc->hdlc_bits1 = 0;
492                                 hdlc->data_received = 1;
493                         }
494                         break;
495                 case HDLC_SEND_FIRST_FLAG:
496                         hdlc->data_received = 1;
497                         if(hdlc->data_bits==8){
498                                 hdlc->state = HDLC_SEND_DATA;
499                                 hdlc->crc = 0xffff;
500                                 hdlc->hdlc_bits1 = 0;
501                                 break;
502                         }
503                         hdlc->cbin <<= 1;
504                         hdlc->data_bits++;
505                         if(hdlc->shift_reg & 0x01)
506                                 hdlc->cbin++;
507                         hdlc->shift_reg >>= 1;
508                         hdlc->bit_shift--;
509                         if(hdlc->bit_shift==0){
510                                 hdlc->state = HDLC_SEND_DATA;
511                                 hdlc->crc = 0xffff;
512                                 hdlc->hdlc_bits1 = 0;
513                         }
514                         break;
515                 case HDLC_SEND_DATA:
516                         hdlc->cbin <<= 1;
517                         hdlc->data_bits++;
518                         if(hdlc->hdlc_bits1 == 5){
519                                 hdlc->hdlc_bits1 = 0;
520                                 break;
521                         }
522                         if(hdlc->bit_shift==8){
523                                 unsigned cval;
524
525                                 cval = (hdlc->crc^hdlc->shift_reg) & 0xff;
526                                 hdlc->crc = (hdlc->crc>>8)^crc16_tab[cval];
527                         }
528                         if(hdlc->shift_reg & 0x01){
529                                 hdlc->hdlc_bits1++;
530                                 hdlc->cbin++;
531                                 hdlc->shift_reg >>= 1;
532                                 hdlc->bit_shift--;
533                         } else {
534                                 hdlc->hdlc_bits1 = 0;
535                                 hdlc->shift_reg >>= 1;
536                                 hdlc->bit_shift--;
537                         }
538                         break;
539                 case HDLC_SEND_CRC1:
540                         hdlc->cbin <<= 1;
541                         hdlc->data_bits++;
542                         if(hdlc->hdlc_bits1 == 5){
543                                 hdlc->hdlc_bits1 = 0;
544                                 break;
545                         }
546                         if(hdlc->shift_reg & 0x01){
547                                 hdlc->hdlc_bits1++;
548                                 hdlc->cbin++;
549                                 hdlc->shift_reg >>= 1;
550                                 hdlc->bit_shift--;
551                         } else {
552                                 hdlc->hdlc_bits1 = 0;
553                                 hdlc->shift_reg >>= 1;
554                                 hdlc->bit_shift--;
555                         }
556                         if(hdlc->bit_shift==0){
557                                 hdlc->shift_reg = (hdlc->crc >> 8);
558                                 hdlc->state = HDLC_SEND_CRC2;
559                                 hdlc->bit_shift = 8;
560                         }
561                         break;
562                 case HDLC_SEND_CRC2:
563                         hdlc->cbin <<= 1;
564                         hdlc->data_bits++;
565                         if(hdlc->hdlc_bits1 == 5){
566                                 hdlc->hdlc_bits1 = 0;
567                                 break;
568                         }
569                         if(hdlc->shift_reg & 0x01){
570                                 hdlc->hdlc_bits1++;
571                                 hdlc->cbin++;
572                                 hdlc->shift_reg >>= 1;
573                                 hdlc->bit_shift--;
574                         } else {
575                                 hdlc->hdlc_bits1 = 0;
576                                 hdlc->shift_reg >>= 1;
577                                 hdlc->bit_shift--;
578                         }
579                         if(hdlc->bit_shift==0){
580                                 hdlc->shift_reg = 0x7e;
581                                 hdlc->state = HDLC_SEND_CLOSING_FLAG;
582                                 hdlc->bit_shift = 8;
583                         }
584                         break;
585                 case HDLC_SEND_CLOSING_FLAG:
586                         hdlc->cbin <<= 1;
587                         hdlc->data_bits++;
588                         if(hdlc->hdlc_bits1 == 5){
589                                 hdlc->hdlc_bits1 = 0;
590                                 break;
591                         }
592                         if(hdlc->shift_reg & 0x01){
593                                 hdlc->cbin++;
594                         }
595                         hdlc->shift_reg >>= 1;
596                         hdlc->bit_shift--;
597                         if(hdlc->bit_shift==0){
598                                 hdlc->ffvalue = xfast_flag_value[hdlc->data_bits];
599                                 if(hdlc->dchannel){
600                                         hdlc->ffvalue = 0x7e;
601                                         hdlc->state = HDLC_SEND_IDLE1;
602                                         hdlc->bit_shift = 8-hdlc->data_bits;
603                                         if(hdlc->bit_shift==0)
604                                                 hdlc->state = HDLC_SEND_FAST_IDLE;
605                                 } else {
606                                         if(!hdlc->do_adapt56){
607                                                 hdlc->state = HDLC_SEND_FAST_FLAG;
608                                                 hdlc->data_received = 0;
609                                         } else {
610                                                 hdlc->state = HDLC_SENDFLAG_B0;
611                                                 hdlc->data_received = 0;
612                                         }
613                                         // Finished with this frame, send flags
614                                         if (dsize > 1) dsize = 1;
615                                 }
616                         }
617                         break;
618                 case HDLC_SEND_IDLE1:
619                         hdlc->do_closing = 0;
620                         hdlc->cbin <<= 1;
621                         hdlc->cbin++;
622                         hdlc->data_bits++;
623                         hdlc->bit_shift--;
624                         if(hdlc->bit_shift==0){
625                                 hdlc->state = HDLC_SEND_FAST_IDLE;
626                                 hdlc->bit_shift = 0;
627                         }
628                         break;
629                 case HDLC_SEND_FAST_IDLE:
630                         hdlc->do_closing = 0;
631                         hdlc->cbin = 0xff;
632                         hdlc->data_bits = 8;
633                         if(hdlc->bit_shift == 8){
634                                 hdlc->cbin = 0x7e;
635                                 hdlc->state = HDLC_SEND_FIRST_FLAG;
636                         } else {
637                                 *dst++ = hdlc->cbin;
638                                 hdlc->bit_shift = hdlc->data_bits = 0;
639                                 len++;
640                                 dsize = 0;
641                         }
642                         break;
643                 default:
644                         break;
645                 }
646                 if(hdlc->do_adapt56){
647                         if(hdlc->data_bits==7){
648                                 hdlc->cbin <<= 1;
649                                 hdlc->cbin++;
650                                 hdlc->data_bits++;
651                         }
652                 }
653                 if(hdlc->data_bits==8){
654                         *dst++ = hdlc->cbin;
655                         hdlc->data_bits = 0;
656                         len++;
657                         dsize--;
658                 }
659         }
660         *count -= slen;
661
662         return len;
663 }
664
665 EXPORT_SYMBOL(isdnhdlc_bit_rev_tab);
666 EXPORT_SYMBOL(isdnhdlc_rcv_init);
667 EXPORT_SYMBOL(isdnhdlc_decode);
668 EXPORT_SYMBOL(isdnhdlc_out_init);
669 EXPORT_SYMBOL(isdnhdlc_encode);