11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Generic HDLC support routines for Linux
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
4b3dd65f958354226275522b5a64157834bdc5415Krzysztof Halasa * Copyright (C) 1999-2005 Krzysztof Halasa <khc@pm.waw.pl>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This program is free software; you can redistribute it and/or modify it
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * under the terms of version 2 of the GNU General Public License
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * as published by the Free Software Foundation.
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifndef __HDLC_H
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __HDLC_H
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MAX_MTU 1500	/* Ethernet 1500 bytes */
16eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#if 0
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
18eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#else
19eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#define HDLC_MAX_MRU 1600 /* as required for FR network */
20eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa#endif
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef __KERNEL__
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/skbuff.h>
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netdevice.h>
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/hdlc/ioctl.h>
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
29eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa/* This structure is a private property of HDLC protocols.
30eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa   Hardware drivers have no interest here */
31eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa
32eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasastruct hdlc_proto {
33eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	int (*open)(struct net_device *dev);
34eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	void (*close)(struct net_device *dev);
35eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	void (*start)(struct net_device *dev); /* if open & DCD */
36eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	void (*stop)(struct net_device *dev); /* if open & !DCD */
37eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	void (*detach)(struct net_device *dev);
38eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
39abf17ffda7b7b6c83a29d7ccea91d46065c6ca3eKrzysztof Halasa	__be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
4040d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasa	int (*netif_rx)(struct sk_buff *skb);
414c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger	netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
42eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	struct module *module;
43eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	struct hdlc_proto *next; /* next protocol in the list */
44eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa};
45eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa
46eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa
47b74ca3a896b9ab5f952bc440154758e708c48884Wang Chen/* Pointed to by netdev_priv(dev) */
48eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasatypedef struct hdlc_device {
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* used by HDLC layer to take control over HDLC device from hw driver*/
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int (*attach)(struct net_device *dev,
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		      unsigned short encoding, unsigned short parity);
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* hardware driver must handle this instead of dev->hard_start_xmit */
544c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger	netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Things below are for HDLC layer internal use only */
57eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	const struct hdlc_proto *proto;
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int carrier;
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int open;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spinlock_t state_lock;
61eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	void *state;
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	void *priv;
634c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemminger} hdlc_device;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
67eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa/* Exported from hdlc module */
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Called by hardware driver when a user requests HDLC service */
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be used by hardware driver on module startup/exit */
734a31e348e3ecaf54c50240109ac4574b180f8840Krzysztof Halasa#define register_hdlc_device(dev)	register_netdev(dev)
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid unregister_hdlc_device(struct net_device *dev);
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
76eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa
77eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid register_hdlc_protocol(struct hdlc_proto *proto);
78eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid unregister_hdlc_protocol(struct hdlc_proto *proto);
79eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct net_device *alloc_hdlcdev(void *priv);
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8240d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasastatic inline struct hdlc_device* dev_to_hdlc(struct net_device *dev)
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
842baf8a2daab65cdd3f20bfeb4676a2f6aff7c3bfWang Chen	return netdev_priv(dev);
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic __inline__ void debug_frame(const struct sk_buff *skb)
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int i;
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	for (i=0; i < skb->len; i++) {
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (i == 100) {
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			printk("...\n");
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			return;
951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		}
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(" %02X", skb->data[i]);
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk("\n");
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be called by hardware driver when HDLC device is being opened */
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint hdlc_open(struct net_device *dev);
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Must be called by hardware driver when HDLC device is being closed */
1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid hdlc_close(struct net_device *dev);
106991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasa/* May be used by hardware driver */
107991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasaint hdlc_change_mtu(struct net_device *dev, int new_mtu);
108991990a12de42281f81b4e3a6471586d2d0caf6aKrzysztof Hałasa/* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */
1094c5d502d8b2db8947c44dc44bdc67dbe55cce2b9Stephen Hemmingernetdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);
1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
111eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasaint attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
11240d25142f2ef27084fc317ac8bb5bae460c8ea72Krzysztof Halasa			 size_t size);
1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* May be used by hardware driver to gain control over HDLC device */
114eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasavoid detach_hdlc_protocol(struct net_device *dev);
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
116ab611487d8ada506e511d2b8f22fb8e7be9939b9Alexey Dobriyanstatic __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
117ab611487d8ada506e511d2b8f22fb8e7be9939b9Alexey Dobriyan					 struct net_device *dev)
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	hdlc_device *hdlc = dev_to_hdlc(dev);
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
121459a98ed881802dee55897441bc7f77af614368eArnaldo Carvalho de Melo	skb->dev = dev;
122459a98ed881802dee55897441bc7f77af614368eArnaldo Carvalho de Melo	skb_reset_mac_header(skb);
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
124eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa	if (hdlc->proto->type_trans)
125eb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfbKrzysztof Halasa		return hdlc->proto->type_trans(skb, dev);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return htons(ETH_P_HDLC);
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __KERNEL */
1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif /* __HDLC_H */
132