Rev 422 | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
422 | giacomo | 1 | /* |
2 | * Generic HDLC support routines for Linux |
||
3 | * |
||
4 | * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl> |
||
5 | * |
||
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. |
||
9 | */ |
||
10 | |||
11 | #ifndef __HDLC_H |
||
12 | #define __HDLC_H |
||
13 | |||
14 | #define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */ |
||
15 | |||
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 */ |
||
21 | |||
22 | |||
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 |
||
29 | |||
30 | |||
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 */ |
||
39 | |||
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 */ |
||
44 | |||
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 */ |
||
47 | |||
48 | |||
49 | #ifdef __KERNEL__ |
||
50 | |||
51 | #include <linux/skbuff.h> |
||
52 | #include <linux/netdevice.h> |
||
53 | #include <net/syncppp.h> |
||
54 | #include <linux/hdlc/ioctl.h> |
||
55 | |||
56 | |||
57 | typedef struct { /* Used in Cisco and PPP mode */ |
||
58 | u8 address; |
||
59 | u8 control; |
||
60 | u16 protocol; |
||
61 | }__attribute__ ((packed)) hdlc_header; |
||
62 | |||
63 | |||
64 | |||
65 | typedef struct { |
||
66 | u32 type; /* code */ |
||
67 | u32 par1; |
||
68 | u32 par2; |
||
69 | u16 rel; /* reliability */ |
||
70 | u32 time; |
||
71 | }__attribute__ ((packed)) cisco_packet; |
||
72 | #define CISCO_PACKET_LEN 18 |
||
73 | #define CISCO_BIG_PACKET_LEN 20 |
||
74 | |||
75 | |||
76 | |||
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 */ |
||
82 | int dlci; |
||
83 | int open_count; |
||
84 | |||
85 | struct { |
||
86 | unsigned int new: 1; |
||
87 | unsigned int active: 1; |
||
88 | unsigned int exist: 1; |
||
89 | unsigned int deleted: 1; |
||
90 | unsigned int fecn: 1; |
||
91 | unsigned int becn: 1; |
||
92 | }state; |
||
93 | }pvc_device; |
||
94 | |||
95 | |||
96 | |||
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; |
||
101 | |||
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); |
||
105 | |||
106 | /* hardware driver must handle this instead of dev->hard_start_xmit */ |
||
107 | int (*xmit)(struct sk_buff *skb, struct net_device *dev); |
||
108 | |||
109 | |||
110 | /* Things below are for HDLC layer internal use only */ |
||
111 | struct { |
||
112 | int (*open)(struct hdlc_device_struct *hdlc); |
||
113 | void (*close)(struct hdlc_device_struct *hdlc); |
||
114 | |||
115 | /* if open & DCD */ |
||
116 | void (*start)(struct hdlc_device_struct *hdlc); |
||
117 | /* if open & !DCD */ |
||
118 | void (*stop)(struct hdlc_device_struct *hdlc); |
||
119 | |||
120 | void (*detach)(struct hdlc_device_struct *hdlc); |
||
121 | int (*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. */ |
||
125 | }proto; |
||
126 | |||
127 | int carrier; |
||
128 | int open; |
||
129 | spinlock_t state_lock; |
||
130 | |||
131 | union { |
||
132 | struct { |
||
133 | fr_proto settings; |
||
134 | pvc_device *first_pvc; |
||
135 | int dce_pvc_count; |
||
136 | |||
137 | struct timer_list timer; |
||
138 | int last_poll; |
||
139 | int reliable; |
||
140 | int dce_changed; |
||
141 | int request; |
||
142 | int fullrep_sent; |
||
143 | u32 last_errors; /* last errors bit list */ |
||
144 | u8 n391cnt; |
||
145 | u8 txseq; /* TX sequence number */ |
||
146 | u8 rxseq; /* RX sequence number */ |
||
147 | }fr; |
||
148 | |||
149 | struct { |
||
150 | cisco_proto settings; |
||
151 | |||
152 | struct timer_list timer; |
||
153 | int last_poll; |
||
154 | int up; |
||
155 | u32 txseq; /* TX sequence number */ |
||
156 | u32 rxseq; /* RX sequence number */ |
||
157 | }cisco; |
||
158 | |||
159 | struct { |
||
160 | raw_hdlc_proto settings; |
||
161 | }raw_hdlc; |
||
162 | |||
163 | struct { |
||
164 | struct ppp_device pppdev; |
||
165 | struct ppp_device *syncppp_ptr; |
||
166 | int (*old_change_mtu)(struct net_device *dev, |
||
167 | int new_mtu); |
||
168 | }ppp; |
||
169 | }state; |
||
170 | }hdlc_device; |
||
171 | |||
172 | |||
173 | |||
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); |
||
180 | |||
181 | |||
182 | /* Exported from hdlc.o */ |
||
183 | |||
184 | /* Called by hardware driver when a user requests HDLC service */ |
||
185 | int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); |
||
186 | |||
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); |
||
190 | |||
191 | |||
192 | static __inline__ struct net_device* hdlc_to_dev(hdlc_device *hdlc) |
||
193 | { |
||
194 | return &hdlc->netdev; |
||
195 | } |
||
196 | |||
197 | |||
198 | static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) |
||
199 | { |
||
200 | return (hdlc_device*)dev; |
||
201 | } |
||
202 | |||
203 | |||
204 | static __inline__ pvc_device* dev_to_pvc(struct net_device *dev) |
||
205 | { |
||
206 | return (pvc_device*)dev->priv; |
||
207 | } |
||
208 | |||
209 | |||
210 | static __inline__ const char *hdlc_to_name(hdlc_device *hdlc) |
||
211 | { |
||
212 | return hdlc_to_dev(hdlc)->name; |
||
213 | } |
||
214 | |||
215 | |||
216 | static __inline__ void debug_frame(const struct sk_buff *skb) |
||
217 | { |
||
218 | int i; |
||
219 | |||
220 | for (i=0; i < skb->len; i++) { |
||
221 | if (i == 100) { |
||
222 | printk("...\n"); |
||
223 | return; |
||
224 | } |
||
225 | printk(" %02X", skb->data[i]); |
||
226 | } |
||
227 | printk("\n"); |
||
228 | } |
||
229 | |||
230 | |||
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); |
||
237 | |||
238 | /* May be used by hardware driver to gain control over HDLC device */ |
||
239 | static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) |
||
240 | { |
||
241 | if (hdlc->proto.detach) |
||
242 | hdlc->proto.detach(hdlc); |
||
243 | hdlc->proto.detach = NULL; |
||
244 | } |
||
245 | |||
246 | |||
247 | static __inline__ unsigned short hdlc_type_trans(struct sk_buff *skb, |
||
248 | struct net_device *dev) |
||
249 | { |
||
250 | hdlc_device *hdlc = dev_to_hdlc(skb->dev); |
||
251 | if (hdlc->proto.type_trans) |
||
252 | return hdlc->proto.type_trans(skb, dev); |
||
253 | else |
||
254 | return __constant_htons(ETH_P_HDLC); |
||
255 | } |
||
256 | |||
257 | #endif /* __KERNEL */ |
||
258 | #endif /* __HDLC_H */ |