2 * Generic HDLC support routines for Linux
4 * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of version 2 of the GNU General Public License
8 * as published by the Free Software Foundation.
14 #define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */
16 #define CLOCK_DEFAULT 0 /* Default setting */
17 #define CLOCK_EXT 1 /* External TX and RX clock - DTE */
18 #define CLOCK_INT 2 /* Internal TX and RX clock - DCE */
19 #define CLOCK_TXINT 3 /* Internal TX and external RX clock */
20 #define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */
23 #define ENCODING_DEFAULT 0 /* Default setting */
24 #define ENCODING_NRZ 1
25 #define ENCODING_NRZI 2
26 #define ENCODING_FM_MARK 3
27 #define ENCODING_FM_SPACE 4
28 #define ENCODING_MANCHESTER 5
31 #define PARITY_DEFAULT 0 /* Default setting */
32 #define PARITY_NONE 1 /* No parity */
33 #define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */
34 #define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */
35 #define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */
36 #define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */
37 #define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */
38 #define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */
40 #define LMI_DEFAULT 0 /* Default setting */
41 #define LMI_NONE 1 /* No LMI, all PVCs are static */
42 #define LMI_ANSI 2 /* ANSI Annex D */
43 #define LMI_CCITT 3 /* ITU-T Annex A */
45 #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
46 #define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
51 #include <linux/skbuff.h>
52 #include <linux/netdevice.h>
53 #include <net/syncppp.h>
54 #include <linux/hdlc/ioctl.h>
57 typedef struct { /* Used in Cisco and PPP mode */
61 }__attribute__ ((packed
)) hdlc_header
;
69 u16 rel
; /* reliability */
71 }__attribute__ ((packed
)) cisco_packet
;
72 #define CISCO_PACKET_LEN 18
73 #define CISCO_BIG_PACKET_LEN 20
77 typedef struct pvc_device_struct
{
78 struct hdlc_device_struct
*master
;
79 struct net_device
*main
;
80 struct net_device
*ether
; /* bridged Ethernet interface */
81 struct pvc_device_struct
*next
; /* Sorted in ascending DLCI order */
87 unsigned int active
: 1;
88 unsigned int exist
: 1;
89 unsigned int deleted
: 1;
97 typedef struct hdlc_device_struct
{
98 /* To be initialized by hardware driver */
99 struct net_device netdev
; /* master net device - must be first */
100 struct net_device_stats stats
;
102 /* used by HDLC layer to take control over HDLC device from hw driver*/
103 int (*attach
)(struct hdlc_device_struct
*hdlc
,
104 unsigned short encoding
, unsigned short parity
);
106 /* hardware driver must handle this instead of dev->hard_start_xmit */
107 int (*xmit
)(struct sk_buff
*skb
, struct net_device
*dev
);
110 /* Things below are for HDLC layer internal use only */
112 int (*open
)(struct hdlc_device_struct
*hdlc
);
113 void (*close
)(struct hdlc_device_struct
*hdlc
);
116 void (*start
)(struct hdlc_device_struct
*hdlc
);
118 void (*stop
)(struct hdlc_device_struct
*hdlc
);
120 void (*detach
)(struct hdlc_device_struct
*hdlc
);
121 void (*netif_rx
)(struct sk_buff
*skb
);
122 unsigned short (*type_trans
)(struct sk_buff
*skb
,
123 struct net_device
*dev
);
124 int id
; /* IF_PROTO_HDLC/CISCO/FR/etc. */
129 spinlock_t state_lock
;
134 pvc_device
*first_pvc
;
137 struct timer_list timer
;
143 u32 last_errors
; /* last errors bit list */
145 u8 txseq
; /* TX sequence number */
146 u8 rxseq
; /* RX sequence number */
150 cisco_proto settings
;
152 struct timer_list timer
;
155 u32 txseq
; /* TX sequence number */
156 u32 rxseq
; /* RX sequence number */
160 raw_hdlc_proto settings
;
164 struct ppp_device pppdev
;
165 struct ppp_device
*syncppp_ptr
;
166 int (*old_change_mtu
)(struct net_device
*dev
,
174 int hdlc_raw_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
175 int hdlc_raw_eth_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
176 int hdlc_cisco_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
177 int hdlc_ppp_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
178 int hdlc_fr_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
179 int hdlc_x25_ioctl(hdlc_device
*hdlc
, struct ifreq
*ifr
);
182 /* Exported from hdlc.o */
184 /* Called by hardware driver when a user requests HDLC service */
185 int hdlc_ioctl(struct net_device
*dev
, struct ifreq
*ifr
, int cmd
);
187 /* Must be used by hardware driver on module startup/exit */
188 int register_hdlc_device(hdlc_device
*hdlc
);
189 void unregister_hdlc_device(hdlc_device
*hdlc
);
192 static __inline__
struct net_device
* hdlc_to_dev(hdlc_device
*hdlc
)
194 return &hdlc
->netdev
;
198 static __inline__ hdlc_device
* dev_to_hdlc(struct net_device
*dev
)
200 return (hdlc_device
*)dev
;
204 static __inline__ pvc_device
* dev_to_pvc(struct net_device
*dev
)
206 return (pvc_device
*)dev
->priv
;
210 static __inline__
const char *hdlc_to_name(hdlc_device
*hdlc
)
212 return hdlc_to_dev(hdlc
)->name
;
216 static __inline__
void debug_frame(const struct sk_buff
*skb
)
220 for (i
=0; i
< skb
->len
; i
++) {
225 printk(" %02X", skb
->data
[i
]);
231 /* Must be called by hardware driver when HDLC device is being opened */
232 int hdlc_open(hdlc_device
*hdlc
);
233 /* Must be called by hardware driver when HDLC device is being closed */
234 void hdlc_close(hdlc_device
*hdlc
);
235 /* Called by hardware driver when DCD line level changes */
236 void hdlc_set_carrier(int on
, hdlc_device
*hdlc
);
238 /* May be used by hardware driver to gain control over HDLC device */
239 static __inline__
void hdlc_proto_detach(hdlc_device
*hdlc
)
241 if (hdlc
->proto
.detach
)
242 hdlc
->proto
.detach(hdlc
);
243 hdlc
->proto
.detach
= NULL
;
247 static __inline__
unsigned short hdlc_type_trans(struct sk_buff
*skb
,
248 struct net_device
*dev
)
250 hdlc_device
*hdlc
= dev_to_hdlc(skb
->dev
);
251 if (hdlc
->proto
.type_trans
)
252 return hdlc
->proto
.type_trans(skb
, dev
);
254 return __constant_htons(ETH_P_HDLC
);
257 #endif /* __KERNEL */
258 #endif /* __HDLC_H */