atm/br2684: register notifier event for carrier signal changes.
When a signal change event occurs call netif_carrier_on/off. Signed-off-by: Karl Hiramoto <karl@hiramoto.org> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
committed by
David S. Miller
parent
7313bb8f3d
commit
005066122b
@@ -139,6 +139,43 @@ static struct net_device *br2684_find_dev(const struct br2684_if_spec *s)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int atm_dev_event(struct notifier_block *this, unsigned long event,
|
||||||
|
void *arg)
|
||||||
|
{
|
||||||
|
struct atm_dev *atm_dev = arg;
|
||||||
|
struct list_head *lh;
|
||||||
|
struct net_device *net_dev;
|
||||||
|
struct br2684_vcc *brvcc;
|
||||||
|
struct atm_vcc *atm_vcc;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
|
pr_debug("event=%ld dev=%p\n", event, atm_dev);
|
||||||
|
|
||||||
|
read_lock_irqsave(&devs_lock, flags);
|
||||||
|
list_for_each(lh, &br2684_devs) {
|
||||||
|
net_dev = list_entry_brdev(lh);
|
||||||
|
|
||||||
|
list_for_each_entry(brvcc, &BRPRIV(net_dev)->brvccs, brvccs) {
|
||||||
|
atm_vcc = brvcc->atmvcc;
|
||||||
|
if (atm_vcc && brvcc->atmvcc->dev == atm_dev) {
|
||||||
|
|
||||||
|
if (atm_vcc->dev->signal == ATM_PHY_SIG_LOST)
|
||||||
|
netif_carrier_off(net_dev);
|
||||||
|
else
|
||||||
|
netif_carrier_on(net_dev);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
read_unlock_irqrestore(&devs_lock, flags);
|
||||||
|
|
||||||
|
return NOTIFY_DONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct notifier_block atm_dev_notifier = {
|
||||||
|
.notifier_call = atm_dev_event,
|
||||||
|
};
|
||||||
|
|
||||||
/* chained vcc->pop function. Check if we should wake the netif_queue */
|
/* chained vcc->pop function. Check if we should wake the netif_queue */
|
||||||
static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
static void br2684_pop(struct atm_vcc *vcc, struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
@@ -362,6 +399,12 @@ static void br2684_push(struct atm_vcc *atmvcc, struct sk_buff *skb)
|
|||||||
unregister_netdev(net_dev);
|
unregister_netdev(net_dev);
|
||||||
free_netdev(net_dev);
|
free_netdev(net_dev);
|
||||||
}
|
}
|
||||||
|
read_lock_irq(&devs_lock);
|
||||||
|
if (list_empty(&br2684_devs)) {
|
||||||
|
/* last br2684 device */
|
||||||
|
unregister_atmdevice_notifier(&atm_dev_notifier);
|
||||||
|
}
|
||||||
|
read_unlock_irq(&devs_lock);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -530,6 +573,13 @@ static int br2684_regvcc(struct atm_vcc *atmvcc, void __user * arg)
|
|||||||
|
|
||||||
br2684_push(atmvcc, skb);
|
br2684_push(atmvcc, skb);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* initialize netdev carrier state */
|
||||||
|
if (atmvcc->dev->signal == ATM_PHY_SIG_LOST)
|
||||||
|
netif_carrier_off(net_dev);
|
||||||
|
else
|
||||||
|
netif_carrier_on(net_dev);
|
||||||
|
|
||||||
__module_get(THIS_MODULE);
|
__module_get(THIS_MODULE);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@@ -620,9 +670,16 @@ static int br2684_create(void __user *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
write_lock_irq(&devs_lock);
|
write_lock_irq(&devs_lock);
|
||||||
|
|
||||||
brdev->payload = payload;
|
brdev->payload = payload;
|
||||||
brdev->number = list_empty(&br2684_devs) ? 1 :
|
|
||||||
BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
|
if (list_empty(&br2684_devs)) {
|
||||||
|
/* 1st br2684 device */
|
||||||
|
register_atmdevice_notifier(&atm_dev_notifier);
|
||||||
|
brdev->number = 1;
|
||||||
|
} else
|
||||||
|
brdev->number = BRPRIV(list_entry_brdev(br2684_devs.prev))->number + 1;
|
||||||
|
|
||||||
list_add_tail(&brdev->br2684_devs, &br2684_devs);
|
list_add_tail(&brdev->br2684_devs, &br2684_devs);
|
||||||
write_unlock_irq(&devs_lock);
|
write_unlock_irq(&devs_lock);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -772,6 +829,11 @@ static void __exit br2684_exit(void)
|
|||||||
remove_proc_entry("br2684", atm_proc_root);
|
remove_proc_entry("br2684", atm_proc_root);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* if not already empty */
|
||||||
|
if (!list_empty(&br2684_devs))
|
||||||
|
unregister_atmdevice_notifier(&atm_dev_notifier);
|
||||||
|
|
||||||
while (!list_empty(&br2684_devs)) {
|
while (!list_empty(&br2684_devs)) {
|
||||||
net_dev = list_entry_brdev(br2684_devs.next);
|
net_dev = list_entry_brdev(br2684_devs.next);
|
||||||
brdev = BRPRIV(net_dev);
|
brdev = BRPRIV(net_dev);
|
||||||
|
Reference in New Issue
Block a user