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