Apply patch for sync serial support from Paul Fulghum.

This commit is contained in:
Paul Mackerras 1999-03-30 06:33:10 +00:00
parent 4426185a13
commit c1d7b083dc
7 changed files with 245 additions and 25 deletions

View File

@ -1,4 +1,4 @@
/* $Id: if_ppp.h,v 1.17 1999/03/02 05:37:51 paulus Exp $ */
/* $Id: if_ppp.h,v 1.18 1999/03/30 06:33:07 paulus Exp $ */
/*
* if_ppp.h - Point-to-Point Protocol definitions.
@ -21,7 +21,7 @@
*/
/*
* ==FILEVERSION 990226==
* ==FILEVERSION 990325==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the above date.
@ -67,7 +67,8 @@
#define SC_LOG_OUTPKT 0x00040000 /* log contents of pkts sent */
#define SC_LOG_RAWIN 0x00080000 /* log all chars received */
#define SC_LOG_FLUSH 0x00100000 /* log all chars flushed */
#define SC_MASK 0x0f0000ff /* bits that user can change */
#define SC_SYNC 0x00200000 /* synchronous serial mode */
#define SC_MASK 0x0f2000ff /* bits that user can change */
/* state bits */
#define SC_XMIT_BUSY 0x10000000 /* (used by isdn_ppp?) */

View File

@ -42,7 +42,7 @@
*/
/*
* ==FILEVERSION 990114==
* ==FILEVERSION 990325==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the above date.
@ -89,6 +89,7 @@ struct ppp {
__u8 escape; /* 0x20 if prev char was PPP_ESC */
__u8 toss; /* toss this frame */
volatile __u8 tty_pushing; /* internal state flag */
volatile __u8 woke_up; /* internal state flag */
__u32 xmit_async_map[8]; /* 1 bit means that given control
character is quoted on output*/
__u32 recv_async_map; /* 1 bit means that given control

View File

@ -4,7 +4,7 @@
* Al Longyear <longyear@netcom.com>
* Extensively rewritten by Paul Mackerras <paulus@cs.anu.edu.au>
*
* ==FILEVERSION 990114==
* ==FILEVERSION 990325==
*
* NOTE TO MAINTAINERS:
* If you modify this file at all, please set the number above to the
@ -45,7 +45,7 @@
#define PPP_MAX_RCV_QLEN 32 /* max # frames we queue up for pppd */
/* $Id: ppp.c,v 1.21 1999/02/26 06:48:21 paulus Exp $ */
/* $Id: ppp.c,v 1.22 1999/03/30 06:33:07 paulus Exp $ */
#include <linux/version.h>
#include <linux/config.h>
@ -185,9 +185,11 @@ static void ppp_unregister_compressor (struct compressor *cp);
static void ppp_async_init(struct ppp *ppp);
static void ppp_async_release(struct ppp *ppp);
static int ppp_tty_sync_push(struct ppp *ppp);
static int ppp_tty_push(struct ppp *ppp);
static int ppp_async_encode(struct ppp *ppp);
static int ppp_async_send(struct ppp *, struct sk_buff *);
static int ppp_sync_send(struct ppp *, struct sk_buff *);
static int ppp_ioctl(struct ppp *, unsigned int, unsigned long);
static int ppp_set_compression (struct ppp *ppp, struct ppp_option_data *odp);
@ -954,6 +956,135 @@ ppp_tty_wakeup (struct tty_struct *tty)
ppp_output_wakeup(ppp);
}
/*
* Send a packet to the peer over a synchronous tty line.
* All encoding and FCS are handled by hardware.
* Addr/Ctrl and Protocol field compression implemented.
* Returns -1 iff the packet could not be accepted at present,
* 0 if the packet was accepted but we can't accept another yet, or
* 1 if we can accept another packet immediately.
* If this procedure returns 0, ppp_output_wakeup will be called
* exactly once.
*/
static int
ppp_sync_send(struct ppp *ppp, struct sk_buff *skb)
{
unsigned char *data;
int islcp;
CHECK_PPP(0);
if (ppp->tpkt != NULL)
return -1;
ppp->tpkt = skb;
data = ppp->tpkt->data;
/*
* LCP packets with code values between 1 (configure-reqest)
* and 7 (code-reject) must be sent as though no options
* had been negotiated.
*/
islcp = PPP_PROTOCOL(data) == PPP_LCP
&& 1 <= data[PPP_HDRLEN] && data[PPP_HDRLEN] <= 7;
/* only reset idle time for data packets */
if (PPP_PROTOCOL(data) < 0x8000)
ppp->last_xmit = jiffies;
++ppp->stats.ppp_opackets;
ppp->stats.ppp_ooctects += ppp->tpkt->len;
if ( !(data[2]) && (ppp->flags & SC_COMP_PROT) ) {
/* compress protocol field */
data[2] = data[1];
data[1] = data[0];
skb_pull(ppp->tpkt,1);
data = ppp->tpkt->data;
}
/*
* Do address/control compression
*/
if ((ppp->flags & SC_COMP_AC) && !islcp
&& PPP_ADDRESS(data) == PPP_ALLSTATIONS
&& PPP_CONTROL(data) == PPP_UI) {
/* strip addr and control field */
skb_pull(ppp->tpkt,2);
}
return ppp_tty_sync_push(ppp);
}
/*
* Push a synchronous frame out to the tty.
* Returns 1 if frame accepted (or discarded), 0 otherwise.
*/
static int
ppp_tty_sync_push(struct ppp *ppp)
{
int sent;
struct tty_struct *tty = ppp2tty(ppp);
unsigned long flags;
CHECK_PPP(0);
if (ppp->tpkt == NULL)
return 0;
/* prevent reentrancy with tty_pushing flag */
save_flags(flags);
cli();
if (ppp->tty_pushing) {
/* record wakeup attempt so we don't loose */
/* a wakeup call while doing push processing */
ppp->woke_up=1;
restore_flags(flags);
return 0;
}
ppp->tty_pushing = 1;
restore_flags(flags);
if (tty == NULL || tty->disc_data != (void *) ppp)
goto flush;
for(;;){
ppp->woke_up=0;
/* Note: Sync driver accepts complete frame or nothing */
tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
sent = tty->driver.write(tty, 0, ppp->tpkt->data, ppp->tpkt->len);
if (sent < 0) {
/* write error (possible loss of CD) */
/* record error and discard current packet */
ppp->stats.ppp_oerrors++;
break;
}
ppp->stats.ppp_obytes += sent;
if (sent < ppp->tpkt->len) {
/* driver unable to accept frame just yet */
save_flags(flags);
cli();
if (ppp->woke_up) {
/* wake up called while processing */
/* try to send the frame again */
restore_flags(flags);
continue;
}
/* wait for wakeup callback to try send again */
ppp->tty_pushing = 0;
restore_flags(flags);
return 0;
}
break;
}
flush:
/* done with current packet (sent or discarded) */
KFREE_SKB(ppp->tpkt);
ppp->tpkt = 0;
ppp->tty_pushing = 0;
return 1;
}
/*
* Send a packet to the peer over an async tty line.
* Returns -1 iff the packet could not be accepted at present,
@ -986,6 +1117,9 @@ ppp_tty_push(struct ppp *ppp)
{
int avail, sent, done = 0;
struct tty_struct *tty = ppp2tty(ppp);
if ( ppp->flags & SC_SYNC )
return ppp_tty_sync_push(ppp);
CHECK_PPP(0);
if (ppp->tty_pushing)
@ -1184,6 +1318,74 @@ ppp_tty_receive (struct tty_struct *tty, const __u8 * data,
ppp->stats.ppp_ibytes += count;
skb = ppp->rpkt;
if ( ppp->flags & SC_SYNC ) {
/* synchronous mode */
if (ppp->toss==0xE0) {
/* this is the 1st frame, reset vj comp */
ppp_receive_error(ppp);
ppp->toss = 0;
}
/*
* Allocate an skbuff for frame.
* The 128 is room for VJ header expansion.
*/
if (skb == NULL)
skb = dev_alloc_skb(ppp->mru + 128 + PPP_HDRLEN);
if (skb == NULL) {
if (ppp->flags & SC_DEBUG)
printk(KERN_DEBUG "couldn't "
"alloc skb for recv\n");
} else {
LIBERATE_SKB(skb);
/*
* Decompress A/C and protocol compression here.
*/
p = skb_put(skb, 2);
p[0] = PPP_ALLSTATIONS;
p[1] = PPP_UI;
if (*data == PPP_ALLSTATIONS) {
data += 2;
count -= 2;
}
if ((*data & 1) != 0) {
p = skb_put(skb, 1);
p[0] = 0;
}
/* copy frame to socket buffer */
p = skb_put(skb, count);
memcpy(p,data,count);
/*
* Check if we've overflowed the MRU
*/
if (skb->len >= ppp->mru + PPP_HDRLEN + 2
|| skb_tailroom(skb) <= 0) {
++ppp->estats.rx_length_errors;
if (ppp->flags & SC_DEBUG)
printk(KERN_DEBUG "rcv frame too long: "
"len=%d mru=%d hroom=%d troom=%d\n",
skb->len, ppp->mru, skb_headroom(skb),
skb_tailroom(skb));
} else {
if (!ppp_receive_frame(ppp, skb)) {
KFREE_SKB(skb);
ppp_receive_error(ppp);
}
}
/* Reset for the next frame */
skb = NULL;
}
ppp->rpkt = skb;
return;
}
while (count-- > 0) {
/*
* Collect the character and error condition for the character.
@ -2024,23 +2226,25 @@ ppp_receive_frame(struct ppp *ppp, struct sk_buff *skb)
return 0;
}
/*
* Verify the FCS of the frame and discard the FCS characters
* from the end of the buffer.
*/
if (ppp->rfcs != PPP_GOODFCS) {
if (ppp->flags & SC_DEBUG) {
printk(KERN_DEBUG
"ppp: frame with bad fcs, length = %d\n",
count);
ppp_print_buffer("bad frame", data, count);
if ( !(ppp->flags & SC_SYNC) ) {
/*
* Verify the FCS of the frame and discard the FCS characters
* from the end of the buffer.
*/
if (ppp->rfcs != PPP_GOODFCS) {
if (ppp->flags & SC_DEBUG) {
printk(KERN_DEBUG
"ppp: frame with bad fcs, length = %d\n",
count);
ppp_print_buffer("bad frame", data, count);
}
++ppp->estats.rx_crc_errors;
return 0;
}
++ppp->estats.rx_crc_errors;
return 0;
count -= 2; /* ignore the fcs characters */
skb_trim(skb, count);
}
count -= 2; /* ignore the fcs characters */
skb_trim(skb, count);
/*
* Process the active decompressor.
*/
@ -2410,7 +2614,10 @@ ppp_send_frame(struct ppp *ppp, struct sk_buff *skb)
/*
* Send the frame
*/
ret = ppp_async_send(ppp, skb);
if ( ppp->flags & SC_SYNC )
ret = ppp_sync_send(ppp, skb);
else
ret = ppp_async_send(ppp, skb);
if (ret > 0) {
/* we can release the lock */
ppp->xmit_busy = 0;

View File

@ -18,7 +18,7 @@
*/
#ifndef lint
static char rcsid[] = "$Id: options.c,v 1.55 1999/03/24 05:05:24 paulus Exp $";
static char rcsid[] = "$Id: options.c,v 1.56 1999/03/30 06:33:08 paulus Exp $";
#endif
#include <ctype.h>
@ -89,6 +89,7 @@ int holdoff = 30; /* # seconds to pause before reconnecting */
bool notty = 0; /* Stdin/out is not a tty */
char *record_file = NULL; /* File to record chars sent/received */
int using_pty = 0;
bool sync_serial = 0; /* Device is synchronous serial device */
extern option_t auth_options[];
@ -211,6 +212,8 @@ option_t general_options[] = {
"Show brief listing of options" },
{ "-h", o_special_noarg, showhelp,
"Show brief listing of options" },
{ "sync", o_bool, &sync_serial,
"Use synchronous HDLC serial encoding", 1 },
#ifdef PPP_FILTER
{ "pdebug", o_int, &dflag,

View File

@ -1,5 +1,5 @@
.\" manual page [] for pppd 2.3
.\" $Id: pppd.8,v 1.37 1999/03/23 03:22:34 paulus Exp $
.\" $Id: pppd.8,v 1.38 1999/03/30 06:33:09 paulus Exp $
.\" SH section heading
.\" SS subsection heading
.\" LP paragraph
@ -690,6 +690,12 @@ With this option, pppd will not transmit LCP packets to initiate a
connection until a valid LCP packet is received from the peer (as for
the `passive' option with ancient versions of pppd).
.TP
.B sync
Use synchronous HDLC serial encoding instead of asynchronous.
The device used by pppd with this option must support synchronous
serial communications. Currently supports Microgate SyncLink adapters
under Linux.
.TP
.B usehostname
Enforce the use of the hostname (with domain name appended, if given)
as the name of the local system for authentication purposes (overrides

View File

@ -16,7 +16,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: pppd.h,v 1.35 1999/03/24 05:05:25 paulus Exp $
* $Id: pppd.h,v 1.36 1999/03/30 06:33:09 paulus Exp $
*/
/*
@ -181,6 +181,7 @@ extern int idle_time_limit;/* Shut down link if idle for this long */
extern int holdoff; /* Dead time before restarting */
extern bool notty; /* Stdin/out is not a tty */
extern char *record_file; /* File to record chars sent/received */
extern bool sync_serial; /* Device is synchronous serial device */
#ifdef PPP_FILTER
extern struct bpf_program pass_filter; /* Filter for pkts to pass */

View File

@ -866,6 +866,7 @@ void ppp_send_config (int unit,int mtu,u_int32_t asyncmap,int pcomp,int accomp)
x = get_flags();
x = pcomp ? x | SC_COMP_PROT : x & ~SC_COMP_PROT;
x = accomp ? x | SC_COMP_AC : x & ~SC_COMP_AC;
x = sync_serial ? x | SC_SYNC : x & ~SC_SYNC;
set_flags(x);
}