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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [hdlcdrv.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*****************************************************************************/
2
 
3
/*
4
 *      hdlcdrv.c  -- HDLC packet radio network driver.
5
 *
6
 *      Copyright (C) 1996  Thomas Sailer (sailer@ife.ee.ethz.ch)
7
 *
8
 *      This program is free software; you can redistribute it and/or modify
9
 *      it under the terms of the GNU General Public License as published by
10
 *      the Free Software Foundation; either version 2 of the License, or
11
 *      (at your option) any later version.
12
 *
13
 *      This program is distributed in the hope that it will be useful,
14
 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
15
 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16
 *      GNU General Public License for more details.
17
 *
18
 *      You should have received a copy of the GNU General Public License
19
 *      along with this program; if not, write to the Free Software
20
 *      Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
 *
22
 *  Please note that the GPL allows you to use the driver, NOT the radio.
23
 *  In order to use the radio, you need a license from the communications
24
 *  authority of your country.
25
 *
26
 *  The driver was derived from Donald Beckers skeleton.c
27
 *      Written 1993-94 by Donald Becker.
28
 *
29
 *  History:
30
 *   0.1  21.09.96  Started
31
 *        18.10.96  Changed to new user space access routines
32
 *                  (copy_{to,from}_user)
33
 *   0.2  21.11.96  various small changes
34
 *   0.3  03.03.97  fixed (hopefully) IP not working with ax.25 as a module
35
 *   0.4  16.04.97  init code/data tagged
36
 */
37
 
38
/*****************************************************************************/
39
 
40
#include <linux/config.h>
41
#include <linux/module.h>
42
#include <linux/types.h>
43
#include <linux/net.h>
44
#include <linux/in.h>
45
#include <linux/if.h>
46
#include <linux/malloc.h>
47
#include <linux/errno.h>
48
#include <asm/bitops.h>
49
 
50
#include <linux/netdevice.h>
51
#include <linux/if_arp.h>
52
#include <linux/etherdevice.h>
53
#include <linux/skbuff.h>
54
#include <linux/hdlcdrv.h>
55
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
56
/* prototypes for ax25_encapsulate and ax25_rebuild_header */
57
#include <net/ax25.h> 
58
#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
59
 
60
/* make genksyms happy */
61
#include <linux/ip.h>
62
#include <linux/udp.h>
63
#include <linux/tcp.h>
64
#include <linux/net_alias.h>
65
 
66
/* --------------------------------------------------------------------- */
67
 
68
/*
69
 * currently this module is supposed to support both module styles, i.e.
70
 * the old one present up to about 2.1.9, and the new one functioning
71
 * starting with 2.1.21. The reason is I have a kit allowing to compile
72
 * this module also under 2.0.x which was requested by several people.
73
 * This will go in 2.2
74
 */
75
#include <linux/version.h>
76
 
77
#if LINUX_VERSION_CODE >= 0x20100
78
#include <asm/uaccess.h>
79
#else
80
#include <asm/segment.h>
81
#include <linux/mm.h>
82
 
83
#undef put_user
84
#undef get_user
85
 
86
#define put_user(x,ptr) ({ __put_user((unsigned long)(x),(ptr),sizeof(*(ptr))); 0; })
87
#define get_user(x,ptr) ({ x = ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr)))); 0; })
88
 
89
extern inline int copy_from_user(void *to, const void *from, unsigned long n)
90
{
91
        int i = verify_area(VERIFY_READ, from, n);
92
        if (i)
93
                return i;
94
        memcpy_fromfs(to, from, n);
95
        return 0;
96
}
97
 
98
extern inline int copy_to_user(void *to, const void *from, unsigned long n)
99
{
100
        int i = verify_area(VERIFY_WRITE, to, n);
101
        if (i)
102
                return i;
103
        memcpy_tofs(to, from, n);
104
        return 0;
105
}
106
#endif
107
 
108
/* --------------------------------------------------------------------- */
109
 
110
#if LINUX_VERSION_CODE < 0x20115
111
extern __inline__ void dev_init_buffers(struct device *dev)
112
{
113
        int i;
114
        for(i=0;i<DEV_NUMBUFFS;i++)
115
        {
116
                skb_queue_head_init(&dev->buffs[i]);
117
        }
118
}
119
#endif
120
 
121
/* --------------------------------------------------------------------- */
122
 
123
#if LINUX_VERSION_CODE >= 0x20123
124
#include <linux/init.h>
125
#else
126
#define __init
127
#define __initdata
128
#define __initfunc(x) x
129
#endif
130
 
131
/* --------------------------------------------------------------------- */
132
 
133
#if LINUX_VERSION_CODE < 0x20125
134
#define test_and_set_bit set_bit
135
#define test_and_clear_bit clear_bit
136
#endif
137
 
138
/* --------------------------------------------------------------------- */
139
 
140
/*
141
 * The name of the card. Is used for messages and in the requests for
142
 * io regions, irqs and dma channels
143
 */
144
 
145
static char ax25_bcast[7] =
146
{'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
147
static char ax25_test[7] =
148
{'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
149
 
150
/* --------------------------------------------------------------------- */
151
 
152
#define KISS_VERBOSE
153
 
154
/* --------------------------------------------------------------------- */
155
 
156
#define PARAM_TXDELAY   1
157
#define PARAM_PERSIST   2
158
#define PARAM_SLOTTIME  3
159
#define PARAM_TXTAIL    4
160
#define PARAM_FULLDUP   5
161
#define PARAM_HARDWARE  6
162
#define PARAM_RETURN    255
163
 
164
/* --------------------------------------------------------------------- */
165
 
166
#define min(a, b) (((a) < (b)) ? (a) : (b))
167
#define max(a, b) (((a) > (b)) ? (a) : (b))
168
 
169
/* --------------------------------------------------------------------- */
170
/*
171
 * the CRC routines are stolen from WAMPES
172
 * by Dieter Deyke
173
 */
174
 
175
static const unsigned short crc_ccitt_table[] = {
176
        0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
177
        0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
178
        0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
179
        0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
180
        0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
181
        0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
182
        0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
183
        0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
184
        0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
185
        0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
186
        0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
187
        0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
188
        0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
189
        0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
190
        0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
191
        0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
192
        0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
193
        0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
194
        0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
195
        0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
196
        0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
197
        0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
198
        0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
199
        0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
200
        0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
201
        0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
202
        0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
203
        0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
204
        0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
205
        0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
206
        0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
207
        0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
208
};
209
 
210
/*---------------------------------------------------------------------------*/
211
 
212
static inline void append_crc_ccitt(unsigned char *buffer, int len)
213
{
214
        unsigned int crc = 0xffff;
215
 
216
        for (;len>0;len--)
217
                crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
218
        crc ^= 0xffff;
219
        *buffer++ = crc;
220
        *buffer++ = crc >> 8;
221
}
222
 
223
/*---------------------------------------------------------------------------*/
224
 
225
static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
226
{
227
        unsigned int crc = 0xffff;
228
 
229
        for (; cnt > 0; cnt--)
230
                crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
231
        return (crc & 0xffff) == 0xf0b8;
232
}
233
 
234
/*---------------------------------------------------------------------------*/
235
 
236
#if 0
237
static int calc_crc_ccitt(const unsigned char *buf, int cnt)
238
{
239
        unsigned int crc = 0xffff;
240
 
241
        for (; cnt > 0; cnt--)
242
                crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
243
        crc ^= 0xffff;
244
        return (crc & 0xffff);
245
}
246
#endif
247
 
248
/* ---------------------------------------------------------------------- */
249
 
250
#define tenms_to_2flags(s,tenms) ((tenms * s->par.bitrate) / 100 / 16)
251
 
252
/* ---------------------------------------------------------------------- */
253
/*
254
 * The HDLC routines
255
 */
256
 
257
static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits,
258
                             int num)
259
{
260
        int added = 0;
261
 
262
        while (s->hdlcrx.rx_state && num >= 8) {
263
                if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
264
                        s->hdlcrx.rx_state = 0;
265
                        return 0;
266
                }
267
                *s->hdlcrx.bp++ = bits >> (32-num);
268
                s->hdlcrx.len++;
269
                num -= 8;
270
                added += 8;
271
        }
272
        return added;
273
}
274
 
275
static void hdlc_rx_flag(struct device *dev, struct hdlcdrv_state *s)
276
{
277
        struct sk_buff *skb;
278
        int pkt_len;
279
        unsigned char *cp;
280
 
281
        if (s->hdlcrx.len < 4)
282
                return;
283
        if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len))
284
                return;
285
        pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
286
        if (!(skb = dev_alloc_skb(pkt_len))) {
287
                printk("%s: memory squeeze, dropping packet\n",
288
                       s->ifname);
289
                s->stats.rx_dropped++;
290
                return;
291
        }
292
        skb->dev = dev;
293
        cp = skb_put(skb, pkt_len);
294
        *cp++ = 0; /* KISS kludge */
295
        memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
296
        skb->protocol = htons(ETH_P_AX25);
297
        skb->mac.raw = skb->data;
298
        netif_rx(skb);
299
        s->stats.rx_packets++;
300
}
301
 
302
void hdlcdrv_receiver(struct device *dev, struct hdlcdrv_state *s)
303
{
304
        int i;
305
        unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
306
 
307
        if (!s || s->magic != HDLCDRV_MAGIC)
308
                return;
309
        if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
310
                return;
311
 
312
        while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
313
                word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);
314
 
315
#ifdef HDLCDRV_DEBUG
316
                hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
317
#endif /* HDLCDRV_DEBUG */
318
                s->hdlcrx.bitstream >>= 16;
319
                s->hdlcrx.bitstream |= word << 16;
320
                s->hdlcrx.bitbuf >>= 16;
321
                s->hdlcrx.bitbuf |= word << 16;
322
                s->hdlcrx.numbits += 16;
323
                for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
324
                    mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff;
325
                    i >= 0;
326
                    i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1,
327
                    mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
328
                        if ((s->hdlcrx.bitstream & mask1) == mask1)
329
                                s->hdlcrx.rx_state = 0; /* abort received */
330
                        else if ((s->hdlcrx.bitstream & mask2) == mask3) {
331
                                /* flag received */
332
                                if (s->hdlcrx.rx_state) {
333
                                        hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf
334
                                                          << (8+i),
335
                                                          s->hdlcrx.numbits
336
                                                          -8-i);
337
                                        hdlc_rx_flag(dev, s);
338
                                }
339
                                s->hdlcrx.len = 0;
340
                                s->hdlcrx.bp = s->hdlcrx.buffer;
341
                                s->hdlcrx.rx_state = 1;
342
                                s->hdlcrx.numbits = i;
343
                        } else if ((s->hdlcrx.bitstream & mask4) == mask5) {
344
                                /* stuffed bit */
345
                                s->hdlcrx.numbits--;
346
                                s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
347
                                        ((s->hdlcrx.bitbuf & mask6) << 1);
348
                        }
349
                }
350
                s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
351
                                                       s->hdlcrx.numbits);
352
        }
353
        clear_bit(0, &s->hdlcrx.in_hdlc_rx);
354
}
355
 
356
/* ---------------------------------------------------------------------- */
357
 
358
static void inline do_kiss_params(struct hdlcdrv_state *s,
359
                                  unsigned char *data, unsigned long len)
360
{
361
 
362
#ifdef KISS_VERBOSE
363
#define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", s->ifname, b)
364
#else /* KISS_VERBOSE */              
365
#define PKP(a,b) 
366
#endif /* KISS_VERBOSE */             
367
 
368
        if (len < 2)
369
                return;
370
        switch(data[0]) {
371
        case PARAM_TXDELAY:
372
                s->ch_params.tx_delay = data[1];
373
                PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
374
                break;
375
        case PARAM_PERSIST:
376
                s->ch_params.ppersist = data[1];
377
                PKP("p persistence = %u", s->ch_params.ppersist);
378
                break;
379
        case PARAM_SLOTTIME:
380
                s->ch_params.slottime = data[1];
381
                PKP("slot time = %ums", s->ch_params.slottime);
382
                break;
383
        case PARAM_TXTAIL:
384
                s->ch_params.tx_tail = data[1];
385
                PKP("TX tail = %ums", s->ch_params.tx_tail);
386
                break;
387
        case PARAM_FULLDUP:
388
                s->ch_params.fulldup = !!data[1];
389
                PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
390
                break;
391
        default:
392
                break;
393
        }
394
#undef PKP
395
}
396
 
397
/* ---------------------------------------------------------------------- */
398
 
399
void hdlcdrv_transmitter(struct device *dev, struct hdlcdrv_state *s)
400
{
401
        unsigned int mask1, mask2, mask3;
402
        int i;
403
        struct sk_buff *skb;
404
        int pkt_len;
405
 
406
        if (!s || s->magic != HDLCDRV_MAGIC)
407
                return;
408
        if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
409
                return;
410
        for (;;) {
411
                if (s->hdlctx.numbits >= 16) {
412
                        if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
413
                                clear_bit(0, &s->hdlctx.in_hdlc_tx);
414
                                return;
415
                        }
416
                        hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
417
                        s->hdlctx.bitbuf >>= 16;
418
                        s->hdlctx.numbits -= 16;
419
                }
420
                switch (s->hdlctx.tx_state) {
421
                default:
422
                        clear_bit(0, &s->hdlctx.in_hdlc_tx);
423
                        return;
424
                case 0:
425
                case 1:
426
                        if (s->hdlctx.numflags) {
427
                                s->hdlctx.numflags--;
428
                                s->hdlctx.bitbuf |=
429
                                        0x7e7e << s->hdlctx.numbits;
430
                                s->hdlctx.numbits += 16;
431
                                break;
432
                        }
433
                        if (s->hdlctx.tx_state == 1) {
434
                                clear_bit(0, &s->hdlctx.in_hdlc_tx);
435
                                return;
436
                        }
437
                        if (!(skb = skb_dequeue(&s->send_queue))) {
438
                                int flgs = tenms_to_2flags
439
                                        (s, s->ch_params.tx_tail);
440
                                if (flgs < 2)
441
                                        flgs = 2;
442
                                s->hdlctx.tx_state = 1;
443
                                s->hdlctx.numflags = flgs;
444
                                break;
445
                        }
446
                        if (skb->data[0] != 0) {
447
                                do_kiss_params(s, skb->data, skb->len);
448
                                dev_kfree_skb(skb, FREE_WRITE);
449
                                break;
450
                        }
451
                        pkt_len = skb->len-1; /* strip KISS byte */
452
                        if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
453
                                s->hdlctx.tx_state = 0;
454
                                s->hdlctx.numflags = 1;
455
                                dev_kfree_skb(skb, FREE_WRITE);
456
                                break;
457
                        }
458
                        memcpy(s->hdlctx.buffer, skb->data+1, pkt_len);
459
                        dev_kfree_skb(skb, FREE_WRITE);
460
                        s->hdlctx.bp = s->hdlctx.buffer;
461
                        append_crc_ccitt(s->hdlctx.buffer, pkt_len);
462
                        s->hdlctx.len = pkt_len+2; /* the appended CRC */
463
                        s->hdlctx.tx_state = 2;
464
                        s->hdlctx.bitstream = 0;
465
                        s->stats.tx_packets++;
466
                        break;
467
                case 2:
468
                        if (!s->hdlctx.len) {
469
                                s->hdlctx.tx_state = 0;
470
                                s->hdlctx.numflags = 1;
471
                                break;
472
                        }
473
                        s->hdlctx.len--;
474
                        s->hdlctx.bitbuf |= *s->hdlctx.bp <<
475
                                s->hdlctx.numbits;
476
                        s->hdlctx.bitstream >>= 8;
477
                        s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
478
                        mask1 = 0x1f000;
479
                        mask2 = 0x10000;
480
                        mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
481
                        s->hdlctx.numbits += 8;
482
                        for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1,
483
                            mask3 = (mask3 << 1) | 1) {
484
                                if ((s->hdlctx.bitstream & mask1) != mask1)
485
                                        continue;
486
                                s->hdlctx.bitstream &= ~mask2;
487
                                s->hdlctx.bitbuf =
488
                                        (s->hdlctx.bitbuf & mask3) |
489
                                                ((s->hdlctx.bitbuf &
490
                                                 (~mask3)) << 1);
491
                                s->hdlctx.numbits++;
492
                                mask3 = (mask3 << 1) | 1;
493
                        }
494
                        break;
495
                }
496
        }
497
}
498
 
499
/* ---------------------------------------------------------------------- */
500
 
501
static void start_tx(struct device *dev, struct hdlcdrv_state *s)
502
{
503
        s->hdlctx.tx_state = 0;
504
        s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
505
        s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
506
        hdlcdrv_transmitter(dev, s);
507
        s->hdlctx.ptt = 1;
508
        s->ptt_keyed++;
509
}
510
 
511
/* ---------------------------------------------------------------------- */
512
 
513
static unsigned short random_seed;
514
 
515
static inline unsigned short random_num(void)
516
{
517
        random_seed = 28629 * random_seed + 157;
518
        return random_seed;
519
}
520
 
521
/* ---------------------------------------------------------------------- */
522
 
523
void hdlcdrv_arbitrate(struct device *dev, struct hdlcdrv_state *s)
524
{
525
        if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt ||
526
            skb_queue_empty(&s->send_queue))
527
                return;
528
        if (s->ch_params.fulldup) {
529
                start_tx(dev, s);
530
                return;
531
        }
532
        if (s->hdlcrx.dcd) {
533
                s->hdlctx.slotcnt = s->ch_params.slottime;
534
                return;
535
        }
536
        if ((--s->hdlctx.slotcnt) > 0)
537
                return;
538
        s->hdlctx.slotcnt = s->ch_params.slottime;
539
        if ((random_num() % 256) > s->ch_params.ppersist)
540
                return;
541
        start_tx(dev, s);
542
}
543
 
544
/* --------------------------------------------------------------------- */
545
/*
546
 * ===================== network driver interface =========================
547
 */
548
 
549
static inline int hdlcdrv_paranoia_check(struct device *dev,
550
                                        const char *routine)
551
{
552
        if (!dev || !dev->priv ||
553
            ((struct hdlcdrv_state *)dev->priv)->magic != HDLCDRV_MAGIC) {
554
                printk(KERN_ERR "hdlcdrv: bad magic number for hdlcdrv_state "
555
                       "struct in routine %s\n", routine);
556
                return 1;
557
        }
558
        return 0;
559
}
560
 
561
/* --------------------------------------------------------------------- */
562
 
563
static int hdlcdrv_send_packet(struct sk_buff *skb, struct device *dev)
564
{
565
        struct hdlcdrv_state *sm;
566
 
567
        if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet"))
568
                return 0;
569
        sm = (struct hdlcdrv_state *)dev->priv;
570
        /*
571
         * If some higher layer thinks we've missed an tx-done interrupt
572
         * we are passed NULL. Caution: dev_tint() handles the cli()/sti()
573
         * itself.
574
         */
575
        if (skb == NULL) {
576
                dev_tint(dev);
577
                return 0;
578
        }
579
        skb_queue_tail(&sm->send_queue, skb);
580
        dev->trans_start = jiffies;
581
        return 0;
582
}
583
 
584
/* --------------------------------------------------------------------- */
585
 
586
static int hdlcdrv_set_mac_address(struct device *dev, void *addr)
587
{
588
        struct sockaddr *sa = (struct sockaddr *)addr;
589
 
590
        /* addr is an AX.25 shifted ASCII mac address */
591
        memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
592
        return 0;
593
}
594
 
595
/* --------------------------------------------------------------------- */
596
 
597
#if LINUX_VERSION_CODE >= 0x20119
598
static struct net_device_stats *hdlcdrv_get_stats(struct device *dev)
599
#else
600
static struct enet_statistics *hdlcdrv_get_stats(struct device *dev)
601
#endif
602
{
603
        struct hdlcdrv_state *sm;
604
 
605
        if (hdlcdrv_paranoia_check(dev, "hdlcdrv_get_stats"))
606
                return NULL;
607
        sm = (struct hdlcdrv_state *)dev->priv;
608
        /*
609
         * Get the current statistics.  This may be called with the
610
         * card open or closed.
611
         */
612
        return &sm->stats;
613
}
614
 
615
/* --------------------------------------------------------------------- */
616
/*
617
 * Open/initialize the board. This is called (in the current kernel)
618
 * sometime after booting when the 'ifconfig' program is run.
619
 *
620
 * This routine should set everything up anew at each open, even
621
 * registers that "should" only need to be set once at boot, so that
622
 * there is non-reboot way to recover if something goes wrong.
623
 */
624
 
625
static int hdlcdrv_open(struct device *dev)
626
{
627
        struct hdlcdrv_state *s;
628
        int i;
629
 
630
        if (hdlcdrv_paranoia_check(dev, "hdlcdrv_open"))
631
                return -EINVAL;
632
        s = (struct hdlcdrv_state *)dev->priv;
633
 
634
        if (dev->start)
635
                return 0;
636
        if (!s->ops || !s->ops->open)
637
                return -ENODEV;
638
 
639
        dev->start = 1;
640
        /*
641
         * initialise some variables
642
         */
643
        s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
644
        s->hdlcrx.in_hdlc_rx = 0;
645
        s->hdlcrx.rx_state = 0;
646
 
647
        s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
648
        s->hdlctx.in_hdlc_tx = 0;
649
        s->hdlctx.tx_state = 1;
650
        s->hdlctx.numflags = 0;
651
        s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
652
        s->hdlctx.ptt = 0;
653
        s->hdlctx.slotcnt = s->ch_params.slottime;
654
        s->hdlctx.calibrate = 0;
655
 
656
        i = s->ops->open(dev);
657
        if (i) {
658
                dev->start = 0;
659
                return i;
660
        }
661
 
662
        dev->tbusy = 0;
663
        dev->interrupt = 0;
664
 
665
        return 0;
666
}
667
 
668
/* --------------------------------------------------------------------- */
669
/*
670
 * The inverse routine to hdlcdrv_open().
671
 */
672
 
673
static int hdlcdrv_close(struct device *dev)
674
{
675
        struct hdlcdrv_state *s;
676
        struct sk_buff *skb;
677
        int i = 0;
678
 
679
        if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close"))
680
                return -EINVAL;
681
        s = (struct hdlcdrv_state *)dev->priv;
682
 
683
        if (!dev->start)
684
                return 0;
685
        dev->start = 0;
686
        dev->tbusy = 1;
687
 
688
        if (s->ops && s->ops->close)
689
                i = s->ops->close(dev);
690
        /* Free any buffers left in the hardware transmit queue */
691
        while ((skb = skb_dequeue(&s->send_queue)))
692
                        dev_kfree_skb(skb, FREE_WRITE);
693
        return i;
694
}
695
 
696
/* --------------------------------------------------------------------- */
697
 
698
static int hdlcdrv_ioctl(struct device *dev, struct ifreq *ifr, int cmd)
699
{
700
        struct hdlcdrv_state *s;
701
        struct hdlcdrv_ioctl bi;
702
 
703
        if (hdlcdrv_paranoia_check(dev, "hdlcdrv_ioctl"))
704
                return -EINVAL;
705
        s = (struct hdlcdrv_state *)dev->priv;
706
 
707
        if (cmd != SIOCDEVPRIVATE) {
708
                if (s->ops && s->ops->ioctl)
709
                        return s->ops->ioctl(dev, ifr, &bi, cmd);
710
                return -ENOIOCTLCMD;
711
        }
712
        if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
713
                return -EFAULT;
714
 
715
        switch (bi.cmd) {
716
        default:
717
                if (s->ops && s->ops->ioctl)
718
                        return s->ops->ioctl(dev, ifr, &bi, cmd);
719
                return -ENOIOCTLCMD;
720
 
721
        case HDLCDRVCTL_GETCHANNELPAR:
722
                bi.data.cp.tx_delay = s->ch_params.tx_delay;
723
                bi.data.cp.tx_tail = s->ch_params.tx_tail;
724
                bi.data.cp.slottime = s->ch_params.slottime;
725
                bi.data.cp.ppersist = s->ch_params.ppersist;
726
                bi.data.cp.fulldup = s->ch_params.fulldup;
727
                break;
728
 
729
        case HDLCDRVCTL_SETCHANNELPAR:
730
                if (!suser())
731
                        return -EACCES;
732
                s->ch_params.tx_delay = bi.data.cp.tx_delay;
733
                s->ch_params.tx_tail = bi.data.cp.tx_tail;
734
                s->ch_params.slottime = bi.data.cp.slottime;
735
                s->ch_params.ppersist = bi.data.cp.ppersist;
736
                s->ch_params.fulldup = bi.data.cp.fulldup;
737
                s->hdlctx.slotcnt = 1;
738
                return 0;
739
 
740
        case HDLCDRVCTL_GETMODEMPAR:
741
                bi.data.mp.iobase = dev->base_addr;
742
                bi.data.mp.irq = dev->irq;
743
                bi.data.mp.dma = dev->dma;
744
                bi.data.mp.dma2 = s->ptt_out.dma2;
745
                bi.data.mp.seriobase = s->ptt_out.seriobase;
746
                bi.data.mp.pariobase = s->ptt_out.pariobase;
747
                bi.data.mp.midiiobase = s->ptt_out.midiiobase;
748
                break;
749
 
750
        case HDLCDRVCTL_SETMODEMPAR:
751
                if ((!suser()) || dev->start)
752
                        return -EACCES;
753
                dev->base_addr = bi.data.mp.iobase;
754
                dev->irq = bi.data.mp.irq;
755
                dev->dma = bi.data.mp.dma;
756
                s->ptt_out.dma2 = bi.data.mp.dma2;
757
                s->ptt_out.seriobase = bi.data.mp.seriobase;
758
                s->ptt_out.pariobase = bi.data.mp.pariobase;
759
                s->ptt_out.midiiobase = bi.data.mp.midiiobase;
760
                return 0;
761
 
762
        case HDLCDRVCTL_GETSTAT:
763
                bi.data.cs.ptt = hdlcdrv_ptt(s);
764
                bi.data.cs.dcd = s->hdlcrx.dcd;
765
                bi.data.cs.ptt_keyed = s->ptt_keyed;
766
                bi.data.cs.tx_packets = s->stats.tx_packets;
767
                bi.data.cs.tx_errors = s->stats.tx_errors;
768
                bi.data.cs.rx_packets = s->stats.rx_packets;
769
                bi.data.cs.rx_errors = s->stats.rx_errors;
770
                break;
771
 
772
        case HDLCDRVCTL_OLDGETSTAT:
773
                bi.data.ocs.ptt = hdlcdrv_ptt(s);
774
                bi.data.ocs.dcd = s->hdlcrx.dcd;
775
                bi.data.ocs.ptt_keyed = s->ptt_keyed;
776
#if LINUX_VERSION_CODE < 0x20100
777
                bi.data.ocs.stats = s->stats;
778
#endif
779
                break;
780
 
781
        case HDLCDRVCTL_CALIBRATE:
782
                s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
783
                return 0;
784
 
785
        case HDLCDRVCTL_GETSAMPLES:
786
#ifndef HDLCDRV_DEBUG
787
                return -EPERM;
788
#else /* HDLCDRV_DEBUG */
789
                if (s->bitbuf_channel.rd == s->bitbuf_channel.wr)
790
                        return -EAGAIN;
791
                bi.data.bits =
792
                        s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
793
                s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
794
                        sizeof(s->bitbuf_channel.buffer);
795
                break;
796
#endif /* HDLCDRV_DEBUG */
797
 
798
        case HDLCDRVCTL_GETBITS:
799
#ifndef HDLCDRV_DEBUG
800
                return -EPERM;
801
#else /* HDLCDRV_DEBUG */
802
                if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr)
803
                        return -EAGAIN;
804
                bi.data.bits =
805
                        s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
806
                s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
807
                        sizeof(s->bitbuf_hdlc.buffer);
808
                break;
809
#endif /* HDLCDRV_DEBUG */
810
 
811
        case HDLCDRVCTL_DRIVERNAME:
812
                if (s->ops && s->ops->drvname) {
813
                        strncpy(bi.data.drivername, s->ops->drvname,
814
                                sizeof(bi.data.drivername));
815
                        break;
816
                }
817
                bi.data.drivername[0] = '\0';
818
                break;
819
 
820
        }
821
        if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
822
                return -EFAULT;
823
        return 0;
824
 
825
}
826
 
827
/* --------------------------------------------------------------------- */
828
 
829
/*
830
 * Check for a network adaptor of this type, and return '0' if one exists.
831
 * If dev->base_addr == 0, probe all likely locations.
832
 * If dev->base_addr == 1, always return failure.
833
 * If dev->base_addr == 2, allocate space for the device and return success
834
 * (detachable devices only).
835
 */
836
static int hdlcdrv_probe(struct device *dev)
837
{
838
        const struct hdlcdrv_channel_params dflt_ch_params = {
839
                20, 2, 10, 40, 0
840
        };
841
        struct hdlcdrv_state *s;
842
 
843
        if (!dev)
844
                return -ENXIO;
845
        /*
846
         * not a real probe! only initialize data structures
847
         */
848
        s = (struct hdlcdrv_state *)dev->priv;
849
        /*
850
         * initialize the hdlcdrv_state struct
851
         */
852
        s->ch_params = dflt_ch_params;
853
        s->ptt_keyed = 0;
854
 
855
        s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
856
        s->hdlcrx.in_hdlc_rx = 0;
857
        s->hdlcrx.rx_state = 0;
858
 
859
        s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
860
        s->hdlctx.in_hdlc_tx = 0;
861
        s->hdlctx.tx_state = 1;
862
        s->hdlctx.numflags = 0;
863
        s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
864
        s->hdlctx.ptt = 0;
865
        s->hdlctx.slotcnt = s->ch_params.slottime;
866
        s->hdlctx.calibrate = 0;
867
 
868
#ifdef HDLCDRV_DEBUG
869
        s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
870
        s->bitbuf_channel.shreg = 0x80;
871
 
872
        s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
873
        s->bitbuf_hdlc.shreg = 0x80;
874
#endif /* HDLCDRV_DEBUG */
875
 
876
        /*
877
         * initialize the device struct
878
         */
879
        dev->open = hdlcdrv_open;
880
        dev->stop = hdlcdrv_close;
881
        dev->do_ioctl = hdlcdrv_ioctl;
882
        dev->hard_start_xmit = hdlcdrv_send_packet;
883
        dev->get_stats = hdlcdrv_get_stats;
884
 
885
        /* Fill in the fields of the device structure */
886
 
887
        dev_init_buffers(dev);
888
 
889
        skb_queue_head_init(&s->send_queue);
890
 
891
#if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
892
        dev->hard_header = ax25_encapsulate;
893
        dev->rebuild_header = ax25_rebuild_header;
894
#else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
895
        dev->hard_header = NULL;
896
        dev->rebuild_header = NULL;
897
#endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
898
        dev->set_mac_address = hdlcdrv_set_mac_address;
899
 
900
        dev->type = ARPHRD_AX25;           /* AF_AX25 device */
901
        dev->hard_header_len = 73;         /* We do digipeaters now */
902
        dev->mtu = 1500;                   /* eth_mtu is the default */
903
        dev->addr_len = 7;                 /* sizeof an ax.25 address */
904
        memcpy(dev->broadcast, ax25_bcast, 7);
905
        memcpy(dev->dev_addr, ax25_test, 7);
906
 
907
        /* New style flags */
908
        dev->flags = 0;
909
        dev->family = AF_INET;
910
        dev->pa_addr = 0;
911
        dev->pa_brdaddr = 0;
912
        dev->pa_mask = 0;
913
        dev->pa_alen = sizeof(unsigned long);
914
 
915
        return 0;
916
}
917
 
918
/* --------------------------------------------------------------------- */
919
 
920
int hdlcdrv_register_hdlcdrv(struct device *dev, const struct hdlcdrv_ops *ops,
921
                             unsigned int privsize, char *ifname,
922
                             unsigned int baseaddr, unsigned int irq,
923
                             unsigned int dma)
924
{
925
        struct hdlcdrv_state *s;
926
 
927
        if (!dev || !ops)
928
                return -EACCES;
929
        if (privsize < sizeof(struct hdlcdrv_state))
930
                privsize = sizeof(struct hdlcdrv_state);
931
        memset(dev, 0, sizeof(struct device));
932
        if (!(s = dev->priv = kmalloc(privsize, GFP_KERNEL)))
933
                return -ENOMEM;
934
        /*
935
         * initialize part of the hdlcdrv_state struct
936
         */
937
        memset(s, 0, privsize);
938
        s->magic = HDLCDRV_MAGIC;
939
        strncpy(s->ifname, ifname, sizeof(s->ifname));
940
        s->ops = ops;
941
        /*
942
         * initialize part of the device struct
943
         */
944
        dev->name = s->ifname;
945
        dev->if_port = 0;
946
        dev->init = hdlcdrv_probe;
947
        dev->start = 0;
948
        dev->tbusy = 1;
949
        dev->base_addr = baseaddr;
950
        dev->irq = irq;
951
        dev->dma = dma;
952
        if (register_netdev(dev)) {
953
                printk(KERN_WARNING "hdlcdrv: cannot register net "
954
                       "device %s\n", s->ifname);
955
                kfree(dev->priv);
956
                return -ENXIO;
957
        }
958
        MOD_INC_USE_COUNT;
959
        return 0;
960
}
961
 
962
/* --------------------------------------------------------------------- */
963
 
964
int hdlcdrv_unregister_hdlcdrv(struct device *dev)
965
{
966
        struct hdlcdrv_state *s;
967
 
968
        if (!dev)
969
                return -EINVAL;
970
        if (!(s = (struct hdlcdrv_state *)dev->priv))
971
                return -EINVAL;
972
        if (s->magic != HDLCDRV_MAGIC)
973
                return -EINVAL;
974
        if (dev->start && s->ops->close)
975
                s->ops->close(dev);
976
        unregister_netdev(dev);
977
        kfree(s);
978
        MOD_DEC_USE_COUNT;
979
        return 0;
980
}
981
 
982
/* --------------------------------------------------------------------- */
983
 
984
#if LINUX_VERSION_CODE >= 0x20115
985
 
986
EXPORT_SYMBOL(hdlcdrv_receiver);
987
EXPORT_SYMBOL(hdlcdrv_transmitter);
988
EXPORT_SYMBOL(hdlcdrv_arbitrate);
989
EXPORT_SYMBOL(hdlcdrv_register_hdlcdrv);
990
EXPORT_SYMBOL(hdlcdrv_unregister_hdlcdrv);
991
 
992
#else
993
 
994
static struct symbol_table hdlcdrv_syms = {
995
#include <linux/symtab_begin.h>
996
        X(hdlcdrv_receiver),
997
        X(hdlcdrv_transmitter),
998
        X(hdlcdrv_arbitrate),
999
        X(hdlcdrv_register_hdlcdrv),
1000
        X(hdlcdrv_unregister_hdlcdrv),
1001
#include <linux/symtab_end.h>
1002
};
1003
 
1004
#endif
1005
 
1006
/* --------------------------------------------------------------------- */
1007
 
1008
#ifdef MODULE
1009
 
1010
#if LINUX_VERSION_CODE >= 0x20115
1011
 
1012
MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
1013
MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
1014
 
1015
#endif
1016
 
1017
/* --------------------------------------------------------------------- */
1018
 
1019
__initfunc(int init_module(void))
1020
{
1021
        printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
1022
        printk(KERN_INFO "hdlcdrv: version 0.4 compiled " __TIME__ " " __DATE__ "\n");
1023
#if LINUX_VERSION_CODE < 0x20115
1024
        register_symtab(&hdlcdrv_syms);
1025
#endif
1026
        return 0;
1027
}
1028
 
1029
/* --------------------------------------------------------------------- */
1030
 
1031
void cleanup_module(void)
1032
{
1033
        printk(KERN_INFO "hdlcdrv: cleanup\n");
1034
}
1035
 
1036
#endif /* MODULE */
1037
/* --------------------------------------------------------------------- */

powered by: WebSVN 2.1.0

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