summaryrefslogtreecommitdiffstats
path: root/c/src/libnetworking/modem/ppp_tty.c
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2002-01-31 21:42:11 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2002-01-31 21:42:11 +0000
commit0286b9f6145f9664f6b0e196e24daee8be46b538 (patch)
tree5cdf87997238653f4083fe1c1326213040183044 /c/src/libnetworking/modem/ppp_tty.c
parent2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de> (diff)
downloadrtems-0286b9f6145f9664f6b0e196e24daee8be46b538.tar.bz2
2001-01-31 Mike Siers <mikes@poliac.com>
* Nice Update of PPPD support which eliminates the requiremetn that drivers be in the termios TASK_DRIVEN mode. Mike did significant testing and reports that it seems to be more stable and handle larger packets better. This patch replaces the termios tasks with more general pppd network driver tasks. The functions pppinput() and pppstart() get called from the interrupt service routine. * Makefile.am, configure.ac, net/Makefile.am, net/bpf.h, net/ethernet.h, net/if.c, net/if.h, net/if_arp.h, net/if_dl.h, net/if_ethersubr.c, net/if_llc.h, net/if_loop.c, net/if_ppp.h, net/if_pppvar.h, net/if_types.h, net/netisr.h, net/ppp-comp.h, net/ppp_defs.h, net/pppcompress.h, net/radix.c, net/radix.h, net/raw_cb.c, net/raw_cb.h, net/raw_usrreq.c, net/route.c, net/route.h, net/rtsock.c, pppd/Makefile.am, pppd/README, pppd/STATUS, pppd/auth.c, pppd/cbcp.c, pppd/ccp.c, pppd/ccp.h, pppd/chap.c, pppd/chap.h, pppd/chap_ms.c, pppd/chap_ms.h, pppd/chat.c, pppd/demand.c, pppd/fsm.c, pppd/fsm.h, pppd/ipcp.c, pppd/ipcp.h, pppd/ipxcp.c, pppd/ipxcp.h, pppd/lcp.c, pppd/lcp.h, pppd/magic.c, pppd/magic.h, pppd/options.c, pppd/patchlevel.h, pppd/pathnames.h, pppd/pppd.8, pppd/pppd.h, pppd/rtemsmain.c, pppd/rtemspppd.c, pppd/rtemspppd.h, pppd/sys-rtems.c, pppd/upap.c, pppd/upap.h, pppd/utils.c, pppd/example/README, pppd/example/netconfig.h, wrapup/Makefile.am: Modified. * net/bsd-comp.c, net/if_ppp.c, net/ppp-deflate.c, net/ppp.h, net/ppp_tty.c, net/pppcompress.c, net/zlib.c, net/zlib.h: New file. * modem/, modem/.cvsignore, modem/Makefile.am, modem/ppp.c, modem/ppp.h, modem/ppp_tty.c, modem/pppcompress.c: Subdirectory removed.
Diffstat (limited to 'c/src/libnetworking/modem/ppp_tty.c')
-rw-r--r--c/src/libnetworking/modem/ppp_tty.c1100
1 files changed, 0 insertions, 1100 deletions
diff --git a/c/src/libnetworking/modem/ppp_tty.c b/c/src/libnetworking/modem/ppp_tty.c
deleted file mode 100644
index e3ca3f4a41..0000000000
--- a/c/src/libnetworking/modem/ppp_tty.c
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
- * ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
- * tty devices.
- *
- * Copyright (c) 1989 Carnegie Mellon University.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by Carnegie Mellon University. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Drew D. Perkins
- * Carnegie Mellon University
- * 4910 Forbes Ave.
- * Pittsburgh, PA 15213
- * (412) 268-8576
- * ddp@andrew.cmu.edu
- *
- * Based on:
- * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89
- *
- * Copyright (c) 1987 Regents of the University of California.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms are permitted
- * provided that the above copyright notice and this paragraph are
- * duplicated in all such forms and that any documentation,
- * advertising materials, and other materials related to such
- * distribution and use acknowledge that the software was developed
- * by the University of California, Berkeley. The name of the
- * University may not be used to endorse or promote products derived
- * from this software without specific prior written permission.
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
- * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Serial Line interface
- *
- * Rick Adams
- * Center for Seismic Studies
- * 1300 N 17th Street, Suite 1450
- * Arlington, Virginia 22209
- * (703)276-7900
- * rick@seismo.ARPA
- * seismo!rick
- *
- * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris).
- * Converted to 4.3BSD Beta by Chris Torek.
- * Other changes made at Berkeley, based in part on code by Kirk Smith.
- *
- * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com)
- * Added VJ tcp header compression; more unified ioctls
- *
- * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au).
- * Cleaned up a lot of the mbuf-related code to fix bugs that
- * caused system crashes and packet corruption. Changed pppstart
- * so that it doesn't just give up with a "collision" if the whole
- * packet doesn't fit in the output ring buffer.
- *
- * Added priority queueing for interactive IP packets, following
- * the model of if_sl.c, plus hooks for bpf.
- * Paul Mackerras (paulus@cs.anu.edu.au).
- *
- * Adapted to RTEMS by Thomas Doerfler
- * based on the package of Tomasz Domin delivered
- * in RTEMS snapshot rtems-19991203:
- * Splitted hardware-independent driver parts from the hardware-dependent
- * parts, integrated into termios with newly defined line-discipline support
- */
-
-/* Thomas: ppp_tty.c,v 1.3 2000/09/12 19:26:17 thomas Exp */
-/* $Id$ */
-/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
-/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
-
-#include "ppp.h"
-#if NPPP > 0
-
-#define VJC
-#define PPP_COMPRESS
-
-#include <rtems/rtems_bsdnet.h> /* to get right defines */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/mbuf.h>
-#if 0
-#include <sys/dkstat.h>
-#endif
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#if 0
-#include <sys/tty.h>
-#endif
-#include <sys/kernel.h>
-#if 0
-#include <sys/conf.h>
-#include <sys/vnode.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-
-#ifdef VJC
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <net/pppcompress.h>
-#endif
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <sys/ttycom.h>
-#include <termios.h>
-#include <rtems/termiostypes.h>
-
-#ifdef PPP_FILTER
-#include <net/bpf.h>
-#endif
-#include <net/ppp_defs.h>
-#include <net/if_ppp.h>
-#include <net/if_pppvar.h>
-
-void pppasyncattach __P((void));
-int pppopen __P((struct rtems_termios_tty *tty));
-int pppclose __P((struct rtems_termios_tty *tty));
-int pppread __P((struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args));
-int pppwrite __P((struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args));
-int ppptioctl __P((struct rtems_termios_tty *tty,
- rtems_libio_ioctl_args_t *args));
-int pppinput __P((int c,struct rtems_termios_tty *tty));
-int pppstart __P((struct rtems_termios_tty *tp));
-
-static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
-static void pppasyncstart __P((struct ppp_softc *));
-static void pppasyncctlp __P((struct ppp_softc *));
-static void pppasyncrelinq __P((struct ppp_softc *));
-static void ppp_timeout __P((void *));
-static void pppgetm __P((struct ppp_softc *sc));
-static void pppdumpb __P((u_char *b, int l));
-static void ppplogchar __P((struct ppp_softc *, int));
-
-/*
- * Some useful mbuf macros not in mbuf.h.
- */
-#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
-
-#define M_DATASTART(m) \
- (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \
- (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
-
-#define M_DATASIZE(m) \
- (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \
- (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
-
-/*
- * Does c need to be escaped?
- */
-#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
-
-/*
- * Procedures for using an async tty interface for PPP.
- */
-
-/*
- * compute used space in raw buffer
- */
-#define CCOUNT(rb) (((rb).Size+(rb).Head-(rb).Tail) \
- % (rb).Size)
-/*
- * compute free space in raw buffer
- */
-#define FCOUNT(rb) ((rb).Size-CCOUNT(rb)-1)
-#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
-#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
-/* FIXME: make dependent on raw buffer size */
-
-/*
- * Define the PPP line discipline.
- */
-
-static struct linesw pppdisc = {
- pppopen, pppclose, pppread, pppwrite,
- pppinput, pppstart, ppptioctl, NULL
-};
-
-void
-pppasyncattach()
-{
- linesw[PPPDISC] = pppdisc;
-}
-
-TEXT_SET(pseudo_set, pppasyncattach);
-
-/*
- * Line specific open routine for async tty devices.
- * Attach the given tty to the first available ppp unit.
- * Called from device open routine or ttioctl.
- */
-/* ARGSUSED */
-/*
- * Open the PPP device
- */
-int
-pppopen(struct rtems_termios_tty *tty)
-{
- register struct ppp_softc *sc;
- rtems_status_code status;
-
- if ((tty->t_line == PPPDISC)) {
- sc = tty->t_sc;
- if (sc != NULL && sc->sc_devp == (void *) tty) {
- return (0);
- }
- }
-
- if ((sc = pppalloc(1)) == NULL) {
- return 2;
- }
-
- if (sc->sc_relinq) {
- (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
- }
- /*
- * create communication semaphore
- */
- status = rtems_semaphore_create (rtems_build_name ('P', 'P', 'P',
- '0'+sc->sc_if.if_unit),
- 0,
- RTEMS_COUNTING_SEMAPHORE,
- RTEMS_NO_PRIORITY_CEILING,
- &sc->sem_id);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- sc->sc_ilen = 0;
- sc->sc_m = NULL;
- bzero(sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
- sc->sc_asyncmap[0] = 0xffffffff;
- sc->sc_asyncmap[3] = 0x60000000;
- sc->sc_rasyncmap = 0;
- sc->sc_devp = tty;
- sc->sc_start = pppasyncstart;
- sc->sc_ctlp = pppasyncctlp;
- sc->sc_relinq = pppasyncrelinq;
- sc->sc_outm = NULL;
- pppgetm(sc);
- sc->sc_if.if_flags |= IFF_RUNNING;
- sc->sc_if.if_baudrate = 9600; /* FIXME: get line speed from termios */
-
- tty->t_sc= (void *)sc;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Line specific close routine, called from device close routine
- * and from ttioctl.
- * Detach the tty from the ppp unit.
- * Mimics part of ttyclose().
- */
-int
-pppclose(struct rtems_termios_tty *tty)
-{
- register struct ppp_softc *sc;
- rtems_status_code status;
-
-
- tty->t_line = 0;
- sc = tty->t_sc;
- if (sc != NULL) {
- tty->t_sc = NULL;
- if (tty == (struct rtems_termios_tty *) sc->sc_devp) {
- rtems_bsdnet_semaphore_obtain();
- pppasyncrelinq(sc);
- /*
- * delete communication semaphore
- */
- status = rtems_semaphore_delete (sc->sem_id);
- pppdealloc(sc);
- rtems_bsdnet_semaphore_release();
- }
- }
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Relinquish the interface unit to another device.
- */
-static void
-pppasyncrelinq(sc)
- struct ppp_softc *sc;
-{
- if (sc->sc_outm) {
- m_freem(sc->sc_outm);
- sc->sc_outm = NULL;
- }
- if (sc->sc_m) {
- m_freem(sc->sc_m);
- sc->sc_m = NULL;
- }
- if (sc->sc_flags & SC_TIMEOUT) {
- untimeout(ppp_timeout, (void *) sc);
- sc->sc_flags &= ~SC_TIMEOUT;
- }
-}
-
-/*
- * Line specific (tty) read routine.
- */
-int pppread(struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args)
-{
- char *buffer;
- int count=0,maximum;
- rtems_status_code status;
-
- struct mbuf *m, *m0;
- rtems_interval ticks;
- register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
- buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- ticks=1000000/rtems_bsdnet_microseconds_per_tick;
-
- if (sc == NULL) {
- return 0;
- }
- /*
- * Loop waiting for input, checking that nothing disasterous
- * happens in the meantime.
- */
- for (;;) {
- if (sc->sc_inq.ifq_head != NULL) {
- break;
- }
- status=rtems_semaphore_obtain(sc->sem_id,RTEMS_WAIT,ticks);
- if (status==RTEMS_TIMEOUT) {
- return status;
- }
- }
- rtems_bsdnet_semaphore_obtain();
- IF_DEQUEUE(&sc->sc_inq, m0);
- rtems_bsdnet_semaphore_release();
-
- for (m = m0;
- ((m != NULL) &&
- (count+m->m_len<maximum));
- m = m->m_next) {/* check if packet will fit in buffer */
- memcpy(buffer,mtod(m, u_char *),m->m_len);
- count+=m->m_len;
- buffer+=m->m_len;
- }
- m_freem(m0);
- rw_args->bytes_moved = count;
-
- return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
-}
-
-/*
- * Line specific (tty) write routine.
- */
-int
-pppwrite(struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args)
-{
- int len;
- char *out_buffer;
- int n,maximum;
-
- register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
- struct sockaddr dst;
- struct mbuf *m, *m0, **mp;
-
- out_buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- rtems_bsdnet_semaphore_obtain();
- for (mp = &m0; maximum; mp = &m->m_next) {
- MGET(m, M_WAIT, MT_DATA);
- if ((*mp = m) == NULL) {
- rtems_bsdnet_semaphore_release();
- m_freem(m0);
- return (ENOBUFS);
- }
- m->m_len = 0;
- if (maximum>= MCLBYTES / 2) {
- MCLGET(m, M_DONTWAIT);
- }
- len = M_TRAILINGSPACE(m);
- if (len > maximum) {
- memcpy(mtod(m, u_char *),out_buffer,maximum);
- m->m_len=maximum;
- maximum=0;
- }
- else {
- memcpy(mtod(m, u_char *),out_buffer,len);
- maximum-=len;
- m->m_len=len;
- out_buffer+=len;
- }
- }
-
- dst.sa_family = AF_UNSPEC;
- bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
- m0->m_data += PPP_HDRLEN;
- m0->m_len -= PPP_HDRLEN;
-
- n=pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
- rtems_bsdnet_semaphore_release();
- return n;
-}
-
-/*
- * Line specific (tty) ioctl routine.
- * This discipline requires that tty device drivers call
- * the line specific l_ioctl routine from their ioctl routines.
- */
-/* ARGSUSED */
-int
-ppptioctl(struct rtems_termios_tty *tty,
- rtems_libio_ioctl_args_t *args)
-{
- int error = RTEMS_SUCCESSFUL;
- struct ppp_softc *sc = tty->t_sc;
- int cmd;
- caddr_t data;
-
- cmd=args->command;
- data=args->buffer;
-
- switch (cmd) {
- case RTEMS_IO_GET_ATTRIBUTES:
- case RTEMS_IO_SET_ATTRIBUTES:
- case RTEMS_IO_TCDRAIN:
- case TIOCGETD:
- case TIOCSETD:
- case RTEMS_IO_SNDWAKEUP:
- case RTEMS_IO_RCVWAKEUP:
- error = rtems_termios_ioctl(args);
- break;
-
- case PPPIOCSASYNCMAP:
- sc->sc_asyncmap[0] = *(u_int *)data;
- break;
-
- case PPPIOCGASYNCMAP:
- *(u_int *)data = sc->sc_asyncmap[0];
- break;
-
- case PPPIOCSRASYNCMAP:
- sc->sc_rasyncmap = *(u_int *)data;
- break;
-
- case TIOCMBIS:
- break;
- case TIOCMBIC:
- break;
- case PPPIOCGRASYNCMAP:
- *(u_int *)data = sc->sc_rasyncmap;
- break;
-
- case PPPIOCSXASYNCMAP:
- bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
- sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
- sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
- sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
- break;
-
- case PPPIOCGXASYNCMAP:
- bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
- break;
-
- default:
- rtems_bsdnet_semaphore_obtain();
- error = pppioctl(sc, cmd, data, 0, NULL);
- if (error == 0 && cmd == PPPIOCSMRU)
- pppgetm(sc);
- rtems_bsdnet_semaphore_release();
-
- }
- return error;
-}
-
-/*
- * FCS lookup table as calculated by genfcstab.
- */
-static u_short fcstab[256] = {
- 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
- 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
- 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
- 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
- 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
- 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
- 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
- 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
- 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
- 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
- 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
- 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
- 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
- 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
- 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
- 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
- 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
- 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
- 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
- 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
- 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
- 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
- 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
- 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
- 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
- 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
- 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
- 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
- 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
- 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
- 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
- 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-/*
- * Calculate a new FCS given the current FCS and the new data.
- */
-static u_short
-pppfcs(fcs, cp, len)
- register u_short fcs;
- register u_char *cp;
- register int len;
-{
- while (len--)
- fcs = PPP_FCS(fcs, *cp++);
- return (fcs);
-}
-
-/*
- * This gets called at splsoftnet from if_ppp.c at various times
- * when there is data ready to be sent.
- */
-static void
-pppasyncstart(sc)
- register struct ppp_softc *sc;
-{
- /* Call pppstart to start output again if necessary. */
- pppstart(sc->sc_devp);
-
- /*
- * This timeout is needed for operation on a pseudo-tty,
- * because the pty code doesn't call pppstart after it has
- * drained the t_outq.
- */
-/* if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
- timeout(ppp_timeout, (void *) sc, 1);
- sc->sc_flags |= SC_TIMEOUT;
- }
-*/
-
-}
-
-
-void modem_sendpacket(struct rtems_termios_tty *tty)
-{
- register struct mbuf *m;
- register int len;
- register u_char *start, *stop, *cp;
- int n, ndone, done;
- struct mbuf *m2;
- char c;
- register struct ppp_softc *sc=tty->t_sc;
-
-
- while (CCOUNT(tty->rawOutBuf) < PPP_HIWAT) {
- /*
- * See if we have an existing packet partly sent.
- * If not, get a new packet and start sending it.
- */
- m = sc->sc_outm;
- if (m == NULL) {
- /*
- * Get another packet to be sent.
-
- */
- m = ppp_dequeue(sc);
- if (m == NULL)
- {
- break;
- }
-
- /*
- * The extra PPP_FLAG will start up a new packet, and thus
- * will flush any accumulated garbage. We do this whenever
- * the line may have been idle for some time.
- */
- if (CCOUNT(tty->rawOutBuf) == 0) {
- ++sc->sc_stats.ppp_obytes;
- c = PPP_FLAG;
- rtems_termios_puts(&c,1,tty);
- }
-
- /* Calculate the FCS for the first mbuf's worth. */
- sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
- microtime(&sc->sc_if.if_lastchange);
- }
-
- for (;;) {
- start = mtod(m, u_char *);
- len = m->m_len;
- stop = start + len;
- while (len > 0) {
- /*
- * Find out how many bytes in the string we can
- * handle without doing something special.
- */
- for (cp = start; cp < stop; cp++)
- if (ESCAPE_P(*cp))
- break;
- n = cp - start;
- if (n) {
- register int i;
- i = FCOUNT(tty->rawOutBuf);
- if (n < i) {
- i = n;
- }
- if (i > 0) {
- rtems_termios_puts(start,i,tty);
- }
- ndone = i;
- len -= ndone;
- start += ndone;
- sc->sc_stats.ppp_obytes += ndone;
-
- if (ndone < n)
- break; /* packet doesn't fit */
- }
- /*
- * If there are characters left in the mbuf,
- * the first one must be special.
- * Put it out in a different form.
- */
- if (len) {
- if (FCOUNT(tty->rawOutBuf) < 2) {
- break;
- }
- else {
- char str[2];
- str[0] = PPP_ESCAPE;
- str[1] = *start ^ PPP_TRANS;
- rtems_termios_puts(str,2,tty);
- }
- sc->sc_stats.ppp_obytes += 2;
- start++;
- len--;
- }
- }
-
- /*
- * If we didn't empty this mbuf, remember where we're up to.
- * If we emptied the last mbuf, try to add the FCS and closing
- * flag, and if we can't, leave sc_outm pointing to m, but with
- * m->m_len == 0, to remind us to output the FCS and flag later.
- */
- done = len == 0;
- if (done && m->m_next == NULL) {
- u_char *p;
- int c;
- u_char endseq[8];
-
- /*
- * We may have to escape the bytes in the FCS.
- */
- p = endseq;
- c = ~sc->sc_outfcs & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- c = (~sc->sc_outfcs >> 8) & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- *p++ = PPP_FLAG;
-
- /*
- * Try to output the FCS and flag. If the bytes
- * don't all fit, back out.
- */
- if (FCOUNT(tty->rawOutBuf) > (p-endseq)) {
- rtems_termios_puts(endseq,p-endseq,tty);
- }
- else {
- done = 0;
- }
- if (done)
- sc->sc_stats.ppp_obytes += p - endseq;
- }
-
- if (!done) {
- /* remember where we got to */
- m->m_data = start;
- m->m_len = len;
- break;
- }
-
- /* Finished with this mbuf; free it and move on. */
- MFREE(m, m2);
- m = m2;
- if (m == NULL) {
- /* Finished a packet */
- break;
- }
- sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
- }
-
- /*
- * If m == NULL, we have finished a packet.
- * If m != NULL, we've either done as much work this time
- * as we need to, or else we've filled up the output queue.
- */
- sc->sc_outm = m;
- if (m)
- break;
- }
-}
-
-/*
- * This gets called when a received packet is placed on
- * the inq, at splsoftnet.
- */
-
-static void
-pppasyncctlp(sc)
- struct ppp_softc *sc;
-{
- rtems_semaphore_release(sc->sem_id);
-}
-
-/* Put data in input queue */
-int
-pppstart(struct rtems_termios_tty *tp)
-{
- register struct ppp_softc *sc = tp->t_sc;
-
- /*
- * If there is stuff in the output queue, send it now.
- * We are being called in lieu of ttstart and must do what it would.
- */
- sc->sc_if.if_flags |= IFF_OACTIVE;
-
- /*
- * If the transmit queue has drained and the tty has not hung up
- * or been disconnected from the ppp unit, then tell if_ppp.c that
- * we need more output.
- */
- if (CCOUNT(tp->rawOutBuf) < PPP_LOWAT
- /* && !((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)*/
- && sc != NULL && tp == (struct rtems_termios_tty *) sc->sc_devp) {
- modem_sendpacket(tp);
- }
-
- return 0;
-}
-
-/*
- * Timeout routine - try to start some more output.
- */
-static void
-ppp_timeout(x)
- void *x;
-{
- struct rtems_termios_tty *tty = ((struct rtems_termios_tty *)x);
- struct ppp_softc *sc = tty->t_sc;
- struct rtems_termios_tty *tp = (struct rtems_termios_tty *) sc->sc_devp;
-
- sc->sc_flags &= ~SC_TIMEOUT;
- pppstart(tp);
-}
-
-
-/*
- * Allocate enough mbuf to handle current MRU.
- */
-static void
-pppgetm(sc)
- register struct ppp_softc *sc;
-{
- struct mbuf *m, **mp;
- int len;
-
- mp = &sc->sc_m;
- for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
- if ((m = *mp) == NULL) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- break;
- *mp = m;
- MCLGET(m, M_DONTWAIT);
- }
- len -= M_DATASIZE(m);
- mp = &m->m_next;
- }
-}
-
-/*
- * tty interface receiver interrupt.
- */
-static unsigned paritytab[8] = {
- 0x96696996, 0x69969669, 0x69969669, 0x96696996,
- 0x69969669, 0x96696996, 0x96696996, 0x69969669
-};
-
-
-int
-pppinput(int c,struct rtems_termios_tty *tty)
-
-{
- register struct ppp_softc *sc=tty->t_sc;
- struct mbuf *m;
- int ilen, s;
-
- if (sc == NULL )
- return 0;
-
- ++sc->sc_stats.ppp_ibytes;
-
-#if 0
- if (c & TTY_FE) {
- /* framing error or overrun on this char - abort packet */
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
- goto flush;
- }
-#endif
-
- c &= 0xff;
-
- /*
- * Handle software flow control of output.
- */
-/* if (tp->t_iflag & IXON) {
- if (c == tp->t_cc[VSTOP] ) {
- if ((tp->t_state & TS_TTSTOP) == 0) {
- tp->t_state |= TS_TTSTOP;
- sccppp_stop_transmission(tp);
- }
- return 0;
- }
- if (c == tp->t_cc[VSTART] ) {
- tp->t_state &= ~TS_TTSTOP;
- sccppp_start_transmission(tp);
- return 0;
- }
- }
-*/
-
- if (c & 0x80)
- sc->sc_flags |= SC_RCV_B7_1;
- else
- sc->sc_flags |= SC_RCV_B7_0;
- if (paritytab[c >> 5] & (1 << (c & 0x1F)))
- sc->sc_flags |= SC_RCV_ODDP;
- else
- sc->sc_flags |= SC_RCV_EVNP;
-
-
- if (sc->sc_flags & SC_LOG_RAWIN)
- ppplogchar(sc, c);
-
- if (c == PPP_FLAG) {
- ilen = sc->sc_ilen;
- sc->sc_ilen = 0;
-
- if (sc->sc_rawin_count > 0)
- ppplogchar(sc, -1);
-
- /*
- * If SC_ESCAPED is set, then we've seen the packet
- * abort sequence
- */
- if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
- || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
- sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
- if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad fcs %x, pkt len %d\n",
- sc->sc_if.if_unit, sc->sc_fcs, ilen);
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- } else
- sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
- return 0;
- }
-
- if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
- if (ilen) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- sc->sc_flags |= SC_PKTLOST;
- splx(s);
- }
- return 0;
- }
-
- /*
- * Remove FCS trailer. Somewhat painful...
- */
- ilen -= 2;
- if (--sc->sc_mc->m_len == 0) {
- for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
- ;
- sc->sc_mc = m;
- }
- sc->sc_mc->m_len--;
-
- /* excise this mbuf chain */
- m = sc->sc_m;
- sc->sc_m = sc->sc_mc->m_next;
- sc->sc_mc->m_next = NULL;
- ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
- if (sc->sc_flags & SC_PKTLOST) {
- sc->sc_flags &= ~SC_PKTLOST;
- }
-
- pppgetm(sc);
- return 0;
- }
-
- if (sc->sc_flags & SC_FLUSH) {
- if (sc->sc_flags & SC_LOG_FLUSH)
- ppplogchar(sc, c);
- return 0;
- }
-
- if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
- return 0;
-
- if (sc->sc_flags & SC_ESCAPED) {
- sc->sc_flags &= ~SC_ESCAPED;
- c ^= PPP_TRANS;
- } else if (c == PPP_ESCAPE) {
- sc->sc_flags |= SC_ESCAPED;
- return 0;
- }
-
- /*
- * Initialize buffer on first octet received.
- * First octet could be address or protocol (when compressing
- * address/control).
- * Second octet is control.
- * Third octet is first or second (when compressing protocol)
- * octet of protocol.
- * Fourth octet is second octet of protocol.
- */
- if (sc->sc_ilen == 0) {
- /* reset the first input mbuf */
- if (sc->sc_m == NULL) {
- pppgetm(sc);
- if (sc->sc_m == NULL) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
- goto flush;
- }
- }
- m = sc->sc_m;
- m->m_len = 0;
- m->m_data = M_DATASTART(sc->sc_m);
- sc->sc_mc = m;
- sc->sc_mp = mtod(m, char *);
- sc->sc_fcs = PPP_INITFCS;
- if (c != PPP_ALLSTATIONS) {
- if (sc->sc_flags & SC_REJ_COMP_AC) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
- sc->sc_if.if_unit, c);
- goto flush;
- }
- *sc->sc_mp++ = PPP_ALLSTATIONS;
- *sc->sc_mp++ = PPP_UI;
- sc->sc_ilen += 2;
- m->m_len += 2;
- }
- }
- if (sc->sc_ilen == 1 && c != PPP_UI) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: missing UI (0x3), got 0x%x\n",
- sc->sc_if.if_unit, c);
- goto flush;
- }
- if (sc->sc_ilen == 2 && (c & 1) == 1) {
- /* a compressed protocol */
- *sc->sc_mp++ = 0;
- sc->sc_ilen++;
- sc->sc_mc->m_len++;
- }
- if (sc->sc_ilen == 3 && (c & 1) == 0) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
- (sc->sc_mp[-1] << 8) + c);
- goto flush;
- }
-
- /* packet beyond configured mru? */
- if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
- goto flush;
- }
-
- /* is this mbuf full? */
- m = sc->sc_mc;
- if (M_TRAILINGSPACE(m) <= 0) {
- if (m->m_next == NULL) {
- pppgetm(sc);
- if (m->m_next == NULL) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
- goto flush;
- }
- }
- sc->sc_mc = m = m->m_next;
- m->m_len = 0;
- m->m_data = M_DATASTART(m);
- sc->sc_mp = mtod(m, char *);
- }
-
- ++m->m_len;
- *sc->sc_mp++ = c;
- sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
- return 0;
-
- flush:
- if (!(sc->sc_flags & SC_FLUSH)) {
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- sc->sc_flags |= SC_FLUSH;
- if (sc->sc_flags & SC_LOG_FLUSH)
- ppplogchar(sc, c);
- }
- return 0;
-}
-
-
-#define MAX_DUMP_BYTES 128
-
-static void
-ppplogchar(sc, c)
- struct ppp_softc *sc;
- int c;
-{
- if (c >= 0)
- sc->sc_rawin[sc->sc_rawin_count++] = c;
- if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
- || (c < 0 && sc->sc_rawin_count > 0)) {
- printf("ppp%d input: ", sc->sc_if.if_unit);
- pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
- sc->sc_rawin_count = 0;
- }
-}
-
-static void
-pppdumpb(b, l)
- u_char *b;
- int l;
-{
- char buf[3*MAX_DUMP_BYTES+4];
- char *bp = buf;
- static char digits[] = "0123456789abcdef";
-
- while (l--) {
- if (bp >= buf + sizeof(buf) - 3) {
- *bp++ = '>';
- break;
- }
- *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
- *bp++ = digits[*b++ & 0xf];
- *bp++ = ' ';
- }
-
- *bp = 0;
- printf("%s\n", buf);
-}
-
-#endif /* NPPP > 0 */