]> CyberLeo.Net >> Repos - FreeBSD/releng/7.2.git/blob - sys/i4b/layer1/itjc/i4b_hdlc.h
Create releng/7.2 from stable/7 in preparation for 7.2-RELEASE.
[FreeBSD/releng/7.2.git] / sys / i4b / layer1 / itjc / i4b_hdlc.h
1 /*-
2  * Copyright (c) 2000 Hans Petter Selasky. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25
26 /*---------------------------------------------------------------------------
27  *
28  *      i4b_hdlc.h - software-HDLC header file
29  *      --------------------------------------
30  *
31  *      $Id: i4b_hdlc.h,v 1.5 2000/08/28 07:41:19 hm Exp $
32  *
33  * $FreeBSD$
34  *
35  *      last edit-date: [Thu Jan 11 11:31:01 2001]
36  *
37  *      Please conform "ihfc/i4b_ihfc_drv.c" (ihfc_hdlc_Bxxxx)
38  *      for correct usage! (-hp)
39  *
40  *---------------------------------------------------------------------------*/
41
42 #ifndef _I4B_HDLC_H_
43 #define _I4B_HDLC_H_
44
45 extern const u_short HDLC_FCS_TAB[256];
46 extern const u_short HDLC_BIT_TAB[256];
47
48 /*---------------------------------------------------------------------------*
49  *      HDLC_DECODE
50  *      ===========
51  *
52  *      u_char:  flag, blevel
53  *      u_short: crc, ib, tmp, tmp2, len
54  *
55  *      next: 'continue' or 'goto xxx'
56  *
57  *      cfr: complete frame
58  *      nfr: new frame
59  *           NOTE: must setup 'len' and 'dst', so that 'dst' may be written
60  *                 at most 'len' times.
61  *
62  *      rab: abort
63  *      rdd: read data (read byte is stored in 'tmp2')
64  *      rdo: overflow
65  *
66  *      d: dummy
67  *
68  *      NOTE: setting flag to '0' and len to '0' => recover from rdu
69  *      NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags
70  *      NOTE: these variables have to be 'suspended' / 'resumed' somehow:
71  *              flag, blevel, crc, ib, tmp, len
72  *      NOTE: zero is default value for all variables.
73  *      NOTE: each time 'dst' is written, 'len' is decreased by one.
74  *---------------------------------------------------------------------------*/
75
76 #define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \
77                  cfrcmd, rabcmd, rdocmd, nextcmd, d)                            \
78                                                                                 \
79         rddcmd;                                                                 \
80                                                                                 \
81         ib  += HDLC_BIT_TAB[(u_char)tmp2];                                      \
82                                                                                 \
83         if ((u_char)ib >= 5)                                                    \
84         {                                                                       \
85                 if (ib & 0x20)          /* de-stuff (msb) */                    \
86                 {                                                               \
87                         if ((u_char)tmp2 == 0x7e) goto j0##d;                   \
88                         tmp2 += tmp2 & 0x7f;                                    \
89                         blevel--;                                               \
90                                                                                 \
91                         if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */               \
92                 }                                                               \
93                                                                                 \
94                 ib &= ~0xe0;                                                    \
95                                                                                 \
96                 if ((u_char)ib == 6)    /* flag seq (lsb) */                    \
97                 {                                                               \
98                  j0##d: if (flag >= 2)                                          \
99                         {                                                       \
100                                 len += (4 - flag) & 3;  /* remove CRC bytes */  \
101                                 crc ^= 0xf0b8;                                  \
102                                 cfrcmd;                                         \
103                                 len = 0;                                        \
104                         }                                                       \
105                                                                                 \
106                         flag   = 1;                                             \
107                                                                                 \
108                         blevel = (ib >> 8) & 0xf;                               \
109                         tmp    = ((u_char)tmp2) >> blevel;                      \
110                         blevel = 8 - blevel;                                    \
111                                                                                 \
112                         ib >>= 12;                                              \
113                                                                                 \
114                         nextcmd;                                                \
115                 }                                                               \
116                 if ((u_char)ib >= 7)    /* abort (msb & lsb) */                 \
117                 {                                                               \
118                         if (flag >= 2)                                          \
119                         {                                                       \
120                                 rabcmd;                                         \
121                                 len = 0;                                        \
122                         }                                                       \
123                                                                                 \
124                         flag = 0;                                               \
125                                                                                 \
126                         ib >>= 12;                                              \
127                                                                                 \
128                         nextcmd;                                                \
129                 }                                                               \
130                 if ((u_char)ib == 5)    /* de-stuff (lsb) */                    \
131                 {                                                               \
132                         tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1;                      \
133                         blevel--;                                               \
134                 }                                                               \
135                 if (blevel > 7)         /* EO - bits */                         \
136                 {                                                               \
137                         tmp |= (u_char)tmp2 >> (8 - (blevel &= 7));             \
138                                                                                 \
139                         ib >>= 12;                                              \
140                                                                                 \
141                         nextcmd;                                                \
142                 }                                                               \
143         }                                                                       \
144                                                                                 \
145         tmp |= (u_char)tmp2 << blevel;                                          \
146                                                                                 \
147         if (!len--)                                                             \
148         {                                                                       \
149                 len++;                                                          \
150                                                                                 \
151                 if (!flag++) { flag--; goto j5##d;} /* hunt mode */             \
152                                                                                 \
153                 switch (flag)                                                   \
154                 {   case 2:             /* new frame */                         \
155                         nfrcmd;                                                 \
156                         crc = -1;                                               \
157                         if (!len--) { len++; flag++; goto j4##d; }              \
158                         goto j3##d;                                             \
159                     case 3:             /* CRC (lsb's) */                       \
160                     case 4:             /* CRC (msb's) */                       \
161                         goto j4##d;                                             \
162                     case 5:             /* RDO */                               \
163                         rdocmd;                                                 \
164                         flag = 0;                                               \
165                         break;                                                  \
166                 }                                                               \
167         }                                                                       \
168         else                                                                    \
169         {                                                                       \
170          j3##d: dst = (u_char)tmp;                                              \
171          j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \
172         }                                                                       \
173                                                                                 \
174  j5##d: ib >>= 12;                                                              \
175         tmp >>= 8;                                                              \
176
177 /*------ end of HDLC_DECODE -------------------------------------------------*/
178
179
180 /*---------------------------------------------------------------------------*
181  *      HDLC_ENCODE
182  *      ===========
183  *
184  *      u_char:  flag, src
185  *      u_short: tmp2, blevel, ib, crc, len
186  *      u_int:   tmp
187  *
188  *      gfr: This is the place where you free the last [mbuf] chain, and get
189  *           the next one. If a mbuf is available the code should setup 'len'
190  *           and 'src' so that 'src' may be read 'len' times. If no mbuf is
191  *           available leave 'len' and 'src' untouched.
192  *
193  *      nmb: If your implementation accept/use chained mbufs, this is the
194  *           place where you update 'len' and 'src' to the next mbuf of
195  *           the chain that makes up a frame. If no further mbuf is
196  *           available leave 'len' and 'src' untouched. This is not the
197  *           place where you free the mbuf. Leave the block empty if your
198  *           implementation does not accept/use chained mbufs.
199  *
200  *      wrd: write data (output = (u_char)tmp)
201  *
202  *      d: dummy
203  *
204  *      NOTE: setting flag to '-2' and len to '0' => abort bytes will be sent
205  *      NOTE: these variables have to be 'suspended' / 'resumed' somehow:
206  *              flag, blevel, crc, ib, tmp, len
207  *      NOTE: zero is default value for all variables.
208  *      NOTE: each time 'src' is read, 'len' is decreased by one.
209  *      NOTE: neither cmd's should exit through 'goto' or 'break' statements.
210  *---------------------------------------------------------------------------*/
211
212 #define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, nmbcmd, wrdcmd, d) \
213                                                                                 \
214         if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; }                   \
215                                                                                 \
216         if (!len--)                                                             \
217         {                                                                       \
218                 len++;                                                          \
219                                                                                 \
220                 switch(++flag)                                                  \
221                 { default:                      /* abort */                     \
222                         tmp  = blevel = 0;      /* zero is default */           \
223                         tmp2 = 0xff;                                            \
224                         goto j3##d;                                             \
225                   case 1:                       /* 1st time FS */               \
226                   case 2:                       /* 2nd time FS */               \
227                         tmp2 = 0x7e;                                            \
228                         goto j3##d;                                             \
229                   case 3:                                                       \
230                         gfrcmd;                 /* get new frame */             \
231                         if (!len--)                                             \
232                         {                                                       \
233                                 len++;                                          \
234                                 flag--;         /* don't proceed */             \
235                                 tmp2 = 0x7e;                                    \
236                                 goto j3##d;     /* final FS */                  \
237                         }                                                       \
238                         else                                                    \
239                         {                                                       \
240                                 crc = -1;                                       \
241                                 ib  = 0;                                        \
242                                 goto j1##d;     /* first byte */                \
243                         }                                                       \
244                   case 4:                                                       \
245                         nmbcmd;                 /* get next mbuf in chain */    \
246                         if (!len--)                                             \
247                         {                                                       \
248                                 len++;                                          \
249                                 crc ^= -1;                                      \
250                                 tmp2 = (u_char)crc;                             \
251                                 goto j2##d;     /* CRC (lsb's) */               \
252                         }                                                       \
253                         else                                                    \
254                         {                                                       \
255                                 flag--;                                         \
256                                 goto j1##d;     /* proceed with the frame */    \
257                         }                                                       \
258                   case 5:                                                       \
259                         tmp2  = (u_char)(crc >> 8);                             \
260                         flag  = 1;                                              \
261                         goto j2##d;             /* CRC (msb's) */               \
262                 }                                                               \
263         }                                                                       \
264         else                                                                    \
265         { j1##d :                                                               \
266                 tmp2 = (u_char)src;                                             \
267                 crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \
268           j2##d:                                                                \
269                                                                                 \
270                 ib >>= 12;                                                      \
271                 ib  += HDLC_BIT_TAB[(u_char)tmp2];                              \
272                                                                                 \
273                 if ((u_char)ib >= 5)    /* stuffing */                          \
274                 {                                                               \
275                         blevel &= ~0xff;                                        \
276                                                                                 \
277                         if (ib & 0xc0)          /* bit stuff (msb) */           \
278                         {                                                       \
279                                 tmp2 += tmp2 & (0xff * (ib & 0xc0));            \
280                                 ib %= 0x5000;                                   \
281                                 blevel++;                                       \
282                         }                                                       \
283                                                                                 \
284                         ib &= ~0xf0;                                            \
285                                                                                 \
286                         if ((u_char)ib >= 5)    /* bit stuff (lsb) */           \
287                         {                                                       \
288                                 tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1)   \
289                                                                 & 7);           \
290                                 blevel++;                                       \
291                                                                                 \
292                                 if ((u_char)ib >= 10)   /* bit stuff (msb) */   \
293                                 {                                               \
294                                         tmp2 += tmp2 & ~0x7ff >> ((ib -         \
295                                                         (ib >> 8) + 1) & 7);    \
296                                         blevel++;                               \
297                                 }                                               \
298                                 if (ib & 0x8000)        /* bit walk */          \
299                                 {                                               \
300                                         ib = ((u_char)ib % 5) << 12;            \
301                                 }                                               \
302                         }                                                       \
303                                                                                 \
304                         tmp    |= tmp2 << (u_char)(blevel >> 8);                \
305                         blevel += (u_char)blevel << 8;                          \
306                 }                                                               \
307                 else            /* no stuffing */                               \
308                 {                                                               \
309                   j3##d:tmp    |= tmp2 << (u_char)(blevel >> 8);                \
310                 }                                                               \
311         }                                                                       \
312                                                                                 \
313  j4##d: wrdcmd;                                                                 \
314         tmp >>= 8;                                                              \
315
316 /*------ end of HDLC_ENCODE -------------------------------------------------*/
317
318
319 #endif /* _I4B_HDLC_H_ */