* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / drivers / net / ppp_async.c
blob552061da11d0137da73145b09696726142c89c0b
1 /*
2 * PPP async serial channel driver for Linux.
4 * Copyright 1999 Paul Mackerras.
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
11 * This driver provides the encapsulation and framing for sending
12 * and receiving PPP frames over async serial lines. It relies on
13 * the generic PPP layer to give it frames to send and to process
14 * received frames. It implements the PPP line discipline.
16 * Part of the code in this driver was inspired by the old async-only
17 * PPP driver, written by Michael Callahan and Al Longyear, and
18 * subsequently hacked by Paul Mackerras.
20 * ==FILEVERSION 990806==
23 /* $Id: ppp_async.c,v 1.3 1999/09/02 05:30:10 paulus Exp $ */
25 #include <linux/module.h>
26 #include <linux/kernel.h>
27 #include <linux/skbuff.h>
28 #include <linux/tty.h>
29 #include <linux/netdevice.h>
30 #include <linux/poll.h>
31 #include <linux/ppp_defs.h>
32 #include <linux/if_ppp.h>
33 #include <linux/ppp_channel.h>
34 #include <asm/uaccess.h>
36 #define PPP_VERSION "2.4.0"
38 #define OBUFSIZE 256
40 /* Structure for storing local state. */
41 struct asyncppp {
42 struct tty_struct *tty;
43 unsigned int flags;
44 unsigned int state;
45 unsigned int rbits;
46 int mru;
47 unsigned long busy;
48 u32 xaccm[8];
49 u32 raccm;
50 unsigned int bytes_sent;
51 unsigned int bytes_rcvd;
53 struct sk_buff *tpkt;
54 int tpkt_pos;
55 u16 tfcs;
56 unsigned char *optr;
57 unsigned char *olim;
58 struct sk_buff_head xq;
59 unsigned long last_xmit;
61 struct sk_buff *rpkt;
62 struct sk_buff_head rq;
63 wait_queue_head_t rwait;
65 struct ppp_channel chan; /* interface to generic ppp layer */
66 int connected;
67 unsigned char obuf[OBUFSIZE];
70 /* Bit numbers in busy */
71 #define XMIT_BUSY 0
72 #define RECV_BUSY 1
73 #define XMIT_WAKEUP 2
74 #define XMIT_FULL 3
76 /* State bits */
77 #define SC_TOSS 0x20000000
78 #define SC_ESCAPE 0x40000000
80 /* Bits in rbits */
81 #define SC_RCV_BITS (SC_RCV_B7_1|SC_RCV_B7_0|SC_RCV_ODDP|SC_RCV_EVNP)
83 #define PPPASYNC_MAX_RQLEN 32 /* arbitrary */
85 static int flag_time = HZ;
86 MODULE_PARM(flag_time, "i");
89 * Prototypes.
91 static int ppp_async_encode(struct asyncppp *ap);
92 static int ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb);
93 static int ppp_async_push(struct asyncppp *ap);
94 static void ppp_async_flush_output(struct asyncppp *ap);
95 static void ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
96 char *flags, int count);
98 struct ppp_channel_ops async_ops = {
99 ppp_async_send
103 * Routines for locking and unlocking the transmit and receive paths.
105 static inline void
106 lock_path(struct asyncppp *ap, int bit)
108 do {
109 while (test_bit(bit, &ap->busy))
110 mb();
111 } while (test_and_set_bit(bit, &ap->busy));
112 mb();
115 static inline int
116 trylock_path(struct asyncppp *ap, int bit)
118 if (test_and_set_bit(bit, &ap->busy))
119 return 0;
120 mb();
121 return 1;
124 static inline void
125 unlock_path(struct asyncppp *ap, int bit)
127 mb();
128 clear_bit(bit, &ap->busy);
131 #define lock_xmit_path(ap) lock_path(ap, XMIT_BUSY)
132 #define trylock_xmit_path(ap) trylock_path(ap, XMIT_BUSY)
133 #define unlock_xmit_path(ap) unlock_path(ap, XMIT_BUSY)
134 #define lock_recv_path(ap) lock_path(ap, RECV_BUSY)
135 #define trylock_recv_path(ap) trylock_path(ap, RECV_BUSY)
136 #define unlock_recv_path(ap) unlock_path(ap, RECV_BUSY)
138 static inline void
139 flush_skb_queue(struct sk_buff_head *q)
141 struct sk_buff *skb;
143 while ((skb = skb_dequeue(q)) != 0)
144 kfree_skb(skb);
148 * Routines implementing the PPP line discipline.
152 * Called when a tty is put into PPP line discipline.
154 static int
155 ppp_async_open(struct tty_struct *tty)
157 struct asyncppp *ap;
159 ap = kmalloc(sizeof(*ap), GFP_KERNEL);
160 if (ap == 0)
161 return -ENOMEM;
163 MOD_INC_USE_COUNT;
165 /* initialize the asyncppp structure */
166 memset(ap, 0, sizeof(*ap));
167 ap->tty = tty;
168 ap->mru = PPP_MRU;
169 ap->xaccm[0] = ~0U;
170 ap->xaccm[3] = 0x60000000U;
171 ap->raccm = ~0U;
172 ap->optr = ap->obuf;
173 ap->olim = ap->obuf;
174 skb_queue_head_init(&ap->xq);
175 skb_queue_head_init(&ap->rq);
176 init_waitqueue_head(&ap->rwait);
178 tty->disc_data = ap;
180 return 0;
184 * Called when the tty is put into another line discipline
185 * (or it hangs up).
187 static void
188 ppp_async_close(struct tty_struct *tty)
190 struct asyncppp *ap = tty->disc_data;
192 if (ap == 0)
193 return;
194 tty->disc_data = 0;
195 lock_xmit_path(ap);
196 lock_recv_path(ap);
197 if (ap->rpkt != 0)
198 kfree_skb(ap->rpkt);
199 flush_skb_queue(&ap->rq);
200 if (ap->tpkt != 0)
201 kfree_skb(ap->tpkt);
202 flush_skb_queue(&ap->xq);
203 if (ap->connected)
204 ppp_unregister_channel(&ap->chan);
205 kfree(ap);
206 MOD_DEC_USE_COUNT;
210 * Read a PPP frame. pppd can use this to negotiate over the
211 * channel before it joins it to a bundle.
213 static ssize_t
214 ppp_async_read(struct tty_struct *tty, struct file *file,
215 unsigned char *buf, size_t count)
217 struct asyncppp *ap = tty->disc_data;
218 DECLARE_WAITQUEUE(wait, current);
219 ssize_t ret;
220 struct sk_buff *skb = 0;
222 ret = -ENXIO;
223 if (ap == 0)
224 goto out; /* should never happen */
226 add_wait_queue(&ap->rwait, &wait);
227 current->state = TASK_INTERRUPTIBLE;
228 for (;;) {
229 ret = -EAGAIN;
230 skb = skb_dequeue(&ap->rq);
231 if (skb)
232 break;
233 if (file->f_flags & O_NONBLOCK)
234 break;
235 ret = -ERESTARTSYS;
236 if (signal_pending(current))
237 break;
238 schedule();
240 current->state = TASK_RUNNING;
241 remove_wait_queue(&ap->rwait, &wait);
243 if (skb == 0)
244 goto out;
246 ret = -EOVERFLOW;
247 if (skb->len > count)
248 goto outf;
249 ret = -EFAULT;
250 if (copy_to_user(buf, skb->data, skb->len))
251 goto outf;
252 ret = skb->len;
254 outf:
255 kfree_skb(skb);
256 out:
257 return ret;
261 * Write a ppp frame. pppd can use this to send frames over
262 * this particular channel.
264 static ssize_t
265 ppp_async_write(struct tty_struct *tty, struct file *file,
266 const unsigned char *buf, size_t count)
268 struct asyncppp *ap = tty->disc_data;
269 struct sk_buff *skb;
270 ssize_t ret;
272 ret = -ENXIO;
273 if (ap == 0)
274 goto out; /* should never happen */
276 ret = -ENOMEM;
277 skb = alloc_skb(count + 2, GFP_KERNEL);
278 if (skb == 0)
279 goto out;
280 skb_reserve(skb, 2);
281 ret = -EFAULT;
282 if (copy_from_user(skb_put(skb, count), buf, count)) {
283 kfree_skb(skb);
284 goto out;
287 skb_queue_tail(&ap->xq, skb);
288 ppp_async_push(ap);
290 ret = count;
292 out:
293 return ret;
296 static int
297 ppp_async_ioctl(struct tty_struct *tty, struct file *file,
298 unsigned int cmd, unsigned long arg)
300 struct asyncppp *ap = tty->disc_data;
301 int err, val;
302 u32 accm[8];
303 struct sk_buff *skb;
305 err = -ENXIO;
306 if (ap == 0)
307 goto out; /* should never happen */
308 err = -EPERM;
309 if (!capable(CAP_NET_ADMIN))
310 goto out;
312 err = -EFAULT;
313 switch (cmd) {
314 case PPPIOCGFLAGS:
315 val = ap->flags | ap->rbits;
316 if (put_user(val, (int *) arg))
317 break;
318 err = 0;
319 break;
320 case PPPIOCSFLAGS:
321 if (get_user(val, (int *) arg))
322 break;
323 ap->flags = val & ~SC_RCV_BITS;
324 ap->rbits = val & SC_RCV_BITS;
325 err = 0;
326 break;
328 case PPPIOCGASYNCMAP:
329 if (put_user(ap->xaccm[0], (u32 *) arg))
330 break;
331 err = 0;
332 break;
333 case PPPIOCSASYNCMAP:
334 if (get_user(ap->xaccm[0], (u32 *) arg))
335 break;
336 err = 0;
337 break;
339 case PPPIOCGRASYNCMAP:
340 if (put_user(ap->raccm, (u32 *) arg))
341 break;
342 err = 0;
343 break;
344 case PPPIOCSRASYNCMAP:
345 if (get_user(ap->raccm, (u32 *) arg))
346 break;
347 err = 0;
348 break;
350 case PPPIOCGXASYNCMAP:
351 if (copy_to_user((void *) arg, ap->xaccm, sizeof(ap->xaccm)))
352 break;
353 err = 0;
354 break;
355 case PPPIOCSXASYNCMAP:
356 if (copy_from_user(accm, (void *) arg, sizeof(accm)))
357 break;
358 accm[2] &= ~0x40000000U; /* can't escape 0x5e */
359 accm[3] |= 0x60000000U; /* must escape 0x7d, 0x7e */
360 memcpy(ap->xaccm, accm, sizeof(ap->xaccm));
361 err = 0;
362 break;
364 case PPPIOCGMRU:
365 if (put_user(ap->mru, (int *) arg))
366 break;
367 err = 0;
368 break;
369 case PPPIOCSMRU:
370 if (get_user(val, (int *) arg))
371 break;
372 if (val < PPP_MRU)
373 val = PPP_MRU;
374 ap->mru = val;
375 err = 0;
376 break;
378 case PPPIOCATTACH:
379 if (get_user(val, (int *) arg))
380 break;
381 err = -EALREADY;
382 if (ap->connected)
383 break;
384 ap->chan.private = ap;
385 ap->chan.ops = &async_ops;
386 err = ppp_register_channel(&ap->chan, val);
387 if (err != 0)
388 break;
389 ap->connected = 1;
390 break;
391 case PPPIOCDETACH:
392 err = -ENXIO;
393 if (!ap->connected)
394 break;
395 ppp_unregister_channel(&ap->chan);
396 ap->connected = 0;
397 err = 0;
398 break;
400 case TCGETS:
401 case TCGETA:
402 err = n_tty_ioctl(tty, file, cmd, arg);
403 break;
405 case TCFLSH:
406 /* flush our buffers and the serial port's buffer */
407 if (arg == TCIFLUSH || arg == TCIOFLUSH)
408 flush_skb_queue(&ap->rq);
409 if (arg == TCIOFLUSH || arg == TCOFLUSH)
410 ppp_async_flush_output(ap);
411 err = n_tty_ioctl(tty, file, cmd, arg);
412 break;
414 case FIONREAD:
415 val = 0;
416 if ((skb = skb_peek(&ap->rq)) != 0)
417 val = skb->len;
418 if (put_user(val, (int *) arg))
419 break;
420 err = 0;
421 break;
423 default:
424 err = -ENOIOCTLCMD;
426 out:
427 return err;
430 static unsigned int
431 ppp_async_poll(struct tty_struct *tty, struct file *file, poll_table *wait)
433 struct asyncppp *ap = tty->disc_data;
434 unsigned int mask;
436 if (ap == 0)
437 return 0; /* should never happen */
438 poll_wait(file, &ap->rwait, wait);
439 mask = POLLOUT | POLLWRNORM;
440 if (skb_peek(&ap->rq))
441 mask |= POLLIN | POLLRDNORM;
442 if (test_bit(TTY_OTHER_CLOSED, &tty->flags) || tty_hung_up_p(file))
443 mask |= POLLHUP;
444 return mask;
447 static int
448 ppp_async_room(struct tty_struct *tty)
450 return 65535;
453 static void
454 ppp_async_receive(struct tty_struct *tty, const unsigned char *buf,
455 char *flags, int count)
457 struct asyncppp *ap = tty->disc_data;
459 if (ap == 0)
460 return;
461 trylock_recv_path(ap);
462 ppp_async_input(ap, buf, flags, count);
463 unlock_recv_path(ap);
464 if (test_and_clear_bit(TTY_THROTTLED, &tty->flags)
465 && tty->driver.unthrottle)
466 tty->driver.unthrottle(tty);
469 static void
470 ppp_async_wakeup(struct tty_struct *tty)
472 struct asyncppp *ap = tty->disc_data;
474 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
475 if (ap == 0)
476 return;
477 if (ppp_async_push(ap) && ap->connected)
478 ppp_output_wakeup(&ap->chan);
482 static struct tty_ldisc ppp_ldisc = {
483 magic: TTY_LDISC_MAGIC,
484 name: "ppp",
485 open: ppp_async_open,
486 close: ppp_async_close,
487 read: ppp_async_read,
488 write: ppp_async_write,
489 ioctl: ppp_async_ioctl,
490 poll: ppp_async_poll,
491 receive_room: ppp_async_room,
492 receive_buf: ppp_async_receive,
493 write_wakeup: ppp_async_wakeup,
497 ppp_async_init(void)
499 int err;
501 err = tty_register_ldisc(N_PPP, &ppp_ldisc);
502 if (err != 0)
503 printk(KERN_ERR "PPP_async: error %d registering line disc.\n",
504 err);
505 return err;
509 * Procedures for encapsulation and framing.
512 u16 ppp_crc16_table[256] = {
513 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
514 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
515 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
516 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
517 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
518 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
519 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
520 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
521 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
522 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
523 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
524 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
525 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
526 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
527 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
528 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
529 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
530 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
531 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
532 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
533 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
534 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
535 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
536 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
537 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
538 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
539 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
540 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
541 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
542 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
543 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
544 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
546 EXPORT_SYMBOL(ppp_crc16_table);
547 #define fcstab ppp_crc16_table /* for PPP_FCS macro */
550 * Procedure to encode the data for async serial transmission.
551 * Does octet stuffing (escaping), puts the address/control bytes
552 * on if A/C compression is disabled, and does protocol compression.
553 * Assumes ap->tpkt != 0 on entry.
554 * Returns 1 if we finished the current frame, 0 otherwise.
557 #define PUT_BYTE(ap, buf, c, islcp) do { \
558 if ((islcp && c < 0x20) || (ap->xaccm[c >> 5] & (1 << (c & 0x1f)))) {\
559 *buf++ = PPP_ESCAPE; \
560 *buf++ = c ^ 0x20; \
561 } else \
562 *buf++ = c; \
563 } while (0)
565 static int
566 ppp_async_encode(struct asyncppp *ap)
568 int fcs, i, count, c, proto;
569 unsigned char *buf, *buflim;
570 unsigned char *data;
571 int islcp;
573 buf = ap->obuf;
574 ap->olim = buf;
575 ap->optr = buf;
576 i = ap->tpkt_pos;
577 data = ap->tpkt->data;
578 count = ap->tpkt->len;
579 fcs = ap->tfcs;
580 proto = (data[0] << 8) + data[1];
583 * LCP packets with code values between 1 (configure-reqest)
584 * and 7 (code-reject) must be sent as though no options
585 * had been negotiated.
587 islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7;
589 if (i == 0) {
591 * Start of a new packet - insert the leading FLAG
592 * character if necessary.
594 if (islcp || flag_time == 0
595 || jiffies - ap->last_xmit >= flag_time)
596 *buf++ = PPP_FLAG;
597 ap->last_xmit = jiffies;
598 fcs = PPP_INITFCS;
601 * Put in the address/control bytes if necessary
603 if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
604 PUT_BYTE(ap, buf, 0xff, islcp);
605 fcs = PPP_FCS(fcs, 0xff);
606 PUT_BYTE(ap, buf, 0x03, islcp);
607 fcs = PPP_FCS(fcs, 0x03);
612 * Once we put in the last byte, we need to put in the FCS
613 * and closing flag, so make sure there is at least 7 bytes
614 * of free space in the output buffer.
616 buflim = ap->obuf + OBUFSIZE - 6;
617 while (i < count && buf < buflim) {
618 c = data[i++];
619 if (i == 1 && c == 0 && (ap->flags & SC_COMP_PROT))
620 continue; /* compress protocol field */
621 fcs = PPP_FCS(fcs, c);
622 PUT_BYTE(ap, buf, c, islcp);
625 if (i < count) {
627 * Remember where we are up to in this packet.
629 ap->olim = buf;
630 ap->tpkt_pos = i;
631 ap->tfcs = fcs;
632 return 0;
636 * We have finished the packet. Add the FCS and flag.
638 fcs = ~fcs;
639 c = fcs & 0xff;
640 PUT_BYTE(ap, buf, c, islcp);
641 c = (fcs >> 8) & 0xff;
642 PUT_BYTE(ap, buf, c, islcp);
643 *buf++ = PPP_FLAG;
644 ap->olim = buf;
646 kfree_skb(ap->tpkt);
647 ap->tpkt = 0;
648 return 1;
652 * Transmit-side routines.
656 * Send a packet to the peer over an async tty line.
657 * Returns 1 iff the packet was accepted.
658 * If the packet was not accepted, we will call ppp_output_wakeup
659 * at some later time.
661 static int
662 ppp_async_send(struct ppp_channel *chan, struct sk_buff *skb)
664 struct asyncppp *ap = chan->private;
666 ppp_async_push(ap);
668 if (test_and_set_bit(XMIT_FULL, &ap->busy))
669 return 0; /* already full */
670 ap->tpkt = skb;
671 ap->tpkt_pos = 0;
673 ppp_async_push(ap);
674 return 1;
678 * Push as much data as possible out to the tty.
680 static int
681 ppp_async_push(struct asyncppp *ap)
683 int avail, sent, done = 0;
684 struct tty_struct *tty = ap->tty;
685 int tty_stuffed = 0;
687 if (!trylock_xmit_path(ap)) {
688 set_bit(XMIT_WAKEUP, &ap->busy);
689 return 0;
691 for (;;) {
692 if (test_and_clear_bit(XMIT_WAKEUP, &ap->busy))
693 tty_stuffed = 0;
694 if (!tty_stuffed && ap->optr < ap->olim) {
695 avail = ap->olim - ap->optr;
696 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
697 sent = tty->driver.write(tty, 0, ap->optr, avail);
698 if (sent < 0)
699 goto flush; /* error, e.g. loss of CD */
700 ap->optr += sent;
701 if (sent < avail)
702 tty_stuffed = 1;
703 continue;
705 if (ap->optr == ap->olim && ap->tpkt != 0) {
706 if (ppp_async_encode(ap)) {
707 /* finished processing ap->tpkt */
708 struct sk_buff *skb = skb_dequeue(&ap->xq);
709 if (skb != 0) {
710 ap->tpkt = skb;
711 } else {
712 clear_bit(XMIT_FULL, &ap->busy);
713 done = 1;
716 continue;
718 /* haven't made any progress */
719 unlock_xmit_path(ap);
720 if (!(test_bit(XMIT_WAKEUP, &ap->busy)
721 || (!tty_stuffed && ap->tpkt != 0)))
722 break;
723 if (!trylock_xmit_path(ap))
724 break;
726 return done;
728 flush:
729 if (ap->tpkt != 0) {
730 kfree_skb(ap->tpkt);
731 ap->tpkt = 0;
732 clear_bit(XMIT_FULL, &ap->busy);
733 done = 1;
735 ap->optr = ap->olim;
736 unlock_xmit_path(ap);
737 return done;
741 * Flush output from our internal buffers.
742 * Called for the TCFLSH ioctl.
744 static void
745 ppp_async_flush_output(struct asyncppp *ap)
747 int done = 0;
749 flush_skb_queue(&ap->xq);
750 lock_xmit_path(ap);
751 ap->optr = ap->olim;
752 if (ap->tpkt != NULL) {
753 kfree_skb(ap->tpkt);
754 ap->tpkt = 0;
755 clear_bit(XMIT_FULL, &ap->busy);
756 done = 1;
758 unlock_xmit_path(ap);
759 if (done && ap->connected)
760 ppp_output_wakeup(&ap->chan);
764 * Receive-side routines.
767 /* see how many ordinary chars there are at the start of buf */
768 static inline int
769 scan_ordinary(struct asyncppp *ap, const unsigned char *buf, int count)
771 int i, c;
773 for (i = 0; i < count; ++i) {
774 c = buf[i];
775 if (c == PPP_ESCAPE || c == PPP_FLAG
776 || (c < 0x20 && (ap->raccm & (1 << c)) != 0))
777 break;
779 return i;
782 /* called when a flag is seen - do end-of-packet processing */
783 static inline void
784 process_input_packet(struct asyncppp *ap)
786 struct sk_buff *skb;
787 unsigned char *p;
788 unsigned int len, fcs;
789 int code = 0;
791 skb = ap->rpkt;
792 ap->rpkt = 0;
793 if ((ap->state & (SC_TOSS | SC_ESCAPE)) || skb == 0) {
794 ap->state &= ~(SC_TOSS | SC_ESCAPE);
795 if (skb != 0)
796 kfree_skb(skb);
797 return;
800 /* check the FCS */
801 p = skb->data;
802 len = skb->len;
803 if (len < 3)
804 goto err; /* too short */
805 fcs = PPP_INITFCS;
806 for (; len > 0; --len)
807 fcs = PPP_FCS(fcs, *p++);
808 if (fcs != PPP_GOODFCS)
809 goto err; /* bad FCS */
810 skb_trim(skb, skb->len - 2);
812 /* check for address/control and protocol compression */
813 p = skb->data;
814 if (p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) {
815 /* chop off address/control */
816 if (skb->len < 3)
817 goto err;
818 p = skb_pull(skb, 2);
820 if (p[0] & 1) {
821 /* protocol is compressed */
822 skb_push(skb, 1)[0] = 0;
823 } else if (skb->len < 2)
824 goto err;
826 /* all OK, give it to the generic layer or queue it */
827 if (ap->connected) {
828 ppp_input(&ap->chan, skb);
829 } else {
830 skb_queue_tail(&ap->rq, skb);
831 /* drop old frames if queue too long */
832 while (ap->rq.qlen > PPPASYNC_MAX_RQLEN
833 && (skb = skb_dequeue(&ap->rq)) != 0)
834 kfree(skb);
835 wake_up_interruptible(&ap->rwait);
837 return;
839 err:
840 kfree_skb(skb);
841 if (ap->connected)
842 ppp_input_error(&ap->chan, code);
845 static inline void
846 input_error(struct asyncppp *ap, int code)
848 ap->state |= SC_TOSS;
849 if (ap->connected)
850 ppp_input_error(&ap->chan, code);
853 /* called when the tty driver has data for us. */
854 static void
855 ppp_async_input(struct asyncppp *ap, const unsigned char *buf,
856 char *flags, int count)
858 struct sk_buff *skb;
859 int c, i, j, n, s, f;
860 unsigned char *sp;
862 /* update bits used for 8-bit cleanness detection */
863 if (~ap->rbits & SC_RCV_BITS) {
864 s = 0;
865 for (i = 0; i < count; ++i) {
866 c = buf[i];
867 if (flags != 0 && flags[i] != 0)
868 continue;
869 s |= (c & 0x80)? SC_RCV_B7_1: SC_RCV_B7_0;
870 c = ((c >> 4) ^ c) & 0xf;
871 s |= (0x6996 & (1 << c))? SC_RCV_ODDP: SC_RCV_EVNP;
873 ap->rbits |= s;
876 while (count > 0) {
877 /* scan through and see how many chars we can do in bulk */
878 if ((ap->state & SC_ESCAPE) && buf[0] == PPP_ESCAPE)
879 n = 1;
880 else
881 n = scan_ordinary(ap, buf, count);
883 f = 0;
884 if (flags != 0 && (ap->state & SC_TOSS) == 0) {
885 /* check the flags to see if any char had an error */
886 for (j = 0; j < n; ++j)
887 if ((f = flags[j]) != 0)
888 break;
890 if (f != 0) {
891 /* start tossing */
892 input_error(ap, f);
894 } else if (n > 0 && (ap->state & SC_TOSS) == 0) {
895 /* stuff the chars in the skb */
896 skb = ap->rpkt;
897 if (skb == 0) {
898 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
899 if (skb == 0)
900 goto nomem;
901 /* Try to get the payload 4-byte aligned */
902 if (buf[0] != PPP_ALLSTATIONS)
903 skb_reserve(skb, 2 + (buf[0] & 1));
904 ap->rpkt = skb;
906 if (n > skb_tailroom(skb)) {
907 /* packet overflowed MRU */
908 input_error(ap, 1);
909 } else {
910 sp = skb_put(skb, n);
911 memcpy(sp, buf, n);
912 if (ap->state & SC_ESCAPE) {
913 sp[0] ^= 0x20;
914 ap->state &= ~SC_ESCAPE;
919 if (n >= count)
920 break;
922 c = buf[n];
923 if (c == PPP_FLAG) {
924 process_input_packet(ap);
925 } else if (c == PPP_ESCAPE) {
926 ap->state |= SC_ESCAPE;
928 /* otherwise it's a char in the recv ACCM */
929 ++n;
931 buf += n;
932 if (flags != 0)
933 flags += n;
934 count -= n;
936 return;
938 nomem:
939 printk(KERN_ERR "PPPasync: no memory (input pkt)\n");
940 input_error(ap, 0);
943 #ifdef MODULE
945 init_module(void)
947 return ppp_async_init();
950 void
951 cleanup_module(void)
953 if (tty_register_ldisc(N_PPP, NULL) != 0)
954 printk(KERN_ERR "failed to unregister PPP line discipline\n");
956 #endif /* MODULE */