OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [irda/] [wrapper.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.