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