Parcourir la source

Merge branch 'for-david' of git://git.kernel.org/pub/scm/linux/kernel/git/chris/linux-2.6

David S. Miller il y a 16 ans
Parent
commit
c46920dadb

+ 1 - 1
Documentation/DocBook/Makefile

@@ -6,7 +6,7 @@
 # To add a new book the only step required is to add the book to the
 # list of DOCBOOKS.
 
-DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml \
+DOCBOOKS := z8530book.xml mcabook.xml \
 	    kernel-hacking.xml kernel-locking.xml deviceiobook.xml \
 	    procfs-guide.xml writing_usb_driver.xml networking.xml \
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \

+ 0 - 3
Documentation/DocBook/networking.tmpl

@@ -98,9 +98,6 @@
 X!Enet/core/wireless.c
      </sect1>
 -->
-     <sect1><title>Synchronous PPP</title>
-!Edrivers/net/wan/syncppp.c
-     </sect1>
   </chapter>
 
 </book>

+ 0 - 99
Documentation/DocBook/wanbook.tmpl

@@ -1,99 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
-	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
-
-<book id="WANGuide">
- <bookinfo>
-  <title>Synchronous PPP and Cisco HDLC Programming Guide</title>
-  
-  <authorgroup>
-   <author>
-    <firstname>Alan</firstname>
-    <surname>Cox</surname>
-    <affiliation>
-     <address>
-      <email>alan@lxorguk.ukuu.org.uk</email>
-     </address>
-    </affiliation>
-   </author>
-  </authorgroup>
-
-  <copyright>
-   <year>2000</year>
-   <holder>Alan Cox</holder>
-  </copyright>
-
-  <legalnotice>
-   <para>
-     This documentation is free software; you can redistribute
-     it and/or modify it under the terms of the GNU General Public
-     License as published by the Free Software Foundation; either
-     version 2 of the License, or (at your option) any later
-     version.
-   </para>
-      
-   <para>
-     This program is distributed in the hope that it will be
-     useful, but WITHOUT ANY WARRANTY; without even the implied
-     warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-     See the GNU General Public License for more details.
-   </para>
-      
-   <para>
-     You should have received a copy of the GNU General Public
-     License along with this program; if not, write to the Free
-     Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
-     MA 02111-1307 USA
-   </para>
-      
-   <para>
-     For more details see the file COPYING in the source
-     distribution of Linux.
-   </para>
-  </legalnotice>
- </bookinfo>
-
-<toc></toc>
-
-  <chapter id="intro">
-      <title>Introduction</title>
-  <para>
-	The syncppp drivers in Linux provide a fairly complete 
-	implementation of Cisco HDLC and a minimal implementation of
-	PPP. The longer term goal is to switch the PPP layer to the
-	generic PPP interface that is new in Linux 2.3.x. The API should
-	remain unchanged when this is done, but support will then be
-	available for IPX, compression and other PPP features
-  </para>
-  </chapter>
-  <chapter id="bugs">
-     <title>Known Bugs And Assumptions</title>
-  <para>
-  <variablelist>
-    <varlistentry><term>PPP is minimal</term>
-    <listitem>
-    <para>
-	The current PPP implementation is very basic, although sufficient
-	for most wan usages.
-    </para>
-    </listitem></varlistentry>
-
-    <varlistentry><term>Cisco HDLC Quirks</term>
-    <listitem>
-    <para>
-	Currently we do not end all packets with the correct Cisco multicast
-	or unicast flags. Nothing appears to mind too much but this should
-	be corrected.
-    </para>
-    </listitem></varlistentry>
-  </variablelist>
-	
-  </para>
-  </chapter>
-
-  <chapter id="pubfunctions">
-     <title>Public Functions Provided</title>
-!Edrivers/net/wan/syncppp.c
-  </chapter>
-
-</book>

+ 4 - 4
Documentation/networking/generic-hdlc.txt

@@ -3,15 +3,15 @@ Krzysztof Halasa <khc@pm.waw.pl>
 
 
 Generic HDLC layer currently supports:
-1. Frame Relay (ANSI, CCITT, Cisco and no LMI).
+1. Frame Relay (ANSI, CCITT, Cisco and no LMI)
    - Normal (routed) and Ethernet-bridged (Ethernet device emulation)
      interfaces can share a single PVC.
    - ARP support (no InARP support in the kernel - there is an
      experimental InARP user-space daemon available on:
      http://www.kernel.org/pub/linux/utils/net/hdlc/).
-2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
-3. Cisco HDLC.
-4. PPP (uses syncppp.c).
+2. raw HDLC - either IP (IPv4) interface or Ethernet device emulation
+3. Cisco HDLC
+4. PPP
 5. X.25 (uses X.25 routines).
 
 Generic HDLC is a protocol driver only - it needs a low-level driver

+ 1 - 1
drivers/net/wan/Makefile

@@ -14,7 +14,7 @@ obj-$(CONFIG_HDLC_RAW)		+= hdlc_raw.o
 obj-$(CONFIG_HDLC_RAW_ETH)	+= hdlc_raw_eth.o
 obj-$(CONFIG_HDLC_CISCO)	+= hdlc_cisco.o
 obj-$(CONFIG_HDLC_FR)		+= hdlc_fr.o
-obj-$(CONFIG_HDLC_PPP)		+= hdlc_ppp.o	syncppp.o
+obj-$(CONFIG_HDLC_PPP)		+= hdlc_ppp.o
 obj-$(CONFIG_HDLC_X25)		+= hdlc_x25.o
 
 pc300-y				:= pc300_drv.o

+ 3 - 3
drivers/net/wan/c101.c

@@ -88,7 +88,7 @@ static card_t **new_card = &first_card;
 /* EDA address register must be set in EDAL, EDAH order - 8 bit ISA bus */
 #define sca_outw(value, reg, card) do { \
 	writeb(value & 0xFF, (card)->win0base + C101_SCA + (reg)); \
-	writeb((value >> 8 ) & 0xFF, (card)->win0base + C101_SCA + (reg+1));\
+	writeb((value >> 8 ) & 0xFF, (card)->win0base + C101_SCA + (reg + 1));\
 } while(0)
 
 #define port_to_card(port)	   (port)
@@ -113,7 +113,7 @@ static inline void openwin(card_t *card, u8 page)
 }
 
 
-#include "hd6457x.c"
+#include "hd64570.c"
 
 
 static inline void set_carrier(port_t *port)
@@ -381,7 +381,7 @@ static int __init c101_run(unsigned long irq, unsigned long winbase)
 		return result;
 	}
 
-	sca_init_sync_port(card); /* Set up C101 memory */
+	sca_init_port(card); /* Set up C101 memory */
 	set_carrier(card);
 
 	printk(KERN_INFO "%s: Moxa C101 on IRQ%u,"

+ 55 - 199
drivers/net/wan/hd6457x.c → drivers/net/wan/hd64570.c

@@ -1,5 +1,5 @@
 /*
- * Hitachi SCA HD64570 and HD64572 common driver for Linux
+ * Hitachi SCA HD64570 driver for Linux
  *
  * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
  *
@@ -7,9 +7,7 @@
  * under the terms of version 2 of the GNU General Public License
  * as published by the Free Software Foundation.
  *
- * Sources of information:
- *    Hitachi HD64570 SCA User's Manual
- *    Hitachi HD64572 SCA-II User's Manual
+ * Source of information: Hitachi HD64570 SCA User's Manual
  *
  * We use the following SCA memory map:
  *
@@ -26,33 +24,26 @@
  * tx_ring_buffers * HDLC_MAX_MRU     = logical channel #0 TX buffers (if used)
  */
 
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <linux/jiffies.h>
-#include <linux/types.h>
+#include <linux/bitops.h>
+#include <linux/errno.h>
 #include <linux/fcntl.h>
-#include <linux/interrupt.h>
+#include <linux/hdlc.h>
 #include <linux/in.h>
-#include <linux/string.h>
-#include <linux/errno.h>
 #include <linux/init.h>
+#include <linux/interrupt.h>
 #include <linux/ioport.h>
-#include <linux/bitops.h>
-
-#include <asm/system.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/netdevice.h>
 #include <linux/skbuff.h>
-
-#include <linux/hdlc.h>
-
-#if (!defined (__HD64570_H) && !defined (__HD64572_H)) || \
-    (defined (__HD64570_H) && defined (__HD64572_H))
-#error Either hd64570.h or hd64572.h must be included
-#endif
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include "hd64570.h"
 
 #define get_msci(port)	  (phy_node(port) ?   MSCI1_OFFSET :   MSCI0_OFFSET)
 #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET)
@@ -62,16 +53,6 @@
 #define SCA_INTR_DMAC_RX(node) (node ? 0x20 : 0x02)
 #define SCA_INTR_DMAC_TX(node) (node ? 0x40 : 0x04)
 
-#ifdef __HD64570_H /* HD64570 */
-#define sca_outa(value, reg, card)	sca_outw(value, reg, card)
-#define sca_ina(reg, card)		sca_inw(reg, card)
-#define writea(value, ptr)		writew(value, ptr)
-
-#else /* HD64572 */
-#define sca_outa(value, reg, card)	sca_outl(value, reg, card)
-#define sca_ina(reg, card)		sca_inl(reg, card)
-#define writea(value, ptr)		writel(value, ptr)
-#endif
 
 static inline struct net_device *port_to_dev(port_t *port)
 {
@@ -81,8 +62,6 @@ static inline struct net_device *port_to_dev(port_t *port)
 static inline int sca_intr_status(card_t *card)
 {
 	u8 result = 0;
-
-#ifdef __HD64570_H /* HD64570 */
 	u8 isr0 = sca_in(ISR0, card);
 	u8 isr1 = sca_in(ISR1, card);
 
@@ -93,18 +72,6 @@ static inline int sca_intr_status(card_t *card)
 	if (isr0 & 0x0F) result |= SCA_INTR_MSCI(0);
 	if (isr0 & 0xF0) result |= SCA_INTR_MSCI(1);
 
-#else /* HD64572 */
-	u32 isr0 = sca_inl(ISR0, card);
-
-	if (isr0 & 0x0000000F) result |= SCA_INTR_DMAC_RX(0);
-	if (isr0 & 0x000000F0) result |= SCA_INTR_DMAC_TX(0);
-	if (isr0 & 0x00000F00) result |= SCA_INTR_DMAC_RX(1);
-	if (isr0 & 0x0000F000) result |= SCA_INTR_DMAC_TX(1);
-	if (isr0 & 0x003E0000) result |= SCA_INTR_MSCI(0);
-	if (isr0 & 0x3E000000) result |= SCA_INTR_MSCI(1);
-
-#endif /* HD64570 vs HD64572 */
-
 	if (!(result & SCA_INTR_DMAC_TX(0)))
 		if (sca_in(DSR_TX(0), card) & DSR_EOM)
 			result |= SCA_INTR_DMAC_TX(0);
@@ -127,7 +94,6 @@ static inline u16 next_desc(port_t *port, u16 desc, int transmit)
 }
 
 
-
 static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit)
 {
 	u16 rx_buffs = port_to_card(port)->rx_ring_buffers;
@@ -139,28 +105,26 @@ static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit)
 }
 
 
-
 static inline u16 desc_offset(port_t *port, u16 desc, int transmit)
 {
-	/* Descriptor offset always fits in 16 bytes */
+	/* Descriptor offset always fits in 16 bits */
 	return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc);
 }
 
 
-
-static inline pkt_desc __iomem *desc_address(port_t *port, u16 desc, int transmit)
+static inline pkt_desc __iomem *desc_address(port_t *port, u16 desc,
+					     int transmit)
 {
 #ifdef PAGE0_ALWAYS_MAPPED
 	return (pkt_desc __iomem *)(win0base(port_to_card(port))
-			   + desc_offset(port, desc, transmit));
+				    + desc_offset(port, desc, transmit));
 #else
 	return (pkt_desc __iomem *)(winbase(port_to_card(port))
-			   + desc_offset(port, desc, transmit));
+				    + desc_offset(port, desc, transmit));
 #endif
 }
 
 
-
 static inline u32 buffer_offset(port_t *port, u16 desc, int transmit)
 {
 	return port_to_card(port)->buff_offset +
@@ -186,7 +150,7 @@ static inline void sca_set_carrier(port_t *port)
 }
 
 
-static void sca_init_sync_port(port_t *port)
+static void sca_init_port(port_t *port)
 {
 	card_t *card = port_to_card(port);
 	int transmit, i;
@@ -195,7 +159,7 @@ static void sca_init_sync_port(port_t *port)
 	port->txin = 0;
 	port->txlast = 0;
 
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
+#ifndef PAGE0_ALWAYS_MAPPED
 	openwin(card, 0);
 #endif
 
@@ -209,7 +173,7 @@ static void sca_init_sync_port(port_t *port)
 			u16 chain_off = desc_offset(port, i + 1, transmit);
 			u32 buff_off = buffer_offset(port, i, transmit);
 
-			writea(chain_off, &desc->cp);
+			writew(chain_off, &desc->cp);
 			writel(buff_off, &desc->bp);
 			writew(0, &desc->len);
 			writeb(0, &desc->stat);
@@ -222,16 +186,14 @@ static void sca_init_sync_port(port_t *port)
 		sca_out(DCR_ABORT, transmit ? DCR_TX(phy_node(port)) :
 			DCR_RX(phy_node(port)), card);
 
-#ifdef __HD64570_H
-		sca_out(0, dmac + CPB, card); /* pointer base */
-#endif
 		/* current desc addr */
-		sca_outa(desc_offset(port, 0, transmit), dmac + CDAL, card);
+		sca_out(0, dmac + CPB, card); /* pointer base */
+		sca_outw(desc_offset(port, 0, transmit), dmac + CDAL, card);
 		if (!transmit)
-			sca_outa(desc_offset(port, buffs - 1, transmit),
+			sca_outw(desc_offset(port, buffs - 1, transmit),
 				 dmac + EDAL, card);
 		else
-			sca_outa(desc_offset(port, 0, transmit), dmac + EDAL,
+			sca_outw(desc_offset(port, 0, transmit), dmac + EDAL,
 				 card);
 
 		/* clear frame end interrupt counter */
@@ -258,7 +220,6 @@ static void sca_init_sync_port(port_t *port)
 }
 
 
-
 #ifdef NEED_SCA_MSCI_INTR
 /* MSCI interrupt service */
 static inline void sca_msci_intr(port_t *port)
@@ -282,17 +243,15 @@ static inline void sca_msci_intr(port_t *port)
 #endif
 
 
-
-static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u16 rxin)
+static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc,
+			  u16 rxin)
 {
 	struct net_device *dev = port_to_dev(port);
 	struct sk_buff *skb;
 	u16 len;
 	u32 buff;
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	u32 maxlen;
 	u8 page;
-#endif
 
 	len = readw(&desc->len);
 	skb = dev_alloc_skb(len);
@@ -302,7 +261,6 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
 	}
 
 	buff = buffer_offset(port, rxin, 0);
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	page = buff / winsize(card);
 	buff = buff % winsize(card);
 	maxlen = winsize(card) - buff;
@@ -314,12 +272,10 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
 		openwin(card, page + 1);
 		memcpy_fromio(skb->data + maxlen, winbase(card), len - maxlen);
 	} else
-#endif
-	memcpy_fromio(skb->data, winbase(card) + buff, len);
+		memcpy_fromio(skb->data, winbase(card) + buff, len);
 
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-	/* select pkt_desc table page back */
-	openwin(card, 0);
+#ifndef PAGE0_ALWAYS_MAPPED
+	openwin(card, 0);	/* select pkt_desc table page back */
 #endif
 	skb_put(skb, len);
 #ifdef DEBUG_PKT
@@ -333,7 +289,6 @@ static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc, u1
 }
 
 
-
 /* Receive DMA interrupt service */
 static inline void sca_rx_intr(port_t *port)
 {
@@ -353,7 +308,7 @@ static inline void sca_rx_intr(port_t *port)
 	while (1) {
 		u32 desc_off = desc_offset(port, port->rxin, 0);
 		pkt_desc __iomem *desc;
-		u32 cda = sca_ina(dmac + CDAL, card);
+		u32 cda = sca_inw(dmac + CDAL, card);
 
 		if ((cda >= desc_off) && (cda < desc_off + sizeof(pkt_desc)))
 			break;	/* No frame received */
@@ -377,7 +332,7 @@ static inline void sca_rx_intr(port_t *port)
 			sca_rx(card, port, desc, port->rxin);
 
 		/* Set new error descriptor address */
-		sca_outa(desc_off, dmac + EDAL, card);
+		sca_outw(desc_off, dmac + EDAL, card);
 		port->rxin = next_desc(port, port->rxin, 0);
 	}
 
@@ -386,7 +341,6 @@ static inline void sca_rx_intr(port_t *port)
 }
 
 
-
 /* Transmit DMA interrupt service */
 static inline void sca_tx_intr(port_t *port)
 {
@@ -407,7 +361,7 @@ static inline void sca_tx_intr(port_t *port)
 		pkt_desc __iomem *desc;
 
 		u32 desc_off = desc_offset(port, port->txlast, 1);
-		u32 cda = sca_ina(dmac + CDAL, card);
+		u32 cda = sca_inw(dmac + CDAL, card);
 		if ((cda >= desc_off) && (cda < desc_off + sizeof(pkt_desc)))
 			break;	/* Transmitter is/will_be sending this frame */
 
@@ -423,17 +377,13 @@ static inline void sca_tx_intr(port_t *port)
 }
 
 
-
 static irqreturn_t sca_intr(int irq, void* dev_id)
 {
 	card_t *card = dev_id;
 	int i;
 	u8 stat;
 	int handled = 0;
-
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	u8 page = sca_get_page(card);
-#endif
 
 	while((stat = sca_intr_status(card)) != 0) {
 		handled = 1;
@@ -452,14 +402,11 @@ static irqreturn_t sca_intr(int irq, void* dev_id)
 		}
 	}
 
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	openwin(card, page);		/* Restore original page */
-#endif
 	return IRQ_RETVAL(handled);
 }
 
 
-
 static void sca_set_port(port_t *port)
 {
 	card_t* card = port_to_card(port);
@@ -497,12 +444,7 @@ static void sca_set_port(port_t *port)
 	port->tmc = tmc;
 
 	/* baud divisor - time constant*/
-#ifdef __HD64570_H
 	sca_out(port->tmc, msci + TMC, card);
-#else
-	sca_out(port->tmc, msci + TMCR, card);
-	sca_out(port->tmc, msci + TMCT, card);
-#endif
 
 	/* Set BRG bits */
 	sca_out(port->rxs, msci + RXS, card);
@@ -518,7 +460,6 @@ static void sca_set_port(port_t *port)
 }
 
 
-
 static void sca_open(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
@@ -540,11 +481,7 @@ static void sca_open(struct net_device *dev)
 	switch(port->parity) {
 	case PARITY_CRC16_PR0:	     md0 = MD0_HDLC | MD0_CRC_16_0;  break;
 	case PARITY_CRC16_PR1:	     md0 = MD0_HDLC | MD0_CRC_16;    break;
-#ifdef __HD64570_H
 	case PARITY_CRC16_PR0_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU_0; break;
-#else
-	case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break;
-#endif
 	case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU;   break;
 	default:		     md0 = MD0_HDLC | MD0_CRC_NONE;
 	}
@@ -554,35 +491,20 @@ static void sca_open(struct net_device *dev)
 	sca_out(0x00, msci + MD1, card); /* no address field check */
 	sca_out(md2, msci + MD2, card);
 	sca_out(0x7E, msci + IDL, card); /* flag character 0x7E */
-#ifdef __HD64570_H
 	sca_out(CTL_IDLE, msci + CTL, card);
-#else
-	/* Skip the rest of underrun frame */
-	sca_out(CTL_IDLE | CTL_URCT | CTL_URSKP, msci + CTL, card);
-#endif
 
-#ifdef __HD64570_H
 	/* Allow at least 8 bytes before requesting RX DMA operation */
 	/* TX with higher priority and possibly with shorter transfers */
 	sca_out(0x07, msci + RRC, card); /* +1=RXRDY/DMA activation condition*/
 	sca_out(0x10, msci + TRC0, card); /* = TXRDY/DMA activation condition*/
 	sca_out(0x14, msci + TRC1, card); /* +1=TXRDY/DMA deactiv condition */
-#else
-	sca_out(0x0F, msci + RNR, card); /* +1=RX DMA activation condition */
-	sca_out(0x3C, msci + TFS, card); /* +1 = TX start */
-	sca_out(0x38, msci + TCR, card); /* =Critical TX DMA activ condition */
-	sca_out(0x38, msci + TNR0, card); /* =TX DMA activation condition */
-	sca_out(0x3F, msci + TNR1, card); /* +1=TX DMA deactivation condition*/
-#endif
 
 /* We're using the following interrupts:
    - TXINT (DMAC completed all transmisions, underrun or DCD change)
    - all DMA interrupts
 */
-
 	sca_set_carrier(port);
 
-#ifdef __HD64570_H
 	/* MSCI TX INT and RX INT A IRQ enable */
 	sca_out(IE0_TXINT | IE0_RXINTA, msci + IE0, card);
 	sca_out(IE1_UDRN | IE1_CDCD, msci + IE1, card);
@@ -591,21 +513,8 @@ static void sca_open(struct net_device *dev)
 	/* enable DMA IRQ */
 	sca_out(sca_in(IER1, card) | (phy_node(port) ? 0xF0 : 0x0F),
 		IER1, card);
-#else
-	/* MSCI TXINT and RXINTA interrupt enable */
-	sca_outl(IE0_TXINT | IE0_RXINTA | IE0_UDRN | IE0_CDCD, msci + IE0,
-		 card);
-	/* DMA & MSCI IRQ enable */
-	sca_outl(sca_inl(IER0, card) |
-		 (phy_node(port) ? 0x0A006600 : 0x000A0066), IER0, card);
-#endif
 
-#ifdef __HD64570_H
 	sca_out(port->tmc, msci + TMC, card); /* Restore registers */
-#else
-	sca_out(port->tmc, msci + TMCR, card);
-	sca_out(port->tmc, msci + TMCT, card);
-#endif
 	sca_out(port->rxs, msci + RXS, card);
 	sca_out(port->txs, msci + TXS, card);
 	sca_out(CMD_TX_ENABLE, msci + CMD, card);
@@ -615,7 +524,6 @@ static void sca_open(struct net_device *dev)
 }
 
 
-
 static void sca_close(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
@@ -623,23 +531,17 @@ static void sca_close(struct net_device *dev)
 
 	/* reset channel */
 	sca_out(CMD_RESET, get_msci(port) + CMD, port_to_card(port));
-#ifdef __HD64570_H
 	/* disable MSCI interrupts */
 	sca_out(sca_in(IER0, card) & (phy_node(port) ? 0x0F : 0xF0),
 		IER0, card);
 	/* disable DMA interrupts */
 	sca_out(sca_in(IER1, card) & (phy_node(port) ? 0x0F : 0xF0),
 		IER1, card);
-#else
-	/* disable DMA & MSCI IRQ */
-	sca_outl(sca_inl(IER0, card) &
-		 (phy_node(port) ? 0x00FF00FF : 0xFF00FF00), IER0, card);
-#endif
+
 	netif_stop_queue(dev);
 }
 
 
-
 static int sca_attach(struct net_device *dev, unsigned short encoding,
 		      unsigned short parity)
 {
@@ -653,11 +555,7 @@ static int sca_attach(struct net_device *dev, unsigned short encoding,
 	if (parity != PARITY_NONE &&
 	    parity != PARITY_CRC16_PR0 &&
 	    parity != PARITY_CRC16_PR1 &&
-#ifdef __HD64570_H
 	    parity != PARITY_CRC16_PR0_CCITT &&
-#else
-	    parity != PARITY_CRC32_PR1_CCITT &&
-#endif
 	    parity != PARITY_CRC16_PR1_CCITT)
 		return -EINVAL;
 
@@ -667,34 +565,30 @@ static int sca_attach(struct net_device *dev, unsigned short encoding,
 }
 
 
-
 #ifdef DEBUG_RINGS
 static void sca_dump_rings(struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	card_t *card = port_to_card(port);
 	u16 cnt;
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-	u8 page;
-#endif
+#ifndef PAGE0_ALWAYS_MAPPED
+	u8 page = sca_get_page(card);
 
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
-	page = sca_get_page(card);
 	openwin(card, 0);
 #endif
 
 	printk(KERN_DEBUG "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive",
-	       sca_ina(get_dmac_rx(port) + CDAL, card),
-	       sca_ina(get_dmac_rx(port) + EDAL, card),
+	       sca_inw(get_dmac_rx(port) + CDAL, card),
+	       sca_inw(get_dmac_rx(port) + EDAL, card),
 	       sca_in(DSR_RX(phy_node(port)), card), port->rxin,
-	       sca_in(DSR_RX(phy_node(port)), card) & DSR_DE?"":"in");
+	       sca_in(DSR_RX(phy_node(port)), card) & DSR_DE ? "" : "in");
 	for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++)
 		printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat)));
 
 	printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
 	       "last=%u %sactive",
-	       sca_ina(get_dmac_tx(port) + CDAL, card),
-	       sca_ina(get_dmac_tx(port) + EDAL, card),
+	       sca_inw(get_dmac_tx(port) + CDAL, card),
+	       sca_inw(get_dmac_tx(port) + EDAL, card),
 	       sca_in(DSR_TX(phy_node(port)), card), port->txin, port->txlast,
 	       sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in");
 
@@ -702,12 +596,8 @@ static void sca_dump_rings(struct net_device *dev)
 		printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat)));
 	printk("\n");
 
-	printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, "
-	       "ST: %02x %02x %02x %02x"
-#ifdef __HD64572_H
-	       " %02x"
-#endif
-	       ", FST: %02x CST: %02x %02x\n",
+	printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x, ST: %02x %02x %02x %02x,"
+	       " FST: %02x CST: %02x %02x\n",
 	       sca_in(get_msci(port) + MD0, card),
 	       sca_in(get_msci(port) + MD1, card),
 	       sca_in(get_msci(port) + MD2, card),
@@ -715,52 +605,33 @@ static void sca_dump_rings(struct net_device *dev)
 	       sca_in(get_msci(port) + ST1, card),
 	       sca_in(get_msci(port) + ST2, card),
 	       sca_in(get_msci(port) + ST3, card),
-#ifdef __HD64572_H
-	       sca_in(get_msci(port) + ST4, card),
-#endif
 	       sca_in(get_msci(port) + FST, card),
 	       sca_in(get_msci(port) + CST0, card),
 	       sca_in(get_msci(port) + CST1, card));
 
-#ifdef __HD64572_H
-	printk(KERN_DEBUG "ILAR: %02x ISR: %08x %08x\n", sca_in(ILAR, card),
-	       sca_inl(ISR0, card), sca_inl(ISR1, card));
-#else
 	printk(KERN_DEBUG "ISR: %02x %02x %02x\n", sca_in(ISR0, card),
 	       sca_in(ISR1, card), sca_in(ISR2, card));
-#endif
 
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
+#ifndef PAGE0_ALWAYS_MAPPED
 	openwin(card, page); /* Restore original page */
 #endif
 }
 #endif /* DEBUG_RINGS */
 
 
-
 static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	port_t *port = dev_to_port(dev);
 	card_t *card = port_to_card(port);
 	pkt_desc __iomem *desc;
 	u32 buff, len;
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	u8 page;
 	u32 maxlen;
-#endif
 
 	spin_lock_irq(&port->lock);
 
 	desc = desc_address(port, port->txin + 1, 1);
-	if (readb(&desc->stat)) { /* allow 1 packet gap */
-		/* should never happen - previous xmit should stop queue */
-#ifdef DEBUG_PKT
-		printk(KERN_DEBUG "%s: transmitter buffer full\n", dev->name);
-#endif
-		netif_stop_queue(dev);
-		spin_unlock_irq(&port->lock);
-		return 1;	/* request packet to be queued */
-	}
+	BUG_ON(readb(&desc->stat)); /* previous xmit should stop queue */
 
 #ifdef DEBUG_PKT
 	printk(KERN_DEBUG "%s TX(%i):", dev->name, skb->len);
@@ -770,7 +641,6 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 	desc = desc_address(port, port->txin, 1);
 	buff = buffer_offset(port, port->txin, 1);
 	len = skb->len;
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	page = buff / winsize(card);
 	buff = buff % winsize(card);
 	maxlen = winsize(card) - buff;
@@ -780,12 +650,10 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 		memcpy_toio(winbase(card) + buff, skb->data, maxlen);
 		openwin(card, page + 1);
 		memcpy_toio(winbase(card), skb->data + maxlen, len - maxlen);
-	}
-	else
-#endif
+	} else
 		memcpy_toio(winbase(card) + buff, skb->data, len);
 
-#if !defined(PAGE0_ALWAYS_MAPPED) && !defined(ALL_PAGES_ALWAYS_MAPPED)
+#ifndef PAGE0_ALWAYS_MAPPED
 	openwin(card, 0);	/* select pkt_desc table page back */
 #endif
 	writew(len, &desc->len);
@@ -793,7 +661,7 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 	dev->trans_start = jiffies;
 
 	port->txin = next_desc(port, port->txin, 1);
-	sca_outa(desc_offset(port, port->txin, 1),
+	sca_outw(desc_offset(port, port->txin, 1),
 		 get_dmac_tx(port) + EDAL, card);
 
 	sca_out(DSR_DE, DSR_TX(phy_node(port)), card); /* Enable TX DMA */
@@ -809,40 +677,29 @@ static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
 }
 
 
-
 #ifdef NEED_DETECT_RAM
-static u32 __devinit sca_detect_ram(card_t *card, u8 __iomem *rambase, u32 ramsize)
+static u32 __devinit sca_detect_ram(card_t *card, u8 __iomem *rambase,
+				    u32 ramsize)
 {
 	/* Round RAM size to 32 bits, fill from end to start */
 	u32 i = ramsize &= ~3;
-
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 	u32 size = winsize(card);
 
 	openwin(card, (i - 4) / size); /* select last window */
-#endif
+
 	do {
 		i -= 4;
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 		if ((i + 4) % size == 0)
 			openwin(card, i / size);
 		writel(i ^ 0x12345678, rambase + i % size);
-#else
-		writel(i ^ 0x12345678, rambase + i);
-#endif
-	}while (i > 0);
+	} while (i > 0);
 
 	for (i = 0; i < ramsize ; i += 4) {
-#ifndef ALL_PAGES_ALWAYS_MAPPED
 		if (i % size == 0)
 			openwin(card, i / size);
 
 		if (readl(rambase + i % size) != (i ^ 0x12345678))
 			break;
-#else
-		if (readl(rambase + i) != (i ^ 0x12345678))
-			break;
-#endif
 	}
 
 	return i;
@@ -850,7 +707,6 @@ static u32 __devinit sca_detect_ram(card_t *card, u8 __iomem *rambase, u32 ramsi
 #endif /* NEED_DETECT_RAM */
 
 
-
 static void __devinit sca_init(card_t *card, int wait_states)
 {
 	sca_out(wait_states, WCRL, card); /* Wait Control */

+ 640 - 0
drivers/net/wan/hd64572.c

@@ -0,0 +1,640 @@
+/*
+ * Hitachi (now Renesas) SCA-II HD64572 driver for Linux
+ *
+ * Copyright (C) 1998-2008 Krzysztof Halasa <khc@pm.waw.pl>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * Source of information: HD64572 SCA-II User's Manual
+ *
+ * We use the following SCA memory map:
+ *
+ * Packet buffer descriptor rings - starting from card->rambase:
+ * rx_ring_buffers * sizeof(pkt_desc) = logical channel #0 RX ring
+ * tx_ring_buffers * sizeof(pkt_desc) = logical channel #0 TX ring
+ * rx_ring_buffers * sizeof(pkt_desc) = logical channel #1 RX ring (if used)
+ * tx_ring_buffers * sizeof(pkt_desc) = logical channel #1 TX ring (if used)
+ *
+ * Packet data buffers - starting from card->rambase + buff_offset:
+ * rx_ring_buffers * HDLC_MAX_MRU     = logical channel #0 RX buffers
+ * tx_ring_buffers * HDLC_MAX_MRU     = logical channel #0 TX buffers
+ * rx_ring_buffers * HDLC_MAX_MRU     = logical channel #0 RX buffers (if used)
+ * tx_ring_buffers * HDLC_MAX_MRU     = logical channel #0 TX buffers (if used)
+ */
+
+#include <linux/bitops.h>
+#include <linux/errno.h>
+#include <linux/fcntl.h>
+#include <linux/hdlc.h>
+#include <linux/in.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/ioport.h>
+#include <linux/jiffies.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/netdevice.h>
+#include <linux/skbuff.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <asm/io.h>
+#include <asm/system.h>
+#include <asm/uaccess.h>
+#include "hd64572.h"
+
+#define NAPI_WEIGHT		16
+
+#define get_msci(port)	  (port->chan ?   MSCI1_OFFSET :   MSCI0_OFFSET)
+#define get_dmac_rx(port) (port->chan ? DMAC1RX_OFFSET : DMAC0RX_OFFSET)
+#define get_dmac_tx(port) (port->chan ? DMAC1TX_OFFSET : DMAC0TX_OFFSET)
+
+#define sca_in(reg, card)	     readb(card->scabase + (reg))
+#define sca_out(value, reg, card)    writeb(value, card->scabase + (reg))
+#define sca_inw(reg, card)	     readw(card->scabase + (reg))
+#define sca_outw(value, reg, card)   writew(value, card->scabase + (reg))
+#define sca_inl(reg, card)	     readl(card->scabase + (reg))
+#define sca_outl(value, reg, card)   writel(value, card->scabase + (reg))
+
+static int sca_poll(struct napi_struct *napi, int budget);
+
+static inline port_t* dev_to_port(struct net_device *dev)
+{
+	return dev_to_hdlc(dev)->priv;
+}
+
+static inline void enable_intr(port_t *port)
+{
+	/* enable DMIB and MSCI RXINTA interrupts */
+	sca_outl(sca_inl(IER0, port->card) |
+		 (port->chan ? 0x08002200 : 0x00080022), IER0, port->card);
+}
+
+static inline void disable_intr(port_t *port)
+{
+	sca_outl(sca_inl(IER0, port->card) &
+		 (port->chan ? 0x00FF00FF : 0xFF00FF00), IER0, port->card);
+}
+
+static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit)
+{
+	u16 rx_buffs = port->card->rx_ring_buffers;
+	u16 tx_buffs = port->card->tx_ring_buffers;
+
+	desc %= (transmit ? tx_buffs : rx_buffs); // called with "X + 1" etc.
+	return port->chan * (rx_buffs + tx_buffs) + transmit * rx_buffs + desc;
+}
+
+
+static inline u16 desc_offset(port_t *port, u16 desc, int transmit)
+{
+	/* Descriptor offset always fits in 16 bits */
+	return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc);
+}
+
+
+static inline pkt_desc __iomem *desc_address(port_t *port, u16 desc,
+					     int transmit)
+{
+	return (pkt_desc __iomem *)(port->card->rambase +
+				    desc_offset(port, desc, transmit));
+}
+
+
+static inline u32 buffer_offset(port_t *port, u16 desc, int transmit)
+{
+	return port->card->buff_offset +
+		desc_abs_number(port, desc, transmit) * (u32)HDLC_MAX_MRU;
+}
+
+
+static inline void sca_set_carrier(port_t *port)
+{
+	if (!(sca_in(get_msci(port) + ST3, port->card) & ST3_DCD)) {
+#ifdef DEBUG_LINK
+		printk(KERN_DEBUG "%s: sca_set_carrier on\n",
+		       port->netdev.name);
+#endif
+		netif_carrier_on(port->netdev);
+	} else {
+#ifdef DEBUG_LINK
+		printk(KERN_DEBUG "%s: sca_set_carrier off\n",
+		       port->netdev.name);
+#endif
+		netif_carrier_off(port->netdev);
+	}
+}
+
+
+static void sca_init_port(port_t *port)
+{
+	card_t *card = port->card;
+	u16 dmac_rx = get_dmac_rx(port), dmac_tx = get_dmac_tx(port);
+	int transmit, i;
+
+	port->rxin = 0;
+	port->txin = 0;
+	port->txlast = 0;
+
+	for (transmit = 0; transmit < 2; transmit++) {
+		u16 buffs = transmit ? card->tx_ring_buffers
+			: card->rx_ring_buffers;
+
+		for (i = 0; i < buffs; i++) {
+			pkt_desc __iomem *desc = desc_address(port, i, transmit);
+			u16 chain_off = desc_offset(port, i + 1, transmit);
+			u32 buff_off = buffer_offset(port, i, transmit);
+
+			writel(chain_off, &desc->cp);
+			writel(buff_off, &desc->bp);
+			writew(0, &desc->len);
+			writeb(0, &desc->stat);
+		}
+	}
+
+	/* DMA disable - to halt state */
+	sca_out(0, DSR_RX(port->chan), card);
+	sca_out(0, DSR_TX(port->chan), card);
+
+	/* software ABORT - to initial state */
+	sca_out(DCR_ABORT, DCR_RX(port->chan), card);
+	sca_out(DCR_ABORT, DCR_TX(port->chan), card);
+
+	/* current desc addr */
+	sca_outl(desc_offset(port, 0, 0), dmac_rx + CDAL, card);
+	sca_outl(desc_offset(port, card->tx_ring_buffers - 1, 0),
+		 dmac_rx + EDAL, card);
+	sca_outl(desc_offset(port, 0, 1), dmac_tx + CDAL, card);
+	sca_outl(desc_offset(port, 0, 1), dmac_tx + EDAL, card);
+
+	/* clear frame end interrupt counter */
+	sca_out(DCR_CLEAR_EOF, DCR_RX(port->chan), card);
+	sca_out(DCR_CLEAR_EOF, DCR_TX(port->chan), card);
+
+	/* Receive */
+	sca_outw(HDLC_MAX_MRU, dmac_rx + BFLL, card); /* set buffer length */
+	sca_out(0x14, DMR_RX(port->chan), card); /* Chain mode, Multi-frame */
+	sca_out(DIR_EOME, DIR_RX(port->chan), card); /* enable interrupts */
+	sca_out(DSR_DE, DSR_RX(port->chan), card); /* DMA enable */
+
+	/* Transmit */
+	sca_out(0x14, DMR_TX(port->chan), card); /* Chain mode, Multi-frame */
+	sca_out(DIR_EOME, DIR_TX(port->chan), card); /* enable interrupts */
+
+	sca_set_carrier(port);
+	netif_napi_add(port->netdev, &port->napi, sca_poll, NAPI_WEIGHT);
+}
+
+
+/* MSCI interrupt service */
+static inline void sca_msci_intr(port_t *port)
+{
+	u16 msci = get_msci(port);
+	card_t* card = port->card;
+
+	if (sca_in(msci + ST1, card) & ST1_CDCD) {
+		/* Reset MSCI CDCD status bit */
+		sca_out(ST1_CDCD, msci + ST1, card);
+		sca_set_carrier(port);
+	}
+}
+
+
+static inline void sca_rx(card_t *card, port_t *port, pkt_desc __iomem *desc,
+			  u16 rxin)
+{
+	struct net_device *dev = port->netdev;
+	struct sk_buff *skb;
+	u16 len;
+	u32 buff;
+
+	len = readw(&desc->len);
+	skb = dev_alloc_skb(len);
+	if (!skb) {
+		dev->stats.rx_dropped++;
+		return;
+	}
+
+	buff = buffer_offset(port, rxin, 0);
+	memcpy_fromio(skb->data, card->rambase + buff, len);
+
+	skb_put(skb, len);
+#ifdef DEBUG_PKT
+	printk(KERN_DEBUG "%s RX(%i):", dev->name, skb->len);
+	debug_frame(skb);
+#endif
+	dev->stats.rx_packets++;
+	dev->stats.rx_bytes += skb->len;
+	skb->protocol = hdlc_type_trans(skb, dev);
+	netif_receive_skb(skb);
+}
+
+
+/* Receive DMA service */
+static inline int sca_rx_done(port_t *port, int budget)
+{
+	struct net_device *dev = port->netdev;
+	u16 dmac = get_dmac_rx(port);
+	card_t *card = port->card;
+	u8 stat = sca_in(DSR_RX(port->chan), card); /* read DMA Status */
+	int received = 0;
+
+	/* Reset DSR status bits */
+	sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE,
+		DSR_RX(port->chan), card);
+
+	if (stat & DSR_BOF)
+		/* Dropped one or more frames */
+		dev->stats.rx_over_errors++;
+
+	while (received < budget) {
+		u32 desc_off = desc_offset(port, port->rxin, 0);
+		pkt_desc __iomem *desc;
+		u32 cda = sca_inl(dmac + CDAL, card);
+
+		if ((cda >= desc_off) && (cda < desc_off + sizeof(pkt_desc)))
+			break;	/* No frame received */
+
+		desc = desc_address(port, port->rxin, 0);
+		stat = readb(&desc->stat);
+		if (!(stat & ST_RX_EOM))
+			port->rxpart = 1; /* partial frame received */
+		else if ((stat & ST_ERROR_MASK) || port->rxpart) {
+			dev->stats.rx_errors++;
+			if (stat & ST_RX_OVERRUN)
+				dev->stats.rx_fifo_errors++;
+			else if ((stat & (ST_RX_SHORT | ST_RX_ABORT |
+					  ST_RX_RESBIT)) || port->rxpart)
+				dev->stats.rx_frame_errors++;
+			else if (stat & ST_RX_CRC)
+				dev->stats.rx_crc_errors++;
+			if (stat & ST_RX_EOM)
+				port->rxpart = 0; /* received last fragment */
+		} else {
+			sca_rx(card, port, desc, port->rxin);
+			received++;
+		}
+
+		/* Set new error descriptor address */
+		sca_outl(desc_off, dmac + EDAL, card);
+		port->rxin = (port->rxin + 1) % card->rx_ring_buffers;
+	}
+
+	/* make sure RX DMA is enabled */
+	sca_out(DSR_DE, DSR_RX(port->chan), card);
+	return received;
+}
+
+
+/* Transmit DMA service */
+static inline void sca_tx_done(port_t *port)
+{
+	struct net_device *dev = port->netdev;
+	card_t* card = port->card;
+	u8 stat;
+
+	spin_lock(&port->lock);
+
+	stat = sca_in(DSR_TX(port->chan), card); /* read DMA Status */
+
+	/* Reset DSR status bits */
+	sca_out((stat & (DSR_EOT | DSR_EOM | DSR_BOF | DSR_COF)) | DSR_DWE,
+		DSR_TX(port->chan), card);
+
+	while (1) {
+		pkt_desc __iomem *desc = desc_address(port, port->txlast, 1);
+		u8 stat = readb(&desc->stat);
+
+		if (!(stat & ST_TX_OWNRSHP))
+			break; /* not yet transmitted */
+		if (stat & ST_TX_UNDRRUN) {
+			dev->stats.tx_errors++;
+			dev->stats.tx_fifo_errors++;
+		} else {
+			dev->stats.tx_packets++;
+			dev->stats.tx_bytes += readw(&desc->len);
+		}
+		writeb(0, &desc->stat);	/* Free descriptor */
+		port->txlast = (port->txlast + 1) % card->tx_ring_buffers;
+	}
+
+	netif_wake_queue(dev);
+	spin_unlock(&port->lock);
+}
+
+
+static int sca_poll(struct napi_struct *napi, int budget)
+{
+	port_t *port = container_of(napi, port_t, napi);
+	u32 isr0 = sca_inl(ISR0, port->card);
+	int received = 0;
+
+	if (isr0 & (port->chan ? 0x08000000 : 0x00080000))
+		sca_msci_intr(port);
+
+	if (isr0 & (port->chan ? 0x00002000 : 0x00000020))
+		sca_tx_done(port);
+
+	if (isr0 & (port->chan ? 0x00000200 : 0x00000002))
+		received = sca_rx_done(port, budget);
+
+	if (received < budget) {
+		netif_rx_complete(port->netdev, napi);
+		enable_intr(port);
+	}
+
+	return received;
+}
+
+static irqreturn_t sca_intr(int irq, void *dev_id)
+{
+	card_t *card = dev_id;
+	u32 isr0 = sca_inl(ISR0, card);
+	int i, handled = 0;
+
+	for (i = 0; i < 2; i++) {
+		port_t *port = get_port(card, i);
+		if (port && (isr0 & (i ? 0x08002200 : 0x00080022))) {
+			handled = 1;
+			disable_intr(port);
+			netif_rx_schedule(port->netdev, &port->napi);
+		}
+	}
+
+	return IRQ_RETVAL(handled);
+}
+
+
+static void sca_set_port(port_t *port)
+{
+	card_t* card = port->card;
+	u16 msci = get_msci(port);
+	u8 md2 = sca_in(msci + MD2, card);
+	unsigned int tmc, br = 10, brv = 1024;
+
+
+	if (port->settings.clock_rate > 0) {
+		/* Try lower br for better accuracy*/
+		do {
+			br--;
+			brv >>= 1; /* brv = 2^9 = 512 max in specs */
+
+			/* Baud Rate = CLOCK_BASE / TMC / 2^BR */
+			tmc = CLOCK_BASE / brv / port->settings.clock_rate;
+		}while (br > 1 && tmc <= 128);
+
+		if (tmc < 1) {
+			tmc = 1;
+			br = 0;	/* For baud=CLOCK_BASE we use tmc=1 br=0 */
+			brv = 1;
+		} else if (tmc > 255)
+			tmc = 256; /* tmc=0 means 256 - low baud rates */
+
+		port->settings.clock_rate = CLOCK_BASE / brv / tmc;
+	} else {
+		br = 9; /* Minimum clock rate */
+		tmc = 256;	/* 8bit = 0 */
+		port->settings.clock_rate = CLOCK_BASE / (256 * 512);
+	}
+
+	port->rxs = (port->rxs & ~CLK_BRG_MASK) | br;
+	port->txs = (port->txs & ~CLK_BRG_MASK) | br;
+	port->tmc = tmc;
+
+	/* baud divisor - time constant*/
+	sca_out(port->tmc, msci + TMCR, card);
+	sca_out(port->tmc, msci + TMCT, card);
+
+	/* Set BRG bits */
+	sca_out(port->rxs, msci + RXS, card);
+	sca_out(port->txs, msci + TXS, card);
+
+	if (port->settings.loopback)
+		md2 |= MD2_LOOPBACK;
+	else
+		md2 &= ~MD2_LOOPBACK;
+
+	sca_out(md2, msci + MD2, card);
+
+}
+
+
+static void sca_open(struct net_device *dev)
+{
+	port_t *port = dev_to_port(dev);
+	card_t* card = port->card;
+	u16 msci = get_msci(port);
+	u8 md0, md2;
+
+	switch(port->encoding) {
+	case ENCODING_NRZ:	md2 = MD2_NRZ;		break;
+	case ENCODING_NRZI:	md2 = MD2_NRZI;		break;
+	case ENCODING_FM_MARK:	md2 = MD2_FM_MARK;	break;
+	case ENCODING_FM_SPACE:	md2 = MD2_FM_SPACE;	break;
+	default:		md2 = MD2_MANCHESTER;
+	}
+
+	if (port->settings.loopback)
+		md2 |= MD2_LOOPBACK;
+
+	switch(port->parity) {
+	case PARITY_CRC16_PR0:	     md0 = MD0_HDLC | MD0_CRC_16_0;  break;
+	case PARITY_CRC16_PR1:	     md0 = MD0_HDLC | MD0_CRC_16;    break;
+	case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break;
+	case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU;   break;
+	default:		     md0 = MD0_HDLC | MD0_CRC_NONE;
+	}
+
+	sca_out(CMD_RESET, msci + CMD, card);
+	sca_out(md0, msci + MD0, card);
+	sca_out(0x00, msci + MD1, card); /* no address field check */
+	sca_out(md2, msci + MD2, card);
+	sca_out(0x7E, msci + IDL, card); /* flag character 0x7E */
+	/* Skip the rest of underrun frame */
+	sca_out(CTL_IDLE | CTL_URCT | CTL_URSKP, msci + CTL, card);
+	sca_out(0x0F, msci + RNR, card); /* +1=RX DMA activation condition */
+	sca_out(0x3C, msci + TFS, card); /* +1 = TX start */
+	sca_out(0x38, msci + TCR, card); /* =Critical TX DMA activ condition */
+	sca_out(0x38, msci + TNR0, card); /* =TX DMA activation condition */
+	sca_out(0x3F, msci + TNR1, card); /* +1=TX DMA deactivation condition*/
+
+/* We're using the following interrupts:
+   - RXINTA (DCD changes only)
+   - DMIB (EOM - single frame transfer complete)
+*/
+	sca_outl(IE0_RXINTA | IE0_CDCD, msci + IE0, card);
+
+	sca_out(port->tmc, msci + TMCR, card);
+	sca_out(port->tmc, msci + TMCT, card);
+	sca_out(port->rxs, msci + RXS, card);
+	sca_out(port->txs, msci + TXS, card);
+	sca_out(CMD_TX_ENABLE, msci + CMD, card);
+	sca_out(CMD_RX_ENABLE, msci + CMD, card);
+
+	sca_set_carrier(port);
+	enable_intr(port);
+	napi_enable(&port->napi);
+	netif_start_queue(dev);
+}
+
+
+static void sca_close(struct net_device *dev)
+{
+	port_t *port = dev_to_port(dev);
+
+	/* reset channel */
+	sca_out(CMD_RESET, get_msci(port) + CMD, port->card);
+	disable_intr(port);
+	napi_disable(&port->napi);
+	netif_stop_queue(dev);
+}
+
+
+static int sca_attach(struct net_device *dev, unsigned short encoding,
+		      unsigned short parity)
+{
+	if (encoding != ENCODING_NRZ &&
+	    encoding != ENCODING_NRZI &&
+	    encoding != ENCODING_FM_MARK &&
+	    encoding != ENCODING_FM_SPACE &&
+	    encoding != ENCODING_MANCHESTER)
+		return -EINVAL;
+
+	if (parity != PARITY_NONE &&
+	    parity != PARITY_CRC16_PR0 &&
+	    parity != PARITY_CRC16_PR1 &&
+	    parity != PARITY_CRC32_PR1_CCITT &&
+	    parity != PARITY_CRC16_PR1_CCITT)
+		return -EINVAL;
+
+	dev_to_port(dev)->encoding = encoding;
+	dev_to_port(dev)->parity = parity;
+	return 0;
+}
+
+
+#ifdef DEBUG_RINGS
+static void sca_dump_rings(struct net_device *dev)
+{
+	port_t *port = dev_to_port(dev);
+	card_t *card = port->card;
+	u16 cnt;
+
+	printk(KERN_DEBUG "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive",
+	       sca_inl(get_dmac_rx(port) + CDAL, card),
+	       sca_inl(get_dmac_rx(port) + EDAL, card),
+	       sca_in(DSR_RX(port->chan), card), port->rxin,
+	       sca_in(DSR_RX(port->chan), card) & DSR_DE ? "" : "in");
+	for (cnt = 0; cnt < port->card->rx_ring_buffers; cnt++)
+		printk(" %02X", readb(&(desc_address(port, cnt, 0)->stat)));
+
+	printk("\n" KERN_DEBUG "TX ring: CDA=%u EDA=%u DSR=%02X in=%u "
+	       "last=%u %sactive",
+	       sca_inl(get_dmac_tx(port) + CDAL, card),
+	       sca_inl(get_dmac_tx(port) + EDAL, card),
+	       sca_in(DSR_TX(port->chan), card), port->txin, port->txlast,
+	       sca_in(DSR_TX(port->chan), card) & DSR_DE ? "" : "in");
+
+	for (cnt = 0; cnt < port->card->tx_ring_buffers; cnt++)
+		printk(" %02X", readb(&(desc_address(port, cnt, 1)->stat)));
+	printk("\n");
+
+	printk(KERN_DEBUG "MSCI: MD: %02x %02x %02x,"
+	       " ST: %02x %02x %02x %02x %02x, FST: %02x CST: %02x %02x\n",
+	       sca_in(get_msci(port) + MD0, card),
+	       sca_in(get_msci(port) + MD1, card),
+	       sca_in(get_msci(port) + MD2, card),
+	       sca_in(get_msci(port) + ST0, card),
+	       sca_in(get_msci(port) + ST1, card),
+	       sca_in(get_msci(port) + ST2, card),
+	       sca_in(get_msci(port) + ST3, card),
+	       sca_in(get_msci(port) + ST4, card),
+	       sca_in(get_msci(port) + FST, card),
+	       sca_in(get_msci(port) + CST0, card),
+	       sca_in(get_msci(port) + CST1, card));
+
+	printk(KERN_DEBUG "ILAR: %02x ISR: %08x %08x\n", sca_in(ILAR, card),
+	       sca_inl(ISR0, card), sca_inl(ISR1, card));
+}
+#endif /* DEBUG_RINGS */
+
+
+static int sca_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+	port_t *port = dev_to_port(dev);
+	card_t *card = port->card;
+	pkt_desc __iomem *desc;
+	u32 buff, len;
+
+	spin_lock_irq(&port->lock);
+
+	desc = desc_address(port, port->txin + 1, 1);
+	BUG_ON(readb(&desc->stat)); /* previous xmit should stop queue */
+
+#ifdef DEBUG_PKT
+	printk(KERN_DEBUG "%s TX(%i):", dev->name, skb->len);
+	debug_frame(skb);
+#endif
+
+	desc = desc_address(port, port->txin, 1);
+	buff = buffer_offset(port, port->txin, 1);
+	len = skb->len;
+	memcpy_toio(card->rambase + buff, skb->data, len);
+
+	writew(len, &desc->len);
+	writeb(ST_TX_EOM, &desc->stat);
+	dev->trans_start = jiffies;
+
+	port->txin = (port->txin + 1) % card->tx_ring_buffers;
+	sca_outl(desc_offset(port, port->txin, 1),
+		 get_dmac_tx(port) + EDAL, card);
+
+	sca_out(DSR_DE, DSR_TX(port->chan), card); /* Enable TX DMA */
+
+	desc = desc_address(port, port->txin + 1, 1);
+	if (readb(&desc->stat)) /* allow 1 packet gap */
+		netif_stop_queue(dev);
+
+	spin_unlock_irq(&port->lock);
+
+	dev_kfree_skb(skb);
+	return 0;
+}
+
+
+static u32 __devinit sca_detect_ram(card_t *card, u8 __iomem *rambase,
+				    u32 ramsize)
+{
+	/* Round RAM size to 32 bits, fill from end to start */
+	u32 i = ramsize &= ~3;
+
+	do {
+		i -= 4;
+		writel(i ^ 0x12345678, rambase + i);
+	} while (i > 0);
+
+	for (i = 0; i < ramsize ; i += 4) {
+		if (readl(rambase + i) != (i ^ 0x12345678))
+			break;
+	}
+
+	return i;
+}
+
+
+static void __devinit sca_init(card_t *card, int wait_states)
+{
+	sca_out(wait_states, WCRL, card); /* Wait Control */
+	sca_out(wait_states, WCRM, card);
+	sca_out(wait_states, WCRH, card);
+
+	sca_out(0, DMER, card);	/* DMA Master disable */
+	sca_out(0x03, PCR, card); /* DMA priority */
+	sca_out(0, DSR_RX(0), card); /* DMA disable - to halt state */
+	sca_out(0, DSR_TX(0), card);
+	sca_out(0, DSR_RX(1), card);
+	sca_out(0, DSR_TX(1), card);
+	sca_out(DMER_DME, DMER, card); /* DMA Master enable */
+}

+ 601 - 47
drivers/net/wan/hdlc_ppp.c

@@ -2,7 +2,7 @@
  * Generic HDLC support routines for Linux
  * Point-to-point protocol support
  *
- * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 1999 - 2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -18,87 +18,632 @@
 #include <linux/module.h>
 #include <linux/pkt_sched.h>
 #include <linux/poll.h>
-#include <linux/rtnetlink.h>
 #include <linux/skbuff.h>
 #include <linux/slab.h>
-#include <net/syncppp.h>
+#include <linux/spinlock.h>
+
+#define DEBUG_CP		0 /* also bytes# to dump */
+#define DEBUG_STATE		0
+#define DEBUG_HARD_HEADER	0
+
+#define HDLC_ADDR_ALLSTATIONS	0xFF
+#define HDLC_CTRL_UI		0x03
+
+#define PID_LCP			0xC021
+#define PID_IP			0x0021
+#define PID_IPCP		0x8021
+#define PID_IPV6		0x0057
+#define PID_IPV6CP		0x8057
+
+enum {IDX_LCP = 0, IDX_IPCP, IDX_IPV6CP, IDX_COUNT};
+enum {CP_CONF_REQ = 1, CP_CONF_ACK, CP_CONF_NAK, CP_CONF_REJ, CP_TERM_REQ,
+      CP_TERM_ACK, CP_CODE_REJ, LCP_PROTO_REJ, LCP_ECHO_REQ, LCP_ECHO_REPLY,
+      LCP_DISC_REQ, CP_CODES};
+#if DEBUG_CP
+static const char *const code_names[CP_CODES] = {
+	"0", "ConfReq", "ConfAck", "ConfNak", "ConfRej", "TermReq",
+	"TermAck", "CodeRej", "ProtoRej", "EchoReq", "EchoReply", "Discard"
+};
+static char debug_buffer[64 + 3 * DEBUG_CP];
+#endif
+
+enum {LCP_OPTION_MRU = 1, LCP_OPTION_ACCM, LCP_OPTION_MAGIC = 5};
+
+struct hdlc_header {
+	u8 address;
+	u8 control;
+	__be16 protocol;
+};
+
+struct cp_header {
+	u8 code;
+	u8 id;
+	__be16 len;
+};
+
 
-struct ppp_state {
-	struct ppp_device pppdev;
-	struct ppp_device *syncppp_ptr;
-	int (*old_change_mtu)(struct net_device *dev, int new_mtu);
+struct proto {
+	struct net_device *dev;
+	struct timer_list timer;
+	unsigned long timeout;
+	u16 pid;		/* protocol ID */
+	u8 state;
+	u8 cr_id;		/* ID of last Configuration-Request */
+	u8 restart_counter;
 };
 
+struct ppp {
+	struct proto protos[IDX_COUNT];
+	spinlock_t lock;
+	unsigned long last_pong;
+	unsigned int req_timeout, cr_retries, term_retries;
+	unsigned int keepalive_interval, keepalive_timeout;
+	u8 seq;			/* local sequence number for requests */
+	u8 echo_id;		/* ID of last Echo-Request (LCP) */
+};
+
+enum {CLOSED = 0, STOPPED, STOPPING, REQ_SENT, ACK_RECV, ACK_SENT, OPENED,
+      STATES, STATE_MASK = 0xF};
+enum {START = 0, STOP, TO_GOOD, TO_BAD, RCR_GOOD, RCR_BAD, RCA, RCN, RTR, RTA,
+      RUC, RXJ_GOOD, RXJ_BAD, EVENTS};
+enum {INV = 0x10, IRC = 0x20, ZRC = 0x40, SCR = 0x80, SCA = 0x100,
+      SCN = 0x200, STR = 0x400, STA = 0x800, SCJ = 0x1000};
+
+#if DEBUG_STATE
+static const char *const state_names[STATES] = {
+	"Closed", "Stopped", "Stopping", "ReqSent", "AckRecv", "AckSent",
+	"Opened"
+};
+static const char *const event_names[EVENTS] = {
+	"Start", "Stop", "TO+", "TO-", "RCR+", "RCR-", "RCA", "RCN",
+	"RTR", "RTA", "RUC", "RXJ+", "RXJ-"
+};
+#endif
+
+static struct sk_buff_head tx_queue; /* used when holding the spin lock */
+
 static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr);
 
+static inline struct ppp* get_ppp(struct net_device *dev)
+{
+	return (struct ppp *)dev_to_hdlc(dev)->state;
+}
 
-static inline struct ppp_state* state(hdlc_device *hdlc)
+static inline struct proto* get_proto(struct net_device *dev, u16 pid)
 {
-	return(struct ppp_state *)(hdlc->state);
+	struct ppp *ppp = get_ppp(dev);
+
+	switch (pid) {
+	case PID_LCP:
+		return &ppp->protos[IDX_LCP];
+	case PID_IPCP:
+		return &ppp->protos[IDX_IPCP];
+	case PID_IPV6CP:
+		return &ppp->protos[IDX_IPV6CP];
+	default:
+		return NULL;
+	}
 }
 
+static inline const char* proto_name(u16 pid)
+{
+	switch (pid) {
+	case PID_LCP:
+		return "LCP";
+	case PID_IPCP:
+		return "IPCP";
+	case PID_IPV6CP:
+		return "IPV6CP";
+	default:
+		return NULL;
+	}
+}
 
-static int ppp_open(struct net_device *dev)
+static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
 {
-	hdlc_device *hdlc = dev_to_hdlc(dev);
-	int (*old_ioctl)(struct net_device *, struct ifreq *, int);
-	int result;
+	struct hdlc_header *data = (struct hdlc_header*)skb->data;
+
+	if (skb->len < sizeof(struct hdlc_header))
+		return htons(ETH_P_HDLC);
+	if (data->address != HDLC_ADDR_ALLSTATIONS ||
+	    data->control != HDLC_CTRL_UI)
+		return htons(ETH_P_HDLC);
+
+	switch (data->protocol) {
+	case __constant_htons(PID_IP):
+		skb_pull(skb, sizeof(struct hdlc_header));
+		return htons(ETH_P_IP);
 
-	dev->ml_priv = &state(hdlc)->syncppp_ptr;
-	state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
-	state(hdlc)->pppdev.dev = dev;
+	case __constant_htons(PID_IPV6):
+		skb_pull(skb, sizeof(struct hdlc_header));
+		return htons(ETH_P_IPV6);
 
-	old_ioctl = dev->do_ioctl;
-	state(hdlc)->old_change_mtu = dev->change_mtu;
-	sppp_attach(&state(hdlc)->pppdev);
-	/* sppp_attach nukes them. We don't need syncppp's ioctl */
-	dev->do_ioctl = old_ioctl;
-	state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO;
-	dev->type = ARPHRD_PPP;
-	result = sppp_open(dev);
-	if (result) {
-		sppp_detach(dev);
-		return result;
+	default:
+		return htons(ETH_P_HDLC);
 	}
+}
 
-	return 0;
+
+static int ppp_hard_header(struct sk_buff *skb, struct net_device *dev,
+			   u16 type, const void *daddr, const void *saddr,
+			   unsigned int len)
+{
+	struct hdlc_header *data;
+#if DEBUG_HARD_HEADER
+	printk(KERN_DEBUG "%s: ppp_hard_header() called\n", dev->name);
+#endif
+
+	skb_push(skb, sizeof(struct hdlc_header));
+	data = (struct hdlc_header*)skb->data;
+
+	data->address = HDLC_ADDR_ALLSTATIONS;
+	data->control = HDLC_CTRL_UI;
+	switch (type) {
+	case ETH_P_IP:
+		data->protocol = htons(PID_IP);
+		break;
+	case ETH_P_IPV6:
+		data->protocol = htons(PID_IPV6);
+		break;
+	case PID_LCP:
+	case PID_IPCP:
+	case PID_IPV6CP:
+		data->protocol = htons(type);
+		break;
+	default:		/* unknown protocol */
+		data->protocol = 0;
+	}
+	return sizeof(struct hdlc_header);
 }
 
 
+static void ppp_tx_flush(void)
+{
+	struct sk_buff *skb;
+	while ((skb = skb_dequeue(&tx_queue)) != NULL)
+		dev_queue_xmit(skb);
+}
 
-static void ppp_close(struct net_device *dev)
+static void ppp_tx_cp(struct net_device *dev, u16 pid, u8 code,
+		      u8 id, unsigned int len, const void *data)
 {
-	hdlc_device *hdlc = dev_to_hdlc(dev);
+	struct sk_buff *skb;
+	struct cp_header *cp;
+	unsigned int magic_len = 0;
+	static u32 magic;
+
+#if DEBUG_CP
+	int i;
+	char *ptr;
+#endif
+
+	if (pid == PID_LCP && (code == LCP_ECHO_REQ || code == LCP_ECHO_REPLY))
+		magic_len = sizeof(magic);
+
+	skb = dev_alloc_skb(sizeof(struct hdlc_header) +
+			    sizeof(struct cp_header) + magic_len + len);
+	if (!skb) {
+		printk(KERN_WARNING "%s: out of memory in ppp_tx_cp()\n",
+		       dev->name);
+		return;
+	}
+	skb_reserve(skb, sizeof(struct hdlc_header));
+
+	cp = (struct cp_header *)skb_put(skb, sizeof(struct cp_header));
+	cp->code = code;
+	cp->id = id;
+	cp->len = htons(sizeof(struct cp_header) + magic_len + len);
+
+	if (magic_len)
+		memcpy(skb_put(skb, magic_len), &magic, magic_len);
+	if (len)
+		memcpy(skb_put(skb, len), data, len);
+
+#if DEBUG_CP
+	BUG_ON(code >= CP_CODES);
+	ptr = debug_buffer;
+	*ptr = '\x0';
+	for (i = 0; i < min_t(unsigned int, magic_len + len, DEBUG_CP); i++) {
+		sprintf(ptr, " %02X", skb->data[sizeof(struct cp_header) + i]);
+		ptr += strlen(ptr);
+	}
+	printk(KERN_DEBUG "%s: TX %s [%s id 0x%X]%s\n", dev->name,
+	       proto_name(pid), code_names[code], id, debug_buffer);
+#endif
 
-	sppp_close(dev);
-	sppp_detach(dev);
+	ppp_hard_header(skb, dev, pid, NULL, NULL, 0);
 
-	dev->change_mtu = state(hdlc)->old_change_mtu;
-	dev->mtu = HDLC_MAX_MTU;
-	dev->hard_header_len = 16;
+	skb->priority = TC_PRIO_CONTROL;
+	skb->dev = dev;
+	skb_reset_network_header(skb);
+	skb_queue_tail(&tx_queue, skb);
 }
 
 
+/* State transition table (compare STD-51)
+   Events                                   Actions
+   TO+  = Timeout with counter > 0          irc = Initialize-Restart-Count
+   TO-  = Timeout with counter expired      zrc = Zero-Restart-Count
+
+   RCR+ = Receive-Configure-Request (Good)  scr = Send-Configure-Request
+   RCR- = Receive-Configure-Request (Bad)
+   RCA  = Receive-Configure-Ack             sca = Send-Configure-Ack
+   RCN  = Receive-Configure-Nak/Rej         scn = Send-Configure-Nak/Rej
+
+   RTR  = Receive-Terminate-Request         str = Send-Terminate-Request
+   RTA  = Receive-Terminate-Ack             sta = Send-Terminate-Ack
+
+   RUC  = Receive-Unknown-Code              scj = Send-Code-Reject
+   RXJ+ = Receive-Code-Reject (permitted)
+       or Receive-Protocol-Reject
+   RXJ- = Receive-Code-Reject (catastrophic)
+       or Receive-Protocol-Reject
+*/
+static int cp_table[EVENTS][STATES] = {
+	/* CLOSED     STOPPED STOPPING REQ_SENT ACK_RECV ACK_SENT OPENED
+	     0           1         2       3       4      5          6    */
+	{IRC|SCR|3,     INV     , INV ,   INV   , INV ,  INV    ,   INV   }, /* START */
+	{   INV   ,      0      ,  0  ,    0    ,  0  ,   0     ,    0    }, /* STOP */
+	{   INV   ,     INV     ,STR|2,  SCR|3  ,SCR|3,  SCR|5  ,   INV   }, /* TO+ */
+	{   INV   ,     INV     ,  1  ,    1    ,  1  ,    1    ,   INV   }, /* TO- */
+	{  STA|0  ,IRC|SCR|SCA|5,  2  ,  SCA|5  ,SCA|6,  SCA|5  ,SCR|SCA|5}, /* RCR+ */
+	{  STA|0  ,IRC|SCR|SCN|3,  2  ,  SCN|3  ,SCN|4,  SCN|3  ,SCR|SCN|3}, /* RCR- */
+	{  STA|0  ,    STA|1    ,  2  ,  IRC|4  ,SCR|3,    6    , SCR|3   }, /* RCA */
+	{  STA|0  ,    STA|1    ,  2  ,IRC|SCR|3,SCR|3,IRC|SCR|5, SCR|3   }, /* RCN */
+	{  STA|0  ,    STA|1    ,STA|2,  STA|3  ,STA|3,  STA|3  ,ZRC|STA|2}, /* RTR */
+	{    0    ,      1      ,  1  ,    3    ,  3  ,    5    ,  SCR|3  }, /* RTA */
+	{  SCJ|0  ,    SCJ|1    ,SCJ|2,  SCJ|3  ,SCJ|4,  SCJ|5  ,  SCJ|6  }, /* RUC */
+	{    0    ,      1      ,  2  ,    3    ,  3  ,    5    ,    6    }, /* RXJ+ */
+	{    0    ,      1      ,  1  ,    1    ,  1  ,    1    ,IRC|STR|2}, /* RXJ- */
+};
+
 
-static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
+/* SCA: RCR+ must supply id, len and data
+   SCN: RCR- must supply code, id, len and data
+   STA: RTR must supply id
+   SCJ: RUC must supply CP packet len and data */
+static void ppp_cp_event(struct net_device *dev, u16 pid, u16 event, u8 code,
+			 u8 id, unsigned int len, void *data)
 {
-	return __constant_htons(ETH_P_WAN_PPP);
+	int old_state, action;
+	struct ppp *ppp = get_ppp(dev);
+	struct proto *proto = get_proto(dev, pid);
+
+	old_state = proto->state;
+	BUG_ON(old_state >= STATES);
+	BUG_ON(event >= EVENTS);
+
+#if DEBUG_STATE
+	printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) %s ...\n", dev->name,
+	       proto_name(pid), event_names[event], state_names[proto->state]);
+#endif
+
+	action = cp_table[event][old_state];
+
+	proto->state = action & STATE_MASK;
+	if (action & (SCR | STR)) /* set Configure-Req/Terminate-Req timer */
+		mod_timer(&proto->timer, proto->timeout =
+			  jiffies + ppp->req_timeout * HZ);
+	if (action & ZRC)
+		proto->restart_counter = 0;
+	if (action & IRC)
+		proto->restart_counter = (proto->state == STOPPING) ?
+			ppp->term_retries : ppp->cr_retries;
+
+	if (action & SCR)	/* send Configure-Request */
+		ppp_tx_cp(dev, pid, CP_CONF_REQ, proto->cr_id = ++ppp->seq,
+			  0, NULL);
+	if (action & SCA)	/* send Configure-Ack */
+		ppp_tx_cp(dev, pid, CP_CONF_ACK, id, len, data);
+	if (action & SCN)	/* send Configure-Nak/Reject */
+		ppp_tx_cp(dev, pid, code, id, len, data);
+	if (action & STR)	/* send Terminate-Request */
+		ppp_tx_cp(dev, pid, CP_TERM_REQ, ++ppp->seq, 0, NULL);
+	if (action & STA)	/* send Terminate-Ack */
+		ppp_tx_cp(dev, pid, CP_TERM_ACK, id, 0, NULL);
+	if (action & SCJ)	/* send Code-Reject */
+		ppp_tx_cp(dev, pid, CP_CODE_REJ, ++ppp->seq, len, data);
+
+	if (old_state != OPENED && proto->state == OPENED) {
+		printk(KERN_INFO "%s: %s up\n", dev->name, proto_name(pid));
+		if (pid == PID_LCP) {
+			netif_dormant_off(dev);
+			ppp_cp_event(dev, PID_IPCP, START, 0, 0, 0, NULL);
+			ppp_cp_event(dev, PID_IPV6CP, START, 0, 0, 0, NULL);
+			ppp->last_pong = jiffies;
+			mod_timer(&proto->timer, proto->timeout =
+				  jiffies + ppp->keepalive_interval * HZ);
+		}
+	}
+	if (old_state == OPENED && proto->state != OPENED) {
+		printk(KERN_INFO "%s: %s down\n", dev->name, proto_name(pid));
+		if (pid == PID_LCP) {
+			netif_dormant_on(dev);
+			ppp_cp_event(dev, PID_IPCP, STOP, 0, 0, 0, NULL);
+			ppp_cp_event(dev, PID_IPV6CP, STOP, 0, 0, 0, NULL);
+		}
+	}
+	if (old_state != CLOSED && proto->state == CLOSED)
+		del_timer(&proto->timer);
+
+#if DEBUG_STATE
+	printk(KERN_DEBUG "%s: %s ppp_cp_event(%s) ... %s\n", dev->name,
+	       proto_name(pid), event_names[event], state_names[proto->state]);
+#endif
 }
 
 
+static void ppp_cp_parse_cr(struct net_device *dev, u16 pid, u8 id,
+			    unsigned int len, u8 *data)
+{
+	static u8 const valid_accm[6] = { LCP_OPTION_ACCM, 6, 0, 0, 0, 0 };
+	u8 *opt, *out;
+	unsigned int nak_len = 0, rej_len = 0;
+
+	if (!(out = kmalloc(len, GFP_ATOMIC))) {
+		dev->stats.rx_dropped++;
+		return;	/* out of memory, ignore CR packet */
+	}
+
+	for (opt = data; len; len -= opt[1], opt += opt[1]) {
+		if (len < 2 || len < opt[1]) {
+			dev->stats.rx_errors++;
+			return; /* bad packet, drop silently */
+		}
+
+		if (pid == PID_LCP)
+			switch (opt[0]) {
+			case LCP_OPTION_MRU:
+				continue; /* MRU always OK and > 1500 bytes? */
+
+			case LCP_OPTION_ACCM: /* async control character map */
+				if (!memcmp(opt, valid_accm,
+					    sizeof(valid_accm)))
+					continue;
+				if (!rej_len) { /* NAK it */
+					memcpy(out + nak_len, valid_accm,
+					       sizeof(valid_accm));
+					nak_len += sizeof(valid_accm);
+					continue;
+				}
+				break;
+			case LCP_OPTION_MAGIC:
+				if (opt[1] != 6 || (!opt[2] && !opt[3] &&
+						    !opt[4] && !opt[5]))
+					break; /* reject invalid magic number */
+				continue;
+			}
+		/* reject this option */
+		memcpy(out + rej_len, opt, opt[1]);
+		rej_len += opt[1];
+	}
+
+	if (rej_len)
+		ppp_cp_event(dev, pid, RCR_BAD, CP_CONF_REJ, id, rej_len, out);
+	else if (nak_len)
+		ppp_cp_event(dev, pid, RCR_BAD, CP_CONF_NAK, id, nak_len, out);
+	else
+		ppp_cp_event(dev, pid, RCR_GOOD, CP_CONF_ACK, id, len, data);
+
+	kfree(out);
+}
+
+static int ppp_rx(struct sk_buff *skb)
+{
+	struct hdlc_header *hdr = (struct hdlc_header*)skb->data;
+	struct net_device *dev = skb->dev;
+	struct ppp *ppp = get_ppp(dev);
+	struct proto *proto;
+	struct cp_header *cp;
+	unsigned long flags;
+	unsigned int len;
+	u16 pid;
+#if DEBUG_CP
+	int i;
+	char *ptr;
+#endif
+
+	spin_lock_irqsave(&ppp->lock, flags);
+	/* Check HDLC header */
+	if (skb->len < sizeof(struct hdlc_header))
+		goto rx_error;
+	cp = (struct cp_header*)skb_pull(skb, sizeof(struct hdlc_header));
+	if (hdr->address != HDLC_ADDR_ALLSTATIONS ||
+	    hdr->control != HDLC_CTRL_UI)
+		goto rx_error;
+
+	pid = ntohs(hdr->protocol);
+	proto = get_proto(dev, pid);
+	if (!proto) {
+		if (ppp->protos[IDX_LCP].state == OPENED)
+			ppp_tx_cp(dev, PID_LCP, LCP_PROTO_REJ,
+				  ++ppp->seq, skb->len + 2, &hdr->protocol);
+		goto rx_error;
+	}
+
+	len = ntohs(cp->len);
+	if (len < sizeof(struct cp_header) /* no complete CP header? */ ||
+	    skb->len < len /* truncated packet? */)
+		goto rx_error;
+	skb_pull(skb, sizeof(struct cp_header));
+	len -= sizeof(struct cp_header);
+
+	/* HDLC and CP headers stripped from skb */
+#if DEBUG_CP
+	if (cp->code < CP_CODES)
+		sprintf(debug_buffer, "[%s id 0x%X]", code_names[cp->code],
+			cp->id);
+	else
+		sprintf(debug_buffer, "[code %u id 0x%X]", cp->code, cp->id);
+	ptr = debug_buffer + strlen(debug_buffer);
+	for (i = 0; i < min_t(unsigned int, len, DEBUG_CP); i++) {
+		sprintf(ptr, " %02X", skb->data[i]);
+		ptr += strlen(ptr);
+	}
+	printk(KERN_DEBUG "%s: RX %s %s\n", dev->name, proto_name(pid),
+	       debug_buffer);
+#endif
+
+	/* LCP only */
+	if (pid == PID_LCP)
+		switch (cp->code) {
+		case LCP_PROTO_REJ:
+			pid = ntohs(*(__be16*)skb->data);
+			if (pid == PID_LCP || pid == PID_IPCP ||
+			    pid == PID_IPV6CP)
+				ppp_cp_event(dev, pid, RXJ_BAD, 0, 0,
+					     0, NULL);
+			goto out;
+
+		case LCP_ECHO_REQ: /* send Echo-Reply */
+			if (len >= 4 && proto->state == OPENED)
+				ppp_tx_cp(dev, PID_LCP, LCP_ECHO_REPLY,
+					  cp->id, len - 4, skb->data + 4);
+			goto out;
+
+		case LCP_ECHO_REPLY:
+			if (cp->id == ppp->echo_id)
+				ppp->last_pong = jiffies;
+			goto out;
+
+		case LCP_DISC_REQ: /* discard */
+			goto out;
+		}
+
+	/* LCP, IPCP and IPV6CP */
+	switch (cp->code) {
+	case CP_CONF_REQ:
+		ppp_cp_parse_cr(dev, pid, cp->id, len, skb->data);
+		goto out;
+
+	case CP_CONF_ACK:
+		if (cp->id == proto->cr_id)
+			ppp_cp_event(dev, pid, RCA, 0, 0, 0, NULL);
+		goto out;
+
+	case CP_CONF_REJ:
+	case CP_CONF_NAK:
+		if (cp->id == proto->cr_id)
+			ppp_cp_event(dev, pid, RCN, 0, 0, 0, NULL);
+		goto out;
+
+	case CP_TERM_REQ:
+		ppp_cp_event(dev, pid, RTR, 0, cp->id, 0, NULL);
+		goto out;
+
+	case CP_TERM_ACK:
+		ppp_cp_event(dev, pid, RTA, 0, 0, 0, NULL);
+		goto out;
+
+	case CP_CODE_REJ:
+		ppp_cp_event(dev, pid, RXJ_BAD, 0, 0, 0, NULL);
+		goto out;
+
+	default:
+		len += sizeof(struct cp_header);
+		if (len > dev->mtu)
+			len = dev->mtu;
+		ppp_cp_event(dev, pid, RUC, 0, 0, len, cp);
+		goto out;
+	}
+	goto out;
+
+rx_error:
+	dev->stats.rx_errors++;
+out:
+	spin_unlock_irqrestore(&ppp->lock, flags);
+	dev_kfree_skb_any(skb);
+	ppp_tx_flush();
+	return NET_RX_DROP;
+}
+
+
+static void ppp_timer(unsigned long arg)
+{
+	struct proto *proto = (struct proto *)arg;
+	struct ppp *ppp = get_ppp(proto->dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&ppp->lock, flags);
+	switch (proto->state) {
+	case STOPPING:
+	case REQ_SENT:
+	case ACK_RECV:
+	case ACK_SENT:
+		if (proto->restart_counter) {
+			ppp_cp_event(proto->dev, proto->pid, TO_GOOD, 0, 0,
+				     0, NULL);
+			proto->restart_counter--;
+		} else
+			ppp_cp_event(proto->dev, proto->pid, TO_BAD, 0, 0,
+				     0, NULL);
+		break;
+
+	case OPENED:
+		if (proto->pid != PID_LCP)
+			break;
+		if (time_after(jiffies, ppp->last_pong +
+			       ppp->keepalive_timeout * HZ)) {
+			printk(KERN_INFO "%s: Link down\n", proto->dev->name);
+			ppp_cp_event(proto->dev, PID_LCP, STOP, 0, 0, 0, NULL);
+			ppp_cp_event(proto->dev, PID_LCP, START, 0, 0, 0, NULL);
+		} else {	/* send keep-alive packet */
+			ppp->echo_id = ++ppp->seq;
+			ppp_tx_cp(proto->dev, PID_LCP, LCP_ECHO_REQ,
+				  ppp->echo_id, 0, NULL);
+			proto->timer.expires = jiffies +
+				ppp->keepalive_interval * HZ;
+			add_timer(&proto->timer);
+		}
+		break;
+	}
+	spin_unlock_irqrestore(&ppp->lock, flags);
+	ppp_tx_flush();
+}
+
+
+static void ppp_start(struct net_device *dev)
+{
+	struct ppp *ppp = get_ppp(dev);
+	int i;
+
+	for (i = 0; i < IDX_COUNT; i++) {
+		struct proto *proto = &ppp->protos[i];
+		proto->dev = dev;
+		init_timer(&proto->timer);
+		proto->timer.function = ppp_timer;
+		proto->timer.data = (unsigned long)proto;
+		proto->state = CLOSED;
+	}
+	ppp->protos[IDX_LCP].pid = PID_LCP;
+	ppp->protos[IDX_IPCP].pid = PID_IPCP;
+	ppp->protos[IDX_IPV6CP].pid = PID_IPV6CP;
+
+	ppp_cp_event(dev, PID_LCP, START, 0, 0, 0, NULL);
+}
+
+static void ppp_stop(struct net_device *dev)
+{
+	ppp_cp_event(dev, PID_LCP, STOP, 0, 0, 0, NULL);
+}
 
 static struct hdlc_proto proto = {
-	.open		= ppp_open,
-	.close		= ppp_close,
+	.start		= ppp_start,
+	.stop		= ppp_stop,
 	.type_trans	= ppp_type_trans,
 	.ioctl		= ppp_ioctl,
+	.netif_rx	= ppp_rx,
 	.module		= THIS_MODULE,
 };
 
+static const struct header_ops ppp_header_ops = {
+	.create = ppp_hard_header,
+};
 
 static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
+	struct ppp *ppp;
 	int result;
 
 	switch (ifr->ifr_settings.type) {
@@ -109,25 +654,35 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
 		return 0; /* return protocol only, no settable parameters */
 
 	case IF_PROTO_PPP:
-		if(!capable(CAP_NET_ADMIN))
+		if (!capable(CAP_NET_ADMIN))
 			return -EPERM;
 
-		if(dev->flags & IFF_UP)
+		if (dev->flags & IFF_UP)
 			return -EBUSY;
 
 		/* no settable parameters */
 
-		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
+		result = hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
 		if (result)
 			return result;
 
-		result = attach_hdlc_protocol(dev, &proto,
-					      sizeof(struct ppp_state));
+		result = attach_hdlc_protocol(dev, &proto, sizeof(struct ppp));
 		if (result)
 			return result;
+
+		ppp = get_ppp(dev);
+		spin_lock_init(&ppp->lock);
+		ppp->req_timeout = 2;
+		ppp->cr_retries = 10;
+		ppp->term_retries = 2;
+		ppp->keepalive_interval = 10;
+		ppp->keepalive_timeout = 60;
+
 		dev->hard_start_xmit = hdlc->xmit;
+		dev->hard_header_len = sizeof(struct hdlc_header);
+		dev->header_ops = &ppp_header_ops;
 		dev->type = ARPHRD_PPP;
-		netif_dormant_off(dev);
+		netif_dormant_on(dev);
 		return 0;
 	}
 
@@ -137,12 +692,11 @@ static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
 
 static int __init mod_init(void)
 {
+	skb_queue_head_init(&tx_queue);
 	register_hdlc_protocol(&proto);
 	return 0;
 }
 
-
-
 static void __exit mod_exit(void)
 {
 	unregister_hdlc_protocol(&proto);

+ 3 - 6
drivers/net/wan/n2.c

@@ -53,7 +53,7 @@ static const char* devname = "RISCom/N2";
 #define NEED_SCA_MSCI_INTR
 #define MAX_TX_BUFFERS 10
 
-static char *hw = NULL;	/* pointer to hw=xxx command line string */
+static char *hw;	/* pointer to hw=xxx command line string */
 
 /* RISCom/N2 Board Registers */
 
@@ -145,7 +145,6 @@ static card_t **new_card = &first_card;
 					 &(card)->ports[port] : NULL)
 
 
-
 static __inline__ u8 sca_get_page(card_t *card)
 {
 	return inb(card->io + N2_PSR) & PSR_PAGEBITS;
@@ -159,9 +158,7 @@ static __inline__ void openwin(card_t *card, u8 page)
 }
 
 
-
-#include "hd6457x.c"
-
+#include "hd64570.c"
 
 
 static void n2_set_iface(port_t *port)
@@ -478,7 +475,7 @@ static int __init n2_run(unsigned long io, unsigned long irq,
 			n2_destroy_card(card);
 			return -ENOBUFS;
 		}
-		sca_init_sync_port(port); /* Set up SCA memory */
+		sca_init_port(port); /* Set up SCA memory */
 
 		printk(KERN_INFO "%s: RISCom/N2 node %d\n",
 		       dev->name, port->phy_node);

+ 46 - 73
drivers/net/wan/pc300too.c

@@ -1,7 +1,7 @@
 /*
  * Cyclades PC300 synchronous serial card driver for Linux
  *
- * Copyright (C) 2000-2007 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 2000-2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -11,7 +11,7 @@
  *
  * Sources of information:
  *    Hitachi HD64572 SCA-II User's Manual
- *    Cyclades PC300 Linux driver
+ *    Original Cyclades PC300 Linux driver
  *
  * This driver currently supports only PC300/RSV (V.24/V.35) and
  * PC300/X21 cards.
@@ -37,17 +37,11 @@
 
 #include "hd64572.h"
 
-static const char* version = "Cyclades PC300 driver version: 1.17";
-static const char* devname = "PC300";
-
 #undef DEBUG_PKT
 #define DEBUG_RINGS
 
 #define PC300_PLX_SIZE		0x80    /* PLX control window size (128 B) */
 #define PC300_SCA_SIZE		0x400   /* SCA window size (1 KB) */
-#define ALL_PAGES_ALWAYS_MAPPED
-#define NEED_DETECT_RAM
-#define NEED_SCA_MSCI_INTR
 #define MAX_TX_BUFFERS		10
 
 static int pci_clock_freq = 33000000;
@@ -81,7 +75,8 @@ typedef struct {
 
 
 typedef struct port_s {
-	struct net_device *dev;
+	struct napi_struct napi;
+	struct net_device *netdev;
 	struct card_s *card;
 	spinlock_t lock;	/* TX lock */
 	sync_serial_settings settings;
@@ -93,7 +88,7 @@ typedef struct port_s {
 	u16 txin;		/* tx ring buffer 'in' and 'last' pointers */
 	u16 txlast;
 	u8 rxs, txs, tmc;	/* SCA registers */
-	u8 phy_node;		/* physical port # - 0 or 1 */
+	u8 chan;		/* physical port # - 0 or 1 */
 }port_t;
 
 
@@ -114,21 +109,10 @@ typedef struct card_s {
 }card_t;
 
 
-#define sca_in(reg, card)	     readb(card->scabase + (reg))
-#define sca_out(value, reg, card)    writeb(value, card->scabase + (reg))
-#define sca_inw(reg, card)	     readw(card->scabase + (reg))
-#define sca_outw(value, reg, card)   writew(value, card->scabase + (reg))
-#define sca_inl(reg, card)	     readl(card->scabase + (reg))
-#define sca_outl(value, reg, card)   writel(value, card->scabase + (reg))
-
-#define port_to_card(port)	     (port->card)
-#define log_node(port)		     (port->phy_node)
-#define phy_node(port)		     (port->phy_node)
-#define winbase(card)		     (card->rambase)
 #define get_port(card, port)	     ((port) < (card)->n_ports ? \
 					 (&(card)->ports[port]) : (NULL))
 
-#include "hd6457x.c"
+#include "hd64572.c"
 
 
 static void pc300_set_iface(port_t *port)
@@ -139,8 +123,8 @@ static void pc300_set_iface(port_t *port)
 	u8 rxs = port->rxs & CLK_BRG_MASK;
 	u8 txs = port->txs & CLK_BRG_MASK;
 
-	sca_out(EXS_TES1, (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS,
-		port_to_card(port));
+	sca_out(EXS_TES1, (port->chan ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS,
+		port->card);
 	switch(port->settings.clock_type) {
 	case CLOCK_INT:
 		rxs |= CLK_BRG; /* BRG output */
@@ -172,10 +156,10 @@ static void pc300_set_iface(port_t *port)
 	if (port->card->type == PC300_RSV) {
 		if (port->iface == IF_IFACE_V35)
 			writel(card->init_ctrl_value |
-			       PC300_CHMEDIA_MASK(port->phy_node), init_ctrl);
+			       PC300_CHMEDIA_MASK(port->chan), init_ctrl);
 		else
 			writel(card->init_ctrl_value &
-			       ~PC300_CHMEDIA_MASK(port->phy_node), init_ctrl);
+			       ~PC300_CHMEDIA_MASK(port->chan), init_ctrl);
 	}
 }
 
@@ -280,10 +264,8 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
 	card_t *card = pci_get_drvdata(pdev);
 
 	for (i = 0; i < 2; i++)
-		if (card->ports[i].card) {
-			struct net_device *dev = port_to_dev(&card->ports[i]);
-			unregister_hdlc_device(dev);
-		}
+		if (card->ports[i].card)
+			unregister_hdlc_device(card->ports[i].netdev);
 
 	if (card->irq)
 		free_irq(card->irq, card);
@@ -298,10 +280,10 @@ static void pc300_pci_remove_one(struct pci_dev *pdev)
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	if (card->ports[0].dev)
-		free_netdev(card->ports[0].dev);
-	if (card->ports[1].dev)
-		free_netdev(card->ports[1].dev);
+	if (card->ports[0].netdev)
+		free_netdev(card->ports[0].netdev);
+	if (card->ports[1].netdev)
+		free_netdev(card->ports[1].netdev);
 	kfree(card);
 }
 
@@ -318,12 +300,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 	u32 scaphys;		/* SCA memory base */
 	u32 plxphys;		/* PLX registers memory base */
 
-#ifndef MODULE
-	static int printed_version;
-	if (!printed_version++)
-		printk(KERN_INFO "%s\n", version);
-#endif
-
 	i = pci_enable_device(pdev);
 	if (i)
 		return i;
@@ -343,27 +319,6 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 	}
 	pci_set_drvdata(pdev, card);
 
-	if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 ||
-	    pdev->device == PCI_DEVICE_ID_PC300_TE_2)
-		card->type = PC300_TE; /* not fully supported */
-	else if (card->init_ctrl_value & PC300_CTYPE_MASK)
-		card->type = PC300_X21;
-	else
-		card->type = PC300_RSV;
-
-	if (pdev->device == PCI_DEVICE_ID_PC300_RX_1 ||
-	    pdev->device == PCI_DEVICE_ID_PC300_TE_1)
-		card->n_ports = 1;
-	else
-		card->n_ports = 2;
-
-	for (i = 0; i < card->n_ports; i++)
-		if (!(card->ports[i].dev = alloc_hdlcdev(&card->ports[i]))) {
-			printk(KERN_ERR "pc300: unable to allocate memory\n");
-			pc300_pci_remove_one(pdev);
-			return -ENOMEM;
-		}
-
 	if (pci_resource_len(pdev, 0) != PC300_PLX_SIZE ||
 	    pci_resource_len(pdev, 2) != PC300_SCA_SIZE ||
 	    pci_resource_len(pdev, 3) < 16384) {
@@ -372,13 +327,13 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 		return -EFAULT;
 	}
 
-	plxphys = pci_resource_start(pdev,0) & PCI_BASE_ADDRESS_MEM_MASK;
+	plxphys = pci_resource_start(pdev, 0) & PCI_BASE_ADDRESS_MEM_MASK;
 	card->plxbase = ioremap(plxphys, PC300_PLX_SIZE);
 
-	scaphys = pci_resource_start(pdev,2) & PCI_BASE_ADDRESS_MEM_MASK;
+	scaphys = pci_resource_start(pdev, 2) & PCI_BASE_ADDRESS_MEM_MASK;
 	card->scabase = ioremap(scaphys, PC300_SCA_SIZE);
 
-	ramphys = pci_resource_start(pdev,3) & PCI_BASE_ADDRESS_MEM_MASK;
+	ramphys = pci_resource_start(pdev, 3) & PCI_BASE_ADDRESS_MEM_MASK;
 	card->rambase = pci_ioremap_bar(pdev, 3);
 
 	if (card->plxbase == NULL ||
@@ -393,6 +348,27 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 	card->init_ctrl_value = readl(&((plx9050 __iomem *)card->scabase)->init_ctrl);
 	pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, plxphys);
 
+	if (pdev->device == PCI_DEVICE_ID_PC300_TE_1 ||
+	    pdev->device == PCI_DEVICE_ID_PC300_TE_2)
+		card->type = PC300_TE; /* not fully supported */
+	else if (card->init_ctrl_value & PC300_CTYPE_MASK)
+		card->type = PC300_X21;
+	else
+		card->type = PC300_RSV;
+
+	if (pdev->device == PCI_DEVICE_ID_PC300_RX_1 ||
+	    pdev->device == PCI_DEVICE_ID_PC300_TE_1)
+		card->n_ports = 1;
+	else
+		card->n_ports = 2;
+
+	for (i = 0; i < card->n_ports; i++)
+		if (!(card->ports[i].netdev = alloc_hdlcdev(&card->ports[i]))) {
+			printk(KERN_ERR "pc300: unable to allocate memory\n");
+			pc300_pci_remove_one(pdev);
+			return -ENOMEM;
+		}
+
 	/* Reset PLX */
 	p = &card->plxbase->init_ctrl;
 	writel(card->init_ctrl_value | 0x40000000, p);
@@ -446,7 +422,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 	writew(0x0041, &card->plxbase->intr_ctrl_stat);
 
 	/* Allocate IRQ */
-	if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, devname, card)) {
+	if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, "pc300", card)) {
 		printk(KERN_WARNING "pc300: could not allocate IRQ%d.\n",
 		       pdev->irq);
 		pc300_pci_remove_one(pdev);
@@ -463,9 +439,9 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 
 	for (i = 0; i < card->n_ports; i++) {
 		port_t *port = &card->ports[i];
-		struct net_device *dev = port_to_dev(port);
+		struct net_device *dev = port->netdev;
 		hdlc_device *hdlc = dev_to_hdlc(dev);
-		port->phy_node = i;
+		port->chan = i;
 
 		spin_lock_init(&port->lock);
 		dev->irq = card->irq;
@@ -484,6 +460,7 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 		else
 			port->iface = IF_IFACE_V35;
 
+		sca_init_port(port);
 		if (register_hdlc_device(dev)) {
 			printk(KERN_ERR "pc300: unable to register hdlc "
 			       "device\n");
@@ -491,10 +468,9 @@ static int __devinit pc300_pci_init_one(struct pci_dev *pdev,
 			pc300_pci_remove_one(pdev);
 			return -ENOBUFS;
 		}
-		sca_init_sync_port(port);	/* Set up SCA memory */
 
-		printk(KERN_INFO "%s: PC300 node %d\n",
-		       dev->name, port->phy_node);
+		printk(KERN_INFO "%s: PC300 channel %d\n",
+		       dev->name, port->chan);
 	}
 	return 0;
 }
@@ -524,9 +500,6 @@ static struct pci_driver pc300_pci_driver = {
 
 static int __init pc300_init_module(void)
 {
-#ifdef MODULE
-	printk(KERN_INFO "%s\n", version);
-#endif
 	if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) {
 		printk(KERN_ERR "pc300: Invalid PCI clock frequency\n");
 		return -EINVAL;

+ 25 - 52
drivers/net/wan/pci200syn.c

@@ -1,7 +1,7 @@
 /*
  * Goramo PCI200SYN synchronous serial card driver for Linux
  *
- * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl>
+ * Copyright (C) 2002-2008 Krzysztof Halasa <khc@pm.waw.pl>
  *
  * This program is free software; you can redistribute it and/or modify it
  * under the terms of version 2 of the GNU General Public License
@@ -33,17 +33,11 @@
 
 #include "hd64572.h"
 
-static const char* version = "Goramo PCI200SYN driver version: 1.16";
-static const char* devname = "PCI200SYN";
-
 #undef DEBUG_PKT
 #define DEBUG_RINGS
 
 #define PCI200SYN_PLX_SIZE	0x80	/* PLX control window size (128b) */
 #define PCI200SYN_SCA_SIZE	0x400	/* SCA window size (1Kb) */
-#define ALL_PAGES_ALWAYS_MAPPED
-#define NEED_DETECT_RAM
-#define NEED_SCA_MSCI_INTR
 #define MAX_TX_BUFFERS		10
 
 static int pci_clock_freq = 33000000;
@@ -68,7 +62,8 @@ typedef struct {
 
 
 typedef struct port_s {
-	struct net_device *dev;
+	struct napi_struct napi;
+	struct net_device *netdev;
 	struct card_s *card;
 	spinlock_t lock;	/* TX lock */
 	sync_serial_settings settings;
@@ -79,7 +74,7 @@ typedef struct port_s {
 	u16 txin;		/* tx ring buffer 'in' and 'last' pointers */
 	u16 txlast;
 	u8 rxs, txs, tmc;	/* SCA registers */
-	u8 phy_node;		/* physical port # - 0 or 1 */
+	u8 chan;		/* physical port # - 0 or 1 */
 }port_t;
 
 
@@ -97,17 +92,6 @@ typedef struct card_s {
 }card_t;
 
 
-#define sca_in(reg, card)	     readb(card->scabase + (reg))
-#define sca_out(value, reg, card)    writeb(value, card->scabase + (reg))
-#define sca_inw(reg, card)	     readw(card->scabase + (reg))
-#define sca_outw(value, reg, card)   writew(value, card->scabase + (reg))
-#define sca_inl(reg, card)	     readl(card->scabase + (reg))
-#define sca_outl(value, reg, card)   writel(value, card->scabase + (reg))
-
-#define port_to_card(port)	     (port->card)
-#define log_node(port)		     (port->phy_node)
-#define phy_node(port)		     (port->phy_node)
-#define winbase(card)		     (card->rambase)
 #define get_port(card, port)	     (&card->ports[port])
 #define sca_flush(card)		     (sca_in(IER0, card));
 
@@ -127,7 +111,7 @@ static inline void new_memcpy_toio(char __iomem *dest, char *src, int length)
 #undef memcpy_toio
 #define memcpy_toio new_memcpy_toio
 
-#include "hd6457x.c"
+#include "hd64572.c"
 
 
 static void pci200_set_iface(port_t *port)
@@ -137,8 +121,8 @@ static void pci200_set_iface(port_t *port)
 	u8 rxs = port->rxs & CLK_BRG_MASK;
 	u8 txs = port->txs & CLK_BRG_MASK;
 
-	sca_out(EXS_TES1, (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS,
-		port_to_card(port));
+	sca_out(EXS_TES1, (port->chan ? MSCI1_OFFSET : MSCI0_OFFSET) + EXS,
+		port->card);
 	switch(port->settings.clock_type) {
 	case CLOCK_INT:
 		rxs |= CLK_BRG; /* BRG output */
@@ -180,7 +164,7 @@ static int pci200_open(struct net_device *dev)
 
 	sca_open(dev);
 	pci200_set_iface(port);
-	sca_flush(port_to_card(port));
+	sca_flush(port->card);
 	return 0;
 }
 
@@ -189,7 +173,7 @@ static int pci200_open(struct net_device *dev)
 static int pci200_close(struct net_device *dev)
 {
 	sca_close(dev);
-	sca_flush(port_to_card(dev_to_port(dev)));
+	sca_flush(dev_to_port(dev)->card);
 	hdlc_close(dev);
 	return 0;
 }
@@ -242,7 +226,7 @@ static int pci200_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 
 		memcpy(&port->settings, &new_line, size); /* Update settings */
 		pci200_set_iface(port);
-		sca_flush(port_to_card(port));
+		sca_flush(port->card);
 		return 0;
 
 	default:
@@ -258,10 +242,8 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
 	card_t *card = pci_get_drvdata(pdev);
 
 	for (i = 0; i < 2; i++)
-		if (card->ports[i].card) {
-			struct net_device *dev = port_to_dev(&card->ports[i]);
-			unregister_hdlc_device(dev);
-		}
+		if (card->ports[i].card)
+			unregister_hdlc_device(card->ports[i].netdev);
 
 	if (card->irq)
 		free_irq(card->irq, card);
@@ -276,10 +258,10 @@ static void pci200_pci_remove_one(struct pci_dev *pdev)
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
-	if (card->ports[0].dev)
-		free_netdev(card->ports[0].dev);
-	if (card->ports[1].dev)
-		free_netdev(card->ports[1].dev);
+	if (card->ports[0].netdev)
+		free_netdev(card->ports[0].netdev);
+	if (card->ports[1].netdev)
+		free_netdev(card->ports[1].netdev);
 	kfree(card);
 }
 
@@ -296,12 +278,6 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 	u32 scaphys;		/* SCA memory base */
 	u32 plxphys;		/* PLX registers memory base */
 
-#ifndef MODULE
-	static int printed_version;
-	if (!printed_version++)
-		printk(KERN_INFO "%s\n", version);
-#endif
-
 	i = pci_enable_device(pdev);
 	if (i)
 		return i;
@@ -320,9 +296,9 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 		return -ENOBUFS;
 	}
 	pci_set_drvdata(pdev, card);
-	card->ports[0].dev = alloc_hdlcdev(&card->ports[0]);
-	card->ports[1].dev = alloc_hdlcdev(&card->ports[1]);
-	if (!card->ports[0].dev || !card->ports[1].dev) {
+	card->ports[0].netdev = alloc_hdlcdev(&card->ports[0]);
+	card->ports[1].netdev = alloc_hdlcdev(&card->ports[1]);
+	if (!card->ports[0].netdev || !card->ports[1].netdev) {
 		printk(KERN_ERR "pci200syn: unable to allocate memory\n");
 		pci200_pci_remove_one(pdev);
 		return -ENOMEM;
@@ -398,7 +374,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 	writew(readw(p) | 0x0040, p);
 
 	/* Allocate IRQ */
-	if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, devname, card)) {
+	if (request_irq(pdev->irq, sca_intr, IRQF_SHARED, "pci200syn", card)) {
 		printk(KERN_WARNING "pci200syn: could not allocate IRQ%d.\n",
 		       pdev->irq);
 		pci200_pci_remove_one(pdev);
@@ -410,9 +386,9 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 
 	for (i = 0; i < 2; i++) {
 		port_t *port = &card->ports[i];
-		struct net_device *dev = port_to_dev(port);
+		struct net_device *dev = port->netdev;
 		hdlc_device *hdlc = dev_to_hdlc(dev);
-		port->phy_node = i;
+		port->chan = i;
 
 		spin_lock_init(&port->lock);
 		dev->irq = card->irq;
@@ -426,6 +402,7 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 		hdlc->xmit = sca_xmit;
 		port->settings.clock_type = CLOCK_EXT;
 		port->card = card;
+		sca_init_port(port);
 		if (register_hdlc_device(dev)) {
 			printk(KERN_ERR "pci200syn: unable to register hdlc "
 			       "device\n");
@@ -433,10 +410,9 @@ static int __devinit pci200_pci_init_one(struct pci_dev *pdev,
 			pci200_pci_remove_one(pdev);
 			return -ENOBUFS;
 		}
-		sca_init_sync_port(port);	/* Set up SCA memory */
 
-		printk(KERN_INFO "%s: PCI200SYN node %d\n",
-		       dev->name, port->phy_node);
+		printk(KERN_INFO "%s: PCI200SYN channel %d\n",
+		       dev->name, port->chan);
 	}
 
 	sca_flush(card);
@@ -464,9 +440,6 @@ static struct pci_driver pci200_pci_driver = {
 
 static int __init pci200_init_module(void)
 {
-#ifdef MODULE
-	printk(KERN_INFO "%s\n", version);
-#endif
 	if (pci_clock_freq < 1000000 || pci_clock_freq > 80000000) {
 		printk(KERN_ERR "pci200syn: Invalid PCI clock frequency\n");
 		return -EINVAL;

+ 0 - 1476
drivers/net/wan/syncppp.c

@@ -1,1476 +0,0 @@
-/*
- *	NET3:	A (fairly minimal) implementation of synchronous PPP for Linux
- *		as well as a CISCO HDLC implementation. See the copyright 
- *		message below for the original source.
- *
- *	This program is free software; you can redistribute it and/or
- *	modify it under the terms of the GNU General Public License
- *	as published by the Free Software Foundation; either version
- *	2 of the license, or (at your option) any later version.
- *
- *	Note however. This code is also used in a different form by FreeBSD.
- *	Therefore when making any non OS specific change please consider
- *	contributing it back to the original author under the terms
- *	below in addition.
- *		-- Alan
- *
- *	Port for Linux-2.1 by Jan "Yenya" Kasprzak <kas@fi.muni.cz>
- */
-
-/*
- * Synchronous PPP/Cisco link level subroutines.
- * Keepalive protocol implemented in both Cisco and PPP modes.
- *
- * Copyright (C) 1994 Cronyx Ltd.
- * Author: Serge Vakulenko, <vak@zebub.msk.su>
- *
- * This software is distributed with NO WARRANTIES, not even the implied
- * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Authors grant any other persons or organisations permission to use
- * or modify this software as long as this message is kept with the software,
- * all derivative works or modified versions.
- *
- * Version 1.9, Wed Oct  4 18:58:15 MSK 1995
- *
- * $Id: syncppp.c,v 1.18 2000/04/11 05:25:31 asj Exp $
- */
-#undef DEBUG
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/errno.h>
-#include <linux/init.h>
-#include <linux/if_arp.h>
-#include <linux/skbuff.h>
-#include <linux/route.h>
-#include <linux/netdevice.h>
-#include <linux/inetdevice.h>
-#include <linux/random.h>
-#include <linux/pkt_sched.h>
-#include <linux/spinlock.h>
-#include <linux/rcupdate.h>
-
-#include <net/net_namespace.h>
-#include <net/syncppp.h>
-
-#include <asm/byteorder.h>
-#include <asm/uaccess.h>
-
-#define MAXALIVECNT     6               /* max. alive packets */
-
-#define PPP_ALLSTATIONS 0xff            /* All-Stations broadcast address */
-#define PPP_UI          0x03            /* Unnumbered Information */
-#define PPP_IP          0x0021          /* Internet Protocol */
-#define PPP_ISO         0x0023          /* ISO OSI Protocol */
-#define PPP_XNS         0x0025          /* Xerox NS Protocol */
-#define PPP_IPX         0x002b          /* Novell IPX Protocol */
-#define PPP_LCP         0xc021          /* Link Control Protocol */
-#define PPP_IPCP        0x8021          /* Internet Protocol Control Protocol */
-
-#define LCP_CONF_REQ    1               /* PPP LCP configure request */
-#define LCP_CONF_ACK    2               /* PPP LCP configure acknowledge */
-#define LCP_CONF_NAK    3               /* PPP LCP configure negative ack */
-#define LCP_CONF_REJ    4               /* PPP LCP configure reject */
-#define LCP_TERM_REQ    5               /* PPP LCP terminate request */
-#define LCP_TERM_ACK    6               /* PPP LCP terminate acknowledge */
-#define LCP_CODE_REJ    7               /* PPP LCP code reject */
-#define LCP_PROTO_REJ   8               /* PPP LCP protocol reject */
-#define LCP_ECHO_REQ    9               /* PPP LCP echo request */
-#define LCP_ECHO_REPLY  10              /* PPP LCP echo reply */
-#define LCP_DISC_REQ    11              /* PPP LCP discard request */
-
-#define LCP_OPT_MRU             1       /* maximum receive unit */
-#define LCP_OPT_ASYNC_MAP       2       /* async control character map */
-#define LCP_OPT_AUTH_PROTO      3       /* authentication protocol */
-#define LCP_OPT_QUAL_PROTO      4       /* quality protocol */
-#define LCP_OPT_MAGIC           5       /* magic number */
-#define LCP_OPT_RESERVED        6       /* reserved */
-#define LCP_OPT_PROTO_COMP      7       /* protocol field compression */
-#define LCP_OPT_ADDR_COMP       8       /* address/control field compression */
-
-#define IPCP_CONF_REQ   LCP_CONF_REQ    /* PPP IPCP configure request */
-#define IPCP_CONF_ACK   LCP_CONF_ACK    /* PPP IPCP configure acknowledge */
-#define IPCP_CONF_NAK   LCP_CONF_NAK    /* PPP IPCP configure negative ack */
-#define IPCP_CONF_REJ   LCP_CONF_REJ    /* PPP IPCP configure reject */
-#define IPCP_TERM_REQ   LCP_TERM_REQ    /* PPP IPCP terminate request */
-#define IPCP_TERM_ACK   LCP_TERM_ACK    /* PPP IPCP terminate acknowledge */
-#define IPCP_CODE_REJ   LCP_CODE_REJ    /* PPP IPCP code reject */
-
-#define CISCO_MULTICAST         0x8f    /* Cisco multicast address */
-#define CISCO_UNICAST           0x0f    /* Cisco unicast address */
-#define CISCO_KEEPALIVE         0x8035  /* Cisco keepalive protocol */
-#define CISCO_ADDR_REQ          0       /* Cisco address request */
-#define CISCO_ADDR_REPLY        1       /* Cisco address reply */
-#define CISCO_KEEPALIVE_REQ     2       /* Cisco keepalive request */
-
-struct ppp_header {
-	u8 address;
-	u8 control;
-	__be16 protocol;
-};
-#define PPP_HEADER_LEN          sizeof (struct ppp_header)
-
-struct lcp_header {
-	u8 type;
-	u8 ident;
-	__be16 len;
-};
-#define LCP_HEADER_LEN          sizeof (struct lcp_header)
-
-struct cisco_packet {
-	__be32 type;
-	__be32 par1;
-	__be32 par2;
-	__be16 rel;
-	__be16 time0;
-	__be16 time1;
-};
-#define CISCO_PACKET_LEN 18
-#define CISCO_BIG_PACKET_LEN 20
-
-static struct sppp *spppq;
-static struct timer_list sppp_keepalive_timer;
-static DEFINE_SPINLOCK(spppq_lock);
-
-/* global xmit queue for sending packets while spinlock is held */
-static struct sk_buff_head tx_queue;
-
-static void sppp_keepalive (unsigned long dummy);
-static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
-	u8 ident, u16 len, void *data);
-static void sppp_cisco_send (struct sppp *sp, int type, u32 par1, u32 par2);
-static void sppp_lcp_input (struct sppp *sp, struct sk_buff *m);
-static void sppp_cisco_input (struct sppp *sp, struct sk_buff *m);
-static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *m);
-static void sppp_lcp_open (struct sppp *sp);
-static void sppp_ipcp_open (struct sppp *sp);
-static int sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h,
-	int len, u32 *magic);
-static void sppp_cp_timeout (unsigned long arg);
-static char *sppp_lcp_type_name (u8 type);
-static char *sppp_ipcp_type_name (u8 type);
-static void sppp_print_bytes (u8 *p, u16 len);
-
-static int debug;
-
-/* Flush global outgoing packet queue to dev_queue_xmit().
- *
- * dev_queue_xmit() must be called with interrupts enabled
- * which means it can't be called with spinlocks held.
- * If a packet needs to be sent while a spinlock is held,
- * then put the packet into tx_queue, and call sppp_flush_xmit()
- * after spinlock is released.
- */
-static void sppp_flush_xmit(void)
-{
-	struct sk_buff *skb;
-	while ((skb = skb_dequeue(&tx_queue)) != NULL)
-		dev_queue_xmit(skb);
-}
-
-/*
- *	Interface down stub
- */	
-
-static void if_down(struct net_device *dev)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-
-	sp->pp_link_state=SPPP_LINK_DOWN;
-}
-
-/*
- * Timeout routine activations.
- */
-
-static void sppp_set_timeout(struct sppp *p,int s) 
-{
-	if (! (p->pp_flags & PP_TIMO)) 
-	{
-		init_timer(&p->pp_timer);
-		p->pp_timer.function=sppp_cp_timeout;
-		p->pp_timer.expires=jiffies+s*HZ;
-		p->pp_timer.data=(unsigned long)p;
-		p->pp_flags |= PP_TIMO;
-		add_timer(&p->pp_timer);
-	}
-}
-
-static void sppp_clear_timeout(struct sppp *p)
-{
-	if (p->pp_flags & PP_TIMO) 
-	{
-		del_timer(&p->pp_timer);
-		p->pp_flags &= ~PP_TIMO; 
-	}
-}
-
-/**
- *	sppp_input -	receive and process a WAN PPP frame
- *	@skb:	The buffer to process
- *	@dev:	The device it arrived on
- *
- *	This can be called directly by cards that do not have
- *	timing constraints but is normally called from the network layer
- *	after interrupt servicing to process frames queued via netif_rx().
- *
- *	We process the options in the card. If the frame is destined for
- *	the protocol stacks then it requeues the frame for the upper level
- *	protocol. If it is a control from it is processed and discarded
- *	here.
- */
- 
-static void sppp_input (struct net_device *dev, struct sk_buff *skb)
-{
-	struct ppp_header *h;
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	unsigned long flags;
-
-	skb->dev=dev;
-	skb_reset_mac_header(skb);
-
-	if (!pskb_may_pull(skb, PPP_HEADER_LEN)) {
-		/* Too small packet, drop it. */
-		if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",
-				dev->name, skb->len);
-		kfree_skb(skb);
-		return;
-	}
-
-	/* Get PPP header. */
-	h = (struct ppp_header *)skb->data;
-	skb_pull(skb,sizeof(struct ppp_header));
-
-	spin_lock_irqsave(&sp->lock, flags);
-	
-	switch (h->address) {
-	default:        /* Invalid PPP packet. */
-		goto invalid;
-	case PPP_ALLSTATIONS:
-		if (h->control != PPP_UI)
-			goto invalid;
-		if (sp->pp_flags & PP_CISCO) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: PPP packet in Cisco mode <0x%x 0x%x 0x%x>\n",
-					dev->name,
-					h->address, h->control, ntohs (h->protocol));
-			goto drop;
-		}
-		switch (ntohs (h->protocol)) {
-		default:
-			if (sp->lcp.state == LCP_STATE_OPENED)
-				sppp_cp_send (sp, PPP_LCP, LCP_PROTO_REJ,
-					++sp->pp_seq, skb->len + 2,
-					&h->protocol);
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: invalid input protocol <0x%x 0x%x 0x%x>\n",
-					dev->name,
-					h->address, h->control, ntohs (h->protocol));
-			goto drop;
-		case PPP_LCP:
-			sppp_lcp_input (sp, skb);
-			goto drop;
-		case PPP_IPCP:
-			if (sp->lcp.state == LCP_STATE_OPENED)
-				sppp_ipcp_input (sp, skb);
-			else
-				printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n");
-			goto drop;
-		case PPP_IP:
-			if (sp->ipcp.state == IPCP_STATE_OPENED) {
-				if(sp->pp_flags&PP_DEBUG)
-					printk(KERN_DEBUG "Yow an IP frame.\n");
-				skb->protocol=htons(ETH_P_IP);
-				netif_rx(skb);
-				goto done;
-			}
-			break;
-#ifdef IPX
-		case PPP_IPX:
-			/* IPX IPXCP not implemented yet */
-			if (sp->lcp.state == LCP_STATE_OPENED) {
-				skb->protocol=htons(ETH_P_IPX);
-				netif_rx(skb);
-				goto done;
-			}
-			break;
-#endif
-		}
-		break;
-	case CISCO_MULTICAST:
-	case CISCO_UNICAST:
-		/* Don't check the control field here (RFC 1547). */
-		if (! (sp->pp_flags & PP_CISCO)) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: Cisco packet in PPP mode <0x%x 0x%x 0x%x>\n",
-					dev->name,
-					h->address, h->control, ntohs (h->protocol));
-			goto drop;
-		}
-		switch (ntohs (h->protocol)) {
-		default:
-			goto invalid;
-		case CISCO_KEEPALIVE:
-			sppp_cisco_input (sp, skb);
-			goto drop;
-#ifdef CONFIG_INET
-		case ETH_P_IP:
-			skb->protocol=htons(ETH_P_IP);
-			netif_rx(skb);
-			goto done;
-#endif
-#ifdef CONFIG_IPX
-		case ETH_P_IPX:
-			skb->protocol=htons(ETH_P_IPX);
-			netif_rx(skb);
-			goto done;
-#endif
-		}
-		break;
-	}
-	goto drop;
-
-invalid:
-	if (sp->pp_flags & PP_DEBUG)
-		printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",
-			dev->name, h->address, h->control, ntohs (h->protocol));
-drop:
-	kfree_skb(skb);
-done:
-	spin_unlock_irqrestore(&sp->lock, flags);
-	sppp_flush_xmit();
-	return;
-}
-
-/*
- *	Handle transmit packets.
- */
- 
-static int sppp_hard_header(struct sk_buff *skb,
-			    struct net_device *dev, __u16 type,
-			    const void *daddr, const void *saddr,
-			    unsigned int len)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	struct ppp_header *h;
-	skb_push(skb,sizeof(struct ppp_header));
-	h=(struct ppp_header *)skb->data;
-	if(sp->pp_flags&PP_CISCO)
-	{
-		h->address = CISCO_UNICAST;
-		h->control = 0;
-	}
-	else
-	{
-		h->address = PPP_ALLSTATIONS;
-		h->control = PPP_UI;
-	}
-	if(sp->pp_flags & PP_CISCO)
-	{
-		h->protocol = htons(type);
-	}
-	else switch(type)
-	{
-		case ETH_P_IP:
-			h->protocol = htons(PPP_IP);
-			break;
-		case ETH_P_IPX:
-			h->protocol = htons(PPP_IPX);
-			break;
-	}
-	return sizeof(struct ppp_header);
-}
-
-static const struct header_ops sppp_header_ops = {
-	.create = sppp_hard_header,
-};
-
-/*
- * Send keepalive packets, every 10 seconds.
- */
-
-static void sppp_keepalive (unsigned long dummy)
-{
-	struct sppp *sp;
-	unsigned long flags;
-
-	spin_lock_irqsave(&spppq_lock, flags);
-
-	for (sp=spppq; sp; sp=sp->pp_next) 
-	{
-		struct net_device *dev = sp->pp_if;
-
-		/* Keepalive mode disabled or channel down? */
-		if (! (sp->pp_flags & PP_KEEPALIVE) ||
-		    ! (dev->flags & IFF_UP))
-			continue;
-
-		spin_lock(&sp->lock);
-
-		/* No keepalive in PPP mode if LCP not opened yet. */
-		if (! (sp->pp_flags & PP_CISCO) &&
-		    sp->lcp.state != LCP_STATE_OPENED) {
-			spin_unlock(&sp->lock);
-			continue;
-		}
-
-		if (sp->pp_alivecnt == MAXALIVECNT) {
-			/* No keepalive packets got.  Stop the interface. */
-			printk (KERN_WARNING "%s: protocol down\n", dev->name);
-			if_down (dev);
-			if (! (sp->pp_flags & PP_CISCO)) {
-				/* Shut down the PPP link. */
-				sp->lcp.magic = jiffies;
-				sp->lcp.state = LCP_STATE_CLOSED;
-				sp->ipcp.state = IPCP_STATE_CLOSED;
-				sppp_clear_timeout (sp);
-				/* Initiate negotiation. */
-				sppp_lcp_open (sp);
-			}
-		}
-		if (sp->pp_alivecnt <= MAXALIVECNT)
-			++sp->pp_alivecnt;
-		if (sp->pp_flags & PP_CISCO)
-			sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq,
-				sp->pp_rseq);
-		else if (sp->lcp.state == LCP_STATE_OPENED) {
-			__be32 nmagic = htonl (sp->lcp.magic);
-			sp->lcp.echoid = ++sp->pp_seq;
-			sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ,
-				sp->lcp.echoid, 4, &nmagic);
-		}
-
-		spin_unlock(&sp->lock);
-	}
-	spin_unlock_irqrestore(&spppq_lock, flags);
-	sppp_flush_xmit();
-	sppp_keepalive_timer.expires=jiffies+10*HZ;
-	add_timer(&sppp_keepalive_timer);
-}
-
-/*
- * Handle incoming PPP Link Control Protocol packets.
- */
- 
-static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb)
-{
-	struct lcp_header *h;
-	struct net_device *dev = sp->pp_if;
-	int len = skb->len;
-	u8 *p, opt[6];
-	u32 rmagic = 0;
-
-	if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
-		if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n",
-				dev->name, len);
-		return;
-	}
-	h = (struct lcp_header *)skb->data;
-	skb_pull(skb,sizeof(struct lcp_header *));
-	
-	if (sp->pp_flags & PP_DEBUG) 
-	{
-		char state = '?';
-		switch (sp->lcp.state) {
-		case LCP_STATE_CLOSED:   state = 'C'; break;
-		case LCP_STATE_ACK_RCVD: state = 'R'; break;
-		case LCP_STATE_ACK_SENT: state = 'S'; break;
-		case LCP_STATE_OPENED:   state = 'O'; break;
-		}
-		printk (KERN_WARNING "%s: lcp input(%c): %d bytes <%s id=%xh len=%xh",
-			dev->name, state, len,
-			sppp_lcp_type_name (h->type), h->ident, ntohs (h->len));
-		if (len > 4)
-			sppp_print_bytes ((u8*) (h+1), len-4);
-		printk (">\n");
-	}
-	if (len > ntohs (h->len))
-		len = ntohs (h->len);
-	switch (h->type) {
-	default:
-		/* Unknown packet type -- send Code-Reject packet. */
-		sppp_cp_send (sp, PPP_LCP, LCP_CODE_REJ, ++sp->pp_seq,
-			skb->len, h);
-		break;
-	case LCP_CONF_REQ:
-		if (len < 4) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_DEBUG"%s: invalid lcp configure request packet length: %d bytes\n",
-					dev->name, len);
-			break;
-		}
-		if (len>4 && !sppp_lcp_conf_parse_options (sp, h, len, &rmagic))
-			goto badreq;
-		if (rmagic == sp->lcp.magic) {
-			/* Local and remote magics equal -- loopback? */
-			if (sp->pp_loopcnt >= MAXALIVECNT*5) {
-				printk (KERN_WARNING "%s: loopback\n",
-					dev->name);
-				sp->pp_loopcnt = 0;
-				if (dev->flags & IFF_UP) {
-					if_down (dev);
-				}
-			} else if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_DEBUG "%s: conf req: magic glitch\n",
-					dev->name);
-			++sp->pp_loopcnt;
-
-			/* MUST send Conf-Nack packet. */
-			rmagic = ~sp->lcp.magic;
-			opt[0] = LCP_OPT_MAGIC;
-			opt[1] = sizeof (opt);
-			opt[2] = rmagic >> 24;
-			opt[3] = rmagic >> 16;
-			opt[4] = rmagic >> 8;
-			opt[5] = rmagic;
-			sppp_cp_send (sp, PPP_LCP, LCP_CONF_NAK,
-				h->ident, sizeof (opt), &opt);
-badreq:
-			switch (sp->lcp.state) {
-			case LCP_STATE_OPENED:
-				/* Initiate renegotiation. */
-				sppp_lcp_open (sp);
-				/* fall through... */
-			case LCP_STATE_ACK_SENT:
-				/* Go to closed state. */
-				sp->lcp.state = LCP_STATE_CLOSED;
-				sp->ipcp.state = IPCP_STATE_CLOSED;
-			}
-			break;
-		}
-		/* Send Configure-Ack packet. */
-		sp->pp_loopcnt = 0;
-		if (sp->lcp.state != LCP_STATE_OPENED) {
-			sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,
-					h->ident, len-4, h+1);
-		}
-		/* Change the state. */
-		switch (sp->lcp.state) {
-		case LCP_STATE_CLOSED:
-			sp->lcp.state = LCP_STATE_ACK_SENT;
-			break;
-		case LCP_STATE_ACK_RCVD:
-			sp->lcp.state = LCP_STATE_OPENED;
-			sppp_ipcp_open (sp);
-			break;
-		case LCP_STATE_OPENED:
-			/* Remote magic changed -- close session. */
-			sp->lcp.state = LCP_STATE_CLOSED;
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-			/* Initiate renegotiation. */
-			sppp_lcp_open (sp);
-			/* Send ACK after our REQ in attempt to break loop */
-			sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK,
-					h->ident, len-4, h+1);
-			sp->lcp.state = LCP_STATE_ACK_SENT;
-			break;
-		}
-		break;
-	case LCP_CONF_ACK:
-		if (h->ident != sp->lcp.confid)
-			break;
-		sppp_clear_timeout (sp);
-		if ((sp->pp_link_state != SPPP_LINK_UP) &&
-		    (dev->flags & IFF_UP)) {
-			/* Coming out of loopback mode. */
-			sp->pp_link_state=SPPP_LINK_UP;
-			printk (KERN_INFO "%s: protocol up\n", dev->name);
-		}
-		switch (sp->lcp.state) {
-		case LCP_STATE_CLOSED:
-			sp->lcp.state = LCP_STATE_ACK_RCVD;
-			sppp_set_timeout (sp, 5);
-			break;
-		case LCP_STATE_ACK_SENT:
-			sp->lcp.state = LCP_STATE_OPENED;
-			sppp_ipcp_open (sp);
-			break;
-		}
-		break;
-	case LCP_CONF_NAK:
-		if (h->ident != sp->lcp.confid)
-			break;
-		p = (u8*) (h+1);
-		if (len>=10 && p[0] == LCP_OPT_MAGIC && p[1] >= 4) {
-			rmagic = (u32)p[2] << 24 |
-				(u32)p[3] << 16 | p[4] << 8 | p[5];
-			if (rmagic == ~sp->lcp.magic) {
-				int newmagic;
-				if (sp->pp_flags & PP_DEBUG)
-					printk (KERN_DEBUG "%s: conf nak: magic glitch\n",
-						dev->name);
-				get_random_bytes(&newmagic, sizeof(newmagic));
-				sp->lcp.magic += newmagic;
-			} else
-				sp->lcp.magic = rmagic;
-			}
-		if (sp->lcp.state != LCP_STATE_ACK_SENT) {
-			/* Go to closed state. */
-			sp->lcp.state = LCP_STATE_CLOSED;
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-		}
-		/* The link will be renegotiated after timeout,
-		 * to avoid endless req-nack loop. */
-		sppp_clear_timeout (sp);
-		sppp_set_timeout (sp, 2);
-		break;
-	case LCP_CONF_REJ:
-		if (h->ident != sp->lcp.confid)
-			break;
-		sppp_clear_timeout (sp);
-		/* Initiate renegotiation. */
-		sppp_lcp_open (sp);
-		if (sp->lcp.state != LCP_STATE_ACK_SENT) {
-			/* Go to closed state. */
-			sp->lcp.state = LCP_STATE_CLOSED;
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-		}
-		break;
-	case LCP_TERM_REQ:
-		sppp_clear_timeout (sp);
-		/* Send Terminate-Ack packet. */
-		sppp_cp_send (sp, PPP_LCP, LCP_TERM_ACK, h->ident, 0, NULL);
-		/* Go to closed state. */
-		sp->lcp.state = LCP_STATE_CLOSED;
-		sp->ipcp.state = IPCP_STATE_CLOSED;
-		/* Initiate renegotiation. */
-		sppp_lcp_open (sp);
-		break;
-	case LCP_TERM_ACK:
-	case LCP_CODE_REJ:
-	case LCP_PROTO_REJ:
-		/* Ignore for now. */
-		break;
-	case LCP_DISC_REQ:
-		/* Discard the packet. */
-		break;
-	case LCP_ECHO_REQ:
-		if (sp->lcp.state != LCP_STATE_OPENED)
-			break;
-		if (len < 8) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: invalid lcp echo request packet length: %d bytes\n",
-					dev->name, len);
-			break;
-		}
-		if (ntohl (*(__be32*)(h+1)) == sp->lcp.magic) {
-			/* Line loopback mode detected. */
-			printk (KERN_WARNING "%s: loopback\n", dev->name);
-			if_down (dev);
-
-			/* Shut down the PPP link. */
-			sp->lcp.state = LCP_STATE_CLOSED;
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-			sppp_clear_timeout (sp);
-			/* Initiate negotiation. */
-			sppp_lcp_open (sp);
-			break;
-		}
-		*(__be32 *)(h+1) = htonl (sp->lcp.magic);
-		sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REPLY, h->ident, len-4, h+1);
-		break;
-	case LCP_ECHO_REPLY:
-		if (h->ident != sp->lcp.echoid)
-			break;
-		if (len < 8) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: invalid lcp echo reply packet length: %d bytes\n",
-					dev->name, len);
-			break;
-		}
-		if (ntohl(*(__be32 *)(h+1)) != sp->lcp.magic)
-		sp->pp_alivecnt = 0;
-		break;
-	}
-}
-
-/*
- * Handle incoming Cisco keepalive protocol packets.
- */
-
-static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb)
-{
-	struct cisco_packet *h;
-	struct net_device *dev = sp->pp_if;
-
-	if (!pskb_may_pull(skb, sizeof(struct cisco_packet))
-	    || (skb->len != CISCO_PACKET_LEN
-		&& skb->len != CISCO_BIG_PACKET_LEN)) {
-		if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n",
-				dev->name,  skb->len);
-		return;
-	}
-	h = (struct cisco_packet *)skb->data;
-	skb_pull(skb, sizeof(struct cisco_packet*));
-	if (sp->pp_flags & PP_DEBUG)
-		printk (KERN_WARNING "%s: cisco input: %d bytes <%xh %xh %xh %xh %xh-%xh>\n",
-			dev->name,  skb->len,
-			ntohl (h->type), h->par1, h->par2, h->rel,
-			h->time0, h->time1);
-	switch (ntohl (h->type)) {
-	default:
-		if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: unknown cisco packet type: 0x%x\n",
-				dev->name,  ntohl (h->type));
-		break;
-	case CISCO_ADDR_REPLY:
-		/* Reply on address request, ignore */
-		break;
-	case CISCO_KEEPALIVE_REQ:
-		sp->pp_alivecnt = 0;
-		sp->pp_rseq = ntohl (h->par1);
-		if (sp->pp_seq == sp->pp_rseq) {
-			/* Local and remote sequence numbers are equal.
-			 * Probably, the line is in loopback mode. */
-			int newseq;
-			if (sp->pp_loopcnt >= MAXALIVECNT) {
-				printk (KERN_WARNING "%s: loopback\n",
-					dev->name);
-				sp->pp_loopcnt = 0;
-				if (dev->flags & IFF_UP) {
-					if_down (dev);
-				}
-			}
-			++sp->pp_loopcnt;
-
-			/* Generate new local sequence number */
-			get_random_bytes(&newseq, sizeof(newseq));
-			sp->pp_seq ^= newseq;
-			break;
-		}
-		sp->pp_loopcnt = 0;
-		if (sp->pp_link_state==SPPP_LINK_DOWN &&
-		    (dev->flags & IFF_UP)) {
-			sp->pp_link_state=SPPP_LINK_UP;
-			printk (KERN_INFO "%s: protocol up\n", dev->name);
-		}
-		break;
-	case CISCO_ADDR_REQ:
-		/* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */
-		{
-		__be32 addr = 0, mask = htonl(~0U); /* FIXME: is the mask correct? */
-#ifdef CONFIG_INET
-		struct in_device *in_dev;
-		struct in_ifaddr *ifa;
-
-		rcu_read_lock();
-		if ((in_dev = __in_dev_get_rcu(dev)) != NULL)
-		{
-			for (ifa=in_dev->ifa_list; ifa != NULL;
-				ifa=ifa->ifa_next) {
-				if (strcmp(dev->name, ifa->ifa_label) == 0) 
-				{
-					addr = ifa->ifa_local;
-					mask = ifa->ifa_mask;
-					break;
-				}
-			}
-		}
-		rcu_read_unlock();
-#endif		
-		sppp_cisco_send (sp, CISCO_ADDR_REPLY, ntohl(addr), ntohl(mask));
-		break;
-		}
-	}
-}
-
-
-/*
- * Send PPP LCP packet.
- */
-
-static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
-	u8 ident, u16 len, void *data)
-{
-	struct ppp_header *h;
-	struct lcp_header *lh;
-	struct sk_buff *skb;
-	struct net_device *dev = sp->pp_if;
-
-	skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len,
-		GFP_ATOMIC);
-	if (skb==NULL)
-		return;
-
-	skb_reserve(skb,dev->hard_header_len);
-	
-	h = (struct ppp_header *)skb_put(skb, sizeof(struct ppp_header));
-	h->address = PPP_ALLSTATIONS;        /* broadcast address */
-	h->control = PPP_UI;                 /* Unnumbered Info */
-	h->protocol = htons (proto);         /* Link Control Protocol */
-
-	lh = (struct lcp_header *)skb_put(skb, sizeof(struct lcp_header));
-	lh->type = type;
-	lh->ident = ident;
-	lh->len = htons (LCP_HEADER_LEN + len);
-
-	if (len)
-		memcpy(skb_put(skb,len),data, len);
-
-	if (sp->pp_flags & PP_DEBUG) {
-		printk (KERN_WARNING "%s: %s output <%s id=%xh len=%xh",
-			dev->name, 
-			proto==PPP_LCP ? "lcp" : "ipcp",
-			proto==PPP_LCP ? sppp_lcp_type_name (lh->type) :
-			sppp_ipcp_type_name (lh->type), lh->ident,
-			ntohs (lh->len));
-		if (len)
-			sppp_print_bytes ((u8*) (lh+1), len);
-		printk (">\n");
-	}
-	/* Control is high priority so it doesn't get queued behind data */
-	skb->priority=TC_PRIO_CONTROL;
-	skb->dev = dev;
-	skb_queue_tail(&tx_queue, skb);
-}
-
-/*
- * Send Cisco keepalive packet.
- */
-
-static void sppp_cisco_send (struct sppp *sp, int type, u32 par1, u32 par2)
-{
-	struct ppp_header *h;
-	struct cisco_packet *ch;
-	struct sk_buff *skb;
-	struct net_device *dev = sp->pp_if;
-	u32 t = jiffies * 1000/HZ;
-
-	skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN,
-		GFP_ATOMIC);
-
-	if(skb==NULL)
-		return;
-		
-	skb_reserve(skb, dev->hard_header_len);
-	h = (struct ppp_header *)skb_put (skb, sizeof(struct ppp_header));
-	h->address = CISCO_MULTICAST;
-	h->control = 0;
-	h->protocol = htons (CISCO_KEEPALIVE);
-
-	ch = (struct cisco_packet*)skb_put(skb, CISCO_PACKET_LEN);
-	ch->type = htonl (type);
-	ch->par1 = htonl (par1);
-	ch->par2 = htonl (par2);
-	ch->rel = htons(0xffff);
-	ch->time0 = htons ((u16) (t >> 16));
-	ch->time1 = htons ((u16) t);
-
-	if (sp->pp_flags & PP_DEBUG)
-		printk (KERN_WARNING "%s: cisco output: <%xh %xh %xh %xh %xh-%xh>\n",
-			dev->name,  ntohl (ch->type), ch->par1,
-			ch->par2, ch->rel, ch->time0, ch->time1);
-	skb->priority=TC_PRIO_CONTROL;
-	skb->dev = dev;
-	skb_queue_tail(&tx_queue, skb);
-}
-
-/**
- *	sppp_close - close down a synchronous PPP or Cisco HDLC link
- *	@dev: The network device to drop the link of
- *
- *	This drops the logical interface to the channel. It is not
- *	done politely as we assume we will also be dropping DTR. Any
- *	timeouts are killed.
- */
-
-int sppp_close (struct net_device *dev)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&sp->lock, flags);
-	sp->pp_link_state = SPPP_LINK_DOWN;
-	sp->lcp.state = LCP_STATE_CLOSED;
-	sp->ipcp.state = IPCP_STATE_CLOSED;
-	sppp_clear_timeout (sp);
-	spin_unlock_irqrestore(&sp->lock, flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(sppp_close);
-
-/**
- *	sppp_open - open a synchronous PPP or Cisco HDLC link
- *	@dev:	Network device to activate
- *	
- *	Close down any existing synchronous session and commence
- *	from scratch. In the PPP case this means negotiating LCP/IPCP
- *	and friends, while for Cisco HDLC we simply need to start sending
- *	keepalives
- */
-
-int sppp_open (struct net_device *dev)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	unsigned long flags;
-
-	sppp_close(dev);
-
-	spin_lock_irqsave(&sp->lock, flags);
-	if (!(sp->pp_flags & PP_CISCO)) {
-		sppp_lcp_open (sp);
-	}
-	sp->pp_link_state = SPPP_LINK_DOWN;
-	spin_unlock_irqrestore(&sp->lock, flags);
-	sppp_flush_xmit();
-
-	return 0;
-}
-
-EXPORT_SYMBOL(sppp_open);
-
-/**
- *	sppp_reopen - notify of physical link loss
- *	@dev: Device that lost the link
- *
- *	This function informs the synchronous protocol code that
- *	the underlying link died (for example a carrier drop on X.21)
- *
- *	We increment the magic numbers to ensure that if the other end
- *	failed to notice we will correctly start a new session. It happens
- *	do to the nature of telco circuits is that you can lose carrier on
- *	one endonly.
- *
- *	Having done this we go back to negotiating. This function may
- *	be called from an interrupt context.
- */
- 
-int sppp_reopen (struct net_device *dev)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	unsigned long flags;
-
-	sppp_close(dev);
-
-	spin_lock_irqsave(&sp->lock, flags);
-	if (!(sp->pp_flags & PP_CISCO))
-	{
-		sp->lcp.magic = jiffies;
-		++sp->pp_seq;
-		sp->lcp.state = LCP_STATE_CLOSED;
-		sp->ipcp.state = IPCP_STATE_CLOSED;
-		/* Give it a moment for the line to settle then go */
-		sppp_set_timeout (sp, 1);
-	} 
-	sp->pp_link_state=SPPP_LINK_DOWN;
-	spin_unlock_irqrestore(&sp->lock, flags);
-
-	return 0;
-}
-
-EXPORT_SYMBOL(sppp_reopen);
-
-/**
- *	sppp_change_mtu - Change the link MTU
- *	@dev:	Device to change MTU on
- *	@new_mtu: New MTU
- *
- *	Change the MTU on the link. This can only be called with
- *	the link down. It returns an error if the link is up or
- *	the mtu is out of range.
- */
- 
-static int sppp_change_mtu(struct net_device *dev, int new_mtu)
-{
-	if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
-		return -EINVAL;
-	dev->mtu=new_mtu;
-	return 0;
-}
-
-/**
- *	sppp_do_ioctl - Ioctl handler for ppp/hdlc
- *	@dev: Device subject to ioctl
- *	@ifr: Interface request block from the user
- *	@cmd: Command that is being issued
- *	
- *	This function handles the ioctls that may be issued by the user
- *	to control the settings of a PPP/HDLC link. It does both busy
- *	and security checks. This function is intended to be wrapped by
- *	callers who wish to add additional ioctl calls of their own.
- */
- 
-int sppp_do_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
-{
-	struct sppp *sp = (struct sppp *)sppp_of(dev);
-
-	if(dev->flags&IFF_UP)
-		return -EBUSY;
-		
-	if(!capable(CAP_NET_ADMIN))
-		return -EPERM;
-	
-	switch(cmd)
-	{
-		case SPPPIOCCISCO:
-			sp->pp_flags|=PP_CISCO;
-			dev->type = ARPHRD_HDLC;
-			break;
-		case SPPPIOCPPP:
-			sp->pp_flags&=~PP_CISCO;
-			dev->type = ARPHRD_PPP;
-			break;
-		case SPPPIOCDEBUG:
-			sp->pp_flags&=~PP_DEBUG;
-			if(ifr->ifr_flags)
-				sp->pp_flags|=PP_DEBUG;
-			break;
-		case SPPPIOCGFLAGS:
-			if(copy_to_user(ifr->ifr_data, &sp->pp_flags, sizeof(sp->pp_flags)))
-				return -EFAULT;
-			break;
-		case SPPPIOCSFLAGS:
-			if(copy_from_user(&sp->pp_flags, ifr->ifr_data, sizeof(sp->pp_flags)))
-				return -EFAULT;
-			break;
-		default:
-			return -EINVAL;
-	}
-	return 0;
-}
-
-EXPORT_SYMBOL(sppp_do_ioctl);
-
-/**
- *	sppp_attach - attach synchronous PPP/HDLC to a device
- *	@pd:	PPP device to initialise
- *
- *	This initialises the PPP/HDLC support on an interface. At the
- *	time of calling the dev element must point to the network device
- *	that this interface is attached to. The interface should not yet
- *	be registered. 
- */
- 
-void sppp_attach(struct ppp_device *pd)
-{
-	struct net_device *dev = pd->dev;
-	struct sppp *sp = &pd->sppp;
-	unsigned long flags;
-
-	/* Make sure embedding is safe for sppp_of */
-	BUG_ON(sppp_of(dev) != sp);
-
-	spin_lock_irqsave(&spppq_lock, flags);
-	/* Initialize keepalive handler. */
-	if (! spppq)
-	{
-		init_timer(&sppp_keepalive_timer);
-		sppp_keepalive_timer.expires=jiffies+10*HZ;
-		sppp_keepalive_timer.function=sppp_keepalive;
-		add_timer(&sppp_keepalive_timer);
-	}
-	/* Insert new entry into the keepalive list. */
-	sp->pp_next = spppq;
-	spppq = sp;
-	spin_unlock_irqrestore(&spppq_lock, flags);
-
-	sp->pp_loopcnt = 0;
-	sp->pp_alivecnt = 0;
-	sp->pp_seq = 0;
-	sp->pp_rseq = 0;
-	sp->pp_flags = PP_KEEPALIVE|PP_CISCO|debug;/*PP_DEBUG;*/
-	sp->lcp.magic = 0;
-	sp->lcp.state = LCP_STATE_CLOSED;
-	sp->ipcp.state = IPCP_STATE_CLOSED;
-	sp->pp_if = dev;
-	spin_lock_init(&sp->lock);
-	
-	/* 
-	 *	Device specific setup. All but interrupt handler and
-	 *	hard_start_xmit.
-	 */
-	 
-	dev->header_ops = &sppp_header_ops;
-
-	dev->tx_queue_len = 10;
-	dev->type = ARPHRD_HDLC;
-	dev->addr_len = 0;
-	dev->hard_header_len = sizeof(struct ppp_header);
-	dev->mtu = PPP_MTU;
-	/*
-	 *	These 4 are callers but MUST also call sppp_ functions
-	 */
-	dev->do_ioctl = sppp_do_ioctl;
-#if 0
-	dev->get_stats = NULL;		/* Let the driver override these */
-	dev->open = sppp_open;
-	dev->stop = sppp_close;
-#endif	
-	dev->change_mtu = sppp_change_mtu;
-	dev->flags = IFF_MULTICAST|IFF_POINTOPOINT|IFF_NOARP;
-}
-
-EXPORT_SYMBOL(sppp_attach);
-
-/**
- *	sppp_detach - release PPP resources from a device
- *	@dev:	Network device to release
- *
- *	Stop and free up any PPP/HDLC resources used by this
- *	interface. This must be called before the device is
- *	freed.
- */
- 
-void sppp_detach (struct net_device *dev)
-{
-	struct sppp **q, *p, *sp = (struct sppp *)sppp_of(dev);
-	unsigned long flags;
-
-	spin_lock_irqsave(&spppq_lock, flags);
-	/* Remove the entry from the keepalive list. */
-	for (q = &spppq; (p = *q); q = &p->pp_next)
-		if (p == sp) {
-			*q = p->pp_next;
-			break;
-		}
-
-	/* Stop keepalive handler. */
-	if (! spppq)
-		del_timer(&sppp_keepalive_timer);
-	sppp_clear_timeout (sp);
-	spin_unlock_irqrestore(&spppq_lock, flags);
-}
-
-EXPORT_SYMBOL(sppp_detach);
-
-/*
- * Analyze the LCP Configure-Request options list
- * for the presence of unknown options.
- * If the request contains unknown options, build and
- * send Configure-reject packet, containing only unknown options.
- */
-static int
-sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h,
-	int len, u32 *magic)
-{
-	u8 *buf, *r, *p;
-	int rlen;
-
-	len -= 4;
-	buf = r = kmalloc (len, GFP_ATOMIC);
-	if (! buf)
-		return (0);
-
-	p = (void*) (h+1);
-	for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) {
-		switch (*p) {
-		case LCP_OPT_MAGIC:
-			/* Magic number -- extract. */
-			if (len >= 6 && p[1] == 6) {
-				*magic = (u32)p[2] << 24 |
-					(u32)p[3] << 16 | p[4] << 8 | p[5];
-				continue;
-			}
-			break;
-		case LCP_OPT_ASYNC_MAP:
-			/* Async control character map -- check to be zero. */
-			if (len >= 6 && p[1] == 6 && ! p[2] && ! p[3] &&
-			    ! p[4] && ! p[5])
-				continue;
-			break;
-		case LCP_OPT_MRU:
-			/* Maximum receive unit -- always OK. */
-			continue;
-		default:
-			/* Others not supported. */
-			break;
-		}
-		/* Add the option to rejected list. */
-		memcpy(r, p, p[1]);
-		r += p[1];
-		rlen += p[1];
-	}
-	if (rlen)
-		sppp_cp_send (sp, PPP_LCP, LCP_CONF_REJ, h->ident, rlen, buf);
-	kfree(buf);
-	return (rlen == 0);
-}
-
-static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb)
-{
-	struct lcp_header *h;
-	struct net_device *dev = sp->pp_if;
-	int len = skb->len;
-
-	if (!pskb_may_pull(skb, sizeof(struct lcp_header))) {
-		if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: invalid ipcp packet length: %d bytes\n",
-				dev->name,  len);
-		return;
-	}
-	h = (struct lcp_header *)skb->data;
-	skb_pull(skb,sizeof(struct lcp_header));
-	if (sp->pp_flags & PP_DEBUG) {
-		printk (KERN_WARNING "%s: ipcp input: %d bytes <%s id=%xh len=%xh",
-			dev->name,  len,
-			sppp_ipcp_type_name (h->type), h->ident, ntohs (h->len));
-		if (len > 4)
-			sppp_print_bytes ((u8*) (h+1), len-4);
-		printk (">\n");
-	}
-	if (len > ntohs (h->len))
-		len = ntohs (h->len);
-	switch (h->type) {
-	default:
-		/* Unknown packet type -- send Code-Reject packet. */
-		sppp_cp_send (sp, PPP_IPCP, IPCP_CODE_REJ, ++sp->pp_seq, len, h);
-		break;
-	case IPCP_CONF_REQ:
-		if (len < 4) {
-			if (sp->pp_flags & PP_DEBUG)
-				printk (KERN_WARNING "%s: invalid ipcp configure request packet length: %d bytes\n",
-					dev->name, len);
-			return;
-		}
-		if (len > 4) {
-			sppp_cp_send (sp, PPP_IPCP, LCP_CONF_REJ, h->ident,
-				len-4, h+1);
-
-			switch (sp->ipcp.state) {
-			case IPCP_STATE_OPENED:
-				/* Initiate renegotiation. */
-				sppp_ipcp_open (sp);
-				/* fall through... */
-			case IPCP_STATE_ACK_SENT:
-				/* Go to closed state. */
-				sp->ipcp.state = IPCP_STATE_CLOSED;
-			}
-		} else {
-			/* Send Configure-Ack packet. */
-			sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_ACK, h->ident,
-				0, NULL);
-			/* Change the state. */
-			if (sp->ipcp.state == IPCP_STATE_ACK_RCVD)
-				sp->ipcp.state = IPCP_STATE_OPENED;
-			else
-				sp->ipcp.state = IPCP_STATE_ACK_SENT;
-		}
-		break;
-	case IPCP_CONF_ACK:
-		if (h->ident != sp->ipcp.confid)
-			break;
-		sppp_clear_timeout (sp);
-		switch (sp->ipcp.state) {
-		case IPCP_STATE_CLOSED:
-			sp->ipcp.state = IPCP_STATE_ACK_RCVD;
-			sppp_set_timeout (sp, 5);
-			break;
-		case IPCP_STATE_ACK_SENT:
-			sp->ipcp.state = IPCP_STATE_OPENED;
-			break;
-		}
-		break;
-	case IPCP_CONF_NAK:
-	case IPCP_CONF_REJ:
-		if (h->ident != sp->ipcp.confid)
-			break;
-		sppp_clear_timeout (sp);
-			/* Initiate renegotiation. */
-		sppp_ipcp_open (sp);
-		if (sp->ipcp.state != IPCP_STATE_ACK_SENT)
-			/* Go to closed state. */
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-		break;
-	case IPCP_TERM_REQ:
-		/* Send Terminate-Ack packet. */
-		sppp_cp_send (sp, PPP_IPCP, IPCP_TERM_ACK, h->ident, 0, NULL);
-		/* Go to closed state. */
-		sp->ipcp.state = IPCP_STATE_CLOSED;
-		/* Initiate renegotiation. */
-		sppp_ipcp_open (sp);
-		break;
-	case IPCP_TERM_ACK:
-		/* Ignore for now. */
-	case IPCP_CODE_REJ:
-		/* Ignore for now. */
-		break;
-	}
-}
-
-static void sppp_lcp_open (struct sppp *sp)
-{
-	char opt[6];
-
-	if (! sp->lcp.magic)
-		sp->lcp.magic = jiffies;
-	opt[0] = LCP_OPT_MAGIC;
-	opt[1] = sizeof (opt);
-	opt[2] = sp->lcp.magic >> 24;
-	opt[3] = sp->lcp.magic >> 16;
-	opt[4] = sp->lcp.magic >> 8;
-	opt[5] = sp->lcp.magic;
-	sp->lcp.confid = ++sp->pp_seq;
-	sppp_cp_send (sp, PPP_LCP, LCP_CONF_REQ, sp->lcp.confid,
-		sizeof (opt), &opt);
-	sppp_set_timeout (sp, 2);
-}
-
-static void sppp_ipcp_open (struct sppp *sp)
-{
-	sp->ipcp.confid = ++sp->pp_seq;
-	sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_REQ, sp->ipcp.confid, 0, NULL);
-	sppp_set_timeout (sp, 2);
-}
-
-/*
- * Process PPP control protocol timeouts.
- */
- 
-static void sppp_cp_timeout (unsigned long arg)
-{
-	struct sppp *sp = (struct sppp*) arg;
-	unsigned long flags;
-
-	spin_lock_irqsave(&sp->lock, flags);
-
-	sp->pp_flags &= ~PP_TIMO;
-	if (! (sp->pp_if->flags & IFF_UP) || (sp->pp_flags & PP_CISCO)) {
-		spin_unlock_irqrestore(&sp->lock, flags);
-		return;
-	}
-	switch (sp->lcp.state) {
-	case LCP_STATE_CLOSED:
-		/* No ACK for Configure-Request, retry. */
-		sppp_lcp_open (sp);
-		break;
-	case LCP_STATE_ACK_RCVD:
-		/* ACK got, but no Configure-Request for peer, retry. */
-		sppp_lcp_open (sp);
-		sp->lcp.state = LCP_STATE_CLOSED;
-		break;
-	case LCP_STATE_ACK_SENT:
-		/* ACK sent but no ACK for Configure-Request, retry. */
-		sppp_lcp_open (sp);
-		break;
-	case LCP_STATE_OPENED:
-		/* LCP is already OK, try IPCP. */
-		switch (sp->ipcp.state) {
-		case IPCP_STATE_CLOSED:
-			/* No ACK for Configure-Request, retry. */
-			sppp_ipcp_open (sp);
-			break;
-		case IPCP_STATE_ACK_RCVD:
-			/* ACK got, but no Configure-Request for peer, retry. */
-			sppp_ipcp_open (sp);
-			sp->ipcp.state = IPCP_STATE_CLOSED;
-			break;
-		case IPCP_STATE_ACK_SENT:
-			/* ACK sent but no ACK for Configure-Request, retry. */
-			sppp_ipcp_open (sp);
-			break;
-		case IPCP_STATE_OPENED:
-			/* IPCP is OK. */
-			break;
-		}
-		break;
-	}
-	spin_unlock_irqrestore(&sp->lock, flags);
-	sppp_flush_xmit();
-}
-
-static char *sppp_lcp_type_name (u8 type)
-{
-	static char buf [8];
-	switch (type) {
-	case LCP_CONF_REQ:   return ("conf-req");
-	case LCP_CONF_ACK:   return ("conf-ack");
-	case LCP_CONF_NAK:   return ("conf-nack");
-	case LCP_CONF_REJ:   return ("conf-rej");
-	case LCP_TERM_REQ:   return ("term-req");
-	case LCP_TERM_ACK:   return ("term-ack");
-	case LCP_CODE_REJ:   return ("code-rej");
-	case LCP_PROTO_REJ:  return ("proto-rej");
-	case LCP_ECHO_REQ:   return ("echo-req");
-	case LCP_ECHO_REPLY: return ("echo-reply");
-	case LCP_DISC_REQ:   return ("discard-req");
-	}
-	sprintf (buf, "%xh", type);
-	return (buf);
-}
-
-static char *sppp_ipcp_type_name (u8 type)
-{
-	static char buf [8];
-	switch (type) {
-	case IPCP_CONF_REQ:   return ("conf-req");
-	case IPCP_CONF_ACK:   return ("conf-ack");
-	case IPCP_CONF_NAK:   return ("conf-nack");
-	case IPCP_CONF_REJ:   return ("conf-rej");
-	case IPCP_TERM_REQ:   return ("term-req");
-	case IPCP_TERM_ACK:   return ("term-ack");
-	case IPCP_CODE_REJ:   return ("code-rej");
-	}
-	sprintf (buf, "%xh", type);
-	return (buf);
-}
-
-static void sppp_print_bytes (u_char *p, u16 len)
-{
-	printk (" %x", *p++);
-	while (--len > 0)
-		printk ("-%x", *p++);
-}
-
-/**
- *	sppp_rcv -	receive and process a WAN PPP frame
- *	@skb:	The buffer to process
- *	@dev:	The device it arrived on
- *	@p: Unused
- *	@orig_dev: Unused
- *
- *	Protocol glue. This drives the deferred processing mode the poorer
- *	cards use. This can be called directly by cards that do not have
- *	timing constraints but is normally called from the network layer
- *	after interrupt servicing to process frames queued via netif_rx.
- */
-
-static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p, struct net_device *orig_dev)
-{
-	if (dev_net(dev) != &init_net) {
-		kfree_skb(skb);
-		return 0;
-	}
-
-	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
-		return NET_RX_DROP;
-	sppp_input(dev,skb);
-	return 0;
-}
-
-static struct packet_type sppp_packet_type = {
-	.type	= __constant_htons(ETH_P_WAN_PPP),
-	.func	= sppp_rcv,
-};
-
-static char banner[] __initdata = 
-	KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n"
-	KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & "
-		  "Jan \"Yenya\" Kasprzak.\n";
-
-static int __init sync_ppp_init(void)
-{
-	if(debug)
-		debug=PP_DEBUG;
-	printk(banner);
-	skb_queue_head_init(&tx_queue);
-	dev_add_pack(&sppp_packet_type);
-	return 0;
-}
-
-
-static void __exit sync_ppp_cleanup(void)
-{
-	dev_remove_pack(&sppp_packet_type);
-}
-
-module_init(sync_ppp_init);
-module_exit(sync_ppp_cleanup);
-module_param(debug, int, 0);
-MODULE_LICENSE("GPL");
-

+ 0 - 102
include/net/syncppp.h

@@ -1,102 +0,0 @@
-/*
- * Defines for synchronous PPP/Cisco link level subroutines.
- *
- * Copyright (C) 1994 Cronyx Ltd.
- * Author: Serge Vakulenko, <vak@zebub.msk.su>
- *
- * This software is distributed with NO WARRANTIES, not even the implied
- * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *
- * Authors grant any other persons or organizations permission to use
- * or modify this software as long as this message is kept with the software,
- * all derivative works or modified versions.
- *
- * Version 1.7, Wed Jun  7 22:12:02 MSD 1995
- *
- *
- *
- */
-
-#ifndef _SYNCPPP_H_
-#define _SYNCPPP_H_ 1
-
-#ifdef __KERNEL__
-struct slcp {
-	u16	state;          /* state machine */
-	u32	magic;          /* local magic number */
-	u_char	echoid;         /* id of last keepalive echo request */
-	u_char	confid;         /* id of last configuration request */
-};
-
-struct sipcp {
-	u16	state;          /* state machine */
-	u_char  confid;         /* id of last configuration request */
-};
-
-struct sppp 
-{
-	struct sppp *	pp_next;	/* next interface in keepalive list */
-	u32		pp_flags;	/* use Cisco protocol instead of PPP */
-	u16		pp_alivecnt;	/* keepalive packets counter */
-	u16		pp_loopcnt;	/* loopback detection counter */
-	u32		pp_seq;		/* local sequence number */
-	u32		pp_rseq;	/* remote sequence number */
-	struct slcp	lcp;		/* LCP params */
-	struct sipcp	ipcp;		/* IPCP params */
-	struct timer_list	pp_timer;
-	struct net_device	*pp_if;
-	char		pp_link_state;	/* Link status */
-	spinlock_t      lock;
-};
-
-struct ppp_device
-{	
-	struct net_device *dev;	/* Network device pointer */
-	struct sppp sppp;	/* Synchronous PPP */
-};
-
-static inline struct sppp *sppp_of(struct net_device *dev) 
-{
-	struct ppp_device **ppp = dev->ml_priv;
-	BUG_ON((*ppp)->dev != dev);
-	return &(*ppp)->sppp;
-}
-
-#define PP_KEEPALIVE    0x01    /* use keepalive protocol */
-#define PP_CISCO        0x02    /* use Cisco protocol instead of PPP */
-#define PP_TIMO         0x04    /* cp_timeout routine active */
-#define PP_DEBUG	0x08
-
-#define PPP_MTU          1500    /* max. transmit unit */
-
-#define LCP_STATE_CLOSED        0       /* LCP state: closed (conf-req sent) */
-#define LCP_STATE_ACK_RCVD      1       /* LCP state: conf-ack received */
-#define LCP_STATE_ACK_SENT      2       /* LCP state: conf-ack sent */
-#define LCP_STATE_OPENED        3       /* LCP state: opened */
-
-#define IPCP_STATE_CLOSED       0       /* IPCP state: closed (conf-req sent) */
-#define IPCP_STATE_ACK_RCVD     1       /* IPCP state: conf-ack received */
-#define IPCP_STATE_ACK_SENT     2       /* IPCP state: conf-ack sent */
-#define IPCP_STATE_OPENED       3       /* IPCP state: opened */
-
-#define SPPP_LINK_DOWN		0	/* link down - no keepalive */
-#define SPPP_LINK_UP		1	/* link is up - keepalive ok */
-
-void sppp_attach (struct ppp_device *pd);
-void sppp_detach (struct net_device *dev);
-int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
-struct sk_buff *sppp_dequeue (struct net_device *dev);
-int sppp_isempty (struct net_device *dev);
-void sppp_flush (struct net_device *dev);
-int sppp_open (struct net_device *dev);
-int sppp_reopen (struct net_device *dev);
-int sppp_close (struct net_device *dev);
-#endif
-
-#define SPPPIOCCISCO	(SIOCDEVPRIVATE)
-#define SPPPIOCPPP	(SIOCDEVPRIVATE+1)
-#define SPPPIOCDEBUG	(SIOCDEVPRIVATE+2)
-#define SPPPIOCSFLAGS	(SIOCDEVPRIVATE+3)
-#define SPPPIOCGFLAGS	(SIOCDEVPRIVATE+4)
-
-#endif /* _SYNCPPP_H_ */