Commit dffdfbce authored by Kai Germaschewski's avatar Kai Germaschewski

Merge zephyr:src/kernel/v2.5/linux-2.5.isdn

into tp1.ruhr-uni-bochum.de:/home/kai/kernel/v2.5/linux-2.5.isdn
parents cbe45702 c25b65fe
......@@ -12,7 +12,8 @@ obj-$(CONFIG_ISDN_PPP_BSDCOMP) += isdn_bsdcomp.o
# Multipart objects.
isdn-objs := isdn_net.o isdn_tty.o \
isdn_v110.o isdn_common.o
isdn_v110.o isdn_common.o \
isdn_ciscohdlck.o
# Optional parts of multipart objects.
......
This diff is collapsed.
/*
* Linux ISDN subsystem, CISCO HDLC network interfaces
*
* Copyright 1999-2002 by Kai Germaschewski <kai@germaschewski.name>
* 2001 by Bjoern A. Zeeb <i4l@zabbadoz.net>
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
#ifndef ISDN_CISCOHDLCK_H
#define ISDN_CISCOHDLCK_H
int isdn_ciscohdlck_setup(isdn_net_dev *p);
#endif
......@@ -611,11 +611,9 @@ isdn_status_callback(isdn_ctrl * c)
dbg_statcallb("BHUP: %d\n", i);
dev->drv[di]->online &= ~(1 << (c->arg));
isdn_info_update();
#ifdef CONFIG_ISDN_X25
/* Signal hangup to network-devices */
if (isdn_net_stat_callback(i, c))
break;
#endif
isdn_v110_stat_callback(&slot[i].iv110, c);
if (isdn_tty_stat_callback(i, c))
break;
......
......@@ -12,6 +12,8 @@
*
*/
#include <linux/isdn.h>
#undef ISDN_DEBUG_MODEM_OPEN
#undef ISDN_DEBUG_MODEM_IOCTL
#undef ISDN_DEBUG_MODEM_WAITSENT
......
......@@ -106,3 +106,145 @@ struct concap_proto * isdn_concap_new( int encap )
}
return NULL;
}
void isdn_x25_cleanup(isdn_net_dev *p)
{
isdn_net_local *lp = &p->local;
struct concap_proto * cprot = p -> cprot;
unsigned long flags;
/* delete old encapsulation protocol if present ... */
save_flags(flags);
cli(); /* avoid races with incoming events trying to
call cprot->pops methods */
if( cprot && cprot -> pops )
cprot -> pops -> proto_del ( cprot );
p -> cprot = NULL;
lp -> dops = NULL;
restore_flags(flags);
}
void isdn_x25_open(struct net_device *dev)
{
struct concap_device_ops * dops =
( (isdn_net_local *) dev->priv ) -> dops;
struct concap_proto * cprot =
( (isdn_net_local *) dev->priv ) -> netdev -> cprot;
unsigned long flags;
save_flags(flags);
cli(); /* Avoid glitch on writes to CMD regs */
if( cprot && cprot -> pops && dops )
cprot -> pops -> restart ( cprot, dev, dops );
restore_flags(flags);
}
void isdn_x25_close(struct net_device *dev)
{
struct concap_proto * cprot =
( (isdn_net_local *) dev->priv ) -> netdev -> cprot;
if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
}
static void isdn_x25_connected(isdn_net_local *lp)
{
struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
/* try if there are generic concap receiver routines */
if( pops )
if( pops->connect_ind)
pops->connect_ind(cprot);
isdn_net_device_wake_queue(lp);
}
static void isdn_x25_disconnected(isdn_net_local *lp)
{
struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
/* try if there are generic encap protocol
receiver routines and signal the closure of
the link */
if( pops && pops -> disconn_ind )
pops -> disconn_ind(cprot);
}
int isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
/* At this point hard_start_xmit() passes control to the encapsulation
protocol (if present).
For X.25 auto-dialing is completly bypassed because:
- It does not conform with the semantics of a reliable datalink
service as needed by X.25 PLP.
- I don't want that the interface starts dialing when the network layer
sends a message which requests to disconnect the lapb link (or if it
sends any other message not resulting in data transmission).
Instead, dialing will be initiated by the encapsulation protocol entity
when a dl_establish request is received from the upper layer.
*/
isdn_net_local *lp = (isdn_net_local *) dev->priv;
struct concap_proto * cprot = lp -> netdev -> cprot;
int ret = cprot -> pops -> encap_and_xmit ( cprot , skb);
if (ret)
netif_stop_queue(dev);
return ret;
}
static void
isdn_x25_receive(isdn_net_dev *p, isdn_net_local *olp, struct sk_buff *skb)
{
isdn_net_local *lp = &p->local;
struct concap_proto *cprot = lp -> netdev -> cprot;
/* try if there are generic sync_device receiver routines */
if(cprot)
if(cprot -> pops)
if( cprot -> pops -> data_ind) {
cprot -> pops -> data_ind(cprot,skb);
return;
}
}
void isdn_x25_realrm(isdn_net_dev *p)
{
if( p -> cprot && p -> cprot -> pops )
p -> cprot -> pops -> proto_del ( p -> cprot );
}
int isdn_x25_setup(isdn_net_dev *p, int encap)
{
isdn_net_local *lp = &p->local;
/* ... , prepare for configuration of new one ... */
switch ( encap ){
case ISDN_NET_ENCAP_X25IFACE:
lp -> dops = &isdn_concap_reliable_dl_dops;
}
/* ... and allocate new one ... */
p -> cprot = isdn_concap_new( cfg -> p_encap );
/* p -> cprot == NULL now if p_encap is not supported
by means of the concap_proto mechanism */
if (!p->cprot)
return -EINVAL;
p->dev.type = ARPHRD_X25; /* change ARP type */
p->dev.addr_len = 0;
p->dev.hard_header = NULL;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->local.receive = isdn_x25_receive;
p->local.connected = isdn_x25_connected;
p->local.disconnected = isdn_x25_disconnected;
/* the protocol is not configured yet; this will
happen later when isdn_x25_open() is called */
return 0;
}
#endif /* CONFIG_ISDN_X25 */
......@@ -9,6 +9,51 @@
extern struct concap_device_ops isdn_concap_reliable_dl_dops;
extern struct concap_device_ops isdn_concap_demand_dial_dops;
extern struct concap_proto * isdn_concap_new( int );
struct concap_proto *isdn_concap_new(int);
#ifdef CONFIG_ISDN_X25
int isdn_x25_setup(isdn_net_dev *p, int encap);
void isdn_x25_cleanup(isdn_net_dev *p);
void isdn_x25_open(struct net_device *dev);
void isdn_x25_close(struct net_device *dev);
int isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev);
void isdn_x25_realrm(isdn_net_dev *p);
#else
static inline void
isdn_x25_cleanup(isdn_net_dev *p)
{
}
static inline int
isdn_x25_setup(isdn_net_dev *p, int encap)
{
printk(KERN_WARNING "ISDN: X25 support not configured\n");
return -EINVAL;
}
static inline void
isdn_x25_open(struct net_device *dev)
{
}
static inline void
isdn_x25_close(struct net_device *dev)
{
}
static inline int
isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
return 0;
}
static inline void
isdn_x25_realrm(isdn_net_dev *p)
{
}
#endif
This diff is collapsed.
......@@ -11,7 +11,10 @@
*
*/
/* Definitions for hupflags: */
#include <linux/kernel.h>
#include <linux/netdevice.h>
#include <linux/isdn.h>
/* Definitions for hupflags: */
#define ISDN_CHARGEHUP 4 /* We want to use the charge mechanism */
#define ISDN_INHUP 8 /* Even if incoming, close after huptimeout */
#define ISDN_MANCHARGE 16 /* Charge Interval manually set */
......@@ -51,6 +54,13 @@ extern int isdn_net_dial_req(isdn_net_local *);
extern void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb);
extern void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb);
static inline void
isdn_net_reset_huptimer(isdn_net_local *lp, isdn_net_local *olp)
{
olp->huptimer = 0;
lp->huptimer = 0;
}
#define ISDN_NET_MAX_QUEUE_LENGTH 2
/*
......@@ -135,6 +145,18 @@ static __inline__ void isdn_net_rm_from_bundle(isdn_net_local *lp)
spin_unlock_irqrestore(&master_lp->netdev->queue_lock, flags);
}
/*
* wake up the network -> net_device queue.
* For slaves, wake the corresponding master interface.
*/
static inline void isdn_net_device_wake_queue(isdn_net_local *lp)
{
if (lp->master)
netif_wake_queue(lp->master);
else
netif_wake_queue(&lp->netdev->dev);
}
static inline int
put_u8(unsigned char *p, u8 x)
{
......
......@@ -14,6 +14,7 @@
#include <linux/smp_lock.h>
#include <linux/poll.h>
#include <linux/ppp-comp.h>
#include <linux/if_arp.h>
#include "isdn_common.h"
#include "isdn_ppp.h"
......@@ -98,7 +99,7 @@ isdn_ppp_frame_log(char *info, char *data, int len, int maxlen,int unit,int slot
* note: it can happen, that we hangup/free the master before the slaves
* in this case we bind another lp to the master device
*/
int
static void
isdn_ppp_free(isdn_net_local * lp)
{
unsigned long flags;
......@@ -107,7 +108,7 @@ isdn_ppp_free(isdn_net_local * lp)
if (lp->ppp_slot < 0 || lp->ppp_slot > ISDN_MAX_CHANNELS) {
printk(KERN_ERR "%s: ppp_slot(%d) out of range\n",
__FUNCTION__ , lp->ppp_slot);
return 0;
return;
}
save_flags(flags);
......@@ -128,7 +129,7 @@ isdn_ppp_free(isdn_net_local * lp)
printk(KERN_ERR "%s: ppp_slot(%d) now invalid\n",
__FUNCTION__ , lp->ppp_slot);
restore_flags(flags);
return 0;
return;
}
is = ippp_table[lp->ppp_slot];
if ((is->state & IPPP_CONNECT))
......@@ -143,7 +144,7 @@ isdn_ppp_free(isdn_net_local * lp)
lp->ppp_slot = -1; /* is this OK ?? */
restore_flags(flags);
return 0;
return;
}
/*
......@@ -223,7 +224,7 @@ isdn_ppp_bind(isdn_net_local * lp)
* (wakes up daemon after B-channel connect)
*/
void
static void
isdn_ppp_wakeup_daemon(isdn_net_local * lp)
{
if (lp->ppp_slot < 0 || lp->ppp_slot >= ISDN_MAX_CHANNELS) {
......@@ -961,14 +962,19 @@ static int isdn_ppp_strip_proto(struct sk_buff *skb)
/*
* handler for incoming packets on a syncPPP interface
*/
void isdn_ppp_receive(isdn_net_dev * net_dev, isdn_net_local * lp, struct sk_buff *skb)
static void isdn_ppp_receive(isdn_net_dev *net_dev, isdn_net_local *lp,
struct sk_buff *skb)
{
struct ippp_struct *is;
int slot;
int proto;
if (net_dev->local.master)
BUG(); // we're called with the master device always
/*
* If encapsulation is syncppp, don't reset
* huptimer on LCP packets.
*/
if (PPP_PROTOCOL(skb->data) != PPP_LCP)
isdn_net_reset_huptimer(&net_dev->local,lp);
slot = lp->ppp_slot;
if (slot < 0 || slot > ISDN_MAX_CHANNELS) {
......@@ -2893,3 +2899,35 @@ static int isdn_ppp_set_compressor(struct ippp_struct *is, struct isdn_ppp_comp_
}
return -EINVAL;
}
// ISDN_NET_ENCAP_SYNCPPP
// ======================================================================
static int
isdn_ppp_header(struct sk_buff *skb, struct net_device *dev,
unsigned short type, void *daddr, void *saddr,
unsigned plen)
{
skb_push(skb, IPPP_MAX_HEADER);
return IPPP_MAX_HEADER;
}
int
isdn_ppp_setup(isdn_net_dev *p)
{
p->dev.hard_header = isdn_ppp_header;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
p->dev.type = ARPHRD_PPP; /* change ARP type */
p->dev.addr_len = 0;
p->dev.do_ioctl = isdn_ppp_dev_ioctl;
p->local.receive = isdn_ppp_receive;
p->local.connected = isdn_ppp_wakeup_daemon;
p->local.disconnected = isdn_ppp_free;
return 0;
}
......@@ -16,16 +16,37 @@ extern struct file_operations isdn_ppp_fops;
extern int isdn_ppp_init(void);
extern void isdn_ppp_cleanup(void);
extern int isdn_ppp_free(isdn_net_local *);
extern int isdn_ppp_bind(isdn_net_local *);
extern int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
extern void isdn_ppp_receive(isdn_net_dev *, isdn_net_local *, struct sk_buff *);
extern int isdn_ppp_dev_ioctl(struct net_device *, struct ifreq *, int);
extern int isdn_ppp_dial_slave(char *);
extern void isdn_ppp_wakeup_daemon(isdn_net_local *);
extern int isdn_ppp_hangup_slave(char *);
extern int isdn_ppp_register_compressor(struct isdn_ppp_compressor *ipc);
extern int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *ipc);
#ifdef CONFIG_ISDN_PPP
int isdn_ppp_setup(isdn_net_dev *p);
int isdn_ppp_bind(isdn_net_local *);
int isdn_ppp_xmit(struct sk_buff *, struct net_device *);
#else
static inline int
isdn_ppp_setup(isdn_net_dev *p)
{
printk(KERN_WARNING "ISDN: SyncPPP support not configured\n");
return -EINVAL;
}
static inline int
isdn_ppp_bind(isdn_net_local *)
{
return 0;
}
static inline int
isdn_ppp_xmit(struct sk_buff *, struct net_device *);
{
return 0;
}
#endif
#define IPPP_OPEN 0x01
#define IPPP_CONNECT 0x02
......
......@@ -75,7 +75,6 @@
#define ISDN_NET_ENCAP_UIHDLC 5
#define ISDN_NET_ENCAP_CISCOHDLCK 6 /* With SLARP and keepalive */
#define ISDN_NET_ENCAP_X25IFACE 7 /* Documentation/networking/x25-iface.txt*/
#define ISDN_NET_ENCAP_MAX_ENCAP ISDN_NET_ENCAP_X25IFACE
/* Facility which currently uses an ISDN-channel */
#define ISDN_USAGE_NONE 0
......@@ -353,13 +352,6 @@ typedef struct isdn_net_local_s {
/* a particular channel (including */
/* the frame_cnt */
int (*org_hhc)(
struct neighbour *neigh,
struct hh_cache *hh);
/* Ptr to orig. header_cache_update */
void (*org_hcu)(struct hh_cache *,
struct net_device *,
unsigned char *);
int pppbind; /* ippp device for bindings */
int dialtimeout; /* How long shall we try on dialing? (jiffies) */
int dialwait; /* How long shall we wait after failed attempt? (jiffies) */
......@@ -379,6 +371,11 @@ typedef struct isdn_net_local_s {
char cisco_debserint; /* debugging flag of cisco hdlc with slarp */
struct timer_list cisco_timer;
struct tq_struct tqueue;
void (*receive)(struct isdn_net_dev_s *p,
struct isdn_net_local_s *olp,
struct sk_buff *skb);
void (*connected)(struct isdn_net_local_s *lp);
void (*disconnected)(struct isdn_net_local_s *lp);
} isdn_net_local;
/* the interface itself */
......
......@@ -138,8 +138,6 @@ struct isdn_ppp_compressor {
extern int isdn_ppp_register_compressor(struct isdn_ppp_compressor *);
extern int isdn_ppp_unregister_compressor(struct isdn_ppp_compressor *);
extern int isdn_ppp_dial_slave(char *);
extern int isdn_ppp_hangup_slave(char *);
typedef struct {
unsigned long seqerrs;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment