]>
git.proxmox.com Git - mirror_ubuntu-zesty-kernel.git/blob - net/irda/wrapper.c
1 /*********************************************************************
5 * Description: IrDA SIR async wrapper layer
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
)
61 case BOF
: /* FALLTHROUGH */
62 case EOF
: /* FALLTHROUGH */
64 /* Insert transparently coded */
65 buf
[0] = CE
; /* Send link escape */
66 buf
[1] = byte
^IRDA_TRANS
; /* Complement bit 5 */
70 /* Non-special value, no transparency required */
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
;
94 /* Initialize variables */
99 * Send XBOF's for required min. turn time and for the negotiated
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
109 IRDA_DEBUG(1, "%s(), wrong magic in skb!\n", __FUNCTION__
);
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 */
118 IRDA_DEBUG(0, "%s(), too many xbofs (%d)\n", __FUNCTION__
,
123 memset(tx_buff
+ n
, XBOF
, xbofs
);
126 /* Start of packet character 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 if(n
>= (buffsize
-5)) {
137 IRDA_ERROR("%s(), tx buffer overflow (n=%d)\n",
142 n
+= stuff_byte(skb
->data
[i
], tx_buff
+n
);
143 fcs
.value
= irda_fcs(fcs
.value
, skb
->data
[i
]);
146 /* Insert CRC in little endian format (LSB first) */
147 fcs
.value
= ~fcs
.value
;
148 #ifdef __LITTLE_ENDIAN
149 n
+= stuff_byte(fcs
.bytes
[0], tx_buff
+n
);
150 n
+= stuff_byte(fcs
.bytes
[1], tx_buff
+n
);
151 #else /* ifdef __BIG_ENDIAN */
152 n
+= stuff_byte(fcs
.bytes
[1], tx_buff
+n
);
153 n
+= stuff_byte(fcs
.bytes
[0], tx_buff
+n
);
159 EXPORT_SYMBOL(async_wrap_skb
);
161 /************************* FRAME UNWRAPPING *************************/
163 * Unwrap and unstuff SIR frames
165 * Complete rewrite by Jean II :
166 * More inline, faster, more compact, more logical. Jean II
167 * (16 bytes on P6 200MHz, old 5 to 7 us, new 4 to 6 us)
168 * (24 bytes on P6 200MHz, old 9 to 10 us, new 7 to 8 us)
169 * (for reference, 115200 b/s is 1 byte every 69 us)
170 * And reduce wrapper.o by ~900B in the process ;-)
172 * Then, we have the addition of ZeroCopy, which is optional
173 * (i.e. the driver must initiate it) and improve final processing.
174 * (2005 B frame + EOF on P6 200MHz, without 30 to 50 us, with 10 to 25 us)
176 * Note : at FIR and MIR, HDLC framing is used and usually handled
177 * by the controller, so we come here only for SIR... Jean II
181 * We can also choose where we want to do the CRC calculation. We can
182 * do it "inline", as we receive the bytes, or "postponed", when
183 * receiving the End-Of-Frame.
184 * (16 bytes on P6 200MHz, inlined 4 to 6 us, postponed 4 to 5 us)
185 * (24 bytes on P6 200MHz, inlined 7 to 8 us, postponed 5 to 7 us)
187 * (2005 B frame on P6 200MHz, inlined 10 to 25 us, postponed 140 to 180 us)
189 * (2005 B frame on P6 200MHz, inlined 30 to 50 us, postponed 150 to 180 us)
190 * (Note : numbers taken with irq disabled)
192 * From those numbers, it's not clear which is the best strategy, because
193 * we end up running through a lot of data one way or another (i.e. cache
194 * misses). I personally prefer to avoid the huge latency spike of the
195 * "postponed" solution, because it come just at the time when we have
196 * lot's of protocol processing to do and it will hurt our ability to
197 * reach low link turnaround times... Jean II
199 //#define POSTPONE_RX_CRC
202 * Function async_bump (buf, len, stats)
204 * Got a frame, make a copy of it, and pass it up the stack! We can try
205 * to inline it since it's only called from state_inside_frame
208 async_bump(struct net_device
*dev
,
209 struct net_device_stats
*stats
,
212 struct sk_buff
*newskb
;
213 struct sk_buff
*dataskb
;
216 /* Check if we need to copy the data to a new skb or not.
217 * If the driver doesn't use ZeroCopy Rx, we have to do it.
218 * With ZeroCopy Rx, the rx_buff already point to a valid
219 * skb. But, if the frame is small, it is more efficient to
220 * copy it to save memory (copy will be fast anyway - that's
221 * called Rx-copy-break). Jean II */
222 docopy
= ((rx_buff
->skb
== NULL
) ||
223 (rx_buff
->len
< IRDA_RX_COPY_THRESHOLD
));
225 /* Allocate a new skb */
226 newskb
= dev_alloc_skb(docopy
? rx_buff
->len
+ 1 : rx_buff
->truesize
);
229 /* We could deliver the current skb if doing ZeroCopy Rx,
230 * but this would stall the Rx path. Better drop the
231 * packet... Jean II */
235 /* Align IP header to 20 bytes (i.e. increase skb->data)
236 * Note this is only useful with IrLAN, as PPP has a variable
237 * header size (2 or 1 bytes) - Jean II */
238 skb_reserve(newskb
, 1);
241 /* Copy data without CRC (lenght already checked) */
242 skb_copy_to_linear_data(newskb
, rx_buff
->data
,
244 /* Deliver this skb */
247 /* We are using ZeroCopy. Deliver old skb */
248 dataskb
= rx_buff
->skb
;
249 /* And hook the new skb to the rx_buff */
250 rx_buff
->skb
= newskb
;
251 rx_buff
->head
= newskb
->data
; /* NOT newskb->head */
252 //printk(KERN_DEBUG "ZeroCopy : len = %d, dataskb = %p, newskb = %p\n", rx_buff->len, dataskb, newskb);
255 /* Set proper length on skb (without CRC) */
256 skb_put(dataskb
, rx_buff
->len
- 2);
258 /* Feed it to IrLAP layer */
260 skb_reset_mac_header(dataskb
);
261 dataskb
->protocol
= htons(ETH_P_IRDA
);
266 stats
->rx_bytes
+= rx_buff
->len
;
268 /* Clean up rx_buff (redundant with async_unwrap_bof() ???) */
269 rx_buff
->data
= rx_buff
->head
;
274 * Function async_unwrap_bof(dev, byte)
276 * Handle Beginning Of Frame character received within a frame
280 async_unwrap_bof(struct net_device
*dev
,
281 struct net_device_stats
*stats
,
282 iobuff_t
*rx_buff
, __u8 byte
)
284 switch(rx_buff
->state
) {
287 /* Not supposed to happen, the previous frame is not
288 * finished - Jean II */
289 IRDA_DEBUG(1, "%s(), Discarding incomplete frame\n",
292 stats
->rx_missed_errors
++;
293 irda_device_set_media_busy(dev
, TRUE
);
299 /* We may receive multiple BOF at the start of frame */
303 /* Now receiving frame */
304 rx_buff
->state
= BEGIN_FRAME
;
305 rx_buff
->in_frame
= TRUE
;
307 /* Time to initialize receive buffer */
308 rx_buff
->data
= rx_buff
->head
;
310 rx_buff
->fcs
= INIT_FCS
;
314 * Function async_unwrap_eof(dev, byte)
316 * Handle End Of Frame character received within a frame
320 async_unwrap_eof(struct net_device
*dev
,
321 struct net_device_stats
*stats
,
322 iobuff_t
*rx_buff
, __u8 byte
)
324 #ifdef POSTPONE_RX_CRC
328 switch(rx_buff
->state
) {
330 /* Probably missed the BOF */
332 stats
->rx_missed_errors
++;
333 irda_device_set_media_busy(dev
, TRUE
);
340 /* Note : in the case of BEGIN_FRAME and LINK_ESCAPE,
341 * the fcs will most likely not match and generate an
342 * error, as expected - Jean II */
343 rx_buff
->state
= OUTSIDE_FRAME
;
344 rx_buff
->in_frame
= FALSE
;
346 #ifdef POSTPONE_RX_CRC
347 /* If we haven't done the CRC as we receive bytes, we
348 * must do it now... Jean II */
349 for(i
= 0; i
< rx_buff
->len
; i
++)
350 rx_buff
->fcs
= irda_fcs(rx_buff
->fcs
,
354 /* Test FCS and signal success if the frame is good */
355 if (rx_buff
->fcs
== GOOD_FCS
) {
357 async_bump(dev
, stats
, rx_buff
);
360 /* Wrong CRC, discard frame! */
361 irda_device_set_media_busy(dev
, TRUE
);
363 IRDA_DEBUG(1, "%s(), crc error\n", __FUNCTION__
);
365 stats
->rx_crc_errors
++;
372 * Function async_unwrap_ce(dev, byte)
374 * Handle Character Escape character received within a frame
378 async_unwrap_ce(struct net_device
*dev
,
379 struct net_device_stats
*stats
,
380 iobuff_t
*rx_buff
, __u8 byte
)
382 switch(rx_buff
->state
) {
384 /* Activate carrier sense */
385 irda_device_set_media_busy(dev
, TRUE
);
389 IRDA_WARNING("%s: state not defined\n", __FUNCTION__
);
395 /* Stuffed byte coming */
396 rx_buff
->state
= LINK_ESCAPE
;
402 * Function async_unwrap_other(dev, byte)
404 * Handle other characters received within a frame
408 async_unwrap_other(struct net_device
*dev
,
409 struct net_device_stats
*stats
,
410 iobuff_t
*rx_buff
, __u8 byte
)
412 switch(rx_buff
->state
) {
413 /* This is on the critical path, case are ordered by
414 * probability (most frequent first) - Jean II */
416 /* Must be the next byte of the frame */
417 if (rx_buff
->len
< rx_buff
->truesize
) {
418 rx_buff
->data
[rx_buff
->len
++] = byte
;
419 #ifndef POSTPONE_RX_CRC
420 rx_buff
->fcs
= irda_fcs(rx_buff
->fcs
, byte
);
423 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
425 rx_buff
->state
= OUTSIDE_FRAME
;
431 * Stuffed char, complement bit 5 of byte
432 * following CE, IrLAP p.114
435 if (rx_buff
->len
< rx_buff
->truesize
) {
436 rx_buff
->data
[rx_buff
->len
++] = byte
;
437 #ifndef POSTPONE_RX_CRC
438 rx_buff
->fcs
= irda_fcs(rx_buff
->fcs
, byte
);
440 rx_buff
->state
= INSIDE_FRAME
;
442 IRDA_DEBUG(1, "%s(), Rx buffer overflow, aborting\n",
444 rx_buff
->state
= OUTSIDE_FRAME
;
449 /* Activate carrier sense */
451 irda_device_set_media_busy(dev
, TRUE
);
456 rx_buff
->data
[rx_buff
->len
++] = byte
;
457 #ifndef POSTPONE_RX_CRC
458 rx_buff
->fcs
= irda_fcs(rx_buff
->fcs
, byte
);
460 rx_buff
->state
= INSIDE_FRAME
;
466 * Function async_unwrap_char (dev, rx_buff, byte)
468 * Parse and de-stuff frame received from the IrDA-port
470 * This is the main entry point for SIR drivers.
472 void async_unwrap_char(struct net_device
*dev
,
473 struct net_device_stats
*stats
,
474 iobuff_t
*rx_buff
, __u8 byte
)
478 async_unwrap_ce(dev
, stats
, rx_buff
, byte
);
481 async_unwrap_bof(dev
, stats
, rx_buff
, byte
);
484 async_unwrap_eof(dev
, stats
, rx_buff
, byte
);
487 async_unwrap_other(dev
, stats
, rx_buff
, byte
);
491 EXPORT_SYMBOL(async_unwrap_char
);