Commit a29e933e authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Use a struct to describe types of ISDN net interfaces

Use a struct of methods and parameters to describe the
different kinds of network interfaces supported by isdn_net.c
and friends.
parent 611cc8a5
......@@ -390,18 +390,11 @@ isdn_ciscohdlck_header(struct sk_buff *skb, struct net_device *dev,
return 4;
}
int
isdn_ciscohdlck_setup(isdn_net_dev *p)
{
p->dev.hard_header = isdn_ciscohdlck_header;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
p->dev.do_ioctl = isdn_ciscohdlck_dev_ioctl;
p->local.receive = isdn_ciscohdlck_receive;
p->local.connected = isdn_ciscohdlck_connected;
p->local.disconnected = isdn_ciscohdlck_disconnected;
return 0;
}
struct isdn_netif_ops ciscohdlck_ops = {
.hard_header = isdn_ciscohdlck_header,
.do_ioctl = isdn_ciscohdlck_dev_ioctl,
.flags = IFF_NOARP | IFF_POINTOPOINT,
.receive = isdn_ciscohdlck_receive,
.connected = isdn_ciscohdlck_connected,
.disconnected = isdn_ciscohdlck_disconnected,
};
......@@ -11,6 +11,6 @@
#ifndef ISDN_CISCOHDLCK_H
#define ISDN_CISCOHDLCK_H
int isdn_ciscohdlck_setup(isdn_net_dev *p);
extern struct isdn_netif_ops ciscohdlck_ops;
#endif
......@@ -2415,6 +2415,7 @@ static int __init isdn_init(void)
printk("\n");
#endif
isdn_info_update();
isdn_net_init_module();
return 0;
err_tty_modem:
......
......@@ -126,16 +126,26 @@ void isdn_x25_cleanup(isdn_net_dev *p)
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;
isdn_net_local *lp = dev->priv;
/* ... , prepare for configuration of new one ... */
switch ( lp->p_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;
save_flags(flags);
cli(); /* Avoid glitch on writes to CMD regs */
if( cprot && cprot -> pops && dops )
cprot -> pops -> restart ( cprot, dev, dops );
if( p -> cprot -> pops && lp -> dops )
p -> cprot -> pops -> restart ( p -> cprot, dev, lp -> dops );
restore_flags(flags);
}
......@@ -216,35 +226,12 @@ void isdn_x25_realrm(isdn_net_dev *p)
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;
}
struct isdn_netif_ops isdn_x25_ops = {
.flags = IFF_NOARP | IFF_POINTOPOINT,
.type = ARPHRD_X25,
.receive = isdn_x25_receive,
.connected = isdn_x25_connected,
.disconnected = isdn_x25_disconnected,
};
#endif /* CONFIG_ISDN_X25 */
......@@ -14,7 +14,8 @@ struct concap_proto *isdn_concap_new(int);
#ifdef CONFIG_ISDN_X25
int isdn_x25_setup(isdn_net_dev *p, int encap);
extern struct isdn_netif_ops isdn_x25_ops;
void isdn_x25_cleanup(isdn_net_dev *p);
void isdn_x25_open(struct net_device *dev);
void isdn_x25_close(struct net_device *dev);
......@@ -28,13 +29,6 @@ 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)
{
......
......@@ -185,6 +185,22 @@ static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
#define ISDN_NET_TX_TIMEOUT (20*HZ)
static struct isdn_netif_ops *netif_ops[ISDN_NET_ENCAP_NR];
int
register_isdn_netif(int encap, struct isdn_netif_ops *ops)
{
if (encap < 0 || encap >= ISDN_NET_ENCAP_NR)
return -EINVAL;
if (netif_ops[encap])
return -EBUSY;
netif_ops[encap] = ops;
return 0;
}
/* Prototypes */
int isdn_net_force_dial_lp(isdn_net_local *);
......@@ -193,11 +209,6 @@ static void do_dialout(isdn_net_local *lp);
static int isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg);
static int isdn_rawip_setup(isdn_net_dev *p);
static int isdn_ether_setup(isdn_net_dev *p);
static int isdn_uihdlc_setup(isdn_net_dev *p);
static int isdn_iptyp_setup(isdn_net_dev *p);
char *isdn_net_revision = "$Revision: 1.140.6.11 $";
/*
......@@ -266,8 +277,8 @@ isdn_net_unbind_channel(isdn_net_local * lp)
save_flags(flags);
cli();
if (lp->unbind)
lp->unbind(lp);
if (lp->ops->unbind)
lp->ops->unbind(lp);
skb_queue_purge(&lp->super_tx_queue);
......@@ -305,8 +316,8 @@ isdn_net_bind_channel(isdn_net_local *lp, int idx)
isdn_slot_set_rx_netdev(lp->isdn_slot, lp->netdev);
isdn_slot_set_st_netdev(lp->isdn_slot, lp->netdev);
if (lp->bind)
retval = lp->bind(lp);
if (lp->ops->bind)
retval = lp->ops->bind(lp);
if (retval < 0)
isdn_net_unbind_channel(lp);
......@@ -405,7 +416,10 @@ static void isdn_net_connected(isdn_net_local *lp)
lp->cps = 0;
lp->last_jiffies = jiffies;
lp->connected(lp);
if (lp->ops->connected)
lp->ops->connected(lp);
else
isdn_net_device_wake_queue(lp);
}
/*
......@@ -563,8 +577,8 @@ isdn_net_handle_event(isdn_net_local *lp, int pr, void *arg)
if (!isdn_net_bound(lp))
break;
if (lp->disconnected)
lp->disconnected(lp);
if (lp->ops->disconnected)
lp->ops->disconnected(lp);
isdn_net_lp_disconnected(lp);
isdn_slot_all_eaz(lp->isdn_slot);
......@@ -718,8 +732,8 @@ isdn_net_hangup(isdn_net_local *lp)
}
}
printk(KERN_INFO "isdn_net: local hangup %s\n", lp->name);
if (lp->disconnected)
lp->disconnected(lp);
if (lp->ops->disconnected)
lp->ops->disconnected(lp);
isdn_net_lp_disconnected(lp);
......@@ -1171,7 +1185,7 @@ isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
skb->mac.raw = skb->data;
isdn_dumppkt("R:", skb->data, skb->len, 40);
lp->receive(lp->netdev, olp, skb);
lp->ops->receive(lp->netdev, olp, skb);
}
/*
......@@ -1698,7 +1712,7 @@ static int
isdn_net_set_encap(isdn_net_dev *p, isdn_net_ioctl_cfg *cfg)
{
isdn_net_local *lp = &p->local;
int retval;
int retval = 0;
if (lp->p_encap == cfg->p_encap){
/* nothing to do */
......@@ -1715,35 +1729,21 @@ isdn_net_set_encap(isdn_net_dev *p, isdn_net_ioctl_cfg *cfg)
break;
}
lp->p_encap = cfg->p_encap;
switch (lp->p_encap) {
case ISDN_NET_ENCAP_SYNCPPP:
retval = isdn_ppp_setup(p);
break;
case ISDN_NET_ENCAP_X25IFACE:
retval = isdn_x25_setup(p, cfg->p_encap);
break;
case ISDN_NET_ENCAP_CISCOHDLC:
case ISDN_NET_ENCAP_CISCOHDLCK:
retval = isdn_ciscohdlck_setup(p);
break;
case ISDN_NET_ENCAP_RAWIP:
retval = isdn_rawip_setup(p);
break;
case ISDN_NET_ENCAP_ETHER:
retval = isdn_ether_setup(p);
break;
case ISDN_NET_ENCAP_UIHDLC:
retval = isdn_uihdlc_setup(p);
break;
case ISDN_NET_ENCAP_IPTYP:
retval = isdn_iptyp_setup(p);
break;
default:
if (cfg->p_encap < 0 || cfg->p_encap >= ISDN_NET_ENCAP_NR) {
lp->p_encap = -1;
lp->ops = NULL;
retval = -EINVAL;
break;
goto out;
}
p->dev.hard_header = lp->ops->hard_header;
p->dev.rebuild_header = lp->ops->rebuild_header;
p->dev.do_ioctl = lp->ops->do_ioctl;
p->dev.hard_header_cache = lp->ops->hard_header_cache;
p->dev.header_cache_update = lp->ops->header_cache_update;
lp->p_encap = cfg->p_encap;
lp->ops = netif_ops[lp->p_encap];
if (retval != 0)
lp->p_encap = -1;
......@@ -2268,19 +2268,12 @@ isdn_iptyp_receive(isdn_net_dev *p, isdn_net_local *olp,
netif_rx(skb);
}
static int
isdn_iptyp_setup(isdn_net_dev *p)
{
p->dev.hard_header = isdn_iptyp_header;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
p->local.receive = isdn_iptyp_receive;
p->local.connected = isdn_net_device_wake_queue;
p->local.disconnected = NULL;
return 0;
}
static struct isdn_netif_ops iptyp_ops = {
.hard_header = isdn_iptyp_header,
.flags = IFF_NOARP | IFF_POINTOPOINT,
.addr_len = 2,
.receive = isdn_iptyp_receive,
};
// ISDN_NET_ENCAP_UIHDLC
// HDLC with UI-Frames (for ispa with -h1 option) */
......@@ -2307,19 +2300,12 @@ isdn_uihdlc_receive(isdn_net_dev *p, isdn_net_local *olp,
netif_rx(skb);
}
static int
isdn_uihdlc_setup(isdn_net_dev *p)
{
p->dev.hard_header = isdn_uihdlc_header;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
p->local.receive = isdn_uihdlc_receive;
p->local.connected = isdn_net_device_wake_queue;
p->local.disconnected = NULL;
return 0;
}
static struct isdn_netif_ops uihdlc_ops = {
.hard_header = isdn_uihdlc_header,
.flags = IFF_NOARP | IFF_POINTOPOINT,
.addr_len = 2,
.receive = isdn_uihdlc_receive,
};
// ISDN_NET_ENCAP_RAWIP
// RAW-IP without MAC-Header
......@@ -2336,19 +2322,10 @@ isdn_rawip_receive(isdn_net_dev *p, isdn_net_local *olp,
netif_rx(skb);
}
static int
isdn_rawip_setup(isdn_net_dev *p)
{
p->dev.hard_header = NULL;
p->dev.hard_header_cache = NULL;
p->dev.header_cache_update = NULL;
p->dev.flags = IFF_NOARP|IFF_POINTOPOINT;
p->local.receive = isdn_rawip_receive;
p->local.connected = isdn_net_device_wake_queue;
p->local.disconnected = NULL;
return 0;
}
static struct isdn_netif_ops rawip_ops = {
.flags = IFF_NOARP | IFF_POINTOPOINT,
.receive = isdn_rawip_receive,
};
// ISDN_NET_ENCAP_ETHER
// Ethernet over ISDN
......@@ -2419,17 +2396,32 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp,
netif_rx(skb);
}
static int
isdn_ether_setup(isdn_net_dev *p)
{
p->dev.hard_header = eth_header;
p->dev.hard_header_cache = eth_header_cache;
p->dev.header_cache_update = eth_header_cache_update;
p->dev.rebuild_header = eth_rebuild_header;
p->dev.flags = IFF_BROADCAST | IFF_MULTICAST;
p->local.receive = isdn_ether_receive;
p->local.connected = isdn_net_device_wake_queue;
p->local.disconnected = NULL;
static struct isdn_netif_ops ether_ops = {
.hard_header = eth_header,
.hard_header_cache = eth_header_cache,
.header_cache_update = eth_header_cache_update,
.rebuild_header = eth_rebuild_header,
.flags = IFF_BROADCAST | IFF_MULTICAST,
.type = ARPHRD_ETHER,
.addr_len = ETH_ALEN,
.receive = isdn_ether_receive,
};
return 0;
// ======================================================================
void
isdn_net_init_module(void)
{
register_isdn_netif(ISDN_NET_ENCAP_ETHER, &ether_ops);
register_isdn_netif(ISDN_NET_ENCAP_RAWIP, &rawip_ops);
register_isdn_netif(ISDN_NET_ENCAP_IPTYP, &iptyp_ops);
register_isdn_netif(ISDN_NET_ENCAP_UIHDLC, &uihdlc_ops);
register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLC, &ciscohdlck_ops);
register_isdn_netif(ISDN_NET_ENCAP_CISCOHDLCK, &ciscohdlck_ops);
#ifdef CONFIG_ISDN_X25
register_isdn_netif(ISDN_NET_ENCAP_X25IFACE, &isdn_x25_ops);
#endif
#ifdef CONFIG_ISDN_PPP
register_isdn_netif(ISDN_NET_ENCAP_SYNCPPP, &isdn_ppp_ops);
#endif
}
......@@ -32,6 +32,8 @@
#define CISCO_SLARP_REPLY 1
#define CISCO_SLARP_KEEPALIVE 2
extern void isdn_net_init_module(void);
extern int isdn_net_new(char *, struct net_device *);
extern int isdn_net_newslave(char *);
extern int isdn_net_rm(char *);
......
......@@ -2913,22 +2913,14 @@ isdn_ppp_header(struct sk_buff *skb, struct net_device *dev,
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.bind = isdn_ppp_bind;
p->local.unbind = isdn_ppp_free;
return 0;
}
struct isdn_netif_ops isdn_ppp_ops = {
.hard_header = isdn_ppp_header,
.do_ioctl = isdn_ppp_dev_ioctl,
.flags = IFF_NOARP | IFF_POINTOPOINT,
.type = ARPHRD_PPP,
.receive = isdn_ppp_receive,
.connected = isdn_ppp_wakeup_daemon,
.bind = isdn_ppp_bind,
.unbind = isdn_ppp_free,
};
......@@ -13,6 +13,7 @@
#include <linux/isdn_ppp.h> /* for isdn_ppp info */
extern struct file_operations isdn_ppp_fops;
extern struct isdn_netif_ops isdn_ppp_ops;
extern int isdn_ppp_init(void);
extern void isdn_ppp_cleanup(void);
......@@ -21,25 +22,10 @@ extern int isdn_ppp_hangup_slave(char *);
#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 *);
{
......
......@@ -75,6 +75,7 @@
#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_NR 8
/* Facility which currently uses an ISDN-channel */
#define ISDN_USAGE_NONE 0
......@@ -277,6 +278,36 @@ struct isdn_net_phone {
which holds the linux device structure (here: isdn_net_device)
*/
struct isdn_net_dev_s;
struct isdn_net_local_s;
struct isdn_netif_ops {
int (*hard_header) (struct sk_buff *skb,
struct net_device *dev,
unsigned short type,
void *daddr,
void *saddr,
unsigned len);
int (*rebuild_header)(struct sk_buff *skb);
int (*do_ioctl)(struct net_device *dev,
struct ifreq *ifr, int cmd);
int (*hard_header_cache)(struct neighbour *neigh,
struct hh_cache *hh);
void (*header_cache_update)(struct hh_cache *hh,
struct net_device *dev,
unsigned char * haddr);
unsigned short flags; /* interface flags (a la BSD) */
unsigned short type; /* interface hardware type */
unsigned char addr_len;/* hardware address length */
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);
int (*bind)(struct isdn_net_local_s *lp);
void (*unbind)(struct isdn_net_local_s *lp);
};
/* Local interface-data */
typedef struct isdn_net_local_s {
spinlock_t lock;
......@@ -370,13 +401,7 @@ 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);
int (*bind)(struct isdn_net_local_s *lp);
void (*unbind)(struct isdn_net_local_s *lp);
struct isdn_netif_ops *ops;
} isdn_net_local;
/* the interface itself */
......
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