* added 0.99 linux version
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / net / hamradio / hdlcdrv.c
blob67a835b02f988574a853f22638b09fdd3999640a
1 /*****************************************************************************/
3 /*
4 * hdlcdrv.c -- HDLC packet radio network driver.
6 * Copyright (C) 1996-1999 Thomas Sailer (sailer@ife.ee.ethz.ch)
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.
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.
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.
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.
26 * The driver was derived from Donald Beckers skeleton.c
27 * Written 1993-94 by Donald Becker.
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 * 0.5 30.07.97 made HDLC buffers bigger (solves a problem with the
37 * soundmodem driver)
38 * 0.6 05.04.98 add spinlocks
39 * 0.7 03.08.99 removed some old compatibility cruft
42 /*****************************************************************************/
44 #include <linux/config.h>
45 #include <linux/version.h>
46 #include <linux/module.h>
47 #include <linux/types.h>
48 #include <linux/net.h>
49 #include <linux/in.h>
50 #include <linux/if.h>
51 #include <linux/malloc.h>
52 #include <linux/errno.h>
53 #include <linux/init.h>
54 #include <asm/bitops.h>
55 #include <asm/uaccess.h>
57 #include <linux/netdevice.h>
58 #include <linux/if_arp.h>
59 #include <linux/etherdevice.h>
60 #include <linux/skbuff.h>
61 #include <linux/hdlcdrv.h>
62 /* prototypes for ax25_encapsulate and ax25_rebuild_header */
63 #include <net/ax25.h>
65 /* make genksyms happy */
66 #include <linux/ip.h>
67 #include <linux/udp.h>
68 #include <linux/tcp.h>
70 /* --------------------------------------------------------------------- */
73 * The name of the card. Is used for messages and in the requests for
74 * io regions, irqs and dma channels
77 static char ax25_bcast[AX25_ADDR_LEN] =
78 {'Q' << 1, 'S' << 1, 'T' << 1, ' ' << 1, ' ' << 1, ' ' << 1, '0' << 1};
79 static char ax25_nocall[AX25_ADDR_LEN] =
80 {'L' << 1, 'I' << 1, 'N' << 1, 'U' << 1, 'X' << 1, ' ' << 1, '1' << 1};
82 /* --------------------------------------------------------------------- */
84 #define KISS_VERBOSE
86 /* --------------------------------------------------------------------- */
88 #define PARAM_TXDELAY 1
89 #define PARAM_PERSIST 2
90 #define PARAM_SLOTTIME 3
91 #define PARAM_TXTAIL 4
92 #define PARAM_FULLDUP 5
93 #define PARAM_HARDWARE 6
94 #define PARAM_RETURN 255
96 /* --------------------------------------------------------------------- */
98 #define min(a, b) (((a) < (b)) ? (a) : (b))
99 #define max(a, b) (((a) > (b)) ? (a) : (b))
101 /* --------------------------------------------------------------------- */
103 * the CRC routines are stolen from WAMPES
104 * by Dieter Deyke
107 static const unsigned short crc_ccitt_table[] = {
108 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
109 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
110 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
111 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
112 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
113 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
114 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
115 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
116 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
117 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
118 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
119 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
120 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
121 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
122 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
123 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
124 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
125 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
126 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
127 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
128 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
129 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
130 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
131 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
132 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
133 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
134 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
135 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
136 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
137 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
138 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
139 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
142 /*---------------------------------------------------------------------------*/
144 static inline void append_crc_ccitt(unsigned char *buffer, int len)
146 unsigned int crc = 0xffff;
148 for (;len>0;len--)
149 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buffer++) & 0xff];
150 crc ^= 0xffff;
151 *buffer++ = crc;
152 *buffer++ = crc >> 8;
155 /*---------------------------------------------------------------------------*/
157 static inline int check_crc_ccitt(const unsigned char *buf, int cnt)
159 unsigned int crc = 0xffff;
161 for (; cnt > 0; cnt--)
162 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
163 return (crc & 0xffff) == 0xf0b8;
166 /*---------------------------------------------------------------------------*/
168 #if 0
169 static int calc_crc_ccitt(const unsigned char *buf, int cnt)
171 unsigned int crc = 0xffff;
173 for (; cnt > 0; cnt--)
174 crc = (crc >> 8) ^ crc_ccitt_table[(crc ^ *buf++) & 0xff];
175 crc ^= 0xffff;
176 return (crc & 0xffff);
178 #endif
180 /* ---------------------------------------------------------------------- */
182 #define tenms_to_2flags(s,tenms) ((tenms * s->par.bitrate) / 100 / 16)
184 /* ---------------------------------------------------------------------- */
186 * The HDLC routines
189 static int hdlc_rx_add_bytes(struct hdlcdrv_state *s, unsigned int bits,
190 int num)
192 int added = 0;
194 while (s->hdlcrx.rx_state && num >= 8) {
195 if (s->hdlcrx.len >= sizeof(s->hdlcrx.buffer)) {
196 s->hdlcrx.rx_state = 0;
197 return 0;
199 *s->hdlcrx.bp++ = bits >> (32-num);
200 s->hdlcrx.len++;
201 num -= 8;
202 added += 8;
204 return added;
207 static void hdlc_rx_flag(struct net_device *dev, struct hdlcdrv_state *s)
209 struct sk_buff *skb;
210 int pkt_len;
211 unsigned char *cp;
213 if (s->hdlcrx.len < 4)
214 return;
215 if (!check_crc_ccitt(s->hdlcrx.buffer, s->hdlcrx.len))
216 return;
217 pkt_len = s->hdlcrx.len - 2 + 1; /* KISS kludge */
218 if (!(skb = dev_alloc_skb(pkt_len))) {
219 printk("%s: memory squeeze, dropping packet\n",
220 s->ifname);
221 s->stats.rx_dropped++;
222 return;
224 skb->dev = dev;
225 cp = skb_put(skb, pkt_len);
226 *cp++ = 0; /* KISS kludge */
227 memcpy(cp, s->hdlcrx.buffer, pkt_len - 1);
228 skb->protocol = htons(ETH_P_AX25);
229 skb->mac.raw = skb->data;
230 netif_rx(skb);
231 s->stats.rx_packets++;
234 void hdlcdrv_receiver(struct net_device *dev, struct hdlcdrv_state *s)
236 int i;
237 unsigned int mask1, mask2, mask3, mask4, mask5, mask6, word;
239 if (!s || s->magic != HDLCDRV_MAGIC)
240 return;
241 if (test_and_set_bit(0, &s->hdlcrx.in_hdlc_rx))
242 return;
244 while (!hdlcdrv_hbuf_empty(&s->hdlcrx.hbuf)) {
245 word = hdlcdrv_hbuf_get(&s->hdlcrx.hbuf);
247 #ifdef HDLCDRV_DEBUG
248 hdlcdrv_add_bitbuffer_word(&s->bitbuf_hdlc, word);
249 #endif /* HDLCDRV_DEBUG */
250 s->hdlcrx.bitstream >>= 16;
251 s->hdlcrx.bitstream |= word << 16;
252 s->hdlcrx.bitbuf >>= 16;
253 s->hdlcrx.bitbuf |= word << 16;
254 s->hdlcrx.numbits += 16;
255 for(i = 15, mask1 = 0x1fc00, mask2 = 0x1fe00, mask3 = 0x0fc00,
256 mask4 = 0x1f800, mask5 = 0xf800, mask6 = 0xffff;
257 i >= 0;
258 i--, mask1 <<= 1, mask2 <<= 1, mask3 <<= 1, mask4 <<= 1,
259 mask5 <<= 1, mask6 = (mask6 << 1) | 1) {
260 if ((s->hdlcrx.bitstream & mask1) == mask1)
261 s->hdlcrx.rx_state = 0; /* abort received */
262 else if ((s->hdlcrx.bitstream & mask2) == mask3) {
263 /* flag received */
264 if (s->hdlcrx.rx_state) {
265 hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf
266 << (8+i),
267 s->hdlcrx.numbits
268 -8-i);
269 hdlc_rx_flag(dev, s);
271 s->hdlcrx.len = 0;
272 s->hdlcrx.bp = s->hdlcrx.buffer;
273 s->hdlcrx.rx_state = 1;
274 s->hdlcrx.numbits = i;
275 } else if ((s->hdlcrx.bitstream & mask4) == mask5) {
276 /* stuffed bit */
277 s->hdlcrx.numbits--;
278 s->hdlcrx.bitbuf = (s->hdlcrx.bitbuf & (~mask6)) |
279 ((s->hdlcrx.bitbuf & mask6) << 1);
282 s->hdlcrx.numbits -= hdlc_rx_add_bytes(s, s->hdlcrx.bitbuf,
283 s->hdlcrx.numbits);
285 clear_bit(0, &s->hdlcrx.in_hdlc_rx);
288 /* ---------------------------------------------------------------------- */
290 static void inline do_kiss_params(struct hdlcdrv_state *s,
291 unsigned char *data, unsigned long len)
294 #ifdef KISS_VERBOSE
295 #define PKP(a,b) printk(KERN_INFO "%s: channel params: " a "\n", s->ifname, b)
296 #else /* KISS_VERBOSE */
297 #define PKP(a,b)
298 #endif /* KISS_VERBOSE */
300 if (len < 2)
301 return;
302 switch(data[0]) {
303 case PARAM_TXDELAY:
304 s->ch_params.tx_delay = data[1];
305 PKP("TX delay = %ums", 10 * s->ch_params.tx_delay);
306 break;
307 case PARAM_PERSIST:
308 s->ch_params.ppersist = data[1];
309 PKP("p persistence = %u", s->ch_params.ppersist);
310 break;
311 case PARAM_SLOTTIME:
312 s->ch_params.slottime = data[1];
313 PKP("slot time = %ums", s->ch_params.slottime);
314 break;
315 case PARAM_TXTAIL:
316 s->ch_params.tx_tail = data[1];
317 PKP("TX tail = %ums", s->ch_params.tx_tail);
318 break;
319 case PARAM_FULLDUP:
320 s->ch_params.fulldup = !!data[1];
321 PKP("%s duplex", s->ch_params.fulldup ? "full" : "half");
322 break;
323 default:
324 break;
326 #undef PKP
329 /* ---------------------------------------------------------------------- */
331 void hdlcdrv_transmitter(struct net_device *dev, struct hdlcdrv_state *s)
333 unsigned int mask1, mask2, mask3;
334 int i;
335 struct sk_buff *skb;
336 int pkt_len;
338 if (!s || s->magic != HDLCDRV_MAGIC)
339 return;
340 if (test_and_set_bit(0, &s->hdlctx.in_hdlc_tx))
341 return;
342 for (;;) {
343 if (s->hdlctx.numbits >= 16) {
344 if (hdlcdrv_hbuf_full(&s->hdlctx.hbuf)) {
345 clear_bit(0, &s->hdlctx.in_hdlc_tx);
346 return;
348 hdlcdrv_hbuf_put(&s->hdlctx.hbuf, s->hdlctx.bitbuf);
349 s->hdlctx.bitbuf >>= 16;
350 s->hdlctx.numbits -= 16;
352 switch (s->hdlctx.tx_state) {
353 default:
354 clear_bit(0, &s->hdlctx.in_hdlc_tx);
355 return;
356 case 0:
357 case 1:
358 if (s->hdlctx.numflags) {
359 s->hdlctx.numflags--;
360 s->hdlctx.bitbuf |=
361 0x7e7e << s->hdlctx.numbits;
362 s->hdlctx.numbits += 16;
363 break;
365 if (s->hdlctx.tx_state == 1) {
366 clear_bit(0, &s->hdlctx.in_hdlc_tx);
367 return;
369 if (!(skb = skb_dequeue(&s->send_queue))) {
370 int flgs = tenms_to_2flags
371 (s, s->ch_params.tx_tail);
372 if (flgs < 2)
373 flgs = 2;
374 s->hdlctx.tx_state = 1;
375 s->hdlctx.numflags = flgs;
376 break;
378 if (skb->data[0] != 0) {
379 do_kiss_params(s, skb->data, skb->len);
380 dev_kfree_skb(skb);
381 break;
383 pkt_len = skb->len-1; /* strip KISS byte */
384 if (pkt_len >= HDLCDRV_MAXFLEN || pkt_len < 2) {
385 s->hdlctx.tx_state = 0;
386 s->hdlctx.numflags = 1;
387 dev_kfree_skb(skb);
388 break;
390 memcpy(s->hdlctx.buffer, skb->data+1, pkt_len);
391 dev_kfree_skb(skb);
392 s->hdlctx.bp = s->hdlctx.buffer;
393 append_crc_ccitt(s->hdlctx.buffer, pkt_len);
394 s->hdlctx.len = pkt_len+2; /* the appended CRC */
395 s->hdlctx.tx_state = 2;
396 s->hdlctx.bitstream = 0;
397 s->stats.tx_packets++;
398 break;
399 case 2:
400 if (!s->hdlctx.len) {
401 s->hdlctx.tx_state = 0;
402 s->hdlctx.numflags = 1;
403 break;
405 s->hdlctx.len--;
406 s->hdlctx.bitbuf |= *s->hdlctx.bp <<
407 s->hdlctx.numbits;
408 s->hdlctx.bitstream >>= 8;
409 s->hdlctx.bitstream |= (*s->hdlctx.bp++) << 16;
410 mask1 = 0x1f000;
411 mask2 = 0x10000;
412 mask3 = 0xffffffff >> (31-s->hdlctx.numbits);
413 s->hdlctx.numbits += 8;
414 for(i = 0; i < 8; i++, mask1 <<= 1, mask2 <<= 1,
415 mask3 = (mask3 << 1) | 1) {
416 if ((s->hdlctx.bitstream & mask1) != mask1)
417 continue;
418 s->hdlctx.bitstream &= ~mask2;
419 s->hdlctx.bitbuf =
420 (s->hdlctx.bitbuf & mask3) |
421 ((s->hdlctx.bitbuf &
422 (~mask3)) << 1);
423 s->hdlctx.numbits++;
424 mask3 = (mask3 << 1) | 1;
426 break;
431 /* ---------------------------------------------------------------------- */
433 static void start_tx(struct net_device *dev, struct hdlcdrv_state *s)
435 s->hdlctx.tx_state = 0;
436 s->hdlctx.numflags = tenms_to_2flags(s, s->ch_params.tx_delay);
437 s->hdlctx.bitbuf = s->hdlctx.bitstream = s->hdlctx.numbits = 0;
438 hdlcdrv_transmitter(dev, s);
439 s->hdlctx.ptt = 1;
440 s->ptt_keyed++;
443 /* ---------------------------------------------------------------------- */
445 static unsigned short random_seed;
447 static inline unsigned short random_num(void)
449 random_seed = 28629 * random_seed + 157;
450 return random_seed;
453 /* ---------------------------------------------------------------------- */
455 void hdlcdrv_arbitrate(struct net_device *dev, struct hdlcdrv_state *s)
457 if (!s || s->magic != HDLCDRV_MAGIC || s->hdlctx.ptt ||
458 skb_queue_empty(&s->send_queue))
459 return;
460 if (s->ch_params.fulldup) {
461 start_tx(dev, s);
462 return;
464 if (s->hdlcrx.dcd) {
465 s->hdlctx.slotcnt = s->ch_params.slottime;
466 return;
468 if ((--s->hdlctx.slotcnt) > 0)
469 return;
470 s->hdlctx.slotcnt = s->ch_params.slottime;
471 if ((random_num() % 256) > s->ch_params.ppersist)
472 return;
473 start_tx(dev, s);
476 /* --------------------------------------------------------------------- */
478 * ===================== network driver interface =========================
481 static inline int hdlcdrv_paranoia_check(struct net_device *dev,
482 const char *routine)
484 if (!dev || !dev->priv ||
485 ((struct hdlcdrv_state *)dev->priv)->magic != HDLCDRV_MAGIC) {
486 printk(KERN_ERR "hdlcdrv: bad magic number for hdlcdrv_state "
487 "struct in routine %s\n", routine);
488 return 1;
490 return 0;
493 /* --------------------------------------------------------------------- */
495 static int hdlcdrv_send_packet(struct sk_buff *skb, struct net_device *dev)
497 struct hdlcdrv_state *sm;
499 if (hdlcdrv_paranoia_check(dev, "hdlcdrv_send_packet"))
500 return 0;
501 sm = (struct hdlcdrv_state *)dev->priv;
502 skb_queue_tail(&sm->send_queue, skb);
503 dev->trans_start = jiffies;
504 return 0;
507 /* --------------------------------------------------------------------- */
509 static int hdlcdrv_set_mac_address(struct net_device *dev, void *addr)
511 struct sockaddr *sa = (struct sockaddr *)addr;
513 /* addr is an AX.25 shifted ASCII mac address */
514 memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
515 return 0;
518 /* --------------------------------------------------------------------- */
520 static struct net_device_stats *hdlcdrv_get_stats(struct net_device *dev)
522 struct hdlcdrv_state *sm;
524 if (hdlcdrv_paranoia_check(dev, "hdlcdrv_get_stats"))
525 return NULL;
526 sm = (struct hdlcdrv_state *)dev->priv;
528 * Get the current statistics. This may be called with the
529 * card open or closed.
531 return &sm->stats;
534 /* --------------------------------------------------------------------- */
536 * Open/initialize the board. This is called (in the current kernel)
537 * sometime after booting when the 'ifconfig' program is run.
539 * This routine should set everything up anew at each open, even
540 * registers that "should" only need to be set once at boot, so that
541 * there is non-reboot way to recover if something goes wrong.
544 static int hdlcdrv_open(struct net_device *dev)
546 struct hdlcdrv_state *s;
547 int i;
549 if (hdlcdrv_paranoia_check(dev, "hdlcdrv_open"))
550 return -EINVAL;
551 s = (struct hdlcdrv_state *)dev->priv;
553 if (dev->start)
554 return 0;
555 if (!s->ops || !s->ops->open)
556 return -ENODEV;
558 dev->start = 1;
560 * initialise some variables
562 s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
563 s->hdlcrx.in_hdlc_rx = 0;
564 s->hdlcrx.rx_state = 0;
566 s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
567 s->hdlctx.in_hdlc_tx = 0;
568 s->hdlctx.tx_state = 1;
569 s->hdlctx.numflags = 0;
570 s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
571 s->hdlctx.ptt = 0;
572 s->hdlctx.slotcnt = s->ch_params.slottime;
573 s->hdlctx.calibrate = 0;
575 i = s->ops->open(dev);
576 if (i) {
577 dev->start = 0;
578 return i;
581 dev->tbusy = 0;
582 dev->interrupt = 0;
584 return 0;
587 /* --------------------------------------------------------------------- */
589 * The inverse routine to hdlcdrv_open().
592 static int hdlcdrv_close(struct net_device *dev)
594 struct hdlcdrv_state *s;
595 struct sk_buff *skb;
596 int i = 0;
598 if (hdlcdrv_paranoia_check(dev, "hdlcdrv_close"))
599 return -EINVAL;
600 s = (struct hdlcdrv_state *)dev->priv;
602 if (!dev->start)
603 return 0;
604 dev->start = 0;
605 dev->tbusy = 1;
607 if (s->ops && s->ops->close)
608 i = s->ops->close(dev);
609 /* Free any buffers left in the hardware transmit queue */
610 while ((skb = skb_dequeue(&s->send_queue)))
611 dev_kfree_skb(skb);
612 return i;
615 /* --------------------------------------------------------------------- */
617 static int hdlcdrv_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
619 struct hdlcdrv_state *s;
620 struct hdlcdrv_ioctl bi;
622 if (hdlcdrv_paranoia_check(dev, "hdlcdrv_ioctl"))
623 return -EINVAL;
624 s = (struct hdlcdrv_state *)dev->priv;
626 if (cmd != SIOCDEVPRIVATE) {
627 if (s->ops && s->ops->ioctl)
628 return s->ops->ioctl(dev, ifr, &bi, cmd);
629 return -ENOIOCTLCMD;
631 if (copy_from_user(&bi, ifr->ifr_data, sizeof(bi)))
632 return -EFAULT;
634 switch (bi.cmd) {
635 default:
636 if (s->ops && s->ops->ioctl)
637 return s->ops->ioctl(dev, ifr, &bi, cmd);
638 return -ENOIOCTLCMD;
640 case HDLCDRVCTL_GETCHANNELPAR:
641 bi.data.cp.tx_delay = s->ch_params.tx_delay;
642 bi.data.cp.tx_tail = s->ch_params.tx_tail;
643 bi.data.cp.slottime = s->ch_params.slottime;
644 bi.data.cp.ppersist = s->ch_params.ppersist;
645 bi.data.cp.fulldup = s->ch_params.fulldup;
646 break;
648 case HDLCDRVCTL_SETCHANNELPAR:
649 if (!suser())
650 return -EACCES;
651 s->ch_params.tx_delay = bi.data.cp.tx_delay;
652 s->ch_params.tx_tail = bi.data.cp.tx_tail;
653 s->ch_params.slottime = bi.data.cp.slottime;
654 s->ch_params.ppersist = bi.data.cp.ppersist;
655 s->ch_params.fulldup = bi.data.cp.fulldup;
656 s->hdlctx.slotcnt = 1;
657 return 0;
659 case HDLCDRVCTL_GETMODEMPAR:
660 bi.data.mp.iobase = dev->base_addr;
661 bi.data.mp.irq = dev->irq;
662 bi.data.mp.dma = dev->dma;
663 bi.data.mp.dma2 = s->ptt_out.dma2;
664 bi.data.mp.seriobase = s->ptt_out.seriobase;
665 bi.data.mp.pariobase = s->ptt_out.pariobase;
666 bi.data.mp.midiiobase = s->ptt_out.midiiobase;
667 break;
669 case HDLCDRVCTL_SETMODEMPAR:
670 if ((!suser()) || dev->start)
671 return -EACCES;
672 dev->base_addr = bi.data.mp.iobase;
673 dev->irq = bi.data.mp.irq;
674 dev->dma = bi.data.mp.dma;
675 s->ptt_out.dma2 = bi.data.mp.dma2;
676 s->ptt_out.seriobase = bi.data.mp.seriobase;
677 s->ptt_out.pariobase = bi.data.mp.pariobase;
678 s->ptt_out.midiiobase = bi.data.mp.midiiobase;
679 return 0;
681 case HDLCDRVCTL_GETSTAT:
682 bi.data.cs.ptt = hdlcdrv_ptt(s);
683 bi.data.cs.dcd = s->hdlcrx.dcd;
684 bi.data.cs.ptt_keyed = s->ptt_keyed;
685 bi.data.cs.tx_packets = s->stats.tx_packets;
686 bi.data.cs.tx_errors = s->stats.tx_errors;
687 bi.data.cs.rx_packets = s->stats.rx_packets;
688 bi.data.cs.rx_errors = s->stats.rx_errors;
689 break;
691 case HDLCDRVCTL_OLDGETSTAT:
692 bi.data.ocs.ptt = hdlcdrv_ptt(s);
693 bi.data.ocs.dcd = s->hdlcrx.dcd;
694 bi.data.ocs.ptt_keyed = s->ptt_keyed;
695 break;
697 case HDLCDRVCTL_CALIBRATE:
698 s->hdlctx.calibrate = bi.data.calibrate * s->par.bitrate / 16;
699 return 0;
701 case HDLCDRVCTL_GETSAMPLES:
702 #ifndef HDLCDRV_DEBUG
703 return -EPERM;
704 #else /* HDLCDRV_DEBUG */
705 if (s->bitbuf_channel.rd == s->bitbuf_channel.wr)
706 return -EAGAIN;
707 bi.data.bits =
708 s->bitbuf_channel.buffer[s->bitbuf_channel.rd];
709 s->bitbuf_channel.rd = (s->bitbuf_channel.rd+1) %
710 sizeof(s->bitbuf_channel.buffer);
711 break;
712 #endif /* HDLCDRV_DEBUG */
714 case HDLCDRVCTL_GETBITS:
715 #ifndef HDLCDRV_DEBUG
716 return -EPERM;
717 #else /* HDLCDRV_DEBUG */
718 if (s->bitbuf_hdlc.rd == s->bitbuf_hdlc.wr)
719 return -EAGAIN;
720 bi.data.bits =
721 s->bitbuf_hdlc.buffer[s->bitbuf_hdlc.rd];
722 s->bitbuf_hdlc.rd = (s->bitbuf_hdlc.rd+1) %
723 sizeof(s->bitbuf_hdlc.buffer);
724 break;
725 #endif /* HDLCDRV_DEBUG */
727 case HDLCDRVCTL_DRIVERNAME:
728 if (s->ops && s->ops->drvname) {
729 strncpy(bi.data.drivername, s->ops->drvname,
730 sizeof(bi.data.drivername));
731 break;
733 bi.data.drivername[0] = '\0';
734 break;
737 if (copy_to_user(ifr->ifr_data, &bi, sizeof(bi)))
738 return -EFAULT;
739 return 0;
743 /* --------------------------------------------------------------------- */
746 * Check for a network adaptor of this type, and return '0' if one exists.
747 * If dev->base_addr == 0, probe all likely locations.
748 * If dev->base_addr == 1, always return failure.
749 * If dev->base_addr == 2, allocate space for the device and return success
750 * (detachable devices only).
752 static int hdlcdrv_probe(struct net_device *dev)
754 const struct hdlcdrv_channel_params dflt_ch_params = {
755 20, 2, 10, 40, 0
757 struct hdlcdrv_state *s;
759 if (!dev)
760 return -ENXIO;
762 * not a real probe! only initialize data structures
764 s = (struct hdlcdrv_state *)dev->priv;
766 * initialize the hdlcdrv_state struct
768 s->ch_params = dflt_ch_params;
769 s->ptt_keyed = 0;
771 spin_lock_init(&s->hdlcrx.hbuf.lock);
772 s->hdlcrx.hbuf.rd = s->hdlcrx.hbuf.wr = 0;
773 s->hdlcrx.in_hdlc_rx = 0;
774 s->hdlcrx.rx_state = 0;
776 spin_lock_init(&s->hdlctx.hbuf.lock);
777 s->hdlctx.hbuf.rd = s->hdlctx.hbuf.wr = 0;
778 s->hdlctx.in_hdlc_tx = 0;
779 s->hdlctx.tx_state = 1;
780 s->hdlctx.numflags = 0;
781 s->hdlctx.bitstream = s->hdlctx.bitbuf = s->hdlctx.numbits = 0;
782 s->hdlctx.ptt = 0;
783 s->hdlctx.slotcnt = s->ch_params.slottime;
784 s->hdlctx.calibrate = 0;
786 #ifdef HDLCDRV_DEBUG
787 s->bitbuf_channel.rd = s->bitbuf_channel.wr = 0;
788 s->bitbuf_channel.shreg = 0x80;
790 s->bitbuf_hdlc.rd = s->bitbuf_hdlc.wr = 0;
791 s->bitbuf_hdlc.shreg = 0x80;
792 #endif /* HDLCDRV_DEBUG */
795 * initialize the device struct
797 dev->open = hdlcdrv_open;
798 dev->stop = hdlcdrv_close;
799 dev->do_ioctl = hdlcdrv_ioctl;
800 dev->hard_start_xmit = hdlcdrv_send_packet;
801 dev->get_stats = hdlcdrv_get_stats;
803 /* Fill in the fields of the device structure */
805 dev_init_buffers(dev);
807 skb_queue_head_init(&s->send_queue);
809 #if defined(CONFIG_AX25) || defined(CONFIG_AX25_MODULE)
810 dev->hard_header = ax25_encapsulate;
811 dev->rebuild_header = ax25_rebuild_header;
812 #else /* CONFIG_AX25 || CONFIG_AX25_MODULE */
813 dev->hard_header = NULL;
814 dev->rebuild_header = NULL;
815 #endif /* CONFIG_AX25 || CONFIG_AX25_MODULE */
816 dev->set_mac_address = hdlcdrv_set_mac_address;
818 dev->type = ARPHRD_AX25; /* AF_AX25 device */
819 dev->hard_header_len = AX25_MAX_HEADER_LEN + AX25_BPQ_HEADER_LEN;
820 dev->mtu = AX25_DEF_PACLEN; /* eth_mtu is the default */
821 dev->addr_len = AX25_ADDR_LEN; /* sizeof an ax.25 address */
822 memcpy(dev->broadcast, ax25_bcast, AX25_ADDR_LEN);
823 memcpy(dev->dev_addr, ax25_nocall, AX25_ADDR_LEN);
825 /* New style flags */
826 dev->flags = 0;
828 return 0;
831 /* --------------------------------------------------------------------- */
833 int hdlcdrv_register_hdlcdrv(struct net_device *dev, const struct hdlcdrv_ops *ops,
834 unsigned int privsize, char *ifname,
835 unsigned int baseaddr, unsigned int irq,
836 unsigned int dma)
838 struct hdlcdrv_state *s;
840 if (!dev || !ops)
841 return -EACCES;
842 if (privsize < sizeof(struct hdlcdrv_state))
843 privsize = sizeof(struct hdlcdrv_state);
844 memset(dev, 0, sizeof(struct net_device));
845 if (!(s = dev->priv = kmalloc(privsize, GFP_KERNEL)))
846 return -ENOMEM;
848 * initialize part of the hdlcdrv_state struct
850 memset(s, 0, privsize);
851 s->magic = HDLCDRV_MAGIC;
852 strncpy(s->ifname, ifname, sizeof(s->ifname));
853 s->ops = ops;
855 * initialize part of the device struct
857 dev->name = s->ifname;
858 dev->if_port = 0;
859 dev->init = hdlcdrv_probe;
860 dev->start = 0;
861 dev->tbusy = 1;
862 dev->base_addr = baseaddr;
863 dev->irq = irq;
864 dev->dma = dma;
865 if (register_netdev(dev)) {
866 printk(KERN_WARNING "hdlcdrv: cannot register net "
867 "device %s\n", s->ifname);
868 kfree(dev->priv);
869 return -ENXIO;
871 MOD_INC_USE_COUNT;
872 return 0;
875 /* --------------------------------------------------------------------- */
877 int hdlcdrv_unregister_hdlcdrv(struct net_device *dev)
879 struct hdlcdrv_state *s;
881 if (!dev)
882 return -EINVAL;
883 if (!(s = (struct hdlcdrv_state *)dev->priv))
884 return -EINVAL;
885 if (s->magic != HDLCDRV_MAGIC)
886 return -EINVAL;
887 if (dev->start && s->ops->close)
888 s->ops->close(dev);
889 unregister_netdev(dev);
890 kfree(s);
891 MOD_DEC_USE_COUNT;
892 return 0;
895 /* --------------------------------------------------------------------- */
897 EXPORT_SYMBOL(hdlcdrv_receiver);
898 EXPORT_SYMBOL(hdlcdrv_transmitter);
899 EXPORT_SYMBOL(hdlcdrv_arbitrate);
900 EXPORT_SYMBOL(hdlcdrv_register_hdlcdrv);
901 EXPORT_SYMBOL(hdlcdrv_unregister_hdlcdrv);
903 /* --------------------------------------------------------------------- */
905 #ifdef MODULE
907 MODULE_AUTHOR("Thomas M. Sailer, sailer@ife.ee.ethz.ch, hb9jnx@hb9w.che.eu");
908 MODULE_DESCRIPTION("Packet Radio network interface HDLC encoder/decoder");
910 /* --------------------------------------------------------------------- */
912 int __init init_module(void)
914 printk(KERN_INFO "hdlcdrv: (C) 1996 Thomas Sailer HB9JNX/AE4WA\n");
915 printk(KERN_INFO "hdlcdrv: version 0.7 compiled " __TIME__ " " __DATE__ "\n");
916 return 0;
919 /* --------------------------------------------------------------------- */
921 void cleanup_module(void)
923 printk(KERN_INFO "hdlcdrv: cleanup\n");
926 #endif /* MODULE */
927 /* --------------------------------------------------------------------- */