port more changes to make PCI work
[linux-2.4.git] / net / irda / wrapper.c
1 /*********************************************************************
2  *                
3  * Filename:      wrapper.c
4  * Version:       1.2
5  * Description:   IrDA SIR async wrapper layer
6  * Status:        Stable
7  * Author:        Dag Brattli <dagb@cs.uit.no>
8  * Created at:    Mon Aug  4 20:40:53 1997
9  * Modified at:   Fri Jan 28 13:21:09 2000
10  * Modified by:   Dag Brattli <dagb@cs.uit.no>
11  * Modified at:   Fri May 28  3:11 CST 1999
12  * Modified by:   Horst von Brand <vonbrand@sleipnir.valparaiso.cl>
13  * 
14  *     Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>, 
15  *     All Rights Reserved.
16  *     
17  *     This program is free software; you can redistribute it and/or 
18  *     modify it under the terms of the GNU General Public License as 
19  *     published by the Free Software Foundation; either version 2 of 
20  *     the License, or (at your option) any later version.
21  *
22  *     Neither Dag Brattli nor University of Tromsø admit liability nor
23  *     provide warranty for any of this software. This material is 
24  *     provided "AS-IS" and at no charge.
25  *
26  ********************************************************************/
27
28 #include <linux/skbuff.h>
29 #include <linux/string.h>
30 #include <asm/byteorder.h>
31
32 #include <net/irda/irda.h>
33 #include <net/irda/wrapper.h>
34 #include <net/irda/irtty.h>
35 #include <net/irda/crc.h>
36 #include <net/irda/irlap.h>
37 #include <net/irda/irlap_frame.h>
38 #include <net/irda/irda_device.h>
39
40 static void state_outside_frame(struct net_device *dev, 
41                                 struct net_device_stats *stats, 
42                                 iobuff_t *rx_buff, __u8 byte);
43 static void state_begin_frame(struct net_device *dev, 
44                               struct net_device_stats *stats, 
45                               iobuff_t *rx_buff, __u8 byte);
46 static void state_link_escape(struct net_device *dev, 
47                               struct net_device_stats *stats, 
48                               iobuff_t *rx_buff, __u8 byte);
49 static void state_inside_frame(struct net_device *dev, 
50                                struct net_device_stats *stats, 
51                                iobuff_t *rx_buff, __u8 byte);
52
53 static void (*state[])(struct net_device *dev, struct net_device_stats *stats, 
54                        iobuff_t *rx_buff, __u8 byte) = 
55
56         state_outside_frame,
57         state_begin_frame,
58         state_link_escape,
59         state_inside_frame,
60 };
61
62 /*
63  * Function stuff_byte (byte, buf)
64  *
65  *    Byte stuff one single byte and put the result in buffer pointed to by
66  *    buf. The buffer must at all times be able to have two bytes inserted.
67  * 
68  */
69 static inline int stuff_byte(__u8 byte, __u8 *buf) 
70 {
71         switch (byte) {
72         case BOF: /* FALLTHROUGH */
73         case EOF: /* FALLTHROUGH */
74         case CE:
75                 /* Insert transparently coded */
76                 buf[0] = CE;               /* Send link escape */
77                 buf[1] = byte^IRDA_TRANS;    /* Complement bit 5 */
78                 return 2;
79                 /* break; */
80         default:
81                  /* Non-special value, no transparency required */
82                 buf[0] = byte;
83                 return 1;
84                 /* break; */
85         }
86 }
87
88 /*
89  * Function async_wrap (skb, *tx_buff, buffsize)
90  *
91  *    Makes a new buffer with wrapping and stuffing, should check that 
92  *    we don't get tx buffer overflow.
93  */
94 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
95 {
96         struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
97         int xbofs;
98         int i;
99         int n;
100         union {
101                 __u16 value;
102                 __u8 bytes[2];
103         } fcs;
104
105         /* Initialize variables */
106         fcs.value = INIT_FCS;
107         n = 0;
108
109         /*
110          *  Send  XBOF's for required min. turn time and for the negotiated
111          *  additional XBOFS
112          */
113         
114         if (cb->magic != LAP_MAGIC) {
115                 /* 
116                  * This will happen for all frames sent from user-space.
117                  * Nothing to worry about, but we set the default number of 
118                  * BOF's
119                  */
120                 IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__);
121                 xbofs = 10;
122         } else
123                 xbofs = cb->xbofs + cb->xbofs_delay;
124
125         IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs);
126
127         /* Check that we never use more than 115 + 48 xbofs */
128         if (xbofs > 163) {
129                 IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__, xbofs);
130                 xbofs = 163;
131         }
132
133         memset(tx_buff+n, XBOF, xbofs);
134         n += xbofs;
135
136         /* Start of packet character BOF */
137         tx_buff[n++] = BOF;
138
139         /* Insert frame and calc CRC */
140         for (i=0; i < skb->len; i++) {
141                 /*
142                  *  Check for the possibility of tx buffer overflow. We use
143                  *  bufsize-5 since the maximum number of bytes that can be 
144                  *  transmitted after this point is 5.
145                  */
146                 ASSERT(n < (buffsize-5), return n;);
147
148                 n += stuff_byte(skb->data[i], tx_buff+n);
149                 fcs.value = irda_fcs(fcs.value, skb->data[i]);
150         }
151         
152         /* Insert CRC in little endian format (LSB first) */
153         fcs.value = ~fcs.value;
154 #ifdef __LITTLE_ENDIAN
155         n += stuff_byte(fcs.bytes[0], tx_buff+n);
156         n += stuff_byte(fcs.bytes[1], tx_buff+n);
157 #else /* ifdef __BIG_ENDIAN */
158         n += stuff_byte(fcs.bytes[1], tx_buff+n);
159         n += stuff_byte(fcs.bytes[0], tx_buff+n);
160 #endif
161         tx_buff[n++] = EOF;
162
163         return n;
164 }
165
166 /*
167  * Function async_bump (buf, len, stats)
168  *
169  *    Got a frame, make a copy of it, and pass it up the stack! We can try
170  *    to inline it since it's only called from state_inside_frame
171  */
172 inline void async_bump(struct net_device *dev, struct net_device_stats *stats,
173                        __u8 *buf, int len)
174 {
175         struct sk_buff *skb;
176
177         skb = dev_alloc_skb(len+1);
178         if (!skb)  {
179                 stats->rx_dropped++;
180                 return;
181         }
182
183         /* Align IP header to 20 bytes */
184         skb_reserve(skb, 1);
185         
186         /* Copy data without CRC */
187         memcpy(skb_put(skb, len-2), buf, len-2); 
188         
189         /* Feed it to IrLAP layer */
190         skb->dev = dev;
191         skb->mac.raw  = skb->data;
192         skb->protocol = htons(ETH_P_IRDA);
193
194         netif_rx(skb);
195
196         stats->rx_packets++;
197         stats->rx_bytes += len; 
198 }
199
200 /*
201  * Function async_unwrap_char (dev, rx_buff, byte)
202  *
203  *    Parse and de-stuff frame received from the IrDA-port
204  *
205  */
206 inline void async_unwrap_char(struct net_device *dev, 
207                               struct net_device_stats *stats, 
208                               iobuff_t *rx_buff, __u8 byte)
209 {
210         (*state[rx_buff->state])(dev, stats, rx_buff, byte);
211 }
212          
213 /*
214  * Function state_outside_frame (dev, rx_buff, byte)
215  *
216  *    Not receiving any frame (or just bogus data)
217  *
218  */
219 static void state_outside_frame(struct net_device *dev, 
220                                 struct net_device_stats *stats, 
221                                 iobuff_t *rx_buff, __u8 byte)
222 {
223         switch (byte) {
224         case BOF:
225                 rx_buff->state = BEGIN_FRAME;
226                 rx_buff->in_frame = TRUE;
227                 break;
228         case XBOF:
229                 /* idev->xbofs++; */
230                 break;
231         case EOF:
232                 irda_device_set_media_busy(dev, TRUE);
233                 break;
234         default:
235                 irda_device_set_media_busy(dev, TRUE);
236                 break;
237         }
238 }
239
240 /*
241  * Function state_begin_frame (idev, byte)
242  *
243  *    Begin of frame detected
244  *
245  */
246 static void state_begin_frame(struct net_device *dev, 
247                               struct net_device_stats *stats, 
248                               iobuff_t *rx_buff, __u8 byte)
249 {
250         /* Time to initialize receive buffer */
251         rx_buff->data = rx_buff->head;
252         rx_buff->len = 0;
253         rx_buff->fcs = INIT_FCS;
254
255         switch (byte) {
256         case BOF:
257                 /* Continue */
258                 break;
259         case CE:
260                 /* Stuffed byte */
261                 rx_buff->state = LINK_ESCAPE;
262                 break;
263         case EOF:
264                 /* Abort frame */
265                 rx_buff->state = OUTSIDE_FRAME;
266                 IRDA_DEBUG(1, "%s(), abort frame\n", __FUNCTION__);
267                 stats->rx_errors++;
268                 stats->rx_frame_errors++;
269                 break;
270         default:
271                 rx_buff->data[rx_buff->len++] = byte;
272                 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
273                 rx_buff->state = INSIDE_FRAME;
274                 break;
275         }
276 }
277
278 /*
279  * Function state_link_escape (dev, byte)
280  *
281  *    Found link escape character
282  *
283  */
284 static void state_link_escape(struct net_device *dev, 
285                               struct net_device_stats *stats, 
286                               iobuff_t *rx_buff, __u8 byte)
287 {
288         switch (byte) {
289         case BOF: /* New frame? */
290                 IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n", __FUNCTION__);
291                 rx_buff->state = BEGIN_FRAME;
292                 irda_device_set_media_busy(dev, TRUE);
293                 break;
294         case CE:
295                 WARNING("%s(), state not defined\n", __FUNCTION__);
296                 break;
297         case EOF: /* Abort frame */
298                 rx_buff->state = OUTSIDE_FRAME;
299                 break;
300         default:
301                 /* 
302                  *  Stuffed char, complement bit 5 of byte 
303                  *  following CE, IrLAP p.114 
304                  */
305                 byte ^= IRDA_TRANS;
306                 if (rx_buff->len < rx_buff->truesize)  {
307                         rx_buff->data[rx_buff->len++] = byte;
308                         rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
309                         rx_buff->state = INSIDE_FRAME;
310                 } else {
311                         IRDA_DEBUG(1, "%s(), rx buffer overflow\n", __FUNCTION__);
312                         rx_buff->state = OUTSIDE_FRAME;
313                 }
314                 break;
315         }
316 }
317
318 /*
319  * Function state_inside_frame (dev, byte)
320  *
321  *    Handle bytes received within a frame
322  *
323  */
324 static void state_inside_frame(struct net_device *dev, 
325                                struct net_device_stats *stats,
326                                iobuff_t *rx_buff, __u8 byte)
327 {
328         int ret = 0; 
329
330         switch (byte) {
331         case BOF: /* New frame? */
332                 IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n", __FUNCTION__);
333                 rx_buff->state = BEGIN_FRAME;
334                 irda_device_set_media_busy(dev, TRUE);
335                 break;
336         case CE: /* Stuffed char */
337                 rx_buff->state = LINK_ESCAPE;
338                 break;
339         case EOF: /* End of frame */
340                 rx_buff->state = OUTSIDE_FRAME;
341                 rx_buff->in_frame = FALSE;
342                 
343                 /* Test FCS and signal success if the frame is good */
344                 if (rx_buff->fcs == GOOD_FCS) {
345                         /* Deliver frame */
346                         async_bump(dev, stats, rx_buff->data, rx_buff->len);
347                         ret = TRUE;
348                         break;
349                 } else {
350                         /* Wrong CRC, discard frame!  */
351                         irda_device_set_media_busy(dev, TRUE); 
352
353                         IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
354                         stats->rx_errors++;
355                         stats->rx_crc_errors++;
356                 }                       
357                 break;
358         default: /* Must be the next byte of the frame */
359                 if (rx_buff->len < rx_buff->truesize)  {
360                         rx_buff->data[rx_buff->len++] = byte;
361                         rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
362                 } else {
363                         IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n", __FUNCTION__);
364                         rx_buff->state = OUTSIDE_FRAME;
365                 }
366                 break;
367         }
368 }
369
370