• Home
  • Raw
  • Download

Lines Matching +full:packet +full:- +full:oriented

1 // SPDX-License-Identifier: GPL-2.0-or-later
6 * that are frame oriented, such as synchronous HDLC devices.
24 * Part of the code in this driver was inspired by the old async-only
38 #include <linux/ppp-ioctl.h>
122 * We have a potential race on dereferencing tty->disc_data,
123 * because the tty layer provides no locking at all - thus one
125 * calls ppp_synctty_close, which zeroes tty->disc_data and
139 ap = tty->disc_data; in sp_get()
141 refcount_inc(&ap->refcnt); in sp_get()
148 if (refcount_dec_and_test(&ap->refcnt)) in sp_put()
149 complete(&ap->dead_cmp); in sp_put()
153 * Called when a tty is put into sync-PPP line discipline.
162 if (tty->ops->write == NULL) in ppp_sync_open()
163 return -EOPNOTSUPP; in ppp_sync_open()
166 err = -ENOMEM; in ppp_sync_open()
171 ap->tty = tty; in ppp_sync_open()
172 ap->mru = PPP_MRU; in ppp_sync_open()
173 spin_lock_init(&ap->xmit_lock); in ppp_sync_open()
174 spin_lock_init(&ap->recv_lock); in ppp_sync_open()
175 ap->xaccm[0] = ~0U; in ppp_sync_open()
176 ap->xaccm[3] = 0x60000000U; in ppp_sync_open()
177 ap->raccm = ~0U; in ppp_sync_open()
179 skb_queue_head_init(&ap->rqueue); in ppp_sync_open()
180 tasklet_init(&ap->tsk, ppp_sync_process, (unsigned long) ap); in ppp_sync_open()
182 refcount_set(&ap->refcnt, 1); in ppp_sync_open()
183 init_completion(&ap->dead_cmp); in ppp_sync_open()
185 ap->chan.private = ap; in ppp_sync_open()
186 ap->chan.ops = &sync_ops; in ppp_sync_open()
187 ap->chan.mtu = PPP_MRU; in ppp_sync_open()
188 ap->chan.hdrlen = 2; /* for A/C bytes */ in ppp_sync_open()
190 ap->chan.speed = speed; in ppp_sync_open()
191 err = ppp_register_channel(&ap->chan); in ppp_sync_open()
195 tty->disc_data = ap; in ppp_sync_open()
196 tty->receive_room = 65536; in ppp_sync_open()
219 ap = tty->disc_data; in ppp_sync_close()
220 tty->disc_data = NULL; in ppp_sync_close()
232 if (!refcount_dec_and_test(&ap->refcnt)) in ppp_sync_close()
233 wait_for_completion(&ap->dead_cmp); in ppp_sync_close()
234 tasklet_kill(&ap->tsk); in ppp_sync_close()
236 ppp_unregister_channel(&ap->chan); in ppp_sync_close()
237 skb_queue_purge(&ap->rqueue); in ppp_sync_close()
238 kfree_skb(ap->tpkt); in ppp_sync_close()
255 * Read does nothing - no data is ever available this way.
263 return -EAGAIN; in ppp_sync_read()
274 return -EAGAIN; in ppp_sync_write()
286 return -ENXIO; in ppp_synctty_ioctl()
287 err = -EFAULT; in ppp_synctty_ioctl()
290 err = -EFAULT; in ppp_synctty_ioctl()
291 if (put_user(ppp_channel_index(&ap->chan), p)) in ppp_synctty_ioctl()
297 err = -EFAULT; in ppp_synctty_ioctl()
298 if (put_user(ppp_unit_number(&ap->chan), p)) in ppp_synctty_ioctl()
326 /* No kernel lock - fine */
343 spin_lock_irqsave(&ap->recv_lock, flags); in ppp_sync_receive()
345 spin_unlock_irqrestore(&ap->recv_lock, flags); in ppp_sync_receive()
346 if (!skb_queue_empty(&ap->rqueue)) in ppp_sync_receive()
347 tasklet_schedule(&ap->tsk); in ppp_sync_receive()
357 clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in ppp_sync_wakeup()
360 set_bit(XMIT_WAKEUP, &ap->xmit_flags); in ppp_sync_wakeup()
361 tasklet_schedule(&ap->tsk); in ppp_sync_wakeup()
399 struct syncppp *ap = chan->private; in ppp_sync_ioctl()
405 err = -EFAULT; in ppp_sync_ioctl()
408 val = ap->flags | ap->rbits; in ppp_sync_ioctl()
416 ap->flags = val & ~SC_RCV_BITS; in ppp_sync_ioctl()
417 spin_lock_irq(&ap->recv_lock); in ppp_sync_ioctl()
418 ap->rbits = val & SC_RCV_BITS; in ppp_sync_ioctl()
419 spin_unlock_irq(&ap->recv_lock); in ppp_sync_ioctl()
424 if (put_user(ap->xaccm[0], p)) in ppp_sync_ioctl()
429 if (get_user(ap->xaccm[0], p)) in ppp_sync_ioctl()
435 if (put_user(ap->raccm, p)) in ppp_sync_ioctl()
440 if (get_user(ap->raccm, p)) in ppp_sync_ioctl()
446 if (copy_to_user(argp, ap->xaccm, sizeof(ap->xaccm))) in ppp_sync_ioctl()
455 memcpy(ap->xaccm, accm, sizeof(ap->xaccm)); in ppp_sync_ioctl()
460 if (put_user(ap->mru, (int __user *) argp)) in ppp_sync_ioctl()
468 err = -EINVAL; in ppp_sync_ioctl()
473 ap->mru = val; in ppp_sync_ioctl()
478 err = -ENOTTY; in ppp_sync_ioctl()
494 while ((skb = skb_dequeue(&ap->rqueue)) != NULL) { in ppp_sync_process()
495 if (skb->len == 0) { in ppp_sync_process()
497 ppp_input_error(&ap->chan, 0); in ppp_sync_process()
501 ppp_input(&ap->chan, skb); in ppp_sync_process()
505 if (test_bit(XMIT_WAKEUP, &ap->xmit_flags) && ppp_sync_push(ap)) in ppp_sync_process()
506 ppp_output_wakeup(&ap->chan); in ppp_sync_process()
525 data = skb->data; in ppp_sync_txmunge()
528 /* LCP packets with codes between 1 (configure-request) in ppp_sync_txmunge()
529 * and 7 (code-reject) must be sent as though no options in ppp_sync_txmunge()
535 if (data[0] == 0 && (ap->flags & SC_COMP_PROT) && !islcp) in ppp_sync_txmunge()
539 if ((ap->flags & SC_COMP_AC) == 0 || islcp) { in ppp_sync_txmunge()
541 struct sk_buff *npkt = dev_alloc_skb(skb->len + 2); in ppp_sync_txmunge()
548 skb_put(npkt, skb->len), skb->len); in ppp_sync_txmunge()
553 skb->data[0] = PPP_ALLSTATIONS; in ppp_sync_txmunge()
554 skb->data[1] = PPP_UI; in ppp_sync_txmunge()
557 ap->last_xmit = jiffies; in ppp_sync_txmunge()
559 if (skb && ap->flags & SC_LOG_OUTPKT) in ppp_sync_txmunge()
560 ppp_print_buffer ("send buffer", skb->data, skb->len); in ppp_sync_txmunge()
566 * Transmit-side routines.
570 * Send a packet to the peer over an sync tty line.
571 * Returns 1 iff the packet was accepted.
572 * If the packet was not accepted, we will call ppp_output_wakeup
578 struct syncppp *ap = chan->private; in ppp_sync_send()
582 if (test_and_set_bit(XMIT_FULL, &ap->xmit_flags)) in ppp_sync_send()
586 ap->tpkt = skb; in ppp_sync_send()
588 clear_bit(XMIT_FULL, &ap->xmit_flags); in ppp_sync_send()
601 struct tty_struct *tty = ap->tty; in ppp_sync_push()
604 if (!spin_trylock_bh(&ap->xmit_lock)) in ppp_sync_push()
607 if (test_and_clear_bit(XMIT_WAKEUP, &ap->xmit_flags)) in ppp_sync_push()
609 if (!tty_stuffed && ap->tpkt) { in ppp_sync_push()
610 set_bit(TTY_DO_WRITE_WAKEUP, &tty->flags); in ppp_sync_push()
611 sent = tty->ops->write(tty, ap->tpkt->data, ap->tpkt->len); in ppp_sync_push()
614 if (sent < ap->tpkt->len) { in ppp_sync_push()
617 consume_skb(ap->tpkt); in ppp_sync_push()
618 ap->tpkt = NULL; in ppp_sync_push()
619 clear_bit(XMIT_FULL, &ap->xmit_flags); in ppp_sync_push()
625 spin_unlock_bh(&ap->xmit_lock); in ppp_sync_push()
626 if (!(test_bit(XMIT_WAKEUP, &ap->xmit_flags) || in ppp_sync_push()
627 (!tty_stuffed && ap->tpkt))) in ppp_sync_push()
629 if (!spin_trylock_bh(&ap->xmit_lock)) in ppp_sync_push()
635 if (ap->tpkt) { in ppp_sync_push()
636 kfree_skb(ap->tpkt); in ppp_sync_push()
637 ap->tpkt = NULL; in ppp_sync_push()
638 clear_bit(XMIT_FULL, &ap->xmit_flags); in ppp_sync_push()
641 spin_unlock_bh(&ap->xmit_lock); in ppp_sync_push()
654 spin_lock_bh(&ap->xmit_lock); in ppp_sync_flush_output()
655 if (ap->tpkt != NULL) { in ppp_sync_flush_output()
656 kfree_skb(ap->tpkt); in ppp_sync_flush_output()
657 ap->tpkt = NULL; in ppp_sync_flush_output()
658 clear_bit(XMIT_FULL, &ap->xmit_flags); in ppp_sync_flush_output()
661 spin_unlock_bh(&ap->xmit_lock); in ppp_sync_flush_output()
663 ppp_output_wakeup(&ap->chan); in ppp_sync_flush_output()
667 * Receive-side routines.
672 * Data is frame oriented: each call to ppp_sync_input is considered
673 * a whole frame. If the 1st flag byte is non-zero then the whole
686 if (ap->flags & SC_LOG_INPKT) in ppp_sync_input()
690 skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2); in ppp_sync_input()
695 /* Try to get the payload 4-byte aligned */ in ppp_sync_input()
703 /* packet overflowed MRU */ in ppp_sync_input()
710 p = skb->data; in ppp_sync_input()
711 if (skb->len >= 2 && p[0] == PPP_ALLSTATIONS && p[1] == PPP_UI) { in ppp_sync_input()
713 if (skb->len < 3) in ppp_sync_input()
718 /* PPP packet length should be >= 2 bytes when protocol field is not in ppp_sync_input()
721 if (!(p[0] & 0x01) && skb->len < 2) in ppp_sync_input()
725 skb_queue_tail(&ap->rqueue, skb); in ppp_sync_input()
729 /* queue zero length packet as error indication */ in ppp_sync_input()
732 skb_queue_tail(&ap->rqueue, skb); in ppp_sync_input()