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  */
stuff_byte(__u8 byte,__u8 * buf)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  */
async_wrap_skb(struct sk_buff * skb,__u8 * tx_buff,int buffsize)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  */
async_bump(struct net_device * dev,struct net_device_stats * stats,__u8 * buf,int len)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  */
async_unwrap_char(struct net_device * dev,struct net_device_stats * stats,iobuff_t * rx_buff,__u8 byte)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  */
state_outside_frame(struct net_device * dev,struct net_device_stats * stats,iobuff_t * rx_buff,__u8 byte)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  */
state_begin_frame(struct net_device * dev,struct net_device_stats * stats,iobuff_t * rx_buff,__u8 byte)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  */
state_link_escape(struct net_device * dev,struct net_device_stats * stats,iobuff_t * rx_buff,__u8 byte)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  */
state_inside_frame(struct net_device * dev,struct net_device_stats * stats,iobuff_t * rx_buff,__u8 byte)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 
371