^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Generic HDLC support routines for Linux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (C) 1999 - 2008 Krzysztof Halasa <khc@pm.waw.pl>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Currently supported:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * * raw IP-in-HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * * Cisco HDLC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * * Frame Relay with ANSI or CCITT LMI (both user and network side)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * * PPP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * * X.25
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Use sethdlc utility to set line parameters, protocol and PVCs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * How does it work:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * - proto->open(), close(), start(), stop() calls are serialized.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * The order is: open, [ start, stop ... ] close ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * - proto->start() and stop() are called with spin_lock_irq held.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #include <linux/hdlc.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/inetdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/notifier.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/pkt_sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/poll.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/rtnetlink.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/skbuff.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) static const char* version = "HDLC support module revision 1.22";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #undef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) static struct hdlc_proto *first_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) struct packet_type *p, struct net_device *orig_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) struct hdlc_device *hdlc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /* First make sure "dev" is an HDLC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) if (!(dev->priv_flags & IFF_WAN_HDLC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) return NET_RX_SUCCESS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) if (!net_eq(dev_net(dev), &init_net)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) BUG_ON(!hdlc->proto->netif_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) return hdlc->proto->netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (hdlc->proto->xmit)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) return hdlc->proto->xmit(skb, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return hdlc->xmit(skb, dev); /* call hardware driver directly */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) static inline void hdlc_proto_start(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) if (hdlc->proto->start)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) hdlc->proto->start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) static inline void hdlc_proto_stop(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) if (hdlc->proto->stop)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) hdlc->proto->stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) static int hdlc_device_event(struct notifier_block *this, unsigned long event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) void *ptr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) struct net_device *dev = netdev_notifier_info_to_dev(ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) hdlc_device *hdlc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) int on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) if (!net_eq(dev_net(dev), &init_net))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) if (!(dev->priv_flags & IFF_WAN_HDLC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) return NOTIFY_DONE; /* not an HDLC device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if (event != NETDEV_CHANGE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return NOTIFY_DONE; /* Only interested in carrier changes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) on = netif_carrier_ok(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) #ifdef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) printk(KERN_DEBUG "%s: hdlc_device_event NETDEV_CHANGE, carrier %i\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dev->name, on);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) spin_lock_irqsave(&hdlc->state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) if (hdlc->carrier == on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) goto carrier_exit; /* no change in DCD line level */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) hdlc->carrier = on;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!hdlc->open)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) goto carrier_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) if (hdlc->carrier) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) netdev_info(dev, "Carrier detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) hdlc_proto_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) netdev_info(dev, "Carrier lost\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) hdlc_proto_stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) carrier_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) spin_unlock_irqrestore(&hdlc->state_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) return NOTIFY_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) /* Must be called by hardware driver when HDLC device is being opened */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) int hdlc_open(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) #ifdef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) hdlc->carrier, hdlc->open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) if (hdlc->proto == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return -ENOSYS; /* no protocol attached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) if (hdlc->proto->open) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) int result = hdlc->proto->open(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) if (result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) spin_lock_irq(&hdlc->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) if (hdlc->carrier) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) netdev_info(dev, "Carrier detected\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) hdlc_proto_start(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) netdev_info(dev, "No carrier\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) hdlc->open = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) spin_unlock_irq(&hdlc->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* Must be called by hardware driver when HDLC device is being closed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) void hdlc_close(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) #ifdef DEBUG_LINK
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) hdlc->carrier, hdlc->open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) spin_lock_irq(&hdlc->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) hdlc->open = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) if (hdlc->carrier)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) hdlc_proto_stop(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) spin_unlock_irq(&hdlc->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) if (hdlc->proto->close)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) hdlc->proto->close(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct hdlc_proto *proto = first_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (cmd != SIOCWANDEV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) if (dev_to_hdlc(dev)->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) if (result != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* Not handled by currently attached protocol (if any) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) while (proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) if ((result = proto->ioctl(dev, ifr)) != -EINVAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) proto = proto->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) static const struct header_ops hdlc_null_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) static void hdlc_setup_dev(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* Re-init all variables changed by HDLC protocol drivers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) * including ether_setup() called from hdlc_raw_eth.c.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) dev->flags = IFF_POINTOPOINT | IFF_NOARP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) dev->priv_flags = IFF_WAN_HDLC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) dev->mtu = HDLC_MAX_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) dev->min_mtu = 68;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) dev->max_mtu = HDLC_MAX_MTU;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) dev->type = ARPHRD_RAWHDLC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) dev->hard_header_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) dev->needed_headroom = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) dev->addr_len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) dev->header_ops = &hdlc_null_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) static void hdlc_setup(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) hdlc_setup_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) hdlc->carrier = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) hdlc->open = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) spin_lock_init(&hdlc->state_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) struct net_device *alloc_hdlcdev(void *priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) struct net_device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) dev = alloc_netdev(sizeof(struct hdlc_device), "hdlc%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) NET_NAME_UNKNOWN, hdlc_setup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) if (dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) dev_to_hdlc(dev)->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) return dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) void unregister_hdlc_device(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) detach_hdlc_protocol(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) unregister_netdevice(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) err = detach_hdlc_protocol(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) if (!try_module_get(proto->module))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return -ENOSYS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) if (size) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) dev_to_hdlc(dev)->state = kmalloc(size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) if (dev_to_hdlc(dev)->state == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) module_put(proto->module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) return -ENOBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) dev_to_hdlc(dev)->proto = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) int detach_hdlc_protocol(struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) hdlc_device *hdlc = dev_to_hdlc(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (hdlc->proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) err = call_netdevice_notifiers(NETDEV_PRE_TYPE_CHANGE, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) err = notifier_to_errno(err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) netdev_err(dev, "Refused to change device type\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (hdlc->proto->detach)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) hdlc->proto->detach(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) module_put(hdlc->proto->module);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) hdlc->proto = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) kfree(hdlc->state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) hdlc->state = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) hdlc_setup_dev(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) void register_hdlc_protocol(struct hdlc_proto *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) proto->next = first_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) first_proto = proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) void unregister_hdlc_protocol(struct hdlc_proto *proto)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) struct hdlc_proto **p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) rtnl_lock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) p = &first_proto;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) while (*p != proto) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) BUG_ON(!*p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) p = &((*p)->next);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) *p = proto->next;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) rtnl_unlock();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) MODULE_DESCRIPTION("HDLC support module");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) MODULE_LICENSE("GPL v2");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) EXPORT_SYMBOL(hdlc_start_xmit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) EXPORT_SYMBOL(hdlc_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) EXPORT_SYMBOL(hdlc_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) EXPORT_SYMBOL(hdlc_ioctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) EXPORT_SYMBOL(alloc_hdlcdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) EXPORT_SYMBOL(unregister_hdlc_device);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) EXPORT_SYMBOL(register_hdlc_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) EXPORT_SYMBOL(unregister_hdlc_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) EXPORT_SYMBOL(attach_hdlc_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) EXPORT_SYMBOL(detach_hdlc_protocol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) static struct packet_type hdlc_packet_type __read_mostly = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) .type = cpu_to_be16(ETH_P_HDLC),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) .func = hdlc_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) static struct notifier_block hdlc_notifier = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) .notifier_call = hdlc_device_event,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) static int __init hdlc_module_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) pr_info("%s\n", version);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) if ((result = register_netdevice_notifier(&hdlc_notifier)) != 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) dev_add_pack(&hdlc_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) static void __exit hdlc_module_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) dev_remove_pack(&hdlc_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) unregister_netdevice_notifier(&hdlc_notifier);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) module_init(hdlc_module_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) module_exit(hdlc_module_exit);