aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKrzysztof Halasa <khc@pm.waw.pl>2006-09-26 17:23:45 -0400
committerJeff Garzik <jeff@garzik.org>2006-09-26 17:40:24 -0400
commiteb2a2fd91f7c8a53b15063d6f08cf22b9a56cbfb (patch)
tree1d910a9460b76fd85ed02e8b9131270e4977f6f7
parentc226951b93f7cd7c3a10b17384535b617bd43fd0 (diff)
[PATCH] Modularize generic HDLC
This patch enables building of individual WAN protocol support routines (parts of generic HDLC) as separate modules. All protocol-private definitions are moved from hdlc.h file to protocol drivers. User-space interface and interface between generic HDLC and underlying low-level HDLC drivers are unchanged. Signed-off-by: Krzysztof Halasa <khc@pm.waw.pl> Signed-off-by: Jeff Garzik <jeff@garzik.org>
-rw-r--r--drivers/net/wan/Kconfig12
-rw-r--r--drivers/net/wan/Makefile19
-rw-r--r--drivers/net/wan/hdlc.c (renamed from drivers/net/wan/hdlc_generic.c)169
-rw-r--r--drivers/net/wan/hdlc_cisco.c198
-rw-r--r--drivers/net/wan/hdlc_fr.c389
-rw-r--r--drivers/net/wan/hdlc_ppp.c77
-rw-r--r--drivers/net/wan/hdlc_raw.c50
-rw-r--r--drivers/net/wan/hdlc_raw_eth.c49
-rw-r--r--drivers/net/wan/hdlc_x25.c54
-rw-r--r--include/linux/hdlc.h201
-rw-r--r--include/linux/hdlc/ioctl.h33
11 files changed, 743 insertions, 508 deletions
diff --git a/drivers/net/wan/Kconfig b/drivers/net/wan/Kconfig
index 54b8e492ef97..58b7efbb0750 100644
--- a/drivers/net/wan/Kconfig
+++ b/drivers/net/wan/Kconfig
@@ -154,7 +154,7 @@ config HDLC
154 If unsure, say N. 154 If unsure, say N.
155 155
156config HDLC_RAW 156config HDLC_RAW
157 bool "Raw HDLC support" 157 tristate "Raw HDLC support"
158 depends on HDLC 158 depends on HDLC
159 help 159 help
160 Generic HDLC driver supporting raw HDLC over WAN connections. 160 Generic HDLC driver supporting raw HDLC over WAN connections.
@@ -162,7 +162,7 @@ config HDLC_RAW
162 If unsure, say N. 162 If unsure, say N.
163 163
164config HDLC_RAW_ETH 164config HDLC_RAW_ETH
165 bool "Raw HDLC Ethernet device support" 165 tristate "Raw HDLC Ethernet device support"
166 depends on HDLC 166 depends on HDLC
167 help 167 help
168 Generic HDLC driver supporting raw HDLC Ethernet device emulation 168 Generic HDLC driver supporting raw HDLC Ethernet device emulation
@@ -173,7 +173,7 @@ config HDLC_RAW_ETH
173 If unsure, say N. 173 If unsure, say N.
174 174
175config HDLC_CISCO 175config HDLC_CISCO
176 bool "Cisco HDLC support" 176 tristate "Cisco HDLC support"
177 depends on HDLC 177 depends on HDLC
178 help 178 help
179 Generic HDLC driver supporting Cisco HDLC over WAN connections. 179 Generic HDLC driver supporting Cisco HDLC over WAN connections.
@@ -181,7 +181,7 @@ config HDLC_CISCO
181 If unsure, say N. 181 If unsure, say N.
182 182
183config HDLC_FR 183config HDLC_FR
184 bool "Frame Relay support" 184 tristate "Frame Relay support"
185 depends on HDLC 185 depends on HDLC
186 help 186 help
187 Generic HDLC driver supporting Frame Relay over WAN connections. 187 Generic HDLC driver supporting Frame Relay over WAN connections.
@@ -189,7 +189,7 @@ config HDLC_FR
189 If unsure, say N. 189 If unsure, say N.
190 190
191config HDLC_PPP 191config HDLC_PPP
192 bool "Synchronous Point-to-Point Protocol (PPP) support" 192 tristate "Synchronous Point-to-Point Protocol (PPP) support"
193 depends on HDLC 193 depends on HDLC
194 help 194 help
195 Generic HDLC driver supporting PPP over WAN connections. 195 Generic HDLC driver supporting PPP over WAN connections.
@@ -197,7 +197,7 @@ config HDLC_PPP
197 If unsure, say N. 197 If unsure, say N.
198 198
199config HDLC_X25 199config HDLC_X25
200 bool "X.25 protocol support" 200 tristate "X.25 protocol support"
201 depends on HDLC && (LAPB=m && HDLC=m || LAPB=y) 201 depends on HDLC && (LAPB=m && HDLC=m || LAPB=y)
202 help 202 help
203 Generic HDLC driver supporting X.25 over WAN connections. 203 Generic HDLC driver supporting X.25 over WAN connections.
diff --git a/drivers/net/wan/Makefile b/drivers/net/wan/Makefile
index 316ca6869d5e..83ec2c87ba3f 100644
--- a/drivers/net/wan/Makefile
+++ b/drivers/net/wan/Makefile
@@ -9,14 +9,13 @@ cyclomx-y := cycx_main.o
9cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o 9cyclomx-$(CONFIG_CYCLOMX_X25) += cycx_x25.o
10cyclomx-objs := $(cyclomx-y) 10cyclomx-objs := $(cyclomx-y)
11 11
12hdlc-y := hdlc_generic.o 12obj-$(CONFIG_HDLC) += hdlc.o
13hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o 13obj-$(CONFIG_HDLC_RAW) += hdlc_raw.o
14hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o 14obj-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o
15hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o 15obj-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o
16hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o 16obj-$(CONFIG_HDLC_FR) += hdlc_fr.o
17hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o 17obj-$(CONFIG_HDLC_PPP) += hdlc_ppp.o syncppp.o
18hdlc-$(CONFIG_HDLC_X25) += hdlc_x25.o 18obj-$(CONFIG_HDLC_X25) += hdlc_x25.o
19hdlc-objs := $(hdlc-y)
20 19
21pc300-y := pc300_drv.o 20pc300-y := pc300_drv.o
22pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o 21pc300-$(CONFIG_PC300_MLPPP) += pc300_tty.o
@@ -38,10 +37,6 @@ obj-$(CONFIG_CYCLADES_SYNC) += cycx_drv.o cyclomx.o
38obj-$(CONFIG_LAPBETHER) += lapbether.o 37obj-$(CONFIG_LAPBETHER) += lapbether.o
39obj-$(CONFIG_SBNI) += sbni.o 38obj-$(CONFIG_SBNI) += sbni.o
40obj-$(CONFIG_PC300) += pc300.o 39obj-$(CONFIG_PC300) += pc300.o
41obj-$(CONFIG_HDLC) += hdlc.o
42ifeq ($(CONFIG_HDLC_PPP),y)
43 obj-$(CONFIG_HDLC) += syncppp.o
44endif
45obj-$(CONFIG_N2) += n2.o 40obj-$(CONFIG_N2) += n2.o
46obj-$(CONFIG_C101) += c101.o 41obj-$(CONFIG_C101) += c101.o
47obj-$(CONFIG_WANXL) += wanxl.o 42obj-$(CONFIG_WANXL) += wanxl.o
diff --git a/drivers/net/wan/hdlc_generic.c b/drivers/net/wan/hdlc.c
index 04ca1f7b6424..db354e0edbe5 100644
--- a/drivers/net/wan/hdlc_generic.c
+++ b/drivers/net/wan/hdlc.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * 3 *
4 * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 4 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify it 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 7 * under the terms of version 2 of the GNU General Public License
@@ -17,9 +17,9 @@
17 * Use sethdlc utility to set line parameters, protocol and PVCs 17 * Use sethdlc utility to set line parameters, protocol and PVCs
18 * 18 *
19 * How does it work: 19 * How does it work:
20 * - proto.open(), close(), start(), stop() calls are serialized. 20 * - proto->open(), close(), start(), stop() calls are serialized.
21 * The order is: open, [ start, stop ... ] close ... 21 * The order is: open, [ start, stop ... ] close ...
22 * - proto.start() and stop() are called with spin_lock_irq held. 22 * - proto->start() and stop() are called with spin_lock_irq held.
23 */ 23 */
24 24
25#include <linux/module.h> 25#include <linux/module.h>
@@ -38,10 +38,12 @@
38#include <linux/hdlc.h> 38#include <linux/hdlc.h>
39 39
40 40
41static const char* version = "HDLC support module revision 1.19"; 41static const char* version = "HDLC support module revision 1.20";
42 42
43#undef DEBUG_LINK 43#undef DEBUG_LINK
44 44
45static struct hdlc_proto *first_proto = NULL;
46
45 47
46static int hdlc_change_mtu(struct net_device *dev, int new_mtu) 48static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
47{ 49{
@@ -63,11 +65,11 @@ static struct net_device_stats *hdlc_get_stats(struct net_device *dev)
63static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev, 65static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
64 struct packet_type *p, struct net_device *orig_dev) 66 struct packet_type *p, struct net_device *orig_dev)
65{ 67{
66 hdlc_device *hdlc = dev_to_hdlc(dev); 68 struct hdlc_device_desc *desc = dev_to_desc(dev);
67 if (hdlc->proto.netif_rx) 69 if (desc->netif_rx)
68 return hdlc->proto.netif_rx(skb); 70 return desc->netif_rx(skb);
69 71
70 hdlc->stats.rx_dropped++; /* Shouldn't happen */ 72 desc->stats.rx_dropped++; /* Shouldn't happen */
71 dev_kfree_skb(skb); 73 dev_kfree_skb(skb);
72 return NET_RX_DROP; 74 return NET_RX_DROP;
73} 75}
@@ -77,8 +79,8 @@ static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
77static inline void hdlc_proto_start(struct net_device *dev) 79static inline void hdlc_proto_start(struct net_device *dev)
78{ 80{
79 hdlc_device *hdlc = dev_to_hdlc(dev); 81 hdlc_device *hdlc = dev_to_hdlc(dev);
80 if (hdlc->proto.start) 82 if (hdlc->proto->start)
81 return hdlc->proto.start(dev); 83 return hdlc->proto->start(dev);
82} 84}
83 85
84 86
@@ -86,8 +88,8 @@ static inline void hdlc_proto_start(struct net_device *dev)
86static inline void hdlc_proto_stop(struct net_device *dev) 88static inline void hdlc_proto_stop(struct net_device *dev)
87{ 89{
88 hdlc_device *hdlc = dev_to_hdlc(dev); 90 hdlc_device *hdlc = dev_to_hdlc(dev);
89 if (hdlc->proto.stop) 91 if (hdlc->proto->stop)
90 return hdlc->proto.stop(dev); 92 return hdlc->proto->stop(dev);
91} 93}
92 94
93 95
@@ -144,15 +146,15 @@ int hdlc_open(struct net_device *dev)
144{ 146{
145 hdlc_device *hdlc = dev_to_hdlc(dev); 147 hdlc_device *hdlc = dev_to_hdlc(dev);
146#ifdef DEBUG_LINK 148#ifdef DEBUG_LINK
147 printk(KERN_DEBUG "hdlc_open() carrier %i open %i\n", 149 printk(KERN_DEBUG "%s: hdlc_open() carrier %i open %i\n", dev->name,
148 hdlc->carrier, hdlc->open); 150 hdlc->carrier, hdlc->open);
149#endif 151#endif
150 152
151 if (hdlc->proto.id == -1) 153 if (hdlc->proto == NULL)
152 return -ENOSYS; /* no protocol attached */ 154 return -ENOSYS; /* no protocol attached */
153 155
154 if (hdlc->proto.open) { 156 if (hdlc->proto->open) {
155 int result = hdlc->proto.open(dev); 157 int result = hdlc->proto->open(dev);
156 if (result) 158 if (result)
157 return result; 159 return result;
158 } 160 }
@@ -178,7 +180,7 @@ void hdlc_close(struct net_device *dev)
178{ 180{
179 hdlc_device *hdlc = dev_to_hdlc(dev); 181 hdlc_device *hdlc = dev_to_hdlc(dev);
180#ifdef DEBUG_LINK 182#ifdef DEBUG_LINK
181 printk(KERN_DEBUG "hdlc_close() carrier %i open %i\n", 183 printk(KERN_DEBUG "%s: hdlc_close() carrier %i open %i\n", dev->name,
182 hdlc->carrier, hdlc->open); 184 hdlc->carrier, hdlc->open);
183#endif 185#endif
184 186
@@ -190,68 +192,34 @@ void hdlc_close(struct net_device *dev)
190 192
191 spin_unlock_irq(&hdlc->state_lock); 193 spin_unlock_irq(&hdlc->state_lock);
192 194
193 if (hdlc->proto.close) 195 if (hdlc->proto->close)
194 hdlc->proto.close(dev); 196 hdlc->proto->close(dev);
195} 197}
196 198
197 199
198 200
199#ifndef CONFIG_HDLC_RAW
200#define hdlc_raw_ioctl(dev, ifr) -ENOSYS
201#endif
202
203#ifndef CONFIG_HDLC_RAW_ETH
204#define hdlc_raw_eth_ioctl(dev, ifr) -ENOSYS
205#endif
206
207#ifndef CONFIG_HDLC_PPP
208#define hdlc_ppp_ioctl(dev, ifr) -ENOSYS
209#endif
210
211#ifndef CONFIG_HDLC_CISCO
212#define hdlc_cisco_ioctl(dev, ifr) -ENOSYS
213#endif
214
215#ifndef CONFIG_HDLC_FR
216#define hdlc_fr_ioctl(dev, ifr) -ENOSYS
217#endif
218
219#ifndef CONFIG_HDLC_X25
220#define hdlc_x25_ioctl(dev, ifr) -ENOSYS
221#endif
222
223
224int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 201int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
225{ 202{
226 hdlc_device *hdlc = dev_to_hdlc(dev); 203 struct hdlc_proto *proto = first_proto;
227 unsigned int proto; 204 int result;
228 205
229 if (cmd != SIOCWANDEV) 206 if (cmd != SIOCWANDEV)
230 return -EINVAL; 207 return -EINVAL;
231 208
232 switch(ifr->ifr_settings.type) { 209 if (dev_to_hdlc(dev)->proto) {
233 case IF_PROTO_HDLC: 210 result = dev_to_hdlc(dev)->proto->ioctl(dev, ifr);
234 case IF_PROTO_HDLC_ETH: 211 if (result != -EINVAL)
235 case IF_PROTO_PPP: 212 return result;
236 case IF_PROTO_CISCO:
237 case IF_PROTO_FR:
238 case IF_PROTO_X25:
239 proto = ifr->ifr_settings.type;
240 break;
241
242 default:
243 proto = hdlc->proto.id;
244 } 213 }
245 214
246 switch(proto) { 215 /* Not handled by currently attached protocol (if any) */
247 case IF_PROTO_HDLC: return hdlc_raw_ioctl(dev, ifr); 216
248 case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(dev, ifr); 217 while (proto) {
249 case IF_PROTO_PPP: return hdlc_ppp_ioctl(dev, ifr); 218 if ((result = proto->ioctl(dev, ifr)) != -EINVAL)
250 case IF_PROTO_CISCO: return hdlc_cisco_ioctl(dev, ifr); 219 return result;
251 case IF_PROTO_FR: return hdlc_fr_ioctl(dev, ifr); 220 proto = proto->next;
252 case IF_PROTO_X25: return hdlc_x25_ioctl(dev, ifr);
253 default: return -EINVAL;
254 } 221 }
222 return -EINVAL;
255} 223}
256 224
257void hdlc_setup(struct net_device *dev) 225void hdlc_setup(struct net_device *dev)
@@ -267,8 +235,6 @@ void hdlc_setup(struct net_device *dev)
267 235
268 dev->flags = IFF_POINTOPOINT | IFF_NOARP; 236 dev->flags = IFF_POINTOPOINT | IFF_NOARP;
269 237
270 hdlc->proto.id = -1;
271 hdlc->proto.detach = NULL;
272 hdlc->carrier = 1; 238 hdlc->carrier = 1;
273 hdlc->open = 0; 239 hdlc->open = 0;
274 spin_lock_init(&hdlc->state_lock); 240 spin_lock_init(&hdlc->state_lock);
@@ -277,7 +243,8 @@ void hdlc_setup(struct net_device *dev)
277struct net_device *alloc_hdlcdev(void *priv) 243struct net_device *alloc_hdlcdev(void *priv)
278{ 244{
279 struct net_device *dev; 245 struct net_device *dev;
280 dev = alloc_netdev(sizeof(hdlc_device), "hdlc%d", hdlc_setup); 246 dev = alloc_netdev(sizeof(struct hdlc_device_desc) +
247 sizeof(hdlc_device), "hdlc%d", hdlc_setup);
281 if (dev) 248 if (dev)
282 dev_to_hdlc(dev)->priv = priv; 249 dev_to_hdlc(dev)->priv = priv;
283 return dev; 250 return dev;
@@ -286,13 +253,71 @@ struct net_device *alloc_hdlcdev(void *priv)
286void unregister_hdlc_device(struct net_device *dev) 253void unregister_hdlc_device(struct net_device *dev)
287{ 254{
288 rtnl_lock(); 255 rtnl_lock();
289 hdlc_proto_detach(dev_to_hdlc(dev));
290 unregister_netdevice(dev); 256 unregister_netdevice(dev);
257 detach_hdlc_protocol(dev);
291 rtnl_unlock(); 258 rtnl_unlock();
292} 259}
293 260
294 261
295 262
263int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
264 int (*rx)(struct sk_buff *skb), size_t size)
265{
266 detach_hdlc_protocol(dev);
267
268 if (!try_module_get(proto->module))
269 return -ENOSYS;
270
271 if (size)
272 if ((dev_to_hdlc(dev)->state = kmalloc(size,
273 GFP_KERNEL)) == NULL) {
274 printk(KERN_WARNING "Memory squeeze on"
275 " hdlc_proto_attach()\n");
276 module_put(proto->module);
277 return -ENOBUFS;
278 }
279 dev_to_hdlc(dev)->proto = proto;
280 dev_to_desc(dev)->netif_rx = rx;
281 return 0;
282}
283
284
285void detach_hdlc_protocol(struct net_device *dev)
286{
287 hdlc_device *hdlc = dev_to_hdlc(dev);
288
289 if (hdlc->proto) {
290 if (hdlc->proto->detach)
291 hdlc->proto->detach(dev);
292 module_put(hdlc->proto->module);
293 hdlc->proto = NULL;
294 }
295 kfree(hdlc->state);
296 hdlc->state = NULL;
297}
298
299
300void register_hdlc_protocol(struct hdlc_proto *proto)
301{
302 proto->next = first_proto;
303 first_proto = proto;
304}
305
306
307void unregister_hdlc_protocol(struct hdlc_proto *proto)
308{
309 struct hdlc_proto **p = &first_proto;
310 while (*p) {
311 if (*p == proto) {
312 *p = proto->next;
313 return;
314 }
315 p = &((*p)->next);
316 }
317}
318
319
320
296MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>"); 321MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
297MODULE_DESCRIPTION("HDLC support module"); 322MODULE_DESCRIPTION("HDLC support module");
298MODULE_LICENSE("GPL v2"); 323MODULE_LICENSE("GPL v2");
@@ -303,6 +328,10 @@ EXPORT_SYMBOL(hdlc_ioctl);
303EXPORT_SYMBOL(hdlc_setup); 328EXPORT_SYMBOL(hdlc_setup);
304EXPORT_SYMBOL(alloc_hdlcdev); 329EXPORT_SYMBOL(alloc_hdlcdev);
305EXPORT_SYMBOL(unregister_hdlc_device); 330EXPORT_SYMBOL(unregister_hdlc_device);
331EXPORT_SYMBOL(register_hdlc_protocol);
332EXPORT_SYMBOL(unregister_hdlc_protocol);
333EXPORT_SYMBOL(attach_hdlc_protocol);
334EXPORT_SYMBOL(detach_hdlc_protocol);
306 335
307static struct packet_type hdlc_packet_type = { 336static struct packet_type hdlc_packet_type = {
308 .type = __constant_htons(ETH_P_HDLC), 337 .type = __constant_htons(ETH_P_HDLC),
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index f289daba0c7b..7ec2b2f9b7ee 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Cisco HDLC support 3 * Cisco HDLC support
4 * 4 *
5 * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 2000 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -34,17 +34,56 @@
34#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ 34#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */
35 35
36 36
37struct hdlc_header {
38 u8 address;
39 u8 control;
40 u16 protocol;
41}__attribute__ ((packed));
42
43
44struct cisco_packet {
45 u32 type; /* code */
46 u32 par1;
47 u32 par2;
48 u16 rel; /* reliability */
49 u32 time;
50}__attribute__ ((packed));
51#define CISCO_PACKET_LEN 18
52#define CISCO_BIG_PACKET_LEN 20
53
54
55struct cisco_state {
56 cisco_proto settings;
57
58 struct timer_list timer;
59 unsigned long last_poll;
60 int up;
61 int request_sent;
62 u32 txseq; /* TX sequence number */
63 u32 rxseq; /* RX sequence number */
64};
65
66
67static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
68
69
70static inline struct cisco_state * state(hdlc_device *hdlc)
71{
72 return(struct cisco_state *)(hdlc->state);
73}
74
75
37static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev, 76static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
38 u16 type, void *daddr, void *saddr, 77 u16 type, void *daddr, void *saddr,
39 unsigned int len) 78 unsigned int len)
40{ 79{
41 hdlc_header *data; 80 struct hdlc_header *data;
42#ifdef DEBUG_HARD_HEADER 81#ifdef DEBUG_HARD_HEADER
43 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name); 82 printk(KERN_DEBUG "%s: cisco_hard_header called\n", dev->name);
44#endif 83#endif
45 84
46 skb_push(skb, sizeof(hdlc_header)); 85 skb_push(skb, sizeof(struct hdlc_header));
47 data = (hdlc_header*)skb->data; 86 data = (struct hdlc_header*)skb->data;
48 if (type == CISCO_KEEPALIVE) 87 if (type == CISCO_KEEPALIVE)
49 data->address = CISCO_MULTICAST; 88 data->address = CISCO_MULTICAST;
50 else 89 else
@@ -52,7 +91,7 @@ static int cisco_hard_header(struct sk_buff *skb, struct net_device *dev,
52 data->control = 0; 91 data->control = 0;
53 data->protocol = htons(type); 92 data->protocol = htons(type);
54 93
55 return sizeof(hdlc_header); 94 return sizeof(struct hdlc_header);
56} 95}
57 96
58 97
@@ -61,9 +100,10 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
61 u32 par1, u32 par2) 100 u32 par1, u32 par2)
62{ 101{
63 struct sk_buff *skb; 102 struct sk_buff *skb;
64 cisco_packet *data; 103 struct cisco_packet *data;
65 104
66 skb = dev_alloc_skb(sizeof(hdlc_header) + sizeof(cisco_packet)); 105 skb = dev_alloc_skb(sizeof(struct hdlc_header) +
106 sizeof(struct cisco_packet));
67 if (!skb) { 107 if (!skb) {
68 printk(KERN_WARNING 108 printk(KERN_WARNING
69 "%s: Memory squeeze on cisco_keepalive_send()\n", 109 "%s: Memory squeeze on cisco_keepalive_send()\n",
@@ -72,7 +112,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
72 } 112 }
73 skb_reserve(skb, 4); 113 skb_reserve(skb, 4);
74 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0); 114 cisco_hard_header(skb, dev, CISCO_KEEPALIVE, NULL, NULL, 0);
75 data = (cisco_packet*)(skb->data + 4); 115 data = (struct cisco_packet*)(skb->data + 4);
76 116
77 data->type = htonl(type); 117 data->type = htonl(type);
78 data->par1 = htonl(par1); 118 data->par1 = htonl(par1);
@@ -81,7 +121,7 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
81 /* we will need do_div here if 1000 % HZ != 0 */ 121 /* we will need do_div here if 1000 % HZ != 0 */
82 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ)); 122 data->time = htonl((jiffies - INITIAL_JIFFIES) * (1000 / HZ));
83 123
84 skb_put(skb, sizeof(cisco_packet)); 124 skb_put(skb, sizeof(struct cisco_packet));
85 skb->priority = TC_PRIO_CONTROL; 125 skb->priority = TC_PRIO_CONTROL;
86 skb->dev = dev; 126 skb->dev = dev;
87 skb->nh.raw = skb->data; 127 skb->nh.raw = skb->data;
@@ -93,9 +133,9 @@ static void cisco_keepalive_send(struct net_device *dev, u32 type,
93 133
94static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev) 134static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
95{ 135{
96 hdlc_header *data = (hdlc_header*)skb->data; 136 struct hdlc_header *data = (struct hdlc_header*)skb->data;
97 137
98 if (skb->len < sizeof(hdlc_header)) 138 if (skb->len < sizeof(struct hdlc_header))
99 return __constant_htons(ETH_P_HDLC); 139 return __constant_htons(ETH_P_HDLC);
100 140
101 if (data->address != CISCO_MULTICAST && 141 if (data->address != CISCO_MULTICAST &&
@@ -106,7 +146,7 @@ static __be16 cisco_type_trans(struct sk_buff *skb, struct net_device *dev)
106 case __constant_htons(ETH_P_IP): 146 case __constant_htons(ETH_P_IP):
107 case __constant_htons(ETH_P_IPX): 147 case __constant_htons(ETH_P_IPX):
108 case __constant_htons(ETH_P_IPV6): 148 case __constant_htons(ETH_P_IPV6):
109 skb_pull(skb, sizeof(hdlc_header)); 149 skb_pull(skb, sizeof(struct hdlc_header));
110 return data->protocol; 150 return data->protocol;
111 default: 151 default:
112 return __constant_htons(ETH_P_HDLC); 152 return __constant_htons(ETH_P_HDLC);
@@ -118,12 +158,12 @@ static int cisco_rx(struct sk_buff *skb)
118{ 158{
119 struct net_device *dev = skb->dev; 159 struct net_device *dev = skb->dev;
120 hdlc_device *hdlc = dev_to_hdlc(dev); 160 hdlc_device *hdlc = dev_to_hdlc(dev);
121 hdlc_header *data = (hdlc_header*)skb->data; 161 struct hdlc_header *data = (struct hdlc_header*)skb->data;
122 cisco_packet *cisco_data; 162 struct cisco_packet *cisco_data;
123 struct in_device *in_dev; 163 struct in_device *in_dev;
124 u32 addr, mask; 164 u32 addr, mask;
125 165
126 if (skb->len < sizeof(hdlc_header)) 166 if (skb->len < sizeof(struct hdlc_header))
127 goto rx_error; 167 goto rx_error;
128 168
129 if (data->address != CISCO_MULTICAST && 169 if (data->address != CISCO_MULTICAST &&
@@ -137,15 +177,17 @@ static int cisco_rx(struct sk_buff *skb)
137 return NET_RX_SUCCESS; 177 return NET_RX_SUCCESS;
138 178
139 case CISCO_KEEPALIVE: 179 case CISCO_KEEPALIVE:
140 if (skb->len != sizeof(hdlc_header) + CISCO_PACKET_LEN && 180 if ((skb->len != sizeof(struct hdlc_header) +
141 skb->len != sizeof(hdlc_header) + CISCO_BIG_PACKET_LEN) { 181 CISCO_PACKET_LEN) &&
142 printk(KERN_INFO "%s: Invalid length of Cisco " 182 (skb->len != sizeof(struct hdlc_header) +
143 "control packet (%d bytes)\n", 183 CISCO_BIG_PACKET_LEN)) {
144 dev->name, skb->len); 184 printk(KERN_INFO "%s: Invalid length of Cisco control"
185 " packet (%d bytes)\n", dev->name, skb->len);
145 goto rx_error; 186 goto rx_error;
146 } 187 }
147 188
148 cisco_data = (cisco_packet*)(skb->data + sizeof(hdlc_header)); 189 cisco_data = (struct cisco_packet*)(skb->data + sizeof
190 (struct hdlc_header));
149 191
150 switch(ntohl (cisco_data->type)) { 192 switch(ntohl (cisco_data->type)) {
151 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */ 193 case CISCO_ADDR_REQ: /* Stolen from syncppp.c :-) */
@@ -178,11 +220,11 @@ static int cisco_rx(struct sk_buff *skb)
178 goto rx_error; 220 goto rx_error;
179 221
180 case CISCO_KEEPALIVE_REQ: 222 case CISCO_KEEPALIVE_REQ:
181 hdlc->state.cisco.rxseq = ntohl(cisco_data->par1); 223 state(hdlc)->rxseq = ntohl(cisco_data->par1);
182 if (hdlc->state.cisco.request_sent && 224 if (state(hdlc)->request_sent &&
183 ntohl(cisco_data->par2)==hdlc->state.cisco.txseq) { 225 ntohl(cisco_data->par2) == state(hdlc)->txseq) {
184 hdlc->state.cisco.last_poll = jiffies; 226 state(hdlc)->last_poll = jiffies;
185 if (!hdlc->state.cisco.up) { 227 if (!state(hdlc)->up) {
186 u32 sec, min, hrs, days; 228 u32 sec, min, hrs, days;
187 sec = ntohl(cisco_data->time) / 1000; 229 sec = ntohl(cisco_data->time) / 1000;
188 min = sec / 60; sec -= min * 60; 230 min = sec / 60; sec -= min * 60;
@@ -193,7 +235,7 @@ static int cisco_rx(struct sk_buff *skb)
193 dev->name, days, hrs, 235 dev->name, days, hrs,
194 min, sec); 236 min, sec);
195 netif_dormant_off(dev); 237 netif_dormant_off(dev);
196 hdlc->state.cisco.up = 1; 238 state(hdlc)->up = 1;
197 } 239 }
198 } 240 }
199 241
@@ -208,7 +250,7 @@ static int cisco_rx(struct sk_buff *skb)
208 return NET_RX_DROP; 250 return NET_RX_DROP;
209 251
210 rx_error: 252 rx_error:
211 hdlc->stats.rx_errors++; /* Mark error */ 253 dev_to_desc(dev)->stats.rx_errors++; /* Mark error */
212 dev_kfree_skb_any(skb); 254 dev_kfree_skb_any(skb);
213 return NET_RX_DROP; 255 return NET_RX_DROP;
214} 256}
@@ -220,23 +262,22 @@ static void cisco_timer(unsigned long arg)
220 struct net_device *dev = (struct net_device *)arg; 262 struct net_device *dev = (struct net_device *)arg;
221 hdlc_device *hdlc = dev_to_hdlc(dev); 263 hdlc_device *hdlc = dev_to_hdlc(dev);
222 264
223 if (hdlc->state.cisco.up && 265 if (state(hdlc)->up &&
224 time_after(jiffies, hdlc->state.cisco.last_poll + 266 time_after(jiffies, state(hdlc)->last_poll +
225 hdlc->state.cisco.settings.timeout * HZ)) { 267 state(hdlc)->settings.timeout * HZ)) {
226 hdlc->state.cisco.up = 0; 268 state(hdlc)->up = 0;
227 printk(KERN_INFO "%s: Link down\n", dev->name); 269 printk(KERN_INFO "%s: Link down\n", dev->name);
228 netif_dormant_on(dev); 270 netif_dormant_on(dev);
229 } 271 }
230 272
231 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, 273 cisco_keepalive_send(dev, CISCO_KEEPALIVE_REQ, ++state(hdlc)->txseq,
232 ++hdlc->state.cisco.txseq, 274 state(hdlc)->rxseq);
233 hdlc->state.cisco.rxseq); 275 state(hdlc)->request_sent = 1;
234 hdlc->state.cisco.request_sent = 1; 276 state(hdlc)->timer.expires = jiffies +
235 hdlc->state.cisco.timer.expires = jiffies + 277 state(hdlc)->settings.interval * HZ;
236 hdlc->state.cisco.settings.interval * HZ; 278 state(hdlc)->timer.function = cisco_timer;
237 hdlc->state.cisco.timer.function = cisco_timer; 279 state(hdlc)->timer.data = arg;
238 hdlc->state.cisco.timer.data = arg; 280 add_timer(&state(hdlc)->timer);
239 add_timer(&hdlc->state.cisco.timer);
240} 281}
241 282
242 283
@@ -244,15 +285,15 @@ static void cisco_timer(unsigned long arg)
244static void cisco_start(struct net_device *dev) 285static void cisco_start(struct net_device *dev)
245{ 286{
246 hdlc_device *hdlc = dev_to_hdlc(dev); 287 hdlc_device *hdlc = dev_to_hdlc(dev);
247 hdlc->state.cisco.up = 0; 288 state(hdlc)->up = 0;
248 hdlc->state.cisco.request_sent = 0; 289 state(hdlc)->request_sent = 0;
249 hdlc->state.cisco.txseq = hdlc->state.cisco.rxseq = 0; 290 state(hdlc)->txseq = state(hdlc)->rxseq = 0;
250 291
251 init_timer(&hdlc->state.cisco.timer); 292 init_timer(&state(hdlc)->timer);
252 hdlc->state.cisco.timer.expires = jiffies + HZ; /*First poll after 1s*/ 293 state(hdlc)->timer.expires = jiffies + HZ; /*First poll after 1s*/
253 hdlc->state.cisco.timer.function = cisco_timer; 294 state(hdlc)->timer.function = cisco_timer;
254 hdlc->state.cisco.timer.data = (unsigned long)dev; 295 state(hdlc)->timer.data = (unsigned long)dev;
255 add_timer(&hdlc->state.cisco.timer); 296 add_timer(&state(hdlc)->timer);
256} 297}
257 298
258 299
@@ -260,15 +301,24 @@ static void cisco_start(struct net_device *dev)
260static void cisco_stop(struct net_device *dev) 301static void cisco_stop(struct net_device *dev)
261{ 302{
262 hdlc_device *hdlc = dev_to_hdlc(dev); 303 hdlc_device *hdlc = dev_to_hdlc(dev);
263 del_timer_sync(&hdlc->state.cisco.timer); 304 del_timer_sync(&state(hdlc)->timer);
264 netif_dormant_on(dev); 305 netif_dormant_on(dev);
265 hdlc->state.cisco.up = 0; 306 state(hdlc)->up = 0;
266 hdlc->state.cisco.request_sent = 0; 307 state(hdlc)->request_sent = 0;
267} 308}
268 309
269 310
270 311
271int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr) 312static struct hdlc_proto proto = {
313 .start = cisco_start,
314 .stop = cisco_stop,
315 .type_trans = cisco_type_trans,
316 .ioctl = cisco_ioctl,
317 .module = THIS_MODULE,
318};
319
320
321static int cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
272{ 322{
273 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco; 323 cisco_proto __user *cisco_s = ifr->ifr_settings.ifs_ifsu.cisco;
274 const size_t size = sizeof(cisco_proto); 324 const size_t size = sizeof(cisco_proto);
@@ -278,12 +328,14 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
278 328
279 switch (ifr->ifr_settings.type) { 329 switch (ifr->ifr_settings.type) {
280 case IF_GET_PROTO: 330 case IF_GET_PROTO:
331 if (dev_to_hdlc(dev)->proto != &proto)
332 return -EINVAL;
281 ifr->ifr_settings.type = IF_PROTO_CISCO; 333 ifr->ifr_settings.type = IF_PROTO_CISCO;
282 if (ifr->ifr_settings.size < size) { 334 if (ifr->ifr_settings.size < size) {
283 ifr->ifr_settings.size = size; /* data size wanted */ 335 ifr->ifr_settings.size = size; /* data size wanted */
284 return -ENOBUFS; 336 return -ENOBUFS;
285 } 337 }
286 if (copy_to_user(cisco_s, &hdlc->state.cisco.settings, size)) 338 if (copy_to_user(cisco_s, &state(hdlc)->settings, size))
287 return -EFAULT; 339 return -EFAULT;
288 return 0; 340 return 0;
289 341
@@ -302,19 +354,15 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
302 return -EINVAL; 354 return -EINVAL;
303 355
304 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT); 356 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
305
306 if (result) 357 if (result)
307 return result; 358 return result;
308 359
309 hdlc_proto_detach(hdlc); 360 result = attach_hdlc_protocol(dev, &proto, cisco_rx,
310 memcpy(&hdlc->state.cisco.settings, &new_settings, size); 361 sizeof(struct cisco_state));
311 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 362 if (result)
363 return result;
312 364
313 hdlc->proto.start = cisco_start; 365 memcpy(&state(hdlc)->settings, &new_settings, size);
314 hdlc->proto.stop = cisco_stop;
315 hdlc->proto.netif_rx = cisco_rx;
316 hdlc->proto.type_trans = cisco_type_trans;
317 hdlc->proto.id = IF_PROTO_CISCO;
318 dev->hard_start_xmit = hdlc->xmit; 366 dev->hard_start_xmit = hdlc->xmit;
319 dev->hard_header = cisco_hard_header; 367 dev->hard_header = cisco_hard_header;
320 dev->hard_header_cache = NULL; 368 dev->hard_header_cache = NULL;
@@ -327,3 +375,25 @@ int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr)
327 375
328 return -EINVAL; 376 return -EINVAL;
329} 377}
378
379
380static int __init mod_init(void)
381{
382 register_hdlc_protocol(&proto);
383 return 0;
384}
385
386
387
388static void __exit mod_exit(void)
389{
390 unregister_hdlc_protocol(&proto);
391}
392
393
394module_init(mod_init);
395module_exit(mod_exit);
396
397MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
398MODULE_DESCRIPTION("Cisco HDLC protocol support for generic HDLC");
399MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 7bb737bbdeb9..b45ab680d2d6 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Frame Relay support 3 * Frame Relay support
4 * 4 *
5 * Copyright (C) 1999 - 2005 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -52,6 +52,8 @@
52#undef DEBUG_PKT 52#undef DEBUG_PKT
53#undef DEBUG_ECN 53#undef DEBUG_ECN
54#undef DEBUG_LINK 54#undef DEBUG_LINK
55#undef DEBUG_PROTO
56#undef DEBUG_PVC
55 57
56#define FR_UI 0x03 58#define FR_UI 0x03
57#define FR_PAD 0x00 59#define FR_PAD 0x00
@@ -115,13 +117,53 @@ typedef struct {
115}__attribute__ ((packed)) fr_hdr; 117}__attribute__ ((packed)) fr_hdr;
116 118
117 119
120typedef struct pvc_device_struct {
121 struct net_device *frad;
122 struct net_device *main;
123 struct net_device *ether; /* bridged Ethernet interface */
124 struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
125 int dlci;
126 int open_count;
127
128 struct {
129 unsigned int new: 1;
130 unsigned int active: 1;
131 unsigned int exist: 1;
132 unsigned int deleted: 1;
133 unsigned int fecn: 1;
134 unsigned int becn: 1;
135 unsigned int bandwidth; /* Cisco LMI reporting only */
136 }state;
137}pvc_device;
138
139
140struct frad_state {
141 fr_proto settings;
142 pvc_device *first_pvc;
143 int dce_pvc_count;
144
145 struct timer_list timer;
146 unsigned long last_poll;
147 int reliable;
148 int dce_changed;
149 int request;
150 int fullrep_sent;
151 u32 last_errors; /* last errors bit list */
152 u8 n391cnt;
153 u8 txseq; /* TX sequence number */
154 u8 rxseq; /* RX sequence number */
155};
156
157
158static int fr_ioctl(struct net_device *dev, struct ifreq *ifr);
159
160
118static inline u16 q922_to_dlci(u8 *hdr) 161static inline u16 q922_to_dlci(u8 *hdr)
119{ 162{
120 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4); 163 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
121} 164}
122 165
123 166
124
125static inline void dlci_to_q922(u8 *hdr, u16 dlci) 167static inline void dlci_to_q922(u8 *hdr, u16 dlci)
126{ 168{
127 hdr[0] = (dlci >> 2) & 0xFC; 169 hdr[0] = (dlci >> 2) & 0xFC;
@@ -129,10 +171,21 @@ static inline void dlci_to_q922(u8 *hdr, u16 dlci)
129} 171}
130 172
131 173
174static inline struct frad_state * state(hdlc_device *hdlc)
175{
176 return(struct frad_state *)(hdlc->state);
177}
178
179
180static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
181{
182 return dev->priv;
183}
184
132 185
133static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci) 186static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
134{ 187{
135 pvc_device *pvc = hdlc->state.fr.first_pvc; 188 pvc_device *pvc = state(hdlc)->first_pvc;
136 189
137 while (pvc) { 190 while (pvc) {
138 if (pvc->dlci == dlci) 191 if (pvc->dlci == dlci)
@@ -146,10 +199,10 @@ static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
146} 199}
147 200
148 201
149static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci) 202static pvc_device* add_pvc(struct net_device *dev, u16 dlci)
150{ 203{
151 hdlc_device *hdlc = dev_to_hdlc(dev); 204 hdlc_device *hdlc = dev_to_hdlc(dev);
152 pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc; 205 pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc;
153 206
154 while (*pvc_p) { 207 while (*pvc_p) {
155 if ((*pvc_p)->dlci == dlci) 208 if ((*pvc_p)->dlci == dlci)
@@ -160,12 +213,15 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci)
160 } 213 }
161 214
162 pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC); 215 pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC);
216#ifdef DEBUG_PVC
217 printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev);
218#endif
163 if (!pvc) 219 if (!pvc)
164 return NULL; 220 return NULL;
165 221
166 memset(pvc, 0, sizeof(pvc_device)); 222 memset(pvc, 0, sizeof(pvc_device));
167 pvc->dlci = dlci; 223 pvc->dlci = dlci;
168 pvc->master = dev; 224 pvc->frad = dev;
169 pvc->next = *pvc_p; /* Put it in the chain */ 225 pvc->next = *pvc_p; /* Put it in the chain */
170 *pvc_p = pvc; 226 *pvc_p = pvc;
171 return pvc; 227 return pvc;
@@ -174,7 +230,7 @@ static inline pvc_device* add_pvc(struct net_device *dev, u16 dlci)
174 230
175static inline int pvc_is_used(pvc_device *pvc) 231static inline int pvc_is_used(pvc_device *pvc)
176{ 232{
177 return pvc->main != NULL || pvc->ether != NULL; 233 return pvc->main || pvc->ether;
178} 234}
179 235
180 236
@@ -200,11 +256,14 @@ static inline void pvc_carrier(int on, pvc_device *pvc)
200 256
201static inline void delete_unused_pvcs(hdlc_device *hdlc) 257static inline void delete_unused_pvcs(hdlc_device *hdlc)
202{ 258{
203 pvc_device **pvc_p = &hdlc->state.fr.first_pvc; 259 pvc_device **pvc_p = &state(hdlc)->first_pvc;
204 260
205 while (*pvc_p) { 261 while (*pvc_p) {
206 if (!pvc_is_used(*pvc_p)) { 262 if (!pvc_is_used(*pvc_p)) {
207 pvc_device *pvc = *pvc_p; 263 pvc_device *pvc = *pvc_p;
264#ifdef DEBUG_PVC
265 printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc);
266#endif
208 *pvc_p = pvc->next; 267 *pvc_p = pvc->next;
209 kfree(pvc); 268 kfree(pvc);
210 continue; 269 continue;
@@ -295,16 +354,16 @@ static int pvc_open(struct net_device *dev)
295{ 354{
296 pvc_device *pvc = dev_to_pvc(dev); 355 pvc_device *pvc = dev_to_pvc(dev);
297 356
298 if ((pvc->master->flags & IFF_UP) == 0) 357 if ((pvc->frad->flags & IFF_UP) == 0)
299 return -EIO; /* Master must be UP in order to activate PVC */ 358 return -EIO; /* Frad must be UP in order to activate PVC */
300 359
301 if (pvc->open_count++ == 0) { 360 if (pvc->open_count++ == 0) {
302 hdlc_device *hdlc = dev_to_hdlc(pvc->master); 361 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
303 if (hdlc->state.fr.settings.lmi == LMI_NONE) 362 if (state(hdlc)->settings.lmi == LMI_NONE)
304 pvc->state.active = netif_carrier_ok(pvc->master); 363 pvc->state.active = netif_carrier_ok(pvc->frad);
305 364
306 pvc_carrier(pvc->state.active, pvc); 365 pvc_carrier(pvc->state.active, pvc);
307 hdlc->state.fr.dce_changed = 1; 366 state(hdlc)->dce_changed = 1;
308 } 367 }
309 return 0; 368 return 0;
310} 369}
@@ -316,12 +375,12 @@ static int pvc_close(struct net_device *dev)
316 pvc_device *pvc = dev_to_pvc(dev); 375 pvc_device *pvc = dev_to_pvc(dev);
317 376
318 if (--pvc->open_count == 0) { 377 if (--pvc->open_count == 0) {
319 hdlc_device *hdlc = dev_to_hdlc(pvc->master); 378 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
320 if (hdlc->state.fr.settings.lmi == LMI_NONE) 379 if (state(hdlc)->settings.lmi == LMI_NONE)
321 pvc->state.active = 0; 380 pvc->state.active = 0;
322 381
323 if (hdlc->state.fr.settings.dce) { 382 if (state(hdlc)->settings.dce) {
324 hdlc->state.fr.dce_changed = 1; 383 state(hdlc)->dce_changed = 1;
325 pvc->state.active = 0; 384 pvc->state.active = 0;
326 } 385 }
327 } 386 }
@@ -348,7 +407,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
348 } 407 }
349 408
350 info.dlci = pvc->dlci; 409 info.dlci = pvc->dlci;
351 memcpy(info.master, pvc->master->name, IFNAMSIZ); 410 memcpy(info.master, pvc->frad->name, IFNAMSIZ);
352 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info, 411 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info,
353 &info, sizeof(info))) 412 &info, sizeof(info)))
354 return -EFAULT; 413 return -EFAULT;
@@ -361,7 +420,7 @@ static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
361 420
362static inline struct net_device_stats *pvc_get_stats(struct net_device *dev) 421static inline struct net_device_stats *pvc_get_stats(struct net_device *dev)
363{ 422{
364 return netdev_priv(dev); 423 return &dev_to_desc(dev)->stats;
365} 424}
366 425
367 426
@@ -393,7 +452,7 @@ static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
393 stats->tx_packets++; 452 stats->tx_packets++;
394 if (pvc->state.fecn) /* TX Congestion counter */ 453 if (pvc->state.fecn) /* TX Congestion counter */
395 stats->tx_compressed++; 454 stats->tx_compressed++;
396 skb->dev = pvc->master; 455 skb->dev = pvc->frad;
397 dev_queue_xmit(skb); 456 dev_queue_xmit(skb);
398 return 0; 457 return 0;
399 } 458 }
@@ -419,7 +478,7 @@ static int pvc_change_mtu(struct net_device *dev, int new_mtu)
419static inline void fr_log_dlci_active(pvc_device *pvc) 478static inline void fr_log_dlci_active(pvc_device *pvc)
420{ 479{
421 printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n", 480 printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
422 pvc->master->name, 481 pvc->frad->name,
423 pvc->dlci, 482 pvc->dlci,
424 pvc->main ? pvc->main->name : "", 483 pvc->main ? pvc->main->name : "",
425 pvc->main && pvc->ether ? " " : "", 484 pvc->main && pvc->ether ? " " : "",
@@ -438,21 +497,20 @@ static inline u8 fr_lmi_nextseq(u8 x)
438} 497}
439 498
440 499
441
442static void fr_lmi_send(struct net_device *dev, int fullrep) 500static void fr_lmi_send(struct net_device *dev, int fullrep)
443{ 501{
444 hdlc_device *hdlc = dev_to_hdlc(dev); 502 hdlc_device *hdlc = dev_to_hdlc(dev);
445 struct sk_buff *skb; 503 struct sk_buff *skb;
446 pvc_device *pvc = hdlc->state.fr.first_pvc; 504 pvc_device *pvc = state(hdlc)->first_pvc;
447 int lmi = hdlc->state.fr.settings.lmi; 505 int lmi = state(hdlc)->settings.lmi;
448 int dce = hdlc->state.fr.settings.dce; 506 int dce = state(hdlc)->settings.dce;
449 int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH; 507 int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
450 int stat_len = (lmi == LMI_CISCO) ? 6 : 3; 508 int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
451 u8 *data; 509 u8 *data;
452 int i = 0; 510 int i = 0;
453 511
454 if (dce && fullrep) { 512 if (dce && fullrep) {
455 len += hdlc->state.fr.dce_pvc_count * (2 + stat_len); 513 len += state(hdlc)->dce_pvc_count * (2 + stat_len);
456 if (len > HDLC_MAX_MRU) { 514 if (len > HDLC_MAX_MRU) {
457 printk(KERN_WARNING "%s: Too many PVCs while sending " 515 printk(KERN_WARNING "%s: Too many PVCs while sending "
458 "LMI full report\n", dev->name); 516 "LMI full report\n", dev->name);
@@ -486,8 +544,9 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
486 data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY; 544 data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
487 data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE; 545 data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
488 data[i++] = LMI_INTEG_LEN; 546 data[i++] = LMI_INTEG_LEN;
489 data[i++] = hdlc->state.fr.txseq =fr_lmi_nextseq(hdlc->state.fr.txseq); 547 data[i++] = state(hdlc)->txseq =
490 data[i++] = hdlc->state.fr.rxseq; 548 fr_lmi_nextseq(state(hdlc)->txseq);
549 data[i++] = state(hdlc)->rxseq;
491 550
492 if (dce && fullrep) { 551 if (dce && fullrep) {
493 while (pvc) { 552 while (pvc) {
@@ -496,7 +555,7 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
496 data[i++] = stat_len; 555 data[i++] = stat_len;
497 556
498 /* LMI start/restart */ 557 /* LMI start/restart */
499 if (hdlc->state.fr.reliable && !pvc->state.exist) { 558 if (state(hdlc)->reliable && !pvc->state.exist) {
500 pvc->state.exist = pvc->state.new = 1; 559 pvc->state.exist = pvc->state.new = 1;
501 fr_log_dlci_active(pvc); 560 fr_log_dlci_active(pvc);
502 } 561 }
@@ -541,15 +600,15 @@ static void fr_lmi_send(struct net_device *dev, int fullrep)
541static void fr_set_link_state(int reliable, struct net_device *dev) 600static void fr_set_link_state(int reliable, struct net_device *dev)
542{ 601{
543 hdlc_device *hdlc = dev_to_hdlc(dev); 602 hdlc_device *hdlc = dev_to_hdlc(dev);
544 pvc_device *pvc = hdlc->state.fr.first_pvc; 603 pvc_device *pvc = state(hdlc)->first_pvc;
545 604
546 hdlc->state.fr.reliable = reliable; 605 state(hdlc)->reliable = reliable;
547 if (reliable) { 606 if (reliable) {
548 netif_dormant_off(dev); 607 netif_dormant_off(dev);
549 hdlc->state.fr.n391cnt = 0; /* Request full status */ 608 state(hdlc)->n391cnt = 0; /* Request full status */
550 hdlc->state.fr.dce_changed = 1; 609 state(hdlc)->dce_changed = 1;
551 610
552 if (hdlc->state.fr.settings.lmi == LMI_NONE) { 611 if (state(hdlc)->settings.lmi == LMI_NONE) {
553 while (pvc) { /* Activate all PVCs */ 612 while (pvc) { /* Activate all PVCs */
554 pvc_carrier(1, pvc); 613 pvc_carrier(1, pvc);
555 pvc->state.exist = pvc->state.active = 1; 614 pvc->state.exist = pvc->state.active = 1;
@@ -563,7 +622,7 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
563 pvc_carrier(0, pvc); 622 pvc_carrier(0, pvc);
564 pvc->state.exist = pvc->state.active = 0; 623 pvc->state.exist = pvc->state.active = 0;
565 pvc->state.new = 0; 624 pvc->state.new = 0;
566 if (!hdlc->state.fr.settings.dce) 625 if (!state(hdlc)->settings.dce)
567 pvc->state.bandwidth = 0; 626 pvc->state.bandwidth = 0;
568 pvc = pvc->next; 627 pvc = pvc->next;
569 } 628 }
@@ -571,7 +630,6 @@ static void fr_set_link_state(int reliable, struct net_device *dev)
571} 630}
572 631
573 632
574
575static void fr_timer(unsigned long arg) 633static void fr_timer(unsigned long arg)
576{ 634{
577 struct net_device *dev = (struct net_device *)arg; 635 struct net_device *dev = (struct net_device *)arg;
@@ -579,62 +637,61 @@ static void fr_timer(unsigned long arg)
579 int i, cnt = 0, reliable; 637 int i, cnt = 0, reliable;
580 u32 list; 638 u32 list;
581 639
582 if (hdlc->state.fr.settings.dce) { 640 if (state(hdlc)->settings.dce) {
583 reliable = hdlc->state.fr.request && 641 reliable = state(hdlc)->request &&
584 time_before(jiffies, hdlc->state.fr.last_poll + 642 time_before(jiffies, state(hdlc)->last_poll +
585 hdlc->state.fr.settings.t392 * HZ); 643 state(hdlc)->settings.t392 * HZ);
586 hdlc->state.fr.request = 0; 644 state(hdlc)->request = 0;
587 } else { 645 } else {
588 hdlc->state.fr.last_errors <<= 1; /* Shift the list */ 646 state(hdlc)->last_errors <<= 1; /* Shift the list */
589 if (hdlc->state.fr.request) { 647 if (state(hdlc)->request) {
590 if (hdlc->state.fr.reliable) 648 if (state(hdlc)->reliable)
591 printk(KERN_INFO "%s: No LMI status reply " 649 printk(KERN_INFO "%s: No LMI status reply "
592 "received\n", dev->name); 650 "received\n", dev->name);
593 hdlc->state.fr.last_errors |= 1; 651 state(hdlc)->last_errors |= 1;
594 } 652 }
595 653
596 list = hdlc->state.fr.last_errors; 654 list = state(hdlc)->last_errors;
597 for (i = 0; i < hdlc->state.fr.settings.n393; i++, list >>= 1) 655 for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1)
598 cnt += (list & 1); /* errors count */ 656 cnt += (list & 1); /* errors count */
599 657
600 reliable = (cnt < hdlc->state.fr.settings.n392); 658 reliable = (cnt < state(hdlc)->settings.n392);
601 } 659 }
602 660
603 if (hdlc->state.fr.reliable != reliable) { 661 if (state(hdlc)->reliable != reliable) {
604 printk(KERN_INFO "%s: Link %sreliable\n", dev->name, 662 printk(KERN_INFO "%s: Link %sreliable\n", dev->name,
605 reliable ? "" : "un"); 663 reliable ? "" : "un");
606 fr_set_link_state(reliable, dev); 664 fr_set_link_state(reliable, dev);
607 } 665 }
608 666
609 if (hdlc->state.fr.settings.dce) 667 if (state(hdlc)->settings.dce)
610 hdlc->state.fr.timer.expires = jiffies + 668 state(hdlc)->timer.expires = jiffies +
611 hdlc->state.fr.settings.t392 * HZ; 669 state(hdlc)->settings.t392 * HZ;
612 else { 670 else {
613 if (hdlc->state.fr.n391cnt) 671 if (state(hdlc)->n391cnt)
614 hdlc->state.fr.n391cnt--; 672 state(hdlc)->n391cnt--;
615 673
616 fr_lmi_send(dev, hdlc->state.fr.n391cnt == 0); 674 fr_lmi_send(dev, state(hdlc)->n391cnt == 0);
617 675
618 hdlc->state.fr.last_poll = jiffies; 676 state(hdlc)->last_poll = jiffies;
619 hdlc->state.fr.request = 1; 677 state(hdlc)->request = 1;
620 hdlc->state.fr.timer.expires = jiffies + 678 state(hdlc)->timer.expires = jiffies +
621 hdlc->state.fr.settings.t391 * HZ; 679 state(hdlc)->settings.t391 * HZ;
622 } 680 }
623 681
624 hdlc->state.fr.timer.function = fr_timer; 682 state(hdlc)->timer.function = fr_timer;
625 hdlc->state.fr.timer.data = arg; 683 state(hdlc)->timer.data = arg;
626 add_timer(&hdlc->state.fr.timer); 684 add_timer(&state(hdlc)->timer);
627} 685}
628 686
629 687
630
631static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb) 688static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
632{ 689{
633 hdlc_device *hdlc = dev_to_hdlc(dev); 690 hdlc_device *hdlc = dev_to_hdlc(dev);
634 pvc_device *pvc; 691 pvc_device *pvc;
635 u8 rxseq, txseq; 692 u8 rxseq, txseq;
636 int lmi = hdlc->state.fr.settings.lmi; 693 int lmi = state(hdlc)->settings.lmi;
637 int dce = hdlc->state.fr.settings.dce; 694 int dce = state(hdlc)->settings.dce;
638 int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i; 695 int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
639 696
640 if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH : 697 if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
@@ -645,8 +702,8 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
645 702
646 if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI : 703 if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
647 NLPID_CCITT_ANSI_LMI)) { 704 NLPID_CCITT_ANSI_LMI)) {
648 printk(KERN_INFO "%s: Received non-LMI frame with LMI" 705 printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
649 " DLCI\n", dev->name); 706 dev->name);
650 return 1; 707 return 1;
651 } 708 }
652 709
@@ -706,53 +763,53 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
706 } 763 }
707 i++; 764 i++;
708 765
709 hdlc->state.fr.rxseq = skb->data[i++]; /* TX sequence from peer */ 766 state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */
710 rxseq = skb->data[i++]; /* Should confirm our sequence */ 767 rxseq = skb->data[i++]; /* Should confirm our sequence */
711 768
712 txseq = hdlc->state.fr.txseq; 769 txseq = state(hdlc)->txseq;
713 770
714 if (dce) 771 if (dce)
715 hdlc->state.fr.last_poll = jiffies; 772 state(hdlc)->last_poll = jiffies;
716 773
717 error = 0; 774 error = 0;
718 if (!hdlc->state.fr.reliable) 775 if (!state(hdlc)->reliable)
719 error = 1; 776 error = 1;
720 777
721 if (rxseq == 0 || rxseq != txseq) { 778 if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */
722 hdlc->state.fr.n391cnt = 0; /* Ask for full report next time */ 779 state(hdlc)->n391cnt = 0;
723 error = 1; 780 error = 1;
724 } 781 }
725 782
726 if (dce) { 783 if (dce) {
727 if (hdlc->state.fr.fullrep_sent && !error) { 784 if (state(hdlc)->fullrep_sent && !error) {
728/* Stop sending full report - the last one has been confirmed by DTE */ 785/* Stop sending full report - the last one has been confirmed by DTE */
729 hdlc->state.fr.fullrep_sent = 0; 786 state(hdlc)->fullrep_sent = 0;
730 pvc = hdlc->state.fr.first_pvc; 787 pvc = state(hdlc)->first_pvc;
731 while (pvc) { 788 while (pvc) {
732 if (pvc->state.new) { 789 if (pvc->state.new) {
733 pvc->state.new = 0; 790 pvc->state.new = 0;
734 791
735/* Tell DTE that new PVC is now active */ 792/* Tell DTE that new PVC is now active */
736 hdlc->state.fr.dce_changed = 1; 793 state(hdlc)->dce_changed = 1;
737 } 794 }
738 pvc = pvc->next; 795 pvc = pvc->next;
739 } 796 }
740 } 797 }
741 798
742 if (hdlc->state.fr.dce_changed) { 799 if (state(hdlc)->dce_changed) {
743 reptype = LMI_FULLREP; 800 reptype = LMI_FULLREP;
744 hdlc->state.fr.fullrep_sent = 1; 801 state(hdlc)->fullrep_sent = 1;
745 hdlc->state.fr.dce_changed = 0; 802 state(hdlc)->dce_changed = 0;
746 } 803 }
747 804
748 hdlc->state.fr.request = 1; /* got request */ 805 state(hdlc)->request = 1; /* got request */
749 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0); 806 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
750 return 0; 807 return 0;
751 } 808 }
752 809
753 /* DTE */ 810 /* DTE */
754 811
755 hdlc->state.fr.request = 0; /* got response, no request pending */ 812 state(hdlc)->request = 0; /* got response, no request pending */
756 813
757 if (error) 814 if (error)
758 return 0; 815 return 0;
@@ -760,7 +817,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
760 if (reptype != LMI_FULLREP) 817 if (reptype != LMI_FULLREP)
761 return 0; 818 return 0;
762 819
763 pvc = hdlc->state.fr.first_pvc; 820 pvc = state(hdlc)->first_pvc;
764 821
765 while (pvc) { 822 while (pvc) {
766 pvc->state.deleted = 1; 823 pvc->state.deleted = 1;
@@ -827,7 +884,7 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
827 i += stat_len; 884 i += stat_len;
828 } 885 }
829 886
830 pvc = hdlc->state.fr.first_pvc; 887 pvc = state(hdlc)->first_pvc;
831 888
832 while (pvc) { 889 while (pvc) {
833 if (pvc->state.deleted && pvc->state.exist) { 890 if (pvc->state.deleted && pvc->state.exist) {
@@ -841,17 +898,16 @@ static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
841 } 898 }
842 899
843 /* Next full report after N391 polls */ 900 /* Next full report after N391 polls */
844 hdlc->state.fr.n391cnt = hdlc->state.fr.settings.n391; 901 state(hdlc)->n391cnt = state(hdlc)->settings.n391;
845 902
846 return 0; 903 return 0;
847} 904}
848 905
849 906
850
851static int fr_rx(struct sk_buff *skb) 907static int fr_rx(struct sk_buff *skb)
852{ 908{
853 struct net_device *ndev = skb->dev; 909 struct net_device *frad = skb->dev;
854 hdlc_device *hdlc = dev_to_hdlc(ndev); 910 hdlc_device *hdlc = dev_to_hdlc(frad);
855 fr_hdr *fh = (fr_hdr*)skb->data; 911 fr_hdr *fh = (fr_hdr*)skb->data;
856 u8 *data = skb->data; 912 u8 *data = skb->data;
857 u16 dlci; 913 u16 dlci;
@@ -864,11 +920,11 @@ static int fr_rx(struct sk_buff *skb)
864 dlci = q922_to_dlci(skb->data); 920 dlci = q922_to_dlci(skb->data);
865 921
866 if ((dlci == LMI_CCITT_ANSI_DLCI && 922 if ((dlci == LMI_CCITT_ANSI_DLCI &&
867 (hdlc->state.fr.settings.lmi == LMI_ANSI || 923 (state(hdlc)->settings.lmi == LMI_ANSI ||
868 hdlc->state.fr.settings.lmi == LMI_CCITT)) || 924 state(hdlc)->settings.lmi == LMI_CCITT)) ||
869 (dlci == LMI_CISCO_DLCI && 925 (dlci == LMI_CISCO_DLCI &&
870 hdlc->state.fr.settings.lmi == LMI_CISCO)) { 926 state(hdlc)->settings.lmi == LMI_CISCO)) {
871 if (fr_lmi_recv(ndev, skb)) 927 if (fr_lmi_recv(frad, skb))
872 goto rx_error; 928 goto rx_error;
873 dev_kfree_skb_any(skb); 929 dev_kfree_skb_any(skb);
874 return NET_RX_SUCCESS; 930 return NET_RX_SUCCESS;
@@ -878,7 +934,7 @@ static int fr_rx(struct sk_buff *skb)
878 if (!pvc) { 934 if (!pvc) {
879#ifdef DEBUG_PKT 935#ifdef DEBUG_PKT
880 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n", 936 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n",
881 ndev->name, dlci); 937 frad->name, dlci);
882#endif 938#endif
883 dev_kfree_skb_any(skb); 939 dev_kfree_skb_any(skb);
884 return NET_RX_DROP; 940 return NET_RX_DROP;
@@ -886,7 +942,7 @@ static int fr_rx(struct sk_buff *skb)
886 942
887 if (pvc->state.fecn != fh->fecn) { 943 if (pvc->state.fecn != fh->fecn) {
888#ifdef DEBUG_ECN 944#ifdef DEBUG_ECN
889 printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", ndev->name, 945 printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name,
890 dlci, fh->fecn ? "N" : "FF"); 946 dlci, fh->fecn ? "N" : "FF");
891#endif 947#endif
892 pvc->state.fecn ^= 1; 948 pvc->state.fecn ^= 1;
@@ -894,7 +950,7 @@ static int fr_rx(struct sk_buff *skb)
894 950
895 if (pvc->state.becn != fh->becn) { 951 if (pvc->state.becn != fh->becn) {
896#ifdef DEBUG_ECN 952#ifdef DEBUG_ECN
897 printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", ndev->name, 953 printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name,
898 dlci, fh->becn ? "N" : "FF"); 954 dlci, fh->becn ? "N" : "FF");
899#endif 955#endif
900 pvc->state.becn ^= 1; 956 pvc->state.becn ^= 1;
@@ -902,7 +958,7 @@ static int fr_rx(struct sk_buff *skb)
902 958
903 959
904 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 960 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
905 hdlc->stats.rx_dropped++; 961 dev_to_desc(frad)->stats.rx_dropped++;
906 return NET_RX_DROP; 962 return NET_RX_DROP;
907 } 963 }
908 964
@@ -938,13 +994,13 @@ static int fr_rx(struct sk_buff *skb)
938 994
939 default: 995 default:
940 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x " 996 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x "
941 "PID=%x\n", ndev->name, oui, pid); 997 "PID=%x\n", frad->name, oui, pid);
942 dev_kfree_skb_any(skb); 998 dev_kfree_skb_any(skb);
943 return NET_RX_DROP; 999 return NET_RX_DROP;
944 } 1000 }
945 } else { 1001 } else {
946 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x " 1002 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x "
947 "length = %i\n", ndev->name, data[3], skb->len); 1003 "length = %i\n", frad->name, data[3], skb->len);
948 dev_kfree_skb_any(skb); 1004 dev_kfree_skb_any(skb);
949 return NET_RX_DROP; 1005 return NET_RX_DROP;
950 } 1006 }
@@ -964,7 +1020,7 @@ static int fr_rx(struct sk_buff *skb)
964 } 1020 }
965 1021
966 rx_error: 1022 rx_error:
967 hdlc->stats.rx_errors++; /* Mark error */ 1023 dev_to_desc(frad)->stats.rx_errors++; /* Mark error */
968 dev_kfree_skb_any(skb); 1024 dev_kfree_skb_any(skb);
969 return NET_RX_DROP; 1025 return NET_RX_DROP;
970} 1026}
@@ -977,44 +1033,42 @@ static void fr_start(struct net_device *dev)
977#ifdef DEBUG_LINK 1033#ifdef DEBUG_LINK
978 printk(KERN_DEBUG "fr_start\n"); 1034 printk(KERN_DEBUG "fr_start\n");
979#endif 1035#endif
980 if (hdlc->state.fr.settings.lmi != LMI_NONE) { 1036 if (state(hdlc)->settings.lmi != LMI_NONE) {
981 hdlc->state.fr.reliable = 0; 1037 state(hdlc)->reliable = 0;
982 hdlc->state.fr.dce_changed = 1; 1038 state(hdlc)->dce_changed = 1;
983 hdlc->state.fr.request = 0; 1039 state(hdlc)->request = 0;
984 hdlc->state.fr.fullrep_sent = 0; 1040 state(hdlc)->fullrep_sent = 0;
985 hdlc->state.fr.last_errors = 0xFFFFFFFF; 1041 state(hdlc)->last_errors = 0xFFFFFFFF;
986 hdlc->state.fr.n391cnt = 0; 1042 state(hdlc)->n391cnt = 0;
987 hdlc->state.fr.txseq = hdlc->state.fr.rxseq = 0; 1043 state(hdlc)->txseq = state(hdlc)->rxseq = 0;
988 1044
989 init_timer(&hdlc->state.fr.timer); 1045 init_timer(&state(hdlc)->timer);
990 /* First poll after 1 s */ 1046 /* First poll after 1 s */
991 hdlc->state.fr.timer.expires = jiffies + HZ; 1047 state(hdlc)->timer.expires = jiffies + HZ;
992 hdlc->state.fr.timer.function = fr_timer; 1048 state(hdlc)->timer.function = fr_timer;
993 hdlc->state.fr.timer.data = (unsigned long)dev; 1049 state(hdlc)->timer.data = (unsigned long)dev;
994 add_timer(&hdlc->state.fr.timer); 1050 add_timer(&state(hdlc)->timer);
995 } else 1051 } else
996 fr_set_link_state(1, dev); 1052 fr_set_link_state(1, dev);
997} 1053}
998 1054
999 1055
1000
1001static void fr_stop(struct net_device *dev) 1056static void fr_stop(struct net_device *dev)
1002{ 1057{
1003 hdlc_device *hdlc = dev_to_hdlc(dev); 1058 hdlc_device *hdlc = dev_to_hdlc(dev);
1004#ifdef DEBUG_LINK 1059#ifdef DEBUG_LINK
1005 printk(KERN_DEBUG "fr_stop\n"); 1060 printk(KERN_DEBUG "fr_stop\n");
1006#endif 1061#endif
1007 if (hdlc->state.fr.settings.lmi != LMI_NONE) 1062 if (state(hdlc)->settings.lmi != LMI_NONE)
1008 del_timer_sync(&hdlc->state.fr.timer); 1063 del_timer_sync(&state(hdlc)->timer);
1009 fr_set_link_state(0, dev); 1064 fr_set_link_state(0, dev);
1010} 1065}
1011 1066
1012 1067
1013
1014static void fr_close(struct net_device *dev) 1068static void fr_close(struct net_device *dev)
1015{ 1069{
1016 hdlc_device *hdlc = dev_to_hdlc(dev); 1070 hdlc_device *hdlc = dev_to_hdlc(dev);
1017 pvc_device *pvc = hdlc->state.fr.first_pvc; 1071 pvc_device *pvc = state(hdlc)->first_pvc;
1018 1072
1019 while (pvc) { /* Shutdown all PVCs for this FRAD */ 1073 while (pvc) { /* Shutdown all PVCs for this FRAD */
1020 if (pvc->main) 1074 if (pvc->main)
@@ -1025,7 +1079,8 @@ static void fr_close(struct net_device *dev)
1025 } 1079 }
1026} 1080}
1027 1081
1028static void dlci_setup(struct net_device *dev) 1082
1083static void pvc_setup(struct net_device *dev)
1029{ 1084{
1030 dev->type = ARPHRD_DLCI; 1085 dev->type = ARPHRD_DLCI;
1031 dev->flags = IFF_POINTOPOINT; 1086 dev->flags = IFF_POINTOPOINT;
@@ -1033,9 +1088,9 @@ static void dlci_setup(struct net_device *dev)
1033 dev->addr_len = 2; 1088 dev->addr_len = 2;
1034} 1089}
1035 1090
1036static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type) 1091static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1037{ 1092{
1038 hdlc_device *hdlc = dev_to_hdlc(master); 1093 hdlc_device *hdlc = dev_to_hdlc(frad);
1039 pvc_device *pvc = NULL; 1094 pvc_device *pvc = NULL;
1040 struct net_device *dev; 1095 struct net_device *dev;
1041 int result, used; 1096 int result, used;
@@ -1044,9 +1099,9 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1044 if (type == ARPHRD_ETHER) 1099 if (type == ARPHRD_ETHER)
1045 prefix = "pvceth%d"; 1100 prefix = "pvceth%d";
1046 1101
1047 if ((pvc = add_pvc(master, dlci)) == NULL) { 1102 if ((pvc = add_pvc(frad, dlci)) == NULL) {
1048 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n", 1103 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
1049 master->name); 1104 frad->name);
1050 return -ENOBUFS; 1105 return -ENOBUFS;
1051 } 1106 }
1052 1107
@@ -1060,11 +1115,11 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1060 "pvceth%d", ether_setup); 1115 "pvceth%d", ether_setup);
1061 else 1116 else
1062 dev = alloc_netdev(sizeof(struct net_device_stats), 1117 dev = alloc_netdev(sizeof(struct net_device_stats),
1063 "pvc%d", dlci_setup); 1118 "pvc%d", pvc_setup);
1064 1119
1065 if (!dev) { 1120 if (!dev) {
1066 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n", 1121 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1067 master->name); 1122 frad->name);
1068 delete_unused_pvcs(hdlc); 1123 delete_unused_pvcs(hdlc);
1069 return -ENOBUFS; 1124 return -ENOBUFS;
1070 } 1125 }
@@ -1102,8 +1157,8 @@ static int fr_add_pvc(struct net_device *master, unsigned int dlci, int type)
1102 dev->destructor = free_netdev; 1157 dev->destructor = free_netdev;
1103 *get_dev_p(pvc, type) = dev; 1158 *get_dev_p(pvc, type) = dev;
1104 if (!used) { 1159 if (!used) {
1105 hdlc->state.fr.dce_changed = 1; 1160 state(hdlc)->dce_changed = 1;
1106 hdlc->state.fr.dce_pvc_count++; 1161 state(hdlc)->dce_pvc_count++;
1107 } 1162 }
1108 return 0; 1163 return 0;
1109} 1164}
@@ -1128,8 +1183,8 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1128 *get_dev_p(pvc, type) = NULL; 1183 *get_dev_p(pvc, type) = NULL;
1129 1184
1130 if (!pvc_is_used(pvc)) { 1185 if (!pvc_is_used(pvc)) {
1131 hdlc->state.fr.dce_pvc_count--; 1186 state(hdlc)->dce_pvc_count--;
1132 hdlc->state.fr.dce_changed = 1; 1187 state(hdlc)->dce_changed = 1;
1133 } 1188 }
1134 delete_unused_pvcs(hdlc); 1189 delete_unused_pvcs(hdlc);
1135 return 0; 1190 return 0;
@@ -1137,14 +1192,13 @@ static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1137 1192
1138 1193
1139 1194
1140static void fr_destroy(hdlc_device *hdlc) 1195static void fr_destroy(struct net_device *frad)
1141{ 1196{
1142 pvc_device *pvc; 1197 hdlc_device *hdlc = dev_to_hdlc(frad);
1143 1198 pvc_device *pvc = state(hdlc)->first_pvc;
1144 pvc = hdlc->state.fr.first_pvc; 1199 state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */
1145 hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */ 1200 state(hdlc)->dce_pvc_count = 0;
1146 hdlc->state.fr.dce_pvc_count = 0; 1201 state(hdlc)->dce_changed = 1;
1147 hdlc->state.fr.dce_changed = 1;
1148 1202
1149 while (pvc) { 1203 while (pvc) {
1150 pvc_device *next = pvc->next; 1204 pvc_device *next = pvc->next;
@@ -1161,8 +1215,17 @@ static void fr_destroy(hdlc_device *hdlc)
1161} 1215}
1162 1216
1163 1217
1218static struct hdlc_proto proto = {
1219 .close = fr_close,
1220 .start = fr_start,
1221 .stop = fr_stop,
1222 .detach = fr_destroy,
1223 .ioctl = fr_ioctl,
1224 .module = THIS_MODULE,
1225};
1226
1164 1227
1165int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr) 1228static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1166{ 1229{
1167 fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr; 1230 fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
1168 const size_t size = sizeof(fr_proto); 1231 const size_t size = sizeof(fr_proto);
@@ -1173,12 +1236,14 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1173 1236
1174 switch (ifr->ifr_settings.type) { 1237 switch (ifr->ifr_settings.type) {
1175 case IF_GET_PROTO: 1238 case IF_GET_PROTO:
1239 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1240 return -EINVAL;
1176 ifr->ifr_settings.type = IF_PROTO_FR; 1241 ifr->ifr_settings.type = IF_PROTO_FR;
1177 if (ifr->ifr_settings.size < size) { 1242 if (ifr->ifr_settings.size < size) {
1178 ifr->ifr_settings.size = size; /* data size wanted */ 1243 ifr->ifr_settings.size = size; /* data size wanted */
1179 return -ENOBUFS; 1244 return -ENOBUFS;
1180 } 1245 }
1181 if (copy_to_user(fr_s, &hdlc->state.fr.settings, size)) 1246 if (copy_to_user(fr_s, &state(hdlc)->settings, size))
1182 return -EFAULT; 1247 return -EFAULT;
1183 return 0; 1248 return 0;
1184 1249
@@ -1213,20 +1278,16 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1213 if (result) 1278 if (result)
1214 return result; 1279 return result;
1215 1280
1216 if (hdlc->proto.id != IF_PROTO_FR) { 1281 if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
1217 hdlc_proto_detach(hdlc); 1282 result = attach_hdlc_protocol(dev, &proto, fr_rx,
1218 hdlc->state.fr.first_pvc = NULL; 1283 sizeof(struct frad_state));
1219 hdlc->state.fr.dce_pvc_count = 0; 1284 if (result)
1285 return result;
1286 state(hdlc)->first_pvc = NULL;
1287 state(hdlc)->dce_pvc_count = 0;
1220 } 1288 }
1221 memcpy(&hdlc->state.fr.settings, &new_settings, size); 1289 memcpy(&state(hdlc)->settings, &new_settings, size);
1222 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 1290
1223
1224 hdlc->proto.close = fr_close;
1225 hdlc->proto.start = fr_start;
1226 hdlc->proto.stop = fr_stop;
1227 hdlc->proto.detach = fr_destroy;
1228 hdlc->proto.netif_rx = fr_rx;
1229 hdlc->proto.id = IF_PROTO_FR;
1230 dev->hard_start_xmit = hdlc->xmit; 1291 dev->hard_start_xmit = hdlc->xmit;
1231 dev->hard_header = NULL; 1292 dev->hard_header = NULL;
1232 dev->type = ARPHRD_FRAD; 1293 dev->type = ARPHRD_FRAD;
@@ -1238,6 +1299,9 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1238 case IF_PROTO_FR_DEL_PVC: 1299 case IF_PROTO_FR_DEL_PVC:
1239 case IF_PROTO_FR_ADD_ETH_PVC: 1300 case IF_PROTO_FR_ADD_ETH_PVC:
1240 case IF_PROTO_FR_DEL_ETH_PVC: 1301 case IF_PROTO_FR_DEL_ETH_PVC:
1302 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1303 return -EINVAL;
1304
1241 if(!capable(CAP_NET_ADMIN)) 1305 if(!capable(CAP_NET_ADMIN))
1242 return -EPERM; 1306 return -EPERM;
1243 1307
@@ -1263,3 +1327,24 @@ int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1263 1327
1264 return -EINVAL; 1328 return -EINVAL;
1265} 1329}
1330
1331
1332static int __init mod_init(void)
1333{
1334 register_hdlc_protocol(&proto);
1335 return 0;
1336}
1337
1338
1339static void __exit mod_exit(void)
1340{
1341 unregister_hdlc_protocol(&proto);
1342}
1343
1344
1345module_init(mod_init);
1346module_exit(mod_exit);
1347
1348MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1349MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
1350MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_ppp.c b/drivers/net/wan/hdlc_ppp.c
index fbaab5bf71eb..e9f717070fde 100644
--- a/drivers/net/wan/hdlc_ppp.c
+++ b/drivers/net/wan/hdlc_ppp.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * Point-to-point protocol support 3 * Point-to-point protocol support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -22,6 +22,21 @@
22#include <linux/lapb.h> 22#include <linux/lapb.h>
23#include <linux/rtnetlink.h> 23#include <linux/rtnetlink.h>
24#include <linux/hdlc.h> 24#include <linux/hdlc.h>
25#include <net/syncppp.h>
26
27struct ppp_state {
28 struct ppp_device pppdev;
29 struct ppp_device *syncppp_ptr;
30 int (*old_change_mtu)(struct net_device *dev, int new_mtu);
31};
32
33static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr);
34
35
36static inline struct ppp_state* state(hdlc_device *hdlc)
37{
38 return(struct ppp_state *)(hdlc->state);
39}
25 40
26 41
27static int ppp_open(struct net_device *dev) 42static int ppp_open(struct net_device *dev)
@@ -30,16 +45,16 @@ static int ppp_open(struct net_device *dev)
30 void *old_ioctl; 45 void *old_ioctl;
31 int result; 46 int result;
32 47
33 dev->priv = &hdlc->state.ppp.syncppp_ptr; 48 dev->priv = &state(hdlc)->syncppp_ptr;
34 hdlc->state.ppp.syncppp_ptr = &hdlc->state.ppp.pppdev; 49 state(hdlc)->syncppp_ptr = &state(hdlc)->pppdev;
35 hdlc->state.ppp.pppdev.dev = dev; 50 state(hdlc)->pppdev.dev = dev;
36 51
37 old_ioctl = dev->do_ioctl; 52 old_ioctl = dev->do_ioctl;
38 hdlc->state.ppp.old_change_mtu = dev->change_mtu; 53 state(hdlc)->old_change_mtu = dev->change_mtu;
39 sppp_attach(&hdlc->state.ppp.pppdev); 54 sppp_attach(&state(hdlc)->pppdev);
40 /* sppp_attach nukes them. We don't need syncppp's ioctl */ 55 /* sppp_attach nukes them. We don't need syncppp's ioctl */
41 dev->do_ioctl = old_ioctl; 56 dev->do_ioctl = old_ioctl;
42 hdlc->state.ppp.pppdev.sppp.pp_flags &= ~PP_CISCO; 57 state(hdlc)->pppdev.sppp.pp_flags &= ~PP_CISCO;
43 dev->type = ARPHRD_PPP; 58 dev->type = ARPHRD_PPP;
44 result = sppp_open(dev); 59 result = sppp_open(dev);
45 if (result) { 60 if (result) {
@@ -59,7 +74,7 @@ static void ppp_close(struct net_device *dev)
59 sppp_close(dev); 74 sppp_close(dev);
60 sppp_detach(dev); 75 sppp_detach(dev);
61 dev->rebuild_header = NULL; 76 dev->rebuild_header = NULL;
62 dev->change_mtu = hdlc->state.ppp.old_change_mtu; 77 dev->change_mtu = state(hdlc)->old_change_mtu;
63 dev->mtu = HDLC_MAX_MTU; 78 dev->mtu = HDLC_MAX_MTU;
64 dev->hard_header_len = 16; 79 dev->hard_header_len = 16;
65} 80}
@@ -73,13 +88,24 @@ static __be16 ppp_type_trans(struct sk_buff *skb, struct net_device *dev)
73 88
74 89
75 90
76int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr) 91static struct hdlc_proto proto = {
92 .open = ppp_open,
93 .close = ppp_close,
94 .type_trans = ppp_type_trans,
95 .ioctl = ppp_ioctl,
96 .module = THIS_MODULE,
97};
98
99
100static int ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
77{ 101{
78 hdlc_device *hdlc = dev_to_hdlc(dev); 102 hdlc_device *hdlc = dev_to_hdlc(dev);
79 int result; 103 int result;
80 104
81 switch (ifr->ifr_settings.type) { 105 switch (ifr->ifr_settings.type) {
82 case IF_GET_PROTO: 106 case IF_GET_PROTO:
107 if (dev_to_hdlc(dev)->proto != &proto)
108 return -EINVAL;
83 ifr->ifr_settings.type = IF_PROTO_PPP; 109 ifr->ifr_settings.type = IF_PROTO_PPP;
84 return 0; /* return protocol only, no settable parameters */ 110 return 0; /* return protocol only, no settable parameters */
85 111
@@ -96,13 +122,10 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
96 if (result) 122 if (result)
97 return result; 123 return result;
98 124
99 hdlc_proto_detach(hdlc); 125 result = attach_hdlc_protocol(dev, &proto, NULL,
100 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 126 sizeof(struct ppp_state));
101 127 if (result)
102 hdlc->proto.open = ppp_open; 128 return result;
103 hdlc->proto.close = ppp_close;
104 hdlc->proto.type_trans = ppp_type_trans;
105 hdlc->proto.id = IF_PROTO_PPP;
106 dev->hard_start_xmit = hdlc->xmit; 129 dev->hard_start_xmit = hdlc->xmit;
107 dev->hard_header = NULL; 130 dev->hard_header = NULL;
108 dev->type = ARPHRD_PPP; 131 dev->type = ARPHRD_PPP;
@@ -113,3 +136,25 @@ int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr)
113 136
114 return -EINVAL; 137 return -EINVAL;
115} 138}
139
140
141static int __init mod_init(void)
142{
143 register_hdlc_protocol(&proto);
144 return 0;
145}
146
147
148
149static void __exit mod_exit(void)
150{
151 unregister_hdlc_protocol(&proto);
152}
153
154
155module_init(mod_init);
156module_exit(mod_exit);
157
158MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
159MODULE_DESCRIPTION("PPP protocol support for generic HDLC");
160MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_raw.c b/drivers/net/wan/hdlc_raw.c
index f15aa6ba77f1..fe3cae5c6b9d 100644
--- a/drivers/net/wan/hdlc_raw.c
+++ b/drivers/net/wan/hdlc_raw.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * HDLC support 3 * HDLC support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -24,6 +24,8 @@
24#include <linux/hdlc.h> 24#include <linux/hdlc.h>
25 25
26 26
27static int raw_ioctl(struct net_device *dev, struct ifreq *ifr);
28
27static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev) 29static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
28{ 30{
29 return __constant_htons(ETH_P_IP); 31 return __constant_htons(ETH_P_IP);
@@ -31,7 +33,14 @@ static __be16 raw_type_trans(struct sk_buff *skb, struct net_device *dev)
31 33
32 34
33 35
34int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr) 36static struct hdlc_proto proto = {
37 .type_trans = raw_type_trans,
38 .ioctl = raw_ioctl,
39 .module = THIS_MODULE,
40};
41
42
43static int raw_ioctl(struct net_device *dev, struct ifreq *ifr)
35{ 44{
36 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 45 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
37 const size_t size = sizeof(raw_hdlc_proto); 46 const size_t size = sizeof(raw_hdlc_proto);
@@ -41,12 +50,14 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
41 50
42 switch (ifr->ifr_settings.type) { 51 switch (ifr->ifr_settings.type) {
43 case IF_GET_PROTO: 52 case IF_GET_PROTO:
53 if (dev_to_hdlc(dev)->proto != &proto)
54 return -EINVAL;
44 ifr->ifr_settings.type = IF_PROTO_HDLC; 55 ifr->ifr_settings.type = IF_PROTO_HDLC;
45 if (ifr->ifr_settings.size < size) { 56 if (ifr->ifr_settings.size < size) {
46 ifr->ifr_settings.size = size; /* data size wanted */ 57 ifr->ifr_settings.size = size; /* data size wanted */
47 return -ENOBUFS; 58 return -ENOBUFS;
48 } 59 }
49 if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 60 if (copy_to_user(raw_s, hdlc->state, size))
50 return -EFAULT; 61 return -EFAULT;
51 return 0; 62 return 0;
52 63
@@ -71,12 +82,11 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
71 if (result) 82 if (result)
72 return result; 83 return result;
73 84
74 hdlc_proto_detach(hdlc); 85 result = attach_hdlc_protocol(dev, &proto, NULL,
75 memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 86 sizeof(raw_hdlc_proto));
76 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 87 if (result)
77 88 return result;
78 hdlc->proto.type_trans = raw_type_trans; 89 memcpy(hdlc->state, &new_settings, size);
79 hdlc->proto.id = IF_PROTO_HDLC;
80 dev->hard_start_xmit = hdlc->xmit; 90 dev->hard_start_xmit = hdlc->xmit;
81 dev->hard_header = NULL; 91 dev->hard_header = NULL;
82 dev->type = ARPHRD_RAWHDLC; 92 dev->type = ARPHRD_RAWHDLC;
@@ -88,3 +98,25 @@ int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr)
88 98
89 return -EINVAL; 99 return -EINVAL;
90} 100}
101
102
103static int __init mod_init(void)
104{
105 register_hdlc_protocol(&proto);
106 return 0;
107}
108
109
110
111static void __exit mod_exit(void)
112{
113 unregister_hdlc_protocol(&proto);
114}
115
116
117module_init(mod_init);
118module_exit(mod_exit);
119
120MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
121MODULE_DESCRIPTION("Raw HDLC protocol support for generic HDLC");
122MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_raw_eth.c b/drivers/net/wan/hdlc_raw_eth.c
index d1884987f94e..1a69a9aaa9b9 100644
--- a/drivers/net/wan/hdlc_raw_eth.c
+++ b/drivers/net/wan/hdlc_raw_eth.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * HDLC Ethernet emulation support 3 * HDLC Ethernet emulation support
4 * 4 *
5 * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 2002-2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -25,6 +25,7 @@
25#include <linux/etherdevice.h> 25#include <linux/etherdevice.h>
26#include <linux/hdlc.h> 26#include <linux/hdlc.h>
27 27
28static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
28 29
29static int eth_tx(struct sk_buff *skb, struct net_device *dev) 30static int eth_tx(struct sk_buff *skb, struct net_device *dev)
30{ 31{
@@ -44,7 +45,14 @@ static int eth_tx(struct sk_buff *skb, struct net_device *dev)
44} 45}
45 46
46 47
47int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr) 48static struct hdlc_proto proto = {
49 .type_trans = eth_type_trans,
50 .ioctl = raw_eth_ioctl,
51 .module = THIS_MODULE,
52};
53
54
55static int raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
48{ 56{
49 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc; 57 raw_hdlc_proto __user *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
50 const size_t size = sizeof(raw_hdlc_proto); 58 const size_t size = sizeof(raw_hdlc_proto);
@@ -56,12 +64,14 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
56 64
57 switch (ifr->ifr_settings.type) { 65 switch (ifr->ifr_settings.type) {
58 case IF_GET_PROTO: 66 case IF_GET_PROTO:
67 if (dev_to_hdlc(dev)->proto != &proto)
68 return -EINVAL;
59 ifr->ifr_settings.type = IF_PROTO_HDLC_ETH; 69 ifr->ifr_settings.type = IF_PROTO_HDLC_ETH;
60 if (ifr->ifr_settings.size < size) { 70 if (ifr->ifr_settings.size < size) {
61 ifr->ifr_settings.size = size; /* data size wanted */ 71 ifr->ifr_settings.size = size; /* data size wanted */
62 return -ENOBUFS; 72 return -ENOBUFS;
63 } 73 }
64 if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size)) 74 if (copy_to_user(raw_s, hdlc->state, size))
65 return -EFAULT; 75 return -EFAULT;
66 return 0; 76 return 0;
67 77
@@ -86,12 +96,11 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
86 if (result) 96 if (result)
87 return result; 97 return result;
88 98
89 hdlc_proto_detach(hdlc); 99 result = attach_hdlc_protocol(dev, &proto, NULL,
90 memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size); 100 sizeof(raw_hdlc_proto));
91 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 101 if (result)
92 102 return result;
93 hdlc->proto.type_trans = eth_type_trans; 103 memcpy(hdlc->state, &new_settings, size);
94 hdlc->proto.id = IF_PROTO_HDLC_ETH;
95 dev->hard_start_xmit = eth_tx; 104 dev->hard_start_xmit = eth_tx;
96 old_ch_mtu = dev->change_mtu; 105 old_ch_mtu = dev->change_mtu;
97 old_qlen = dev->tx_queue_len; 106 old_qlen = dev->tx_queue_len;
@@ -106,3 +115,25 @@ int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr)
106 115
107 return -EINVAL; 116 return -EINVAL;
108} 117}
118
119
120static int __init mod_init(void)
121{
122 register_hdlc_protocol(&proto);
123 return 0;
124}
125
126
127
128static void __exit mod_exit(void)
129{
130 unregister_hdlc_protocol(&proto);
131}
132
133
134module_init(mod_init);
135module_exit(mod_exit);
136
137MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
138MODULE_DESCRIPTION("Ethernet encapsulation support for generic HDLC");
139MODULE_LICENSE("GPL v2");
diff --git a/drivers/net/wan/hdlc_x25.c b/drivers/net/wan/hdlc_x25.c
index a867fb411f89..e4bb9f8ad433 100644
--- a/drivers/net/wan/hdlc_x25.c
+++ b/drivers/net/wan/hdlc_x25.c
@@ -2,7 +2,7 @@
2 * Generic HDLC support routines for Linux 2 * Generic HDLC support routines for Linux
3 * X.25 support 3 * X.25 support
4 * 4 *
5 * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl> 5 * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of version 2 of the GNU General Public License 8 * under the terms of version 2 of the GNU General Public License
@@ -25,6 +25,8 @@
25 25
26#include <net/x25device.h> 26#include <net/x25device.h>
27 27
28static int x25_ioctl(struct net_device *dev, struct ifreq *ifr);
29
28/* These functions are callbacks called by LAPB layer */ 30/* These functions are callbacks called by LAPB layer */
29 31
30static void x25_connect_disconnect(struct net_device *dev, int reason, int code) 32static void x25_connect_disconnect(struct net_device *dev, int reason, int code)
@@ -162,30 +164,39 @@ static void x25_close(struct net_device *dev)
162 164
163static int x25_rx(struct sk_buff *skb) 165static int x25_rx(struct sk_buff *skb)
164{ 166{
165 hdlc_device *hdlc = dev_to_hdlc(skb->dev); 167 struct hdlc_device_desc *desc = dev_to_desc(skb->dev);
166 168
167 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) { 169 if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
168 hdlc->stats.rx_dropped++; 170 desc->stats.rx_dropped++;
169 return NET_RX_DROP; 171 return NET_RX_DROP;
170 } 172 }
171 173
172 if (lapb_data_received(skb->dev, skb) == LAPB_OK) 174 if (lapb_data_received(skb->dev, skb) == LAPB_OK)
173 return NET_RX_SUCCESS; 175 return NET_RX_SUCCESS;
174 176
175 hdlc->stats.rx_errors++; 177 desc->stats.rx_errors++;
176 dev_kfree_skb_any(skb); 178 dev_kfree_skb_any(skb);
177 return NET_RX_DROP; 179 return NET_RX_DROP;
178} 180}
179 181
180 182
183static struct hdlc_proto proto = {
184 .open = x25_open,
185 .close = x25_close,
186 .ioctl = x25_ioctl,
187 .module = THIS_MODULE,
188};
189
181 190
182int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr) 191static int x25_ioctl(struct net_device *dev, struct ifreq *ifr)
183{ 192{
184 hdlc_device *hdlc = dev_to_hdlc(dev); 193 hdlc_device *hdlc = dev_to_hdlc(dev);
185 int result; 194 int result;
186 195
187 switch (ifr->ifr_settings.type) { 196 switch (ifr->ifr_settings.type) {
188 case IF_GET_PROTO: 197 case IF_GET_PROTO:
198 if (dev_to_hdlc(dev)->proto != &proto)
199 return -EINVAL;
189 ifr->ifr_settings.type = IF_PROTO_X25; 200 ifr->ifr_settings.type = IF_PROTO_X25;
190 return 0; /* return protocol only, no settable parameters */ 201 return 0; /* return protocol only, no settable parameters */
191 202
@@ -200,14 +211,9 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
200 if (result) 211 if (result)
201 return result; 212 return result;
202 213
203 hdlc_proto_detach(hdlc); 214 if ((result = attach_hdlc_protocol(dev, &proto,
204 memset(&hdlc->proto, 0, sizeof(hdlc->proto)); 215 x25_rx, 0)) != 0)
205 216 return result;
206 hdlc->proto.open = x25_open;
207 hdlc->proto.close = x25_close;
208 hdlc->proto.netif_rx = x25_rx;
209 hdlc->proto.type_trans = NULL;
210 hdlc->proto.id = IF_PROTO_X25;
211 dev->hard_start_xmit = x25_xmit; 217 dev->hard_start_xmit = x25_xmit;
212 dev->hard_header = NULL; 218 dev->hard_header = NULL;
213 dev->type = ARPHRD_X25; 219 dev->type = ARPHRD_X25;
@@ -218,3 +224,25 @@ int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr)
218 224
219 return -EINVAL; 225 return -EINVAL;
220} 226}
227
228
229static int __init mod_init(void)
230{
231 register_hdlc_protocol(&proto);
232 return 0;
233}
234
235
236
237static void __exit mod_exit(void)
238{
239 unregister_hdlc_protocol(&proto);
240}
241
242
243module_init(mod_init);
244module_exit(mod_exit);
245
246MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
247MODULE_DESCRIPTION("X.25 protocol support for generic HDLC");
248MODULE_LICENSE("GPL v2");
diff --git a/include/linux/hdlc.h b/include/linux/hdlc.h
index d5ebbb29aeae..d4b333938f73 100644
--- a/include/linux/hdlc.h
+++ b/include/linux/hdlc.h
@@ -11,95 +11,46 @@
11#ifndef __HDLC_H 11#ifndef __HDLC_H
12#define __HDLC_H 12#define __HDLC_H
13 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#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
45 14
46#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */ 15#define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
16#if 0
47#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */ 17#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
18#else
19#define HDLC_MAX_MRU 1600 /* as required for FR network */
20#endif
48 21
49 22
50#ifdef __KERNEL__ 23#ifdef __KERNEL__
51 24
52#include <linux/skbuff.h> 25#include <linux/skbuff.h>
53#include <linux/netdevice.h> 26#include <linux/netdevice.h>
54#include <net/syncppp.h>
55#include <linux/hdlc/ioctl.h> 27#include <linux/hdlc/ioctl.h>
56 28
57 29
58typedef struct { /* Used in Cisco and PPP mode */ 30/* Used by all network devices here, pointed to by netdev_priv(dev) */
59 u8 address; 31struct hdlc_device_desc {
60 u8 control; 32 int (*netif_rx)(struct sk_buff *skb);
61 u16 protocol;
62}__attribute__ ((packed)) hdlc_header;
63
64
65
66typedef struct {
67 u32 type; /* code */
68 u32 par1;
69 u32 par2;
70 u16 rel; /* reliability */
71 u32 time;
72}__attribute__ ((packed)) cisco_packet;
73#define CISCO_PACKET_LEN 18
74#define CISCO_BIG_PACKET_LEN 20
75
76
77
78typedef struct pvc_device_struct {
79 struct net_device *master;
80 struct net_device *main;
81 struct net_device *ether; /* bridged Ethernet interface */
82 struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
83 int dlci;
84 int open_count;
85
86 struct {
87 unsigned int new: 1;
88 unsigned int active: 1;
89 unsigned int exist: 1;
90 unsigned int deleted: 1;
91 unsigned int fecn: 1;
92 unsigned int becn: 1;
93 unsigned int bandwidth; /* Cisco LMI reporting only */
94 }state;
95}pvc_device;
96
97
98
99typedef struct hdlc_device_struct {
100 /* To be initialized by hardware driver */
101 struct net_device_stats stats; 33 struct net_device_stats stats;
102 34};
35
36/* This structure is a private property of HDLC protocols.
37 Hardware drivers have no interest here */
38
39struct hdlc_proto {
40 int (*open)(struct net_device *dev);
41 void (*close)(struct net_device *dev);
42 void (*start)(struct net_device *dev); /* if open & DCD */
43 void (*stop)(struct net_device *dev); /* if open & !DCD */
44 void (*detach)(struct net_device *dev);
45 int (*ioctl)(struct net_device *dev, struct ifreq *ifr);
46 unsigned short (*type_trans)(struct sk_buff *skb,
47 struct net_device *dev);
48 struct module *module;
49 struct hdlc_proto *next; /* next protocol in the list */
50};
51
52
53typedef struct hdlc_device {
103 /* used by HDLC layer to take control over HDLC device from hw driver*/ 54 /* used by HDLC layer to take control over HDLC device from hw driver*/
104 int (*attach)(struct net_device *dev, 55 int (*attach)(struct net_device *dev,
105 unsigned short encoding, unsigned short parity); 56 unsigned short encoding, unsigned short parity);
@@ -107,82 +58,18 @@ typedef struct hdlc_device_struct {
107 /* hardware driver must handle this instead of dev->hard_start_xmit */ 58 /* hardware driver must handle this instead of dev->hard_start_xmit */
108 int (*xmit)(struct sk_buff *skb, struct net_device *dev); 59 int (*xmit)(struct sk_buff *skb, struct net_device *dev);
109 60
110
111 /* Things below are for HDLC layer internal use only */ 61 /* Things below are for HDLC layer internal use only */
112 struct { 62 const struct hdlc_proto *proto;
113 int (*open)(struct net_device *dev);
114 void (*close)(struct net_device *dev);
115
116 /* if open & DCD */
117 void (*start)(struct net_device *dev);
118 /* if open & !DCD */
119 void (*stop)(struct net_device *dev);
120
121 void (*detach)(struct hdlc_device_struct *hdlc);
122 int (*netif_rx)(struct sk_buff *skb);
123 unsigned short (*type_trans)(struct sk_buff *skb,
124 struct net_device *dev);
125 int id; /* IF_PROTO_HDLC/CISCO/FR/etc. */
126 }proto;
127
128 int carrier; 63 int carrier;
129 int open; 64 int open;
130 spinlock_t state_lock; 65 spinlock_t state_lock;
131 66 void *state;
132 union {
133 struct {
134 fr_proto settings;
135 pvc_device *first_pvc;
136 int dce_pvc_count;
137
138 struct timer_list timer;
139 unsigned long last_poll;
140 int reliable;
141 int dce_changed;
142 int request;
143 int fullrep_sent;
144 u32 last_errors; /* last errors bit list */
145 u8 n391cnt;
146 u8 txseq; /* TX sequence number */
147 u8 rxseq; /* RX sequence number */
148 }fr;
149
150 struct {
151 cisco_proto settings;
152
153 struct timer_list timer;
154 unsigned long last_poll;
155 int up;
156 int request_sent;
157 u32 txseq; /* TX sequence number */
158 u32 rxseq; /* RX sequence number */
159 }cisco;
160
161 struct {
162 raw_hdlc_proto settings;
163 }raw_hdlc;
164
165 struct {
166 struct ppp_device pppdev;
167 struct ppp_device *syncppp_ptr;
168 int (*old_change_mtu)(struct net_device *dev,
169 int new_mtu);
170 }ppp;
171 }state;
172 void *priv; 67 void *priv;
173}hdlc_device; 68}hdlc_device;
174 69
175 70
176 71
177int hdlc_raw_ioctl(struct net_device *dev, struct ifreq *ifr); 72/* Exported from hdlc module */
178int hdlc_raw_eth_ioctl(struct net_device *dev, struct ifreq *ifr);
179int hdlc_cisco_ioctl(struct net_device *dev, struct ifreq *ifr);
180int hdlc_ppp_ioctl(struct net_device *dev, struct ifreq *ifr);
181int hdlc_fr_ioctl(struct net_device *dev, struct ifreq *ifr);
182int hdlc_x25_ioctl(struct net_device *dev, struct ifreq *ifr);
183
184
185/* Exported from hdlc.o */
186 73
187/* Called by hardware driver when a user requests HDLC service */ 74/* Called by hardware driver when a user requests HDLC service */
188int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); 75int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
@@ -191,17 +78,21 @@ int hdlc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd);
191#define register_hdlc_device(dev) register_netdev(dev) 78#define register_hdlc_device(dev) register_netdev(dev)
192void unregister_hdlc_device(struct net_device *dev); 79void unregister_hdlc_device(struct net_device *dev);
193 80
81
82void register_hdlc_protocol(struct hdlc_proto *proto);
83void unregister_hdlc_protocol(struct hdlc_proto *proto);
84
194struct net_device *alloc_hdlcdev(void *priv); 85struct net_device *alloc_hdlcdev(void *priv);
195 86
196static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev) 87
88static __inline__ struct hdlc_device_desc* dev_to_desc(struct net_device *dev)
197{ 89{
198 return netdev_priv(dev); 90 return netdev_priv(dev);
199} 91}
200 92
201 93static __inline__ hdlc_device* dev_to_hdlc(struct net_device *dev)
202static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
203{ 94{
204 return (pvc_device*)dev->priv; 95 return netdev_priv(dev) + sizeof(struct hdlc_device_desc);
205} 96}
206 97
207 98
@@ -225,18 +116,14 @@ int hdlc_open(struct net_device *dev);
225/* Must be called by hardware driver when HDLC device is being closed */ 116/* Must be called by hardware driver when HDLC device is being closed */
226void hdlc_close(struct net_device *dev); 117void hdlc_close(struct net_device *dev);
227 118
119int attach_hdlc_protocol(struct net_device *dev, struct hdlc_proto *proto,
120 int (*rx)(struct sk_buff *skb), size_t size);
228/* May be used by hardware driver to gain control over HDLC device */ 121/* May be used by hardware driver to gain control over HDLC device */
229static __inline__ void hdlc_proto_detach(hdlc_device *hdlc) 122void detach_hdlc_protocol(struct net_device *dev);
230{
231 if (hdlc->proto.detach)
232 hdlc->proto.detach(hdlc);
233 hdlc->proto.detach = NULL;
234}
235
236 123
237static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev) 124static __inline__ struct net_device_stats *hdlc_stats(struct net_device *dev)
238{ 125{
239 return &dev_to_hdlc(dev)->stats; 126 return &dev_to_desc(dev)->stats;
240} 127}
241 128
242 129
@@ -248,8 +135,8 @@ static __inline__ __be16 hdlc_type_trans(struct sk_buff *skb,
248 skb->mac.raw = skb->data; 135 skb->mac.raw = skb->data;
249 skb->dev = dev; 136 skb->dev = dev;
250 137
251 if (hdlc->proto.type_trans) 138 if (hdlc->proto->type_trans)
252 return hdlc->proto.type_trans(skb, dev); 139 return hdlc->proto->type_trans(skb, dev);
253 else 140 else
254 return htons(ETH_P_HDLC); 141 return htons(ETH_P_HDLC);
255} 142}
diff --git a/include/linux/hdlc/ioctl.h b/include/linux/hdlc/ioctl.h
index 78430ba3ea69..583972364357 100644
--- a/include/linux/hdlc/ioctl.h
+++ b/include/linux/hdlc/ioctl.h
@@ -1,6 +1,39 @@
1#ifndef __HDLC_IOCTL_H__ 1#ifndef __HDLC_IOCTL_H__
2#define __HDLC_IOCTL_H__ 2#define __HDLC_IOCTL_H__
3 3
4
5#define GENERIC_HDLC_VERSION 4 /* For synchronization with sethdlc utility */
6
7#define CLOCK_DEFAULT 0 /* Default setting */
8#define CLOCK_EXT 1 /* External TX and RX clock - DTE */
9#define CLOCK_INT 2 /* Internal TX and RX clock - DCE */
10#define CLOCK_TXINT 3 /* Internal TX and external RX clock */
11#define CLOCK_TXFROMRX 4 /* TX clock derived from external RX clock */
12
13
14#define ENCODING_DEFAULT 0 /* Default setting */
15#define ENCODING_NRZ 1
16#define ENCODING_NRZI 2
17#define ENCODING_FM_MARK 3
18#define ENCODING_FM_SPACE 4
19#define ENCODING_MANCHESTER 5
20
21
22#define PARITY_DEFAULT 0 /* Default setting */
23#define PARITY_NONE 1 /* No parity */
24#define PARITY_CRC16_PR0 2 /* CRC16, initial value 0x0000 */
25#define PARITY_CRC16_PR1 3 /* CRC16, initial value 0xFFFF */
26#define PARITY_CRC16_PR0_CCITT 4 /* CRC16, initial 0x0000, ITU-T version */
27#define PARITY_CRC16_PR1_CCITT 5 /* CRC16, initial 0xFFFF, ITU-T version */
28#define PARITY_CRC32_PR0_CCITT 6 /* CRC32, initial value 0x00000000 */
29#define PARITY_CRC32_PR1_CCITT 7 /* CRC32, initial value 0xFFFFFFFF */
30
31#define LMI_DEFAULT 0 /* Default setting */
32#define LMI_NONE 1 /* No LMI, all PVCs are static */
33#define LMI_ANSI 2 /* ANSI Annex D */
34#define LMI_CCITT 3 /* ITU-T Annex A */
35#define LMI_CISCO 4 /* The "original" LMI, aka Gang of Four */
36
4typedef struct { 37typedef struct {
5 unsigned int clock_rate; /* bits per second */ 38 unsigned int clock_rate; /* bits per second */
6 unsigned int clock_type; /* internal, external, TX-internal etc. */ 39 unsigned int clock_type; /* internal, external, TX-internal etc. */