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