[PATCH] DVB: Documentation and Kconfig updazes
[linux-2.6/history.git] / net / irda / wrapper.c
blobc96074d325ac00352e10f5dbe9fa7629c7af9e99
1 /*********************************************************************
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>
14 * Copyright (c) 1998-2000 Dag Brattli <dagb@cs.uit.no>,
15 * All Rights Reserved.
16 * Copyright (c) 2000-2002 Jean Tourrilhes <jt@hpl.hp.com>
18 * This program is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU General Public License as
20 * published by the Free Software Foundation; either version 2 of
21 * the License, or (at your option) any later version.
23 * Neither Dag Brattli nor University of Tromsø admit liability nor
24 * provide warranty for any of this software. This material is
25 * provided "AS-IS" and at no charge.
27 ********************************************************************/
29 #include <linux/skbuff.h>
30 #include <linux/string.h>
31 #include <linux/module.h>
32 #include <asm/byteorder.h>
34 #include <net/irda/irda.h>
35 #include <net/irda/wrapper.h>
36 #include <net/irda/crc.h>
37 #include <net/irda/irlap.h>
38 #include <net/irda/irlap_frame.h>
39 #include <net/irda/irda_device.h>
41 /************************** FRAME WRAPPING **************************/
43 * Unwrap and unstuff SIR frames
45 * Note : at FIR and MIR, HDLC framing is used and usually handled
46 * by the controller, so we come here only for SIR... Jean II
50 * Function stuff_byte (byte, buf)
52 * Byte stuff one single byte and put the result in buffer pointed to by
53 * buf. The buffer must at all times be able to have two bytes inserted.
55 * This is in a tight loop, better inline it, so need to be prior to callers.
56 * (2000 bytes on P6 200MHz, non-inlined ~370us, inline ~170us) - Jean II
58 static inline int stuff_byte(__u8 byte, __u8 *buf)
60 switch (byte) {
61 case BOF: /* FALLTHROUGH */
62 case EOF: /* FALLTHROUGH */
63 case CE:
64 /* Insert transparently coded */
65 buf[0] = CE; /* Send link escape */
66 buf[1] = byte^IRDA_TRANS; /* Complement bit 5 */
67 return 2;
68 /* break; */
69 default:
70 /* Non-special value, no transparency required */
71 buf[0] = byte;
72 return 1;
73 /* break; */
78 * Function async_wrap (skb, *tx_buff, buffsize)
80 * Makes a new buffer with wrapping and stuffing, should check that
81 * we don't get tx buffer overflow.
83 int async_wrap_skb(struct sk_buff *skb, __u8 *tx_buff, int buffsize)
85 struct irda_skb_cb *cb = (struct irda_skb_cb *) skb->cb;
86 int xbofs;
87 int i;
88 int n;
89 union {
90 __u16 value;
91 __u8 bytes[2];
92 } fcs;
94 /* Initialize variables */
95 fcs.value = INIT_FCS;
96 n = 0;
99 * Send XBOF's for required min. turn time and for the negotiated
100 * additional XBOFS
103 if (cb->magic != LAP_MAGIC) {
105 * This will happen for all frames sent from user-space.
106 * Nothing to worry about, but we set the default number of
107 * BOF's
109 IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__);
110 xbofs = 10;
111 } else
112 xbofs = cb->xbofs + cb->xbofs_delay;
114 IRDA_DEBUG(4, "%s(), xbofs=%d\n", __FUNCTION__, xbofs);
116 /* Check that we never use more than 115 + 48 xbofs */
117 if (xbofs > 163) {
118 IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__,
119 xbofs);
120 xbofs = 163;
123 memset(tx_buff + n, XBOF, xbofs);
124 n += xbofs;
126 /* Start of packet character BOF */
127 tx_buff[n++] = BOF;
129 /* Insert frame and calc CRC */
130 for (i=0; i < skb->len; i++) {
132 * Check for the possibility of tx buffer overflow. We use
133 * bufsize-5 since the maximum number of bytes that can be
134 * transmitted after this point is 5.
136 ASSERT(n < (buffsize-5), return n;);
138 n += stuff_byte(skb->data[i], tx_buff+n);
139 fcs.value = irda_fcs(fcs.value, skb->data[i]);
142 /* Insert CRC in little endian format (LSB first) */
143 fcs.value = ~fcs.value;
144 #ifdef __LITTLE_ENDIAN
145 n += stuff_byte(fcs.bytes[0], tx_buff+n);
146 n += stuff_byte(fcs.bytes[1], tx_buff+n);
147 #else /* ifdef __BIG_ENDIAN */
148 n += stuff_byte(fcs.bytes[1], tx_buff+n);
149 n += stuff_byte(fcs.bytes[0], tx_buff+n);
150 #endif
151 tx_buff[n++] = EOF;
153 return n;
155 EXPORT_SYMBOL(async_wrap_skb);
157 /************************* FRAME UNWRAPPING *************************/
159 * Unwrap and unstuff SIR frames
161 * Complete rewrite by Jean II :
162 * More inline, faster, more compact, more logical. Jean II
163 * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
164 * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
165 * (for reference, 115200 b/s is 1 byte every 69 us)
166 * And reduce wrapper.o by ~900B in the process ;-)
168 * Then, we have the addition of ZeroCopy, which is optional
169 * (i.e. the driver must initiate it) and improve final processing.
170 * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
172 * Note : at FIR and MIR, HDLC framing is used and usually handled
173 * by the controller, so we come here only for SIR... Jean II
177 * We can also choose where we want to do the CRC calculation. We can
178 * do it "inline", as we receive the bytes, or "postponed", when
179 * receiving the End-Of-Frame.
180 * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
181 * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
182 * With ZeroCopy :
183 * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
184 * Without ZeroCopy :
185 * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
186 * (Note : numbers taken with irq disabled)
188 * From those numbers, it's not clear which is the best strategy, because
189 * we end up running through a lot of data one way or another (i.e. cache
190 * misses). I personally prefer to avoid the huge latency spike of the
191 * "postponed" solution, because it come just at the time when we have
192 * lot's of protocol processing to do and it will hurt our ability to
193 * reach low link turnaround times... Jean II
195 //#define POSTPONE_RX_CRC
198 * Function async_bump (buf, len, stats)
200 * Got a frame, make a copy of it, and pass it up the stack! We can try
201 * to inline it since it's only called from state_inside_frame
203 static inline void
204 async_bump(struct net_device *dev,
205 struct net_device_stats *stats,
206 iobuff_t *rx_buff)
208 struct sk_buff *newskb;
209 struct sk_buff *dataskb;
210 int docopy;
212 /* Check if we need to copy the data to a new skb or not.
213 * If the driver doesn't use ZeroCopy Rx, we have to do it.
214 * With ZeroCopy Rx, the rx_buff already point to a valid
215 * skb. But, if the frame is small, it is more efficient to
216 * copy it to save memory (copy will be fast anyway - that's
217 * called Rx-copy-break). Jean II */
218 docopy = ((rx_buff->skb == NULL) ||
219 (rx_buff->len < IRDA_RX_COPY_THRESHOLD));
221 /* Allocate a new skb */
222 newskb = dev_alloc_skb(docopy ? rx_buff->len + 1 : rx_buff->truesize);
223 if (!newskb) {
224 stats->rx_dropped++;
225 /* We could deliver the current skb if doing ZeroCopy Rx,
226 * but this would stall the Rx path. Better drop the
227 * packet... Jean II */
228 return;
231 /* Align IP header to 20 bytes (i.e. increase skb->data)
232 * Note this is only useful with IrLAN, as PPP has a variable
233 * header size (2 or 1 bytes) - Jean II */
234 skb_reserve(newskb, 1);
236 if(docopy) {
237 /* Copy data without CRC (lenght already checked) */
238 memcpy(newskb->data, rx_buff->data, rx_buff->len - 2);
239 /* Deliver this skb */
240 dataskb = newskb;
241 } else {
242 /* We are using ZeroCopy. Deliver old skb */
243 dataskb = rx_buff->skb;
244 /* And hook the new skb to the rx_buff */
245 rx_buff->skb = newskb;
246 rx_buff->head = newskb->data; /* NOT newskb->head */
247 //printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
250 /* Set proper length on skb (without CRC) */
251 skb_put(dataskb, rx_buff->len - 2);
253 /* Feed it to IrLAP layer */
254 dataskb->dev = dev;
255 dataskb->mac.raw = dataskb->data;
256 dataskb->protocol = htons(ETH_P_IRDA);
258 netif_rx(dataskb);
260 stats->rx_packets++;
261 stats->rx_bytes += rx_buff->len;
263 /* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
264 rx_buff->data = rx_buff->head;
265 rx_buff->len = 0;
269 * Function async_unwrap_bof(dev, byte)
271 * Handle Beginning Of Frame character received within a frame
274 static inline void
275 async_unwrap_bof(struct net_device *dev,
276 struct net_device_stats *stats,
277 iobuff_t *rx_buff, __u8 byte)
279 switch(rx_buff->state) {
280 case LINK_ESCAPE:
281 case INSIDE_FRAME:
282 /* Not supposed to happen, the previous frame is not
283 * finished - Jean II */
284 IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
285 __FUNCTION__);
286 stats->rx_errors++;
287 stats->rx_missed_errors++;
288 irda_device_set_media_busy(dev, TRUE);
289 break;
291 case OUTSIDE_FRAME:
292 case BEGIN_FRAME:
293 default:
294 /* We may receive multiple BOF at the start of frame */
295 break;
298 /* Now receiving frame */
299 rx_buff->state = BEGIN_FRAME;
300 rx_buff->in_frame = TRUE;
302 /* Time to initialize receive buffer */
303 rx_buff->data = rx_buff->head;
304 rx_buff->len = 0;
305 rx_buff->fcs = INIT_FCS;
309 * Function async_unwrap_eof(dev, byte)
311 * Handle End Of Frame character received within a frame
314 static inline void
315 async_unwrap_eof(struct net_device *dev,
316 struct net_device_stats *stats,
317 iobuff_t *rx_buff, __u8 byte)
319 #ifdef POSTPONE_RX_CRC
320 int i;
321 #endif
323 switch(rx_buff->state) {
324 case OUTSIDE_FRAME:
325 /* Probably missed the BOF */
326 stats->rx_errors++;
327 stats->rx_missed_errors++;
328 irda_device_set_media_busy(dev, TRUE);
329 break;
331 case BEGIN_FRAME:
332 case LINK_ESCAPE:
333 case INSIDE_FRAME:
334 default:
335 /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
336 * the fcs will most likely not match and generate an
337 * error, as expected - Jean II */
338 rx_buff->state = OUTSIDE_FRAME;
339 rx_buff->in_frame = FALSE;
341 #ifdef POSTPONE_RX_CRC
342 /* If we haven't done the CRC as we receive bytes, we
343 * must do it now... Jean II */
344 for(i = 0; i < rx_buff->len; i++)
345 rx_buff->fcs = irda_fcs(rx_buff->fcs,
346 rx_buff->data[i]);
347 #endif
349 /* Test FCS and signal success if the frame is good */
350 if (rx_buff->fcs == GOOD_FCS) {
351 /* Deliver frame */
352 async_bump(dev, stats, rx_buff);
353 break;
354 } else {
355 /* Wrong CRC, discard frame! */
356 irda_device_set_media_busy(dev, TRUE);
358 IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__);
359 stats->rx_errors++;
360 stats->rx_crc_errors++;
362 break;
367 * Function async_unwrap_ce(dev, byte)
369 * Handle Character Escape character received within a frame
372 static inline void
373 async_unwrap_ce(struct net_device *dev,
374 struct net_device_stats *stats,
375 iobuff_t *rx_buff, __u8 byte)
377 switch(rx_buff->state) {
378 case OUTSIDE_FRAME:
379 /* Activate carrier sense */
380 irda_device_set_media_busy(dev, TRUE);
381 break;
383 case LINK_ESCAPE:
384 WARNING("%s: state not defined\n", __FUNCTION__);
385 break;
387 case BEGIN_FRAME:
388 case INSIDE_FRAME:
389 default:
390 /* Stuffed byte coming */
391 rx_buff->state = LINK_ESCAPE;
392 break;
397 * Function async_unwrap_other(dev, byte)
399 * Handle other characters received within a frame
402 static inline void
403 async_unwrap_other(struct net_device *dev,
404 struct net_device_stats *stats,
405 iobuff_t *rx_buff, __u8 byte)
407 switch(rx_buff->state) {
408 /* This is on the critical path, case are ordered by
409 * probability (most frequent first) - Jean II */
410 case INSIDE_FRAME:
411 /* Must be the next byte of the frame */
412 if (rx_buff->len < rx_buff->truesize) {
413 rx_buff->data[rx_buff->len++] = byte;
414 #ifndef POSTPONE_RX_CRC
415 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
416 #endif
417 } else {
418 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
419 __FUNCTION__);
420 rx_buff->state = OUTSIDE_FRAME;
422 break;
424 case LINK_ESCAPE:
426 * Stuffed char, complement bit 5 of byte
427 * following CE, IrLAP p.114
429 byte ^= IRDA_TRANS;
430 if (rx_buff->len < rx_buff->truesize) {
431 rx_buff->data[rx_buff->len++] = byte;
432 #ifndef POSTPONE_RX_CRC
433 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
434 #endif
435 rx_buff->state = INSIDE_FRAME;
436 } else {
437 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
438 __FUNCTION__);
439 rx_buff->state = OUTSIDE_FRAME;
441 break;
443 case OUTSIDE_FRAME:
444 /* Activate carrier sense */
445 if(byte != XBOF)
446 irda_device_set_media_busy(dev, TRUE);
447 break;
449 case BEGIN_FRAME:
450 default:
451 rx_buff->data[rx_buff->len++] = byte;
452 #ifndef POSTPONE_RX_CRC
453 rx_buff->fcs = irda_fcs(rx_buff->fcs, byte);
454 #endif
455 rx_buff->state = INSIDE_FRAME;
456 break;
461 * Function async_unwrap_char (dev, rx_buff, byte)
463 * Parse and de-stuff frame received from the IrDA-port
465 * This is the main entry point for SIR drivers.
467 void async_unwrap_char(struct net_device *dev,
468 struct net_device_stats *stats,
469 iobuff_t *rx_buff, __u8 byte)
471 switch(byte) {
472 case CE:
473 async_unwrap_ce(dev, stats, rx_buff, byte);
474 break;
475 case BOF:
476 async_unwrap_bof(dev, stats, rx_buff, byte);
477 break;
478 case EOF:
479 async_unwrap_eof(dev, stats, rx_buff, byte);
480 break;
481 default:
482 async_unwrap_other(dev, stats, rx_buff, byte);
483 break;
486 EXPORT_SYMBOL(async_unwrap_char);