125763b3cSThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
21da177e4SLinus Torvalds /*
31da177e4SLinus Torvalds * Generic HDLC support routines for Linux
41da177e4SLinus Torvalds *
5b3dd65f9SKrzysztof Halasa * Copyright (C) 1999-2005 Krzysztof Halasa <[email protected]>
61da177e4SLinus Torvalds */
71da177e4SLinus Torvalds #ifndef __HDLC_H
81da177e4SLinus Torvalds #define __HDLC_H
91da177e4SLinus Torvalds
101da177e4SLinus Torvalds
111da177e4SLinus Torvalds #include <linux/skbuff.h>
121da177e4SLinus Torvalds #include <linux/netdevice.h>
131da177e4SLinus Torvalds #include <linux/hdlc/ioctl.h>
14607ca46eSDavid Howells #include <uapi/linux/hdlc.h>
151da177e4SLinus Torvalds
16eb2a2fd9SKrzysztof Halasa /* This structure is a private property of HDLC protocols.
17eb2a2fd9SKrzysztof Halasa Hardware drivers have no interest here */
18eb2a2fd9SKrzysztof Halasa
19eb2a2fd9SKrzysztof Halasa struct hdlc_proto {
20eb2a2fd9SKrzysztof Halasa int (*open)(struct net_device *dev);
21eb2a2fd9SKrzysztof Halasa void (*close)(struct net_device *dev);
22eb2a2fd9SKrzysztof Halasa void (*start)(struct net_device *dev); /* if open & DCD */
23eb2a2fd9SKrzysztof Halasa void (*stop)(struct net_device *dev); /* if open & !DCD */
24eb2a2fd9SKrzysztof Halasa void (*detach)(struct net_device *dev);
25*ad7eab2aSArnd Bergmann int (*ioctl)(struct net_device *dev, struct if_settings *ifs);
26abf17ffdSKrzysztof Halasa __be16 (*type_trans)(struct sk_buff *skb, struct net_device *dev);
2740d25142SKrzysztof Halasa int (*netif_rx)(struct sk_buff *skb);
284c5d502dSStephen Hemminger netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
29eb2a2fd9SKrzysztof Halasa struct module *module;
30eb2a2fd9SKrzysztof Halasa struct hdlc_proto *next; /* next protocol in the list */
31eb2a2fd9SKrzysztof Halasa };
32eb2a2fd9SKrzysztof Halasa
33eb2a2fd9SKrzysztof Halasa
34b74ca3a8SWang Chen /* Pointed to by netdev_priv(dev) */
35eb2a2fd9SKrzysztof Halasa typedef struct hdlc_device {
361da177e4SLinus Torvalds /* used by HDLC layer to take control over HDLC device from hw driver*/
371da177e4SLinus Torvalds int (*attach)(struct net_device *dev,
381da177e4SLinus Torvalds unsigned short encoding, unsigned short parity);
391da177e4SLinus Torvalds
401da177e4SLinus Torvalds /* hardware driver must handle this instead of dev->hard_start_xmit */
414c5d502dSStephen Hemminger netdev_tx_t (*xmit)(struct sk_buff *skb, struct net_device *dev);
421da177e4SLinus Torvalds
431da177e4SLinus Torvalds /* Things below are for HDLC layer internal use only */
44eb2a2fd9SKrzysztof Halasa const struct hdlc_proto *proto;
451da177e4SLinus Torvalds int carrier;
461da177e4SLinus Torvalds int open;
471da177e4SLinus Torvalds spinlock_t state_lock;
48eb2a2fd9SKrzysztof Halasa void *state;
491da177e4SLinus Torvalds void *priv;
501da177e4SLinus Torvalds } hdlc_device;
511da177e4SLinus Torvalds
521da177e4SLinus Torvalds
531da177e4SLinus Torvalds
54eb2a2fd9SKrzysztof Halasa /* Exported from hdlc module */
551da177e4SLinus Torvalds
561da177e4SLinus Torvalds /* Called by hardware driver when a user requests HDLC service */
57*ad7eab2aSArnd Bergmann int hdlc_ioctl(struct net_device *dev, struct if_settings *ifs);
581da177e4SLinus Torvalds
591da177e4SLinus Torvalds /* Must be used by hardware driver on module startup/exit */
604a31e348SKrzysztof Halasa #define register_hdlc_device(dev) register_netdev(dev)
611da177e4SLinus Torvalds void unregister_hdlc_device(struct net_device *dev);
621da177e4SLinus Torvalds
63eb2a2fd9SKrzysztof Halasa
64eb2a2fd9SKrzysztof Halasa void register_hdlc_protocol(struct hdlc_proto *proto);
65eb2a2fd9SKrzysztof Halasa void unregister_hdlc_protocol(struct hdlc_proto *proto);
66eb2a2fd9SKrzysztof Halasa
671da177e4SLinus Torvalds struct net_device *alloc_hdlcdev(void *priv);
681da177e4SLinus Torvalds
dev_to_hdlc(struct net_device * dev)6940d25142SKrzysztof Halasa static inline struct hdlc_device* dev_to_hdlc(struct net_device *dev)
701da177e4SLinus Torvalds {
712baf8a2dSWang Chen return netdev_priv(dev);
721da177e4SLinus Torvalds }
731da177e4SLinus Torvalds
debug_frame(const struct sk_buff * skb)741da177e4SLinus Torvalds static __inline__ void debug_frame(const struct sk_buff *skb)
751da177e4SLinus Torvalds {
761da177e4SLinus Torvalds int i;
771da177e4SLinus Torvalds
781da177e4SLinus Torvalds for (i=0; i < skb->len; i++) {
791da177e4SLinus Torvalds if (i == 100) {
801da177e4SLinus Torvalds printk("...\n");
811da177e4SLinus Torvalds return;
821da177e4SLinus Torvalds }
831da177e4SLinus Torvalds printk(" %02X", skb->data[i]);
841da177e4SLinus Torvalds }
851da177e4SLinus Torvalds printk("\n");
861da177e4SLinus Torvalds }
871da177e4SLinus Torvalds
881da177e4SLinus Torvalds
891da177e4SLinus Torvalds /* Must be called by hardware driver when HDLC device is being opened */
901da177e4SLinus Torvalds int hdlc_open(struct net_device *dev);
911da177e4SLinus Torvalds /* Must be called by hardware driver when HDLC device is being closed */
921da177e4SLinus Torvalds void hdlc_close(struct net_device *dev);
93991990a1SKrzysztof Hałasa /* Must be pointed to by hw driver's dev->netdev_ops->ndo_start_xmit */
944c5d502dSStephen Hemminger netdev_tx_t hdlc_start_xmit(struct sk_buff *skb, struct net_device *dev);
951da177e4SLinus Torvalds
96eb2a2fd9SKrzysztof Halasa int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
9740d25142SKrzysztof Halasa size_t size);
981da177e4SLinus Torvalds /* May be used by hardware driver to gain control over HDLC device */
992f8364a2SAndrew Lunn int detach_hdlc_protocol(struct net_device *dev);
1001da177e4SLinus Torvalds
hdlc_type_trans(struct sk_buff * skb,struct net_device * dev)101ab611487SAlexey Dobriyan static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
1021da177e4SLinus Torvalds struct net_device *dev)
1031da177e4SLinus Torvalds {
1041da177e4SLinus Torvalds hdlc_device *hdlc = dev_to_hdlc(dev);
1051da177e4SLinus Torvalds
1061da177e4SLinus Torvalds skb->dev = dev;
107459a98edSArnaldo Carvalho de Melo skb_reset_mac_header(skb);
1081da177e4SLinus Torvalds
109eb2a2fd9SKrzysztof Halasa if (hdlc->proto->type_trans)
110eb2a2fd9SKrzysztof Halasa return hdlc->proto->type_trans(skb, dev);
1111da177e4SLinus Torvalds else
1121da177e4SLinus Torvalds return htons(ETH_P_HDLC);
1131da177e4SLinus Torvalds }
1141da177e4SLinus Torvalds
1151da177e4SLinus Torvalds #endif /* __HDLC_H */
116