binutils/ld: Don't add /usr/lib to the library search path twice.
[dragonfly.git] / sys / net / 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  *      i4b_hdlc.h - software-HDLC header file
28  *      --------------------------------------
29  *
30  *      $Id: i4b_hdlc.h,v 1.5 2000/08/28 07:41:19 hm Exp $
31  *
32  * $FreeBSD: src/sys/i4b/layer1/itjc/i4b_hdlc.h,v 1.1.2.1 2001/08/10 14:08:39 obrien Exp $
33  * $DragonFly: src/sys/net/i4b/layer1/itjc/i4b_hdlc.h,v 1.2 2003/06/17 04:28:40 dillon Exp $
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 /*---------------------------------------------------------------------------*
46  *      HDLC CRC table
47  *
48  * Usage:
49  *      crc = (HDLC_FCS_TAB[(u_char)(crc ^ byte of data)] ^ (u_char)(crc >> 8));
50  *
51  *      For more information see RFC 1662 (p. 10)
52  *---------------------------------------------------------------------------*/
53 static const u_short HDLC_FCS_TAB[256] = { 0x0000, 
54         0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf, 0x8c48, 
55         0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7, 0x1081, 
56         0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e, 0x9cc9, 
57         0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876, 0x2102, 
58         0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd, 0xad4a, 
59         0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5, 0x3183, 
60         0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c, 0xbdcb, 
61         0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974, 0x4204, 
62         0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb, 0xce4c, 
63         0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3, 0x5285, 
64         0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a, 0xdecd, 
65         0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72, 0x6306, 
66         0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9, 0xef4e, 
67         0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1, 0x7387, 
68         0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738, 0xffcf, 
69         0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70, 0x8408, 
70         0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7, 0x0840, 
71         0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff, 0x9489, 
72         0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036, 0x18c1, 
73         0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e, 0xa50a, 
74         0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5, 0x2942, 
75         0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd, 0xb58b, 
76         0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134, 0x39c3, 
77         0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c, 0xc60c, 
78         0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3, 0x4a44, 
79         0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb, 0xd68d, 
80         0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232, 0x5ac5, 
81         0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a, 0xe70e, 
82         0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1, 0x6b46, 
83         0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9, 0xf78f, 
84         0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330, 0x7bc7, 
85         0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78 
86 };
87
88 /*---------------------------------------------------------------------------*
89  *      HDLC bit table
90  *      ==============  
91  *
92  *      bits[0..3]:     A value which tells how many set bits there are at the
93  *                      beginning of the byte.
94  *
95  *      bits[4..7]:     Special bytes like 0x7e, 0x7d, 0xfd ... are flagged here
96  *                      NOTE: Special bytes also means 'abort' bytes (7 or more
97  *                            continuous set bits)
98  *
99  *      bits[8..11]:    A copy of bits[0..3] but only incremented by one.
100  *                      NOTE: 0x7e has value '8' instead of '0'. Internal reasons.
101  *
102  *      bits[12..15]:   A value which tells how many set bits there are at the
103  *                      end of the byte.
104  *                      NOTE: 0xff has both '8' incoming and '8' outgoing bits.
105  *
106  *---------------------------------------------------------------------------*/
107 static const u_short HDLC_BIT_TAB[256] = { 0x0100, 
108         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
109         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, 
110         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
111         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100, 
112         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
113         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, 
114         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
115         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0160, 0x0706, 0x0100, 
116         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
117         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, 
118         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
119         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0605, 0x0100, 
120         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
121         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0504, 0x0100, 
122         0x0201, 0x0100, 0x0302, 0x0100, 0x0201, 0x0100, 0x0403, 0x0100, 
123         0x0201, 0x0100, 0x0302, 0x01a0, 0x02a1, 0x0860, 0x0807, 0x1100, 
124         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, 
125         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100, 
126         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, 
127         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1605, 0x1100, 
128         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, 
129         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1504, 0x1100, 
130         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1100, 0x1403, 0x1100, 
131         0x1201, 0x1100, 0x1302, 0x1100, 0x1201, 0x1160, 0x1706, 0x2100, 
132         0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100, 
133         0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2504, 0x2100, 
134         0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2403, 0x2100, 
135         0x2201, 0x2100, 0x2302, 0x2100, 0x2201, 0x2100, 0x2605, 0x3100, 
136         0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3403, 0x3100, 
137         0x3201, 0x3100, 0x3302, 0x3100, 0x3201, 0x3100, 0x3504, 0x4100, 
138         0x4201, 0x4100, 0x4302, 0x4100, 0x4201, 0x4100, 0x4403, 0x5100, 
139         0x5201, 0x5100, 0x5302, 0x6180, 0x6281, 0x7150, 0x8908 
140 };
141
142 /*---------------------------------------------------------------------------*
143  *      HDLC_DECODE
144  *      ===========
145  *
146  *      u_char:  flag, blevel
147  *      u_short: crc, ib, tmp, tmp2, len
148  *
149  *      next: 'continue' or 'goto xxx'
150  *
151  *      cfr: complete frame
152  *      nfr: new frame
153  *           NOTE: must setup 'len' and 'dst', so that 'dst' may be written
154  *                 at most 'len' times.
155  *
156  *      rab: abort
157  *      rdd: read data (read byte is stored in 'tmp2')
158  *      rdo: overflow
159  *
160  *      d: dummy
161  *
162  *      NOTE: setting flag to '0' and len to '0' => recover from rdu
163  *      NOTE: bits[8 .. ] of tmp2 may be used to store custom data/flags
164  *      NOTE: these variables have to be 'suspended' / 'resumed' somehow:
165  *              flag, blevel, crc, ib, tmp, len
166  *      NOTE: zero is default value for all variables.
167  *      NOTE: each time 'dst' is written, 'len' is decreased by one.
168  *---------------------------------------------------------------------------*/
169
170 #define HDLC_DECODE(dst, len, tmp, tmp2, blevel, ib, crc, flag, rddcmd, nfrcmd, \
171                  cfrcmd, rabcmd, rdocmd, nextcmd, d)                            \
172                                                                                 \
173         rddcmd;                                                                 \
174                                                                                 \
175         ib  += HDLC_BIT_TAB[(u_char)tmp2];                                      \
176                                                                                 \
177         if ((u_char)ib >= 5)                                                    \
178         {                                                                       \
179                 if (ib & 0x20)          /* de-stuff (msb) */                    \
180                 {                                                               \
181                         if ((u_char)tmp2 == 0x7e) goto j0##d;                   \
182                         tmp2 += tmp2 & 0x7f;                                    \
183                         blevel--;                                               \
184                                                                                 \
185                         if ((ib += 0x100) & 0xc) tmp2 |= 1; /* */               \
186                 }                                                               \
187                                                                                 \
188                 ib &= ~0xe0;                                                    \
189                                                                                 \
190                 if ((u_char)ib == 6)    /* flag seq (lsb) */                    \
191                 {                                                               \
192                  j0##d: if (flag >= 2)                                          \
193                         {                                                       \
194                                 len += (4 - flag) & 3;  /* remove CRC bytes */  \
195                                 crc ^= 0xf0b8;                                  \
196                                 cfrcmd;                                         \
197                                 len = 0;                                        \
198                         }                                                       \
199                                                                                 \
200                         flag   = 1;                                             \
201                                                                                 \
202                         blevel = (ib >> 8) & 0xf;                               \
203                         tmp    = ((u_char)tmp2) >> blevel;                      \
204                         blevel = 8 - blevel;                                    \
205                                                                                 \
206                         ib >>= 12;                                              \
207                                                                                 \
208                         nextcmd;                                                \
209                 }                                                               \
210                 if ((u_char)ib >= 7)    /* abort (msb & lsb) */                 \
211                 {                                                               \
212                         if (flag >= 2)                                          \
213                         {                                                       \
214                                 rabcmd;                                         \
215                                 len = 0;                                        \
216                         }                                                       \
217                                                                                 \
218                         flag = 0;                                               \
219                                                                                 \
220                         ib >>= 12;                                              \
221                                                                                 \
222                         nextcmd;                                                \
223                 }                                                               \
224                 if ((u_char)ib == 5)    /* de-stuff (lsb) */                    \
225                 {                                                               \
226                         tmp2 = (tmp2 | (tmp2 + 1)) & ~0x1;                      \
227                         blevel--;                                               \
228                 }                                                               \
229                 if (blevel > 7)         /* EO - bits */                         \
230                 {                                                               \
231                         tmp |= (u_char)tmp2 >> (8 - (blevel &= 7));             \
232                                                                                 \
233                         ib >>= 12;                                              \
234                                                                                 \
235                         nextcmd;                                                \
236                 }                                                               \
237         }                                                                       \
238                                                                                 \
239         tmp |= (u_char)tmp2 << blevel;                                          \
240                                                                                 \
241         if (!len--)                                                             \
242         {                                                                       \
243                 len++;                                                          \
244                                                                                 \
245                 if (!flag++) { flag--; goto j5##d;} /* hunt mode */             \
246                                                                                 \
247                 switch (flag)                                                   \
248                 {   case 2:             /* new frame */                         \
249                         nfrcmd;                                                 \
250                         crc = -1;                                               \
251                         if (!len--) { len++; flag++; goto j4##d; }              \
252                         goto j3##d;                                             \
253                     case 3:             /* CRC (lsb's) */                       \
254                     case 4:             /* CRC (msb's) */                       \
255                         goto j4##d;                                             \
256                     case 5:             /* RDO */                               \
257                         rdocmd;                                                 \
258                         flag = 0;                                               \
259                         break;                                                  \
260                 }                                                               \
261         }                                                                       \
262         else                                                                    \
263         {                                                                       \
264          j3##d: dst = (u_char)tmp;                                              \
265          j4##d: crc = (HDLC_FCS_TAB[(u_char)(tmp ^ crc)] ^ (u_char)(crc >> 8)); \
266         }                                                                       \
267                                                                                 \
268  j5##d: ib >>= 12;                                                              \
269         tmp >>= 8;                                                              \
270
271 /*------ end of HDLC_DECODE -------------------------------------------------*/
272
273
274 /*---------------------------------------------------------------------------*
275  *      HDLC_ENCODE
276  *      ===========
277  *
278  *      u_char:  flag, src
279  *      u_short: tmp2, blevel, ib, crc, len
280  *      u_int:   tmp
281  *
282  *      gfr: This is the place where you free the last [mbuf] chain, and get
283  *           the next one. If a mbuf is available the code should setup 'len'
284  *           and 'src' so that 'src' may be read 'len' times. If no mbuf is
285  *           available leave 'len' and 'src' untouched.
286  *
287  *      nmb: If your implementation accept/use chained mbufs, this is the
288  *           place where you update 'len' and 'src' to the next mbuf of
289  *           the chain that makes up a frame. If no further mbuf is
290  *           available leave 'len' and 'src' untouched. This is not the
291  *           place where you free the mbuf. Leave the block empty if your
292  *           implementation does not accept/use chained mbufs.
293  *
294  *      wrd: write data (output = (u_char)tmp)
295  *
296  *      d: dummy
297  *
298  *      NOTE: setting flag to '-2' and len to '0' => abort bytes will be sent
299  *      NOTE: these variables have to be 'suspended' / 'resumed' somehow:
300  *              flag, blevel, crc, ib, tmp, len
301  *      NOTE: zero is default value for all variables.
302  *      NOTE: each time 'src' is read, 'len' is decreased by one.
303  *      NOTE: neither cmd's should exit through 'goto' or 'break' statements.
304  *---------------------------------------------------------------------------*/
305
306 #define HDLC_ENCODE(src, len, tmp, tmp2, blevel, ib, crc, flag, gfrcmd, nmbcmd, wrdcmd, d) \
307                                                                                 \
308         if (blevel >= 0x800) { blevel -= 0x800; goto j4##d; }                   \
309                                                                                 \
310         if (!len--)                                                             \
311         {                                                                       \
312                 len++;                                                          \
313                                                                                 \
314                 switch(++flag)                                                  \
315                 { default:                      /* abort */                     \
316                         tmp  = blevel = 0;      /* zero is default */           \
317                         tmp2 = 0xff;                                            \
318                         goto j3##d;                                             \
319                   case 1:                       /* 1st time FS */               \
320                   case 2:                       /* 2nd time FS */               \
321                         tmp2 = 0x7e;                                            \
322                         goto j3##d;                                             \
323                   case 3:                                                       \
324                         gfrcmd;                 /* get new frame */             \
325                         if (!len--)                                             \
326                         {                                                       \
327                                 len++;                                          \
328                                 flag--;         /* don't proceed */             \
329                                 tmp2 = 0x7e;                                    \
330                                 goto j3##d;     /* final FS */                  \
331                         }                                                       \
332                         else                                                    \
333                         {                                                       \
334                                 crc = -1;                                       \
335                                 ib  = 0;                                        \
336                                 goto j1##d;     /* first byte */                \
337                         }                                                       \
338                   case 4:                                                       \
339                         nmbcmd;                 /* get next mbuf in chain */    \
340                         if (!len--)                                             \
341                         {                                                       \
342                                 len++;                                          \
343                                 crc ^= -1;                                      \
344                                 tmp2 = (u_char)crc;                             \
345                                 goto j2##d;     /* CRC (lsb's) */               \
346                         }                                                       \
347                         else                                                    \
348                         {                                                       \
349                                 flag--;                                         \
350                                 goto j1##d;     /* proceed with the frame */    \
351                         }                                                       \
352                   case 5:                                                       \
353                         tmp2  = (u_char)(crc >> 8);                             \
354                         flag  = 1;                                              \
355                         goto j2##d;             /* CRC (msb's) */               \
356                 }                                                               \
357         }                                                                       \
358         else                                                                    \
359         { j1##d :                                                               \
360                 tmp2 = (u_char)src;                                             \
361                 crc =(HDLC_FCS_TAB[(u_char)(crc ^ tmp2)] ^ (u_char)(crc >> 8)); \
362           j2##d:                                                                \
363                                                                                 \
364                 ib >>= 12;                                                      \
365                 ib  += HDLC_BIT_TAB[(u_char)tmp2];                              \
366                                                                                 \
367                 if ((u_char)ib >= 5)    /* stuffing */                          \
368                 {                                                               \
369                         blevel &= ~0xff;                                        \
370                                                                                 \
371                         if (ib & 0xc0)          /* bit stuff (msb) */           \
372                         {                                                       \
373                                 tmp2 += tmp2 & (0xff * (ib & 0xc0));            \
374                                 ib %= 0x5000;                                   \
375                                 blevel++;                                       \
376                         }                                                       \
377                                                                                 \
378                         ib &= ~0xf0;                                            \
379                                                                                 \
380                         if ((u_char)ib >= 5)    /* bit stuff (lsb) */           \
381                         {                                                       \
382                                 tmp2 += tmp2 & ~0x1f >> ((ib - (ib >> 8) + 1)   \
383                                                                 & 7);           \
384                                 blevel++;                                       \
385                                                                                 \
386                                 if ((u_char)ib >= 10)   /* bit stuff (msb) */   \
387                                 {                                               \
388                                         tmp2 += tmp2 & ~0x7ff >> ((ib -         \
389                                                         (ib >> 8) + 1) & 7);    \
390                                         blevel++;                               \
391                                 }                                               \
392                                 if (ib & 0x8000)        /* bit walk */          \
393                                 {                                               \
394                                         ib = ((u_char)ib % 5) << 12;            \
395                                 }                                               \
396                         }                                                       \
397                                                                                 \
398                         tmp    |= tmp2 << (u_char)(blevel >> 8);                \
399                         blevel += (u_char)blevel << 8;                          \
400                 }                                                               \
401                 else            /* no stuffing */                               \
402                 {                                                               \
403                   j3##d:tmp    |= tmp2 << (u_char)(blevel >> 8);                \
404                 }                                                               \
405         }                                                                       \
406                                                                                 \
407  j4##d: wrdcmd;                                                                 \
408         tmp >>= 8;                                                              \
409
410 /*------ end of HDLC_ENCODE -------------------------------------------------*/
411
412
413 #endif /* _I4B_HDLC_H_ */