Commit 1a5f681b authored by Kai Germaschewski's avatar Kai Germaschewski

ISDN: Add close()/open() callbacks to ISDN net interface implementation

X25 needs notification if an interface is brought up or down, and
ethernet over ISDN creates a fake MAC address at open time, so put this
into appropriate callbacks as well.
parent f789f058
...@@ -107,12 +107,12 @@ struct concap_proto * isdn_concap_new( int encap ) ...@@ -107,12 +107,12 @@ struct concap_proto * isdn_concap_new( int encap )
return NULL; return NULL;
} }
void isdn_x25_open(struct net_device *dev) static int
isdn_x25_open(isdn_net_local *lp)
{ {
struct concap_proto * cprot = struct net_device * dev = & lp -> netdev -> dev;
( (isdn_net_local *) dev->priv ) -> netdev -> cprot; struct concap_proto * cprot = lp -> netdev -> cprot;
struct concap_proto * dops = struct concap_proto * dops = lp -> dops;
( (isdn_net_local *) dev->priv ) -> dops;
unsigned long flags; unsigned long flags;
save_flags(flags); save_flags(flags);
...@@ -120,17 +120,19 @@ void isdn_x25_open(struct net_device *dev) ...@@ -120,17 +120,19 @@ void isdn_x25_open(struct net_device *dev)
if( cprot -> pops && dops ) if( cprot -> pops && dops )
cprot -> pops -> restart ( cprot, dev, dops ); cprot -> pops -> restart ( cprot, dev, dops );
restore_flags(flags); restore_flags(flags);
return 0;
} }
void isdn_x25_close(struct net_device *dev) static void
isdn_x25_close(isdn_net_local *lp)
{ {
struct concap_proto * cprot = struct concap_proto * cprot = lp -> netdev -> cprot;
( (isdn_net_local *) dev->priv ) -> netdev -> cprot;
if( cprot && cprot -> pops ) cprot -> pops -> close( cprot ); if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
} }
static void isdn_x25_connected(isdn_net_local *lp) static void
isdn_x25_connected(isdn_net_local *lp)
{ {
struct concap_proto *cprot = lp -> netdev -> cprot; struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
...@@ -143,7 +145,8 @@ static void isdn_x25_connected(isdn_net_local *lp) ...@@ -143,7 +145,8 @@ static void isdn_x25_connected(isdn_net_local *lp)
isdn_net_device_wake_queue(lp); isdn_net_device_wake_queue(lp);
} }
static void isdn_x25_disconnected(isdn_net_local *lp) static void
isdn_x25_disconnected(isdn_net_local *lp)
{ {
struct concap_proto *cprot = lp -> netdev -> cprot; struct concap_proto *cprot = lp -> netdev -> cprot;
struct concap_proto_ops *pops = cprot ? cprot -> pops : 0; struct concap_proto_ops *pops = cprot ? cprot -> pops : 0;
...@@ -155,7 +158,8 @@ static void isdn_x25_disconnected(isdn_net_local *lp) ...@@ -155,7 +158,8 @@ static void isdn_x25_disconnected(isdn_net_local *lp)
pops -> disconn_ind(cprot); pops -> disconn_ind(cprot);
} }
int isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev) int
isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
/* At this point hard_start_xmit() passes control to the encapsulation /* At this point hard_start_xmit() passes control to the encapsulation
protocol (if present). protocol (if present).
...@@ -247,6 +251,8 @@ struct isdn_netif_ops isdn_x25_ops = { ...@@ -247,6 +251,8 @@ struct isdn_netif_ops isdn_x25_ops = {
.disconnected = isdn_x25_disconnected, .disconnected = isdn_x25_disconnected,
.init = isdn_x25_init, .init = isdn_x25_init,
.cleanup = isdn_x25_cleanup, .cleanup = isdn_x25_cleanup,
.open = isdn_x25_open,
.close = isdn_x25_close,
}; };
#endif /* CONFIG_ISDN_X25 */ #endif /* CONFIG_ISDN_X25 */
...@@ -16,22 +16,10 @@ struct concap_proto *isdn_concap_new(int); ...@@ -16,22 +16,10 @@ struct concap_proto *isdn_concap_new(int);
extern struct isdn_netif_ops isdn_x25_ops; extern struct isdn_netif_ops isdn_x25_ops;
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); int isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev);
#else #else
static inline void
isdn_x25_open(struct net_device *dev)
{
}
static inline void
isdn_x25_close(struct net_device *dev)
{
}
static inline int static inline int
isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev) isdn_x25_start_xmit(struct sk_buff *skb, struct net_device *dev)
{ {
......
...@@ -232,36 +232,19 @@ isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason) ...@@ -232,36 +232,19 @@ isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
static int static int
isdn_net_open(struct net_device *dev) isdn_net_open(struct net_device *dev)
{ {
int i; isdn_net_local *lp = dev->priv;
struct net_device *p; int retval = 0;
struct in_device *in_dev;
/* moved here from isdn_net_reset, because only the master has an if (!lp->ops)
interface associated which is supposed to be started. BTW: return -ENODEV;
we need to call netif_start_queue, not netif_wake_queue here */
netif_start_queue(dev);
isdn_x25_open(dev); if (lp->ops->open)
/* Fill in the MAC-level header (not needed, but for compatibility... */ retval = lp->ops->open(lp);
for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
dev->dev_addr[i] = 0xfc;
if ((in_dev = dev->ip_ptr) != NULL) {
/*
* Any address will do - we take the first
*/
struct in_ifaddr *ifa = in_dev->ifa_list;
if (ifa != NULL)
memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
}
/* If this interface has slaves, start them also */ if (!retval)
return retval;
if ((p = (((isdn_net_local *) dev->priv)->slave))) { netif_start_queue(dev);
while (p) {
isdn_x25_open(p);
p = (((isdn_net_local *) p->priv)->slave);
}
}
isdn_MOD_INC_USE_COUNT(); isdn_MOD_INC_USE_COUNT();
return 0; return 0;
} }
...@@ -1132,17 +1115,16 @@ static int ...@@ -1132,17 +1115,16 @@ static int
isdn_net_close(struct net_device *dev) isdn_net_close(struct net_device *dev)
{ {
struct net_device *p; struct net_device *p;
isdn_net_local *lp = dev->priv;
if (lp->ops->close)
lp->ops->close(lp);
isdn_x25_close(dev);
netif_stop_queue(dev); netif_stop_queue(dev);
if ((p = (((isdn_net_local *) dev->priv)->slave))) {
/* If this interface has slaves, stop them also */ for (p = lp->slave; p; p = ((isdn_net_local *) p->priv)->slave)
while (p) {
isdn_x25_close(p);
isdn_net_hangup(p->priv); isdn_net_hangup(p->priv);
p = (((isdn_net_local *) p->priv)->slave);
}
}
isdn_net_hangup(dev->priv); isdn_net_hangup(dev->priv);
isdn_MOD_DEC_USE_COUNT(); isdn_MOD_DEC_USE_COUNT();
return 0; return 0;
...@@ -2372,6 +2354,26 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp, ...@@ -2372,6 +2354,26 @@ isdn_ether_receive(isdn_net_dev *p, isdn_net_local *olp,
netif_rx(skb); netif_rx(skb);
} }
static int
isdn_ether_open(isdn_net_local *lp)
{
struct net_device *dev = &lp->netdev->dev;
struct in_device *in_dev;
int i;
/* Fill in the MAC-level header ... */
for (i = 0; i < ETH_ALEN; i++)
dev->dev_addr[i] = 0xfc;
in_dev = dev->ip_ptr;
if (in_dev) {
/* any address will do - we take the first */
struct in_ifaddr *ifa = in_dev->ifa_list;
if (ifa)
memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
}
return 0;
}
static int static int
isdn_ether_init(isdn_net_local *lp) isdn_ether_init(isdn_net_local *lp)
{ {
...@@ -2388,6 +2390,7 @@ static struct isdn_netif_ops ether_ops = { ...@@ -2388,6 +2390,7 @@ static struct isdn_netif_ops ether_ops = {
.hard_header = eth_header, .hard_header = eth_header,
.receive = isdn_ether_receive, .receive = isdn_ether_receive,
.init = isdn_ether_init, .init = isdn_ether_init,
.open = isdn_ether_open,
}; };
// ====================================================================== // ======================================================================
......
...@@ -303,6 +303,8 @@ struct isdn_netif_ops { ...@@ -303,6 +303,8 @@ struct isdn_netif_ops {
void (*unbind)(struct isdn_net_local_s *lp); void (*unbind)(struct isdn_net_local_s *lp);
int (*init)(struct isdn_net_local_s *lp); int (*init)(struct isdn_net_local_s *lp);
void (*cleanup)(struct isdn_net_local_s *lp); void (*cleanup)(struct isdn_net_local_s *lp);
int (*open)(struct isdn_net_local_s *lp);
void (*close)(struct isdn_net_local_s *lp);
}; };
/* Local interface-data */ /* Local interface-data */
......
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