* - proto.start() and stop() are called with spin_lock_irq held.
*/
+#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/inetdevice.h>
#include <linux/lapb.h>
#include <linux/rtnetlink.h>
-#include <linux/notifier.h>
#include <linux/hdlc.h>
-static const char* version = "HDLC support module revision 1.19";
+static const char* version = "HDLC support module revision 1.18";
#undef DEBUG_LINK
-static inline void hdlc_proto_start(struct net_device *dev)
+static void __hdlc_set_carrier_on(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
if (hdlc->proto.start)
return hdlc->proto.start(dev);
+#if 0
+#ifdef DEBUG_LINK
+ if (netif_carrier_ok(dev))
+ printk(KERN_ERR "hdlc_set_carrier_on(): already on\n");
+#endif
+ netif_carrier_on(dev);
+#endif
}
-static inline void hdlc_proto_stop(struct net_device *dev)
+static void __hdlc_set_carrier_off(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
if (hdlc->proto.stop)
return hdlc->proto.stop(dev);
+
+#if 0
+#ifdef DEBUG_LINK
+ if (!netif_carrier_ok(dev))
+ printk(KERN_ERR "hdlc_set_carrier_off(): already off\n");
+#endif
+ netif_carrier_off(dev);
+#endif
}
-static int hdlc_device_event(struct notifier_block *this, unsigned long event,
- void *ptr)
+void hdlc_set_carrier(int on, struct net_device *dev)
{
- struct net_device *dev = ptr;
- hdlc_device *hdlc;
+ hdlc_device *hdlc = dev_to_hdlc(dev);
unsigned long flags;
- int on;
-
- if (dev->get_stats != hdlc_get_stats)
- return NOTIFY_DONE; /* not an HDLC device */
-
- if (event != NETDEV_CHANGE)
- return NOTIFY_DONE; /* Only interrested in carrier changes */
-
- on = netif_carrier_ok(dev);
+ on = on ? 1 : 0;
#ifdef DEBUG_LINK
- printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n",
- dev->name, on);
+ printk(KERN_DEBUG "hdlc_set_carrier %i\n", on);
#endif
- hdlc = dev_to_hdlc(dev);
spin_lock_irqsave(&hdlc->state_lock, flags);
if (hdlc->carrier == on)
goto carrier_exit; /* no change in DCD line level */
+#ifdef DEBUG_LINK
+ printk(KERN_INFO "%s: carrier %s\n", dev->name, on ? "ON" : "off");
+#endif
hdlc->carrier = on;
if (!hdlc->open)
if (hdlc->carrier) {
printk(KERN_INFO "%s: Carrier detected\n", dev->name);
- hdlc_proto_start(dev);
+ __hdlc_set_carrier_on(dev);
} else {
printk(KERN_INFO "%s: Carrier lost\n", dev->name);
- hdlc_proto_stop(dev);
+ __hdlc_set_carrier_off(dev);
}
carrier_exit:
spin_unlock_irqrestore(&hdlc->state_lock, flags);
- return NOTIFY_DONE;
}
if (hdlc->carrier) {
printk(KERN_INFO "%s: Carrier detected\n", dev->name);
- hdlc_proto_start(dev);
+ __hdlc_set_carrier_on(dev);
} else
printk(KERN_INFO "%s: No carrier\n", dev->name);
hdlc->open = 0;
if (hdlc->carrier)
- hdlc_proto_stop(dev);
+ __hdlc_set_carrier_off(dev);
spin_unlock_irq(&hdlc->state_lock);
}
}
-void hdlc_setup(struct net_device *dev)
+static void hdlc_setup(struct net_device *dev)
{
hdlc_device *hdlc = dev_to_hdlc(dev);
return dev;
}
+int register_hdlc_device(struct net_device *dev)
+{
+ int result = dev_alloc_name(dev, "hdlc%d");
+ if (result < 0)
+ return result;
+
+ result = register_netdev(dev);
+ if (result != 0)
+ return -EIO;
+
+#if 0
+ if (netif_carrier_ok(dev))
+ netif_carrier_off(dev); /* no carrier until DCD goes up */
+#endif
+
+ return 0;
+}
+
+
+
void unregister_hdlc_device(struct net_device *dev)
{
rtnl_lock();
EXPORT_SYMBOL(hdlc_open);
EXPORT_SYMBOL(hdlc_close);
+EXPORT_SYMBOL(hdlc_set_carrier);
EXPORT_SYMBOL(hdlc_ioctl);
-EXPORT_SYMBOL(hdlc_setup);
EXPORT_SYMBOL(alloc_hdlcdev);
+EXPORT_SYMBOL(register_hdlc_device);
EXPORT_SYMBOL(unregister_hdlc_device);
static struct packet_type hdlc_packet_type = {
};
-static struct notifier_block hdlc_notifier = {
- .notifier_call = hdlc_device_event,
-};
-
-
static int __init hdlc_module_init(void)
{
- int result;
-
printk(KERN_INFO "%s\n", version);
- if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0)
- return result;
dev_add_pack(&hdlc_packet_type);
return 0;
}
static void __exit hdlc_module_exit(void)
{
dev_remove_pack(&hdlc_packet_type);
- unregister_netdevice_notifier(&hdlc_notifier);
}