]> git.pld-linux.org Git - packages/kernel.git/blame - hdlc-2.4.21-1.14a.patch
- added description of djurban's branch
[packages/kernel.git] / hdlc-2.4.21-1.14a.patch
CommitLineData
d8b99645 1--- linux-2.4.orig/Documentation/networking/generic-hdlc.txt 2003-07-29 23:24:56.000000000 +0200
2+++ linux-2.4/Documentation/networking/generic-hdlc.txt 2003-07-29 23:32:23.000000000 +0200
3@@ -1,11 +1,13 @@
4-Generic HDLC layer for Linux kernel 2.4/2.5
5+Generic HDLC layer
6 Krzysztof Halasa <khc@pm.waw.pl>
7-May, 2001
8+January, 2003
9
10
11 Generic HDLC layer currently supports:
12-- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP),
13-- raw HDLC (IPv4 only),
14+- Frame Relay (ANSI, CCITT and no LMI), with ARP support (no InARP).
15+ Normal (routed) and Ethernet-bridged (Ethernet device emulation)
16+ interfaces can share a single PVC.
17+- raw HDLC - either IP (IPv4) interface or Ethernet device emulation.
18 - Cisco HDLC,
19 - PPP (uses syncppp.c),
20 - X.25 (uses X.25 routines).
21@@ -15,6 +17,10 @@
22 - RISCom/N2 by SDL Communications Inc.
23 - and others, some not in the official kernel.
24
25+Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
26+with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
27+
28+
29 Make sure the hdlc.o and the hardware driver are loaded. It should
30 create a number of "hdlc" (hdlc0 etc) network devices, one for each
31 WAN port. You'll need the "sethdlc" utility, get it from:
32@@ -32,8 +38,10 @@
33 sethdlc hdlc0 cisco interval 10 timeout 25
34 or
35 sethdlc hdlc0 rs232 clock ext
36- sethdlc fr lmi ansi
37- sethdlc create 99
38+ sethdlc hdlc0 fr lmi ansi
39+ sethdlc hdlc0 create 99
40+ ifconfig hdlc0 up
41+ ifconfig pvc0 localIP pointopoint remoteIP
42
43 In Frame Relay mode, ifconfig master hdlc device up (without assigning
44 any IP address to it) before using pvc devices.
45@@ -58,6 +66,9 @@
46 no-parity / crc16 / crc16-pr0 (CRC16 with preset zeros) / crc32-itu
47 crc16-itu (CRC16 with ITU-T polynomial) / crc16-itu-pr0 - sets parity
48
49+* hdlc-eth - Ethernet device emulation using HDLC. Parity and encoding
50+ as above.
51+
52 * cisco - sets Cisco HDLC mode (IP, IPv6 and IPX supported)
53 interval - time in seconds between keepalive packets
54 timeout - time in seconds after last received keepalive packet before
55@@ -77,7 +88,12 @@
56 n392 - error threshold - both user and network
57 n393 - monitored events count - both user and network
58
59-* create | delete n - FR only - adds / deletes PVC interface with DLCI #n.
60+Frame-Relay only:
61+* create n | delete n - adds / deletes PVC interface with DLCI #n.
62+ Newly created interface will be named pvc0, pvc1 etc.
63+
64+* create ether n | delete ether n - adds a device for Ethernet-bridged
65+ frames. The device will be named pvceth0, pvceth1 etc.
66
67
68
69@@ -104,11 +120,11 @@
70
71
72 If you have a problem with N2 or C101 card, you can issue the "private"
73-command to see port's packet descriptor rings:
74+command to see port's packet descriptor rings (in kernel logs):
75
76 sethdlc hdlc0 private
77
78-The hardware driver have to be build with CONFIG_HDLC_DEBUG_RINGS.
79+The hardware driver has to be build with CONFIG_HDLC_DEBUG_RINGS.
80 Attaching this info to bug reports would be helpful. Anyway, let me know
81 if you have problems using this.
82
83--- linux-2.4.orig/include/linux/if.h 2003-07-29 23:25:12.000000000 +0200
84+++ linux-2.4/include/linux/if.h 2003-07-29 23:32:23.000000000 +0200
85@@ -21,6 +21,8 @@
86
87 #include <linux/types.h> /* for "__kernel_caddr_t" et al */
88 #include <linux/socket.h> /* for "struct sockaddr" et al */
89+
90+#define IFNAMSIZ 16
91 #include <linux/hdlc/ioctl.h>
92
93 /* Standard interface flags (netdevice->flags). */
94@@ -59,7 +61,7 @@
95 #define IF_IFACE_X21 0x1002 /* X.21 serial interface */
96 #define IF_IFACE_T1 0x1003 /* T1 telco serial interface */
97 #define IF_IFACE_E1 0x1004 /* E1 telco serial interface */
98-#define IF_IFACE_SYNC_SERIAL 0x1005 /* cant'b be set by software */
99+#define IF_IFACE_SYNC_SERIAL 0x1005 /* can't be set by software */
100
101 /* For definitions see hdlc.h */
102 #define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */
103@@ -69,7 +71,11 @@
104 #define IF_PROTO_FR_ADD_PVC 0x2004 /* Create FR PVC */
105 #define IF_PROTO_FR_DEL_PVC 0x2005 /* Delete FR PVC */
106 #define IF_PROTO_X25 0x2006 /* X.25 */
107-
108+#define IF_PROTO_HDLC_ETH 0x2007 /* raw HDLC, Ethernet emulation */
109+#define IF_PROTO_FR_ADD_ETH_PVC 0x2008 /* Create FR Ethernet-bridged PVC */
110+#define IF_PROTO_FR_DEL_ETH_PVC 0x2009 /* Delete FR Ethernet-bridged PVC */
111+#define IF_PROTO_FR_PVC 0x200A /* for reading PVC status */
112+#define IF_PROTO_FR_ETH_PVC 0x200B
113
114
115 /*
116@@ -103,6 +109,7 @@
117 cisco_proto *cisco;
118 fr_proto *fr;
119 fr_proto_pvc *fr_pvc;
120+ fr_proto_pvc_info *fr_pvc_info;
121
122 /* interface settings */
123 sync_serial_settings *sync;
124@@ -120,7 +127,6 @@
125 struct ifreq
126 {
127 #define IFHWADDRLEN 6
128-#define IFNAMSIZ 16
129 union
130 {
131 char ifrn_name[IFNAMSIZ]; /* if name, e.g. "en0" */
132--- linux-2.4.orig/include/linux/hdlc.h 2003-07-29 23:25:12.000000000 +0200
133+++ linux-2.4/include/linux/hdlc.h 2003-07-29 23:32:23.000000000 +0200
134@@ -1,12 +1,11 @@
135 /*
136 * Generic HDLC support routines for Linux
137 *
138- * Copyright (C) 1999-2002 Krzysztof Halasa <khc@pm.waw.pl>
139+ * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl>
140 *
141 * This program is free software; you can redistribute it and/or modify it
142- * under the terms of the GNU General Public License as published by
143- * the Free Software Foundation; either version 2 of the License, or
144- * (at your option) any later version.
145+ * under the terms of version 2 of the GNU General Public License
146+ * as published by the Free Software Foundation.
147 */
148
149 #ifndef __HDLC_H
150@@ -52,7 +51,7 @@
151 #include <linux/hdlc/ioctl.h>
152
153 #define HDLC_MAX_MTU 1500 /* Ethernet 1500 bytes */
154-#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10) /* max 10 bytes for FR */
155+#define HDLC_MAX_MRU (HDLC_MAX_MTU + 10 + 14 + 4) /* for ETH+VLAN over FR */
156
157 #define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */
158
159@@ -145,17 +144,20 @@
160
161
162 typedef struct pvc_device_struct {
163- struct net_device netdev; /* PVC net device - must be first */
164- struct net_device_stats stats;
165 struct hdlc_device_struct *master;
166- struct pvc_device_struct *next;
167+ struct net_device *main;
168+ struct net_device *ether; /* bridged Ethernet interface */
169+ struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
170+ int dlci;
171+ int open_count;
172
173 struct {
174- int active;
175- int new;
176- int deleted;
177- int fecn;
178- int becn;
179+ unsigned int new: 1;
180+ unsigned int active: 1;
181+ unsigned int exist: 1;
182+ unsigned int deleted: 1;
183+ unsigned int fecn: 1;
184+ unsigned int becn: 1;
185 }state;
186 }pvc_device;
187
188@@ -180,18 +182,20 @@
189 void (*stop)(struct hdlc_device_struct *hdlc);
190 void (*proto_detach)(struct hdlc_device_struct *hdlc);
191 void (*netif_rx)(struct sk_buff *skb);
192+ unsigned short (*type_trans)(struct sk_buff *skb,
193+ struct net_device *dev);
194 int proto; /* IF_PROTO_HDLC/CISCO/FR/etc. */
195
196 union {
197 struct {
198 fr_proto settings;
199 pvc_device *first_pvc;
200- int pvc_count;
201+ int dce_pvc_count;
202
203 struct timer_list timer;
204 int last_poll;
205 int reliable;
206- int changed;
207+ int dce_changed;
208 int request;
209 int fullrep_sent;
210 u32 last_errors; /* last errors bit list */
211@@ -226,6 +230,7 @@
212
213
214 int hdlc_raw_ioctl(hdlc_device *hdlc, struct ifreq *ifr);
215+int hdlc_raw_eth_ioctl(hdlc_device *hdlc, struct ifreq *ifr);
216 int hdlc_cisco_ioctl(hdlc_device *hdlc, struct ifreq *ifr);
217 int hdlc_ppp_ioctl(hdlc_device *hdlc, struct ifreq *ifr);
218 int hdlc_fr_ioctl(hdlc_device *hdlc, struct ifreq *ifr);
219@@ -254,15 +259,9 @@
220 }
221
222
223-static __inline__ struct net_device* pvc_to_dev(pvc_device *pvc)
224-{
225- return &pvc->netdev;
226-}
227-
228-
229 static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
230 {
231- return (pvc_device*)dev;
232+ return (pvc_device*)dev->priv;
233 }
234
235
236@@ -272,19 +271,6 @@
237 }
238
239
240-static __inline__ const char *pvc_to_name(pvc_device *pvc)
241-{
242- return pvc_to_dev(pvc)->name;
243-}
244-
245-
246-static __inline__ u16 netdev_dlci(struct net_device *dev)
247-{
248- return ntohs(*(u16*)dev->dev_addr);
249-}
250-
251-
252-
253 static __inline__ u16 q922_to_dlci(u8 *hdr)
254 {
255 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
256@@ -345,5 +331,15 @@
257 }
258
259
260+static __inline__ unsigned short hdlc_type_trans(struct sk_buff *skb,
261+ struct net_device *dev)
262+{
263+ hdlc_device *hdlc = dev_to_hdlc(skb->dev);
264+ if (hdlc->type_trans)
265+ return hdlc->type_trans(skb, dev);
266+ else
267+ return __constant_htons(ETH_P_HDLC);
268+}
269+
270 #endif /* __KERNEL */
271 #endif /* __HDLC_H */
272--- linux-2.4.orig/include/linux/hdlc/ioctl.h 2003-07-29 23:25:12.000000000 +0200
273+++ linux-2.4/include/linux/hdlc/ioctl.h 2003-07-29 23:32:23.000000000 +0200
274@@ -34,22 +34,15 @@
275 } fr_proto_pvc; /* for creating/deleting FR PVCs */
276
277 typedef struct {
278+ unsigned int dlci;
279+ char master[IFNAMSIZ]; /* Name of master FRAD device */
280+}fr_proto_pvc_info; /* for returning PVC information only */
281+
282+typedef struct {
283 unsigned int interval;
284 unsigned int timeout;
285 } cisco_proto;
286
287 /* PPP doesn't need any info now - supply length = 0 to ioctl */
288
289-union hdlc_settings {
290- raw_hdlc_proto raw_hdlc;
291- cisco_proto cisco;
292- fr_proto fr;
293- fr_proto_pvc fr_pvc;
294-};
295-
296-union line_settings {
297- sync_serial_settings sync;
298- te1_settings te1;
299-};
300-
301 #endif /* __HDLC_IOCTL_H__ */
302--- linux-2.4.orig/drivers/net/wan/Makefile 2003-07-29 23:25:03.000000000 +0200
303+++ linux-2.4/drivers/net/wan/Makefile 2003-07-29 23:32:23.000000000 +0200
304@@ -24,6 +24,7 @@
305
306 hdlc-y := hdlc_generic.o
307 hdlc-$(CONFIG_HDLC_RAW) += hdlc_raw.o
308+hdlc-$(CONFIG_HDLC_RAW_ETH) += hdlc_raw_eth.o
309 hdlc-$(CONFIG_HDLC_CISCO) += hdlc_cisco.o
310 hdlc-$(CONFIG_HDLC_FR) += hdlc_fr.o
311 hdlc-$(CONFIG_HDLC_PPP) += hdlc_ppp.o
312--- linux-2.4.orig/drivers/net/wan/hdlc_cisco.c 2003-07-29 23:25:03.000000000 +0200
313+++ linux-2.4/drivers/net/wan/hdlc_cisco.c 2003-07-29 23:32:23.000000000 +0200
314@@ -2,12 +2,11 @@
315 * Generic HDLC support routines for Linux
316 * Cisco HDLC support
317 *
318- * Copyright (C) 2000 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
319+ * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
320 *
321 * This program is free software; you can redistribute it and/or modify it
322- * under the terms of the GNU General Public License as published by
323- * the Free Software Foundation; either version 2 of the License, or
324- * (at your option) any later version.
325+ * under the terms of version 2 of the GNU General Public License
326+ * as published by the Free Software Foundation.
327 */
328
329 #include <linux/config.h>
330@@ -80,17 +79,43 @@
331 data->par1 = htonl(par1);
332 data->par2 = htonl(par2);
333 data->rel = 0xFFFF;
334- data->time = htonl(jiffies * 1000 / HZ);
335+ /* we will need do_div here if 1000 % HZ != 0 */
336+ data->time = htonl(jiffies * (1000 / HZ));
337
338 skb_put(skb, sizeof(cisco_packet));
339 skb->priority = TC_PRIO_CONTROL;
340 skb->dev = hdlc_to_dev(hdlc);
341+ skb->nh.raw = skb->data;
342
343 dev_queue_xmit(skb);
344 }
345
346
347
348+static unsigned short cisco_type_trans(struct sk_buff *skb,
349+ struct net_device *dev)
350+{
351+ hdlc_header *data = (hdlc_header*)skb->data;
352+
353+ if (skb->len < sizeof(hdlc_header))
354+ return __constant_htons(ETH_P_HDLC);
355+
356+ if (data->address != CISCO_MULTICAST &&
357+ data->address != CISCO_UNICAST)
358+ return __constant_htons(ETH_P_HDLC);
359+
360+ switch(data->protocol) {
361+ case __constant_htons(ETH_P_IP):
362+ case __constant_htons(ETH_P_IPX):
363+ case __constant_htons(ETH_P_IPV6):
364+ skb_pull(skb, sizeof(hdlc_header));
365+ return data->protocol;
366+ default:
367+ return __constant_htons(ETH_P_HDLC);
368+ }
369+}
370+
371+
372 static void cisco_rx(struct sk_buff *skb)
373 {
374 hdlc_device *hdlc = dev_to_hdlc(skb->dev);
375@@ -109,14 +134,6 @@
376 skb_pull(skb, sizeof(hdlc_header));
377
378 switch(ntohs(data->protocol)) {
379- case ETH_P_IP:
380- case ETH_P_IPX:
381- case ETH_P_IPV6:
382- skb->protocol = data->protocol;
383- skb->dev = hdlc_to_dev(hdlc);
384- netif_rx(skb);
385- return;
386-
387 case CISCO_SYS_INFO:
388 /* Packet is not needed, drop it. */
389 dev_kfree_skb_any(skb);
390@@ -288,6 +305,7 @@
391 hdlc->open = cisco_open;
392 hdlc->stop = cisco_close;
393 hdlc->netif_rx = cisco_rx;
394+ hdlc->type_trans = cisco_type_trans;
395 hdlc->proto = IF_PROTO_CISCO;
396 dev->hard_start_xmit = hdlc->xmit;
397 dev->hard_header = cisco_hard_header;
398--- linux-2.4.orig/drivers/net/wan/hdlc_fr.c 2003-07-29 23:25:03.000000000 +0200
399+++ linux-2.4/drivers/net/wan/hdlc_fr.c 2003-07-29 23:32:23.000000000 +0200
400@@ -2,13 +2,22 @@
401 * Generic HDLC support routines for Linux
402 * Frame Relay support
403 *
404- * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
405+ * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
406 *
407 * This program is free software; you can redistribute it and/or modify it
408- * under the terms of the GNU General Public License as published by
409- * the Free Software Foundation; either version 2 of the License, or
410- * (at your option) any later version.
411- */
412+ * under the terms of version 2 of the GNU General Public License
413+ * as published by the Free Software Foundation.
414+ *
415+
416+ Theory of PVC state in DCE mode:
417+
418+ (exist,new) -> 0,0 when "PVC create" or if "link unreliable"
419+ 0,x -> 1,1 if "link reliable" when sending FULL STATUS
420+ 1,1 -> 1,0 if received FULL STATUS ACK
421+
422+ (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create"
423+ -> 1 when "PVC up" and (exist,new) = 1,0
424+*/
425
426 #include <linux/config.h>
427 #include <linux/module.h>
428@@ -20,19 +29,23 @@
429 #include <linux/init.h>
430 #include <linux/skbuff.h>
431 #include <linux/pkt_sched.h>
432+#include <linux/random.h>
433 #include <linux/inetdevice.h>
434 #include <linux/lapb.h>
435 #include <linux/rtnetlink.h>
436+#include <linux/etherdevice.h>
437 #include <linux/hdlc.h>
438
439
440 __inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
441 {
442- pvc_device *pvc=hdlc->state.fr.first_pvc;
443-
444- while (pvc) {
445- if (netdev_dlci(&pvc->netdev) == dlci)
446+ pvc_device *pvc = hdlc->state.fr.first_pvc;
447+
448+ while(pvc) {
449+ if (pvc->dlci == dlci)
450 return pvc;
451+ if (pvc->dlci > dlci)
452+ return NULL; /* the listed is sorted */
453 pvc = pvc->next;
454 }
455
456@@ -40,18 +53,72 @@
457 }
458
459
460+__inline__ pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci)
461+{
462+ pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc;
463+
464+ while(*pvc_p) {
465+ if ((*pvc_p)->dlci == dlci)
466+ return *pvc_p;
467+ if ((*pvc_p)->dlci > dlci)
468+ break; /* the listed is sorted */
469+ pvc_p = &(*pvc_p)->next;
470+ }
471+
472+ pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC);
473+ if (!pvc)
474+ return NULL;
475+
476+ memset(pvc, 0, sizeof(pvc_device));
477+ pvc->dlci = dlci;
478+ pvc->master = hdlc;
479+ pvc->next = *pvc_p; /* Put it in the chain */
480+ *pvc_p = pvc;
481+ return pvc;
482+}
483+
484+
485+__inline__ int pvc_is_used(pvc_device *pvc)
486+{
487+ return pvc->main != NULL || pvc->ether != NULL;
488+}
489+
490+
491+__inline__ void delete_unused_pvcs(hdlc_device *hdlc)
492+{
493+ pvc_device **pvc_p = &hdlc->state.fr.first_pvc;
494+
495+ while(*pvc_p) {
496+ if (!pvc_is_used(*pvc_p)) {
497+ pvc_device *pvc = *pvc_p;
498+ *pvc_p = pvc->next;
499+ kfree(pvc);
500+ continue;
501+ }
502+ pvc_p = &(*pvc_p)->next;
503+ }
504+}
505
506-__inline__ u16 status_to_dlci(hdlc_device *hdlc, u8 *status,
507- int *active, int *new)
508+
509+__inline__ struct net_device** get_dev_p(pvc_device *pvc, int type)
510 {
511- *new = (status[2] & 0x08);
512- *active = (!*new && (status[2] & 0x02));
513+ if (type == ARPHRD_ETHER)
514+ return &pvc->ether;
515+ else
516+ return &pvc->main;
517+}
518+
519+
520+__inline__ u16 status_to_dlci(u8 *status, int *active, int *new)
521+{
522+ *new = (status[2] & 0x08) ? 1 : 0;
523+ *active = (status[2] & 0x02) ? 1 : 0;
524
525 return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3);
526 }
527
528
529-__inline__ void dlci_to_status(hdlc_device *hdlc, u16 dlci, u8 *status,
530+__inline__ void dlci_to_status(u16 dlci, u8 *status,
531 int active, int new)
532 {
533 status[0] = (dlci>>4) & 0x3F;
534@@ -66,37 +133,50 @@
535
536
537
538-static int fr_hard_header(struct sk_buff *skb, struct net_device *dev,
539- u16 type, void *daddr, void *saddr, unsigned int len)
540+static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
541 {
542 u16 head_len;
543+ struct sk_buff *skb = *skb_p;
544
545- if (!daddr)
546- daddr = dev->broadcast;
547-
548-#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER
549- printk(KERN_DEBUG "%s: fr_hard_header called\n", dev->name);
550-#endif
551-
552- switch(type) {
553- case ETH_P_IP:
554+ switch(skb->protocol) {
555+ case __constant_ntohs(ETH_P_IP):
556 head_len = 4;
557 skb_push(skb, head_len);
558 skb->data[3] = NLPID_IP;
559 break;
560
561- case ETH_P_IPV6:
562+ case __constant_ntohs(ETH_P_IPV6):
563 head_len = 4;
564 skb_push(skb, head_len);
565 skb->data[3] = NLPID_IPV6;
566 break;
567
568- case LMI_PROTO:
569+ case __constant_ntohs(LMI_PROTO):
570 head_len = 4;
571 skb_push(skb, head_len);
572 skb->data[3] = LMI_PROTO;
573 break;
574
575+ case __constant_ntohs(ETH_P_802_3):
576+ head_len = 10;
577+ if (skb_headroom(skb) < head_len) {
578+ struct sk_buff *skb2 = skb_realloc_headroom(skb,
579+ head_len);
580+ if (!skb2)
581+ return -ENOBUFS;
582+ dev_kfree_skb(skb);
583+ skb = *skb_p = skb2;
584+ }
585+ skb_push(skb, head_len);
586+ skb->data[3] = FR_PAD;
587+ skb->data[4] = NLPID_SNAP;
588+ skb->data[5] = FR_PAD;
589+ skb->data[6] = 0x80;
590+ skb->data[7] = 0xC2;
591+ skb->data[8] = 0x00;
592+ skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */
593+ break;
594+
595 default:
596 head_len = 10;
597 skb_push(skb, head_len);
598@@ -105,14 +185,12 @@
599 skb->data[5] = FR_PAD;
600 skb->data[6] = FR_PAD;
601 skb->data[7] = FR_PAD;
602- skb->data[8] = type>>8;
603- skb->data[9] = (u8)type;
604+ *(u16*)(skb->data + 8) = skb->protocol;
605 }
606
607- memcpy(skb->data, daddr, 2);
608+ dlci_to_q922(skb->data, dlci);
609 skb->data[2] = FR_UI;
610-
611- return head_len;
612+ return 0;
613 }
614
615
616@@ -124,13 +202,12 @@
617 if ((hdlc_to_dev(pvc->master)->flags & IFF_UP) == 0)
618 return -EIO; /* Master must be UP in order to activate PVC */
619
620- if (pvc->master->state.fr.settings.lmi != LMI_NONE)
621- pvc->state.active = 0;
622- else
623- pvc->state.active = 1;
624+ if (pvc->open_count++ == 0) {
625+ if (pvc->master->state.fr.settings.lmi == LMI_NONE)
626+ pvc->state.active = 1;
627
628- pvc->state.new = 0;
629- pvc->master->state.fr.changed = 1;
630+ pvc->master->state.fr.dce_changed = 1;
631+ }
632 return 0;
633 }
634
635@@ -139,38 +216,94 @@
636 static int pvc_close(struct net_device *dev)
637 {
638 pvc_device *pvc = dev_to_pvc(dev);
639- pvc->state.active = pvc->state.new = 0;
640- pvc->master->state.fr.changed = 1;
641+
642+ if (--pvc->open_count == 0) {
643+ if (pvc->master->state.fr.settings.lmi == LMI_NONE)
644+ pvc->state.active = 0;
645+
646+ if (pvc->master->state.fr.settings.dce) {
647+ pvc->master->state.fr.dce_changed = 1;
648+ pvc->state.active = 0;
649+ }
650+ }
651 return 0;
652 }
653
654
655
656-static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
657+int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
658 {
659 pvc_device *pvc = dev_to_pvc(dev);
660+ fr_proto_pvc_info info;
661
662- if (pvc->state.active) {
663- skb->dev = hdlc_to_dev(pvc->master);
664- pvc->stats.tx_bytes += skb->len;
665- pvc->stats.tx_packets++;
666- if (pvc->state.fecn)
667- pvc->stats.tx_compressed++; /* TX Congestion counter */
668- dev_queue_xmit(skb);
669- } else {
670- pvc->stats.tx_dropped++;
671- dev_kfree_skb(skb);
672+ if (ifr->ifr_settings.type == IF_GET_PROTO) {
673+ if (dev->type == ARPHRD_ETHER)
674+ ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
675+ else
676+ ifr->ifr_settings.type = IF_PROTO_FR_PVC;
677+
678+ if (ifr->ifr_settings.size < sizeof(info)) {
679+ /* data size wanted */
680+ ifr->ifr_settings.size = sizeof(info);
681+ return -ENOBUFS;
682+ }
683+
684+ info.dlci = pvc->dlci;
685+ memcpy(info.master, hdlc_to_name(pvc->master), IFNAMSIZ);
686+ if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info,
687+ &info, sizeof(info)))
688+ return -EFAULT;
689+ return 0;
690 }
691
692- return 0;
693+ return -EINVAL;
694+}
695+
696+
697+__inline__ struct net_device_stats *pvc_get_stats(struct net_device *dev)
698+{
699+ return (struct net_device_stats *)
700+ ((char *)dev + sizeof(struct net_device));
701 }
702
703
704
705-static struct net_device_stats *pvc_get_stats(struct net_device *dev)
706+static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
707 {
708 pvc_device *pvc = dev_to_pvc(dev);
709- return &pvc->stats;
710+ struct net_device_stats *stats = pvc_get_stats(dev);
711+
712+ if (pvc->state.active) {
713+ if (dev->type == ARPHRD_ETHER) {
714+ int pad = ETH_ZLEN - skb->len;
715+ if (pad > 0) { /* Pad the frame with zeros */
716+ int len = skb->len;
717+ if (skb_tailroom(skb) < pad)
718+ if (pskb_expand_head(skb, 0, pad,
719+ GFP_ATOMIC)) {
720+ stats->tx_dropped++;
721+ dev_kfree_skb(skb);
722+ return 0;
723+ }
724+ skb_put(skb, pad);
725+ memset(skb->data + len, 0, pad);
726+ }
727+ skb->protocol = __constant_htons(ETH_P_802_3);
728+ }
729+ if (!fr_hard_header(&skb, pvc->dlci)) {
730+ stats->tx_bytes += skb->len;
731+ stats->tx_packets++;
732+ if (pvc->state.fecn) /* TX Congestion counter */
733+ stats->tx_compressed++;
734+ skb->dev = hdlc_to_dev(pvc->master);
735+ dev_queue_xmit(skb);
736+ return 0;
737+ }
738+ }
739+
740+ stats->tx_dropped++;
741+ dev_kfree_skb(skb);
742+ return 0;
743 }
744
745
746@@ -187,9 +320,15 @@
747
748 static inline void fr_log_dlci_active(pvc_device *pvc)
749 {
750- printk(KERN_INFO "%s: %sactive%s\n", pvc_to_name(pvc),
751- pvc->state.active ? "" : "in",
752- pvc->state.new ? " new" : "");
753+ printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
754+ hdlc_to_name(pvc->master),
755+ pvc->dlci,
756+ pvc->main ? pvc->main->name : "",
757+ pvc->main && pvc->ether ? " " : "",
758+ pvc->ether ? pvc->ether->name : "",
759+ pvc->state.new ? " new" : "",
760+ !pvc->state.exist ? "deleted" :
761+ pvc->state.active ? "active" : "inactive");
762 }
763
764
765@@ -213,8 +352,8 @@
766 int i = 0;
767
768 if (hdlc->state.fr.settings.dce && fullrep) {
769- len += hdlc->state.fr.pvc_count * (2 + stat_len);
770- if (len > HDLC_MAX_MTU) {
771+ len += hdlc->state.fr.dce_pvc_count * (2 + stat_len);
772+ if (len > HDLC_MAX_MRU) {
773 printk(KERN_WARNING "%s: Too many PVCs while sending "
774 "LMI full report\n", hdlc_to_name(hdlc));
775 return;
776@@ -224,12 +363,13 @@
777 skb = dev_alloc_skb(len);
778 if (!skb) {
779 printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n",
780- hdlc_to_name(hdlc));
781+ hdlc_to_name(hdlc));
782 return;
783 }
784 memset(skb->data, 0, len);
785 skb_reserve(skb, 4);
786- fr_hard_header(skb, hdlc_to_dev(hdlc), LMI_PROTO, NULL, NULL, 0);
787+ skb->protocol = __constant_htons(LMI_PROTO);
788+ fr_hard_header(&skb, LMI_DLCI);
789 data = skb->tail;
790 data[i++] = LMI_CALLREF;
791 data[i++] = hdlc->state.fr.settings.dce
792@@ -253,16 +393,20 @@
793 ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT;
794 data[i++] = stat_len;
795
796- if (hdlc->state.fr.reliable &&
797- (pvc->netdev.flags & IFF_UP) &&
798- !pvc->state.active &&
799- !pvc->state.new) {
800- pvc->state.new = 1;
801+ /* LMI start/restart */
802+ if (hdlc->state.fr.reliable && !pvc->state.exist) {
803+ pvc->state.exist = pvc->state.new = 1;
804+ fr_log_dlci_active(pvc);
805+ }
806+
807+ /* ifconfig PVC up */
808+ if (pvc->open_count && !pvc->state.active &&
809+ pvc->state.exist && !pvc->state.new) {
810+ pvc->state.active = 1;
811 fr_log_dlci_active(pvc);
812 }
813
814- dlci_to_status(hdlc, netdev_dlci(&pvc->netdev),
815- data + i,
816+ dlci_to_status(pvc->dlci, data + i,
817 pvc->state.active, pvc->state.new);
818 i += stat_len;
819 pvc = pvc->next;
820@@ -272,6 +416,7 @@
821 skb_put(skb, i);
822 skb->priority = TC_PRIO_CONTROL;
823 skb->dev = hdlc_to_dev(hdlc);
824+ skb->nh.raw = skb->data;
825
826 dev_queue_xmit(skb);
827 }
828@@ -312,10 +457,11 @@
829
830 if (reliable) {
831 hdlc->state.fr.n391cnt = 0; /* Request full status */
832- hdlc->state.fr.changed = 1;
833+ hdlc->state.fr.dce_changed = 1;
834 } else {
835 while (pvc) { /* Deactivate all PVCs */
836- pvc->state.new = pvc->state.active = 0;
837+ pvc->state.exist = 0;
838+ pvc->state.active = pvc->state.new = 0;
839 pvc = pvc->next;
840 }
841 }
842@@ -346,7 +492,7 @@
843 {
844 int stat_len;
845 pvc_device *pvc;
846- int reptype = -1, error;
847+ int reptype = -1, error, no_ram;
848 u8 rxseq, txseq;
849 int i;
850
851@@ -420,20 +566,18 @@
852 while (pvc) {
853 if (pvc->state.new) {
854 pvc->state.new = 0;
855- pvc->state.active = 1;
856- fr_log_dlci_active(pvc);
857
858 /* Tell DTE that new PVC is now active */
859- hdlc->state.fr.changed = 1;
860+ hdlc->state.fr.dce_changed = 1;
861 }
862 pvc = pvc->next;
863 }
864 }
865
866- if (hdlc->state.fr.changed) {
867+ if (hdlc->state.fr.dce_changed) {
868 reptype = LMI_FULLREP;
869 hdlc->state.fr.fullrep_sent = 1;
870- hdlc->state.fr.changed = 0;
871+ hdlc->state.fr.dce_changed = 0;
872 }
873
874 fr_lmi_send(hdlc, reptype == LMI_FULLREP ? 1 : 0);
875@@ -449,13 +593,14 @@
876 pvc = hdlc->state.fr.first_pvc;
877
878 while (pvc) {
879- pvc->state.deleted = pvc->state.active; /* mark active PVCs */
880+ pvc->state.deleted = 1;
881 pvc = pvc->next;
882 }
883
884+ no_ram = 0;
885 while (skb->len >= i + 2 + stat_len) {
886 u16 dlci;
887- int active, new;
888+ unsigned int active, new;
889
890 if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT)
891 ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) {
892@@ -472,21 +617,28 @@
893 }
894 i++;
895
896- dlci = status_to_dlci(hdlc, skb->data + i, &active, &new);
897- pvc = find_pvc(hdlc, dlci);
898+ dlci = status_to_dlci(skb->data + i, &active, &new);
899+
900+ pvc = add_pvc(hdlc, dlci);
901+
902+ if (!pvc && !no_ram) {
903+ printk(KERN_WARNING
904+ "%s: Memory squeeze on fr_lmi_recv()\n",
905+ hdlc_to_name(hdlc));
906+ no_ram = 1;
907+ }
908
909- active |= new;
910 if (pvc) {
911- if (active && !pvc->state.active &&
912- (pvc->netdev.flags & IFF_UP)) {
913+ pvc->state.exist = 1;
914+ pvc->state.deleted = 0;
915+ if (active != pvc->state.active ||
916+ new != pvc->state.new ||
917+ !pvc->state.exist) {
918+ pvc->state.new = new;
919 pvc->state.active = active;
920 fr_log_dlci_active(pvc);
921 }
922- pvc->state.deleted = 0;
923 }
924- else if (new)
925- printk(KERN_INFO "%s: new PVC available, DLCI=%u\n",
926- hdlc_to_name(hdlc), dlci);
927
928 i += stat_len;
929 }
930@@ -494,10 +646,10 @@
931 pvc = hdlc->state.fr.first_pvc;
932
933 while (pvc) {
934- if (pvc->state.deleted) {
935+ if (pvc->state.deleted && pvc->state.exist) {
936 pvc->state.active = pvc->state.new = 0;
937+ pvc->state.exist = 0;
938 fr_log_dlci_active(pvc);
939- pvc->state.deleted = 0;
940 }
941 pvc = pvc->next;
942 }
943@@ -517,8 +669,9 @@
944 u8 *data = skb->data;
945 u16 dlci;
946 pvc_device *pvc;
947+ struct net_device *dev = NULL;
948
949- if (skb->len<4 || fh->ea1 || data[2] != FR_UI)
950+ if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
951 goto rx_error;
952
953 dlci = q922_to_dlci(skb->data);
954@@ -550,57 +703,39 @@
955 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n",
956 hdlc_to_name(hdlc), dlci);
957 #endif
958- goto rx_error;
959- }
960-
961- if ((pvc->netdev.flags & IFF_UP) == 0) {
962-#ifdef CONFIG_HDLC_DEBUG_PKT
963- printk(KERN_INFO "%s: PVC for received frame's DLCI %d is down\n",
964- hdlc_to_name(hdlc), dlci);
965-#endif
966- goto rx_error;
967+ dev_kfree_skb_any(skb);
968+ return;
969 }
970
971- pvc->stats.rx_packets++; /* PVC traffic */
972- pvc->stats.rx_bytes += skb->len;
973-
974- if (pvc->state.fecn != (fh->fecn ? PVC_STATE_FECN : 0)) {
975+ if (pvc->state.fecn != fh->fecn) {
976 #ifdef CONFIG_HDLC_DEBUG_ECN
977- printk(KERN_DEBUG "%s: FECN O%s\n", pvc_to_name(pvc),
978- fh->fecn ? "N" : "FF");
979+ printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", hdlc_to_name(pvc),
980+ dlci, fh->fecn ? "N" : "FF");
981 #endif
982 pvc->state.fecn ^= 1;
983 }
984
985- if (pvc->state.becn != (fh->becn ? PVC_STATE_BECN : 0)) {
986+ if (pvc->state.becn != fh->becn) {
987 #ifdef CONFIG_HDLC_DEBUG_ECN
988- printk(KERN_DEBUG "%s: BECN O%s\n", pvc_to_name(pvc),
989- fh->becn ? "N" : "FF");
990+ printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", hdlc_to_name(pvc),
991+ dlci, fh->becn ? "N" : "FF");
992 #endif
993 pvc->state.becn ^= 1;
994 }
995
996- if (pvc->state.becn)
997- pvc->stats.rx_compressed++;
998-
999- skb->dev = &pvc->netdev;
1000
1001 if (data[3] == NLPID_IP) {
1002 skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
1003+ dev = pvc->main;
1004 skb->protocol = htons(ETH_P_IP);
1005- netif_rx(skb);
1006- return;
1007- }
1008-
1009
1010- if (data[3] == NLPID_IPV6) {
1011+ } else if (data[3] == NLPID_IPV6) {
1012 skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
1013+ dev = pvc->main;
1014 skb->protocol = htons(ETH_P_IPV6);
1015- netif_rx(skb);
1016- return;
1017- }
1018
1019- if (data[3] == FR_PAD && data[4] == NLPID_SNAP && data[5] == FR_PAD) {
1020+ } else if (skb->len > 10 && data[3] == FR_PAD &&
1021+ data[4] == NLPID_SNAP && data[5] == FR_PAD) {
1022 u16 oui = ntohs(*(u16*)(data + 6));
1023 u16 pid = ntohs(*(u16*)(data + 8));
1024 skb_pull(skb, 10);
1025@@ -610,23 +745,39 @@
1026 case ETH_P_IPX:
1027 case ETH_P_IP: /* a long variant */
1028 case ETH_P_IPV6:
1029+ dev = pvc->main;
1030 skb->protocol = htons(pid);
1031 break;
1032
1033+ case 0x80C20007: /* bridged Ethernet frame */
1034+ if ((dev = pvc->ether) != NULL)
1035+ skb->protocol = eth_type_trans(skb, dev);
1036+ break;
1037+
1038 default:
1039 printk(KERN_INFO "%s: Unsupported protocol, OUI=%x "
1040 "PID=%x\n", hdlc_to_name(hdlc), oui, pid);
1041 dev_kfree_skb_any(skb);
1042 return;
1043 }
1044-
1045- netif_rx(skb);
1046+ } else {
1047+ printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x "
1048+ "length = %i\n", hdlc_to_name(hdlc), data[3], skb->len);
1049+ dev_kfree_skb_any(skb);
1050 return;
1051 }
1052
1053- printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x\n",
1054- hdlc_to_name(hdlc), data[3]);
1055- dev_kfree_skb_any(skb);
1056+ if (dev) {
1057+ struct net_device_stats *stats = pvc_get_stats(dev);
1058+ stats->rx_packets++; /* PVC traffic */
1059+ stats->rx_bytes += skb->len;
1060+ if (pvc->state.becn)
1061+ stats->rx_compressed++;
1062+ skb->dev = dev;
1063+ netif_rx(skb);
1064+ } else
1065+ dev_kfree_skb_any(skb);
1066+
1067 return;
1068
1069 rx_error:
1070@@ -641,7 +792,7 @@
1071 if (hdlc->state.fr.settings.lmi != LMI_NONE) {
1072 hdlc->state.fr.last_poll = 0;
1073 hdlc->state.fr.reliable = 0;
1074- hdlc->state.fr.changed = 1;
1075+ hdlc->state.fr.dce_changed = 1;
1076 hdlc->state.fr.request = 0;
1077 hdlc->state.fr.fullrep_sent = 0;
1078 hdlc->state.fr.last_errors = 0xFFFFFFFF;
1079@@ -669,90 +820,119 @@
1080 if (hdlc->state.fr.settings.lmi != LMI_NONE)
1081 del_timer_sync(&hdlc->state.fr.timer);
1082
1083- while(pvc) {
1084- dev_close(&pvc->netdev); /* Shutdown all PVCs for this FRAD */
1085+ while(pvc) { /* Shutdown all PVCs for this FRAD */
1086+ if (pvc->main)
1087+ dev_close(pvc->main);
1088+ if (pvc->ether)
1089+ dev_close(pvc->ether);
1090+ pvc->state.active = pvc->state.new = pvc->state.fecn =
1091+ pvc->state.becn = 0;
1092+ pvc->state.exist = 0;
1093 pvc = pvc->next;
1094 }
1095 }
1096
1097
1098-
1099-static int fr_pvc(hdlc_device *hdlc, unsigned int dlci, int create)
1100+static int fr_add_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1101 {
1102- pvc_device **pvc_p = &hdlc->state.fr.first_pvc;
1103- pvc_device *pvc;
1104- int result;
1105+ pvc_device *pvc = NULL;
1106+ struct net_device *dev;
1107+ int result, used;
1108+ char * prefix = "pvc%d";
1109
1110- if(dlci <= 0 || dlci >= 1024)
1111- return -EINVAL; /* Only 10 bits for DLCI, DLCI 0 reserved */
1112+ if (type == ARPHRD_ETHER)
1113+ prefix = "pvceth%d";
1114
1115- while(*pvc_p) {
1116- if (netdev_dlci(&(*pvc_p)->netdev) == dlci)
1117- break;
1118- pvc_p = &(*pvc_p)->next;
1119+ if ((pvc = add_pvc(hdlc, dlci)) == NULL) {
1120+ printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
1121+ hdlc_to_name(hdlc));
1122+ return -ENOBUFS;
1123 }
1124
1125- if (create) { /* Create PVC */
1126- if (*pvc_p != NULL)
1127- return -EEXIST;
1128-
1129- pvc = *pvc_p = kmalloc(sizeof(pvc_device), GFP_KERNEL);
1130- if (!pvc) {
1131- printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1132- hdlc_to_name(hdlc));
1133- return -ENOBUFS;
1134- }
1135- memset(pvc, 0, sizeof(pvc_device));
1136+ if (*get_dev_p(pvc, type))
1137+ return -EEXIST;
1138
1139- pvc->netdev.hard_start_xmit = pvc_xmit;
1140- pvc->netdev.get_stats = pvc_get_stats;
1141- pvc->netdev.open = pvc_open;
1142- pvc->netdev.stop = pvc_close;
1143- pvc->netdev.change_mtu = pvc_change_mtu;
1144- pvc->netdev.mtu = HDLC_MAX_MTU;
1145-
1146- pvc->netdev.type = ARPHRD_DLCI;
1147- pvc->netdev.hard_header_len = 16;
1148- pvc->netdev.hard_header = fr_hard_header;
1149- pvc->netdev.tx_queue_len = 0;
1150- pvc->netdev.flags = IFF_POINTOPOINT;
1151-
1152- pvc->master = hdlc;
1153- *(u16*)pvc->netdev.dev_addr = htons(dlci);
1154- dlci_to_q922(pvc->netdev.broadcast, dlci);
1155- pvc->netdev.addr_len = 2;
1156+ used = pvc_is_used(pvc);
1157
1158- result = dev_alloc_name(&pvc->netdev, "pvc%d");
1159- if (result < 0) {
1160- kfree(pvc);
1161- *pvc_p = NULL;
1162- return result;
1163- }
1164-
1165- if (register_netdevice(&pvc->netdev) != 0) {
1166- kfree(pvc);
1167- *pvc_p = NULL;
1168- return -EIO;
1169- }
1170+ dev = kmalloc(sizeof(struct net_device) +
1171+ sizeof(struct net_device_stats), GFP_KERNEL);
1172+ if (!dev) {
1173+ printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1174+ hdlc_to_name(hdlc));
1175+ delete_unused_pvcs(hdlc);
1176+ return -ENOBUFS;
1177+ }
1178+ memset(dev, 0, sizeof(struct net_device) +
1179+ sizeof(struct net_device_stats));
1180
1181- hdlc->state.fr.changed = 1;
1182- hdlc->state.fr.pvc_count++;
1183- return 0;
1184+ if (type == ARPHRD_ETHER) {
1185+ ether_setup(dev);
1186+ memcpy(dev->dev_addr, "\x00\x01", 2);
1187+ get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
1188+ } else {
1189+ dev->type = ARPHRD_DLCI;
1190+ dev->flags = IFF_POINTOPOINT;
1191+ dev->hard_header_len = 10;
1192+ dev->addr_len = 2;
1193+ *(u16*)dev->dev_addr = htons(dlci);
1194+ dlci_to_q922(dev->broadcast, dlci);
1195+ }
1196+ dev->hard_start_xmit = pvc_xmit;
1197+ dev->get_stats = pvc_get_stats;
1198+ dev->open = pvc_open;
1199+ dev->stop = pvc_close;
1200+ dev->do_ioctl = pvc_ioctl;
1201+ dev->change_mtu = pvc_change_mtu;
1202+ dev->mtu = HDLC_MAX_MTU;
1203+ dev->tx_queue_len = 0;
1204+ dev->priv = pvc;
1205+
1206+ result = dev_alloc_name(dev, prefix);
1207+ if (result < 0) {
1208+ kfree(dev);
1209+ delete_unused_pvcs(hdlc);
1210+ return result;
1211+ }
1212+
1213+ if (register_netdevice(dev) != 0) {
1214+ kfree(dev);
1215+ delete_unused_pvcs(hdlc);
1216+ return -EIO;
1217+ }
1218+
1219+ *get_dev_p(pvc, type) = dev;
1220+ if (!used) {
1221+ hdlc->state.fr.dce_changed = 1;
1222+ hdlc->state.fr.dce_pvc_count++;
1223 }
1224+ return 0;
1225+}
1226+
1227+
1228
1229- if (*pvc_p == NULL) /* Delete PVC */
1230+static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1231+{
1232+ pvc_device *pvc;
1233+ struct net_device *dev;
1234+
1235+ if ((pvc = find_pvc(hdlc, dlci)) == NULL)
1236 return -ENOENT;
1237
1238- pvc = *pvc_p;
1239+ if ((dev = *get_dev_p(pvc, type)) == NULL)
1240+ return -ENOENT;
1241
1242- if (pvc->netdev.flags & IFF_UP)
1243+ if (dev->flags & IFF_UP)
1244 return -EBUSY; /* PVC in use */
1245
1246- hdlc->state.fr.changed = 1;
1247- hdlc->state.fr.pvc_count--;
1248- *pvc_p = pvc->next;
1249- unregister_netdevice(&pvc->netdev);
1250- kfree(pvc);
1251+ unregister_netdevice(dev);
1252+ kfree(dev);
1253+ *get_dev_p(pvc, type) = NULL;
1254+
1255+ if (!pvc_is_used(pvc)) {
1256+ hdlc->state.fr.dce_pvc_count--;
1257+ hdlc->state.fr.dce_changed = 1;
1258+ }
1259+ delete_unused_pvcs(hdlc);
1260 return 0;
1261 }
1262
1263@@ -763,14 +943,21 @@
1264 pvc_device *pvc = hdlc->state.fr.first_pvc;
1265 while(pvc) {
1266 pvc_device *next = pvc->next;
1267- unregister_netdev(&pvc->netdev);
1268+ if (pvc->main) {
1269+ unregister_netdevice(pvc->main);
1270+ kfree(pvc->main);
1271+ }
1272+ if (pvc->ether) {
1273+ unregister_netdevice(pvc->ether);
1274+ kfree(pvc->ether);
1275+ }
1276 kfree(pvc);
1277 pvc = next;
1278 }
1279
1280 hdlc->state.fr.first_pvc = NULL; /* All PVCs destroyed */
1281- hdlc->state.fr.pvc_count = 0;
1282- hdlc->state.fr.changed = 1;
1283+ hdlc->state.fr.dce_pvc_count = 0;
1284+ hdlc->state.fr.dce_changed = 1;
1285 }
1286
1287
1288@@ -828,25 +1015,27 @@
1289 if (hdlc->proto != IF_PROTO_FR) {
1290 hdlc_proto_detach(hdlc);
1291 hdlc->state.fr.first_pvc = NULL;
1292- hdlc->state.fr.pvc_count = 0;
1293+ hdlc->state.fr.dce_pvc_count = 0;
1294 }
1295 memcpy(&hdlc->state.fr.settings, &new_settings, size);
1296
1297 hdlc->open = fr_open;
1298 hdlc->stop = fr_close;
1299 hdlc->netif_rx = fr_rx;
1300+ hdlc->type_trans = NULL;
1301 hdlc->proto_detach = fr_destroy;
1302 hdlc->proto = IF_PROTO_FR;
1303 dev->hard_start_xmit = hdlc->xmit;
1304- dev->hard_header = fr_hard_header;
1305+ dev->hard_header = NULL;
1306 dev->type = ARPHRD_FRAD;
1307- dev->addr_len = 2;
1308- *(u16*)dev->dev_addr = htons(LMI_DLCI);
1309- dlci_to_q922(dev->broadcast, LMI_DLCI);
1310+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1311+ dev->addr_len = 0;
1312 return 0;
1313
1314 case IF_PROTO_FR_ADD_PVC:
1315 case IF_PROTO_FR_DEL_PVC:
1316+ case IF_PROTO_FR_ADD_ETH_PVC:
1317+ case IF_PROTO_FR_DEL_ETH_PVC:
1318 if(!capable(CAP_NET_ADMIN))
1319 return -EPERM;
1320
1321@@ -854,8 +1043,20 @@
1322 sizeof(fr_proto_pvc)))
1323 return -EFAULT;
1324
1325- return fr_pvc(hdlc, pvc.dlci,
1326- ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC);
1327+ if (pvc.dlci <= 0 || pvc.dlci >= 1024)
1328+ return -EINVAL; /* Only 10 bits, DLCI 0 reserved */
1329+
1330+ if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC ||
1331+ ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC)
1332+ result = ARPHRD_ETHER; /* bridged Ethernet device */
1333+ else
1334+ result = ARPHRD_DLCI;
1335+
1336+ if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC ||
1337+ ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC)
1338+ return fr_add_pvc(hdlc, pvc.dlci, result);
1339+ else
1340+ return fr_del_pvc(hdlc, pvc.dlci, result);
1341 }
1342
1343 return -EINVAL;
1344--- linux-2.4.orig/drivers/net/wan/hdlc_generic.c 2003-07-29 23:25:03.000000000 +0200
1345+++ linux-2.4/drivers/net/wan/hdlc_generic.c 2003-07-29 23:32:23.000000000 +0200
1346@@ -1,17 +1,13 @@
1347 /*
1348 * Generic HDLC support routines for Linux
1349 *
1350- * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1351+ * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
1352 *
1353 * This program is free software; you can redistribute it and/or modify it
1354- * under the terms of the GNU General Public License as published by
1355- * the Free Software Foundation; either version 2 of the License, or
1356- * (at your option) any later version.
1357+ * under the terms of version 2 of the GNU General Public License
1358+ * as published by the Free Software Foundation.
1359 *
1360- * Current status:
1361- * - this is work in progress
1362- * - not heavily tested on SMP
1363- * - currently supported:
1364+ * Currently supported:
1365 * * raw IP-in-HDLC
1366 * * Cisco HDLC
1367 * * Frame Relay with ANSI or CCITT LMI (both user and network side)
1368@@ -37,7 +33,7 @@
1369 #include <linux/hdlc.h>
1370
1371
1372-static const char* version = "HDLC support module revision 1.11";
1373+static const char* version = "HDLC support module revision 1.14";
1374
1375
1376 static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
1377@@ -60,7 +56,13 @@
1378 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
1379 struct packet_type *p)
1380 {
1381- dev_to_hdlc(dev)->netif_rx(skb);
1382+ hdlc_device *hdlc = dev_to_hdlc(dev);
1383+ if (hdlc->netif_rx)
1384+ hdlc->netif_rx(skb);
1385+ else {
1386+ hdlc->stats.rx_dropped++; /* Shouldn't happen */
1387+ dev_kfree_skb(skb);
1388+ }
1389 return 0;
1390 }
1391
1392@@ -69,6 +71,10 @@
1393 #define hdlc_raw_ioctl(hdlc, ifr) -ENOSYS
1394 #endif
1395
1396+#ifndef CONFIG_HDLC_RAW_ETH
1397+#define hdlc_raw_eth_ioctl(hdlc, ifr) -ENOSYS
1398+#endif
1399+
1400 #ifndef CONFIG_HDLC_PPP
1401 #define hdlc_ppp_ioctl(hdlc, ifr) -ENOSYS
1402 #endif
1403@@ -96,6 +102,7 @@
1404
1405 switch(ifr->ifr_settings.type) {
1406 case IF_PROTO_HDLC:
1407+ case IF_PROTO_HDLC_ETH:
1408 case IF_PROTO_PPP:
1409 case IF_PROTO_CISCO:
1410 case IF_PROTO_FR:
1411@@ -109,6 +116,7 @@
1412
1413 switch(proto) {
1414 case IF_PROTO_HDLC: return hdlc_raw_ioctl(hdlc, ifr);
1415+ case IF_PROTO_HDLC_ETH: return hdlc_raw_eth_ioctl(hdlc, ifr);
1416 case IF_PROTO_PPP: return hdlc_ppp_ioctl(hdlc, ifr);
1417 case IF_PROTO_CISCO: return hdlc_cisco_ioctl(hdlc, ifr);
1418 case IF_PROTO_FR: return hdlc_fr_ioctl(hdlc, ifr);
1419@@ -152,9 +160,10 @@
1420
1421 void unregister_hdlc_device(hdlc_device *hdlc)
1422 {
1423+ rtnl_lock();
1424 hdlc_proto_detach(hdlc);
1425-
1426- unregister_netdev(hdlc_to_dev(hdlc));
1427+ unregister_netdevice(hdlc_to_dev(hdlc));
1428+ rtnl_unlock();
1429 MOD_DEC_USE_COUNT;
1430 }
1431
1432@@ -162,7 +171,7 @@
1433
1434 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1435 MODULE_DESCRIPTION("HDLC support module");
1436-MODULE_LICENSE("GPL");
1437+MODULE_LICENSE("GPL v2");
1438
1439 EXPORT_SYMBOL(hdlc_ioctl);
1440 EXPORT_SYMBOL(register_hdlc_device);
1441--- linux-2.4.orig/drivers/net/wan/hdlc_ppp.c 2003-07-29 23:25:03.000000000 +0200
1442+++ linux-2.4/drivers/net/wan/hdlc_ppp.c 2003-07-29 23:32:23.000000000 +0200
1443@@ -2,12 +2,11 @@
1444 * Generic HDLC support routines for Linux
1445 * Point-to-point protocol support
1446 *
1447- * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1448+ * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
1449 *
1450 * This program is free software; you can redistribute it and/or modify it
1451- * under the terms of the GNU General Public License as published by
1452- * the Free Software Foundation; either version 2 of the License, or
1453- * (at your option) any later version.
1454+ * under the terms of version 2 of the GNU General Public License
1455+ * as published by the Free Software Foundation.
1456 */
1457
1458 #include <linux/config.h>
1459@@ -68,10 +67,10 @@
1460
1461
1462
1463-static void ppp_rx(struct sk_buff *skb)
1464+static unsigned short ppp_type_trans(struct sk_buff *skb,
1465+ struct net_device *dev)
1466 {
1467- skb->protocol = htons(ETH_P_WAN_PPP);
1468- netif_rx(skb);
1469+ return __constant_htons(ETH_P_WAN_PPP);
1470 }
1471
1472
1473@@ -103,7 +102,8 @@
1474
1475 hdlc->open = ppp_open;
1476 hdlc->stop = ppp_close;
1477- hdlc->netif_rx = ppp_rx;
1478+ hdlc->netif_rx = NULL;
1479+ hdlc->type_trans = ppp_type_trans;
1480 hdlc->proto = IF_PROTO_PPP;
1481 dev->hard_start_xmit = hdlc->xmit;
1482 dev->hard_header = NULL;
1483--- linux-2.4.orig/drivers/net/wan/hdlc_x25.c 2003-07-29 23:25:03.000000000 +0200
1484+++ linux-2.4/drivers/net/wan/hdlc_x25.c 2003-07-29 23:32:23.000000000 +0200
1485@@ -2,12 +2,11 @@
1486 * Generic HDLC support routines for Linux
1487 * X.25 support
1488 *
1489- * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1490+ * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
1491 *
1492 * This program is free software; you can redistribute it and/or modify it
1493- * under the terms of the GNU General Public License as published by
1494- * the Free Software Foundation; either version 2 of the License, or
1495- * (at your option) any later version.
1496+ * under the terms of version 2 of the GNU General Public License
1497+ * as published by the Free Software Foundation.
1498 */
1499
1500 #include <linux/config.h>
1501@@ -204,6 +203,7 @@
1502 hdlc->open = x25_open;
1503 hdlc->stop = x25_close;
1504 hdlc->netif_rx = x25_rx;
1505+ hdlc->type_trans = NULL;
1506 hdlc->proto = IF_PROTO_X25;
1507 dev->hard_start_xmit = x25_xmit;
1508 dev->hard_header = NULL;
1509--- linux-2.4.orig/drivers/net/wan/hdlc_raw.c 2003-07-29 23:25:03.000000000 +0200
1510+++ linux-2.4/drivers/net/wan/hdlc_raw.c 2003-07-29 23:32:23.000000000 +0200
1511@@ -2,12 +2,11 @@
1512 * Generic HDLC support routines for Linux
1513 * HDLC support
1514 *
1515- * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1516+ * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
1517 *
1518 * This program is free software; you can redistribute it and/or modify it
1519- * under the terms of the GNU General Public License as published by
1520- * the Free Software Foundation; either version 2 of the License, or
1521- * (at your option) any later version.
1522+ * under the terms of version 2 of the GNU General Public License
1523+ * as published by the Free Software Foundation.
1524 */
1525
1526 #include <linux/config.h>
1527@@ -26,10 +25,10 @@
1528 #include <linux/hdlc.h>
1529
1530
1531-static void raw_rx(struct sk_buff *skb)
1532+static unsigned short raw_type_trans(struct sk_buff *skb,
1533+ struct net_device *dev)
1534 {
1535- skb->protocol = htons(ETH_P_IP);
1536- netif_rx(skb);
1537+ return __constant_htons(ETH_P_IP);
1538 }
1539
1540
1541@@ -67,7 +66,7 @@
1542 new_settings.encoding = ENCODING_NRZ;
1543
1544 if (new_settings.parity == PARITY_DEFAULT)
1545- new_settings.parity = PARITY_NONE;
1546+ new_settings.parity = PARITY_CRC16_PR1_CCITT;
1547
1548 result = hdlc->attach(hdlc, new_settings.encoding,
1549 new_settings.parity);
1550@@ -79,11 +78,13 @@
1551
1552 hdlc->open = NULL;
1553 hdlc->stop = NULL;
1554- hdlc->netif_rx = raw_rx;
1555+ hdlc->netif_rx = NULL;
1556+ hdlc->type_trans = raw_type_trans;
1557 hdlc->proto = IF_PROTO_HDLC;
1558 dev->hard_start_xmit = hdlc->xmit;
1559 dev->hard_header = NULL;
1560 dev->type = ARPHRD_RAWHDLC;
1561+ dev->flags = IFF_POINTOPOINT | IFF_NOARP;
1562 dev->addr_len = 0;
1563 return 0;
1564 }
1565--- linux-2.4.orig/drivers/net/wan/hdlc_raw_eth.c 2003-07-29 23:34:24.000000000 +0200
1566+++ linux-2.4/drivers/net/wan/hdlc_raw_eth.c 2003-07-29 23:32:23.000000000 +0200
1567@@ -0,0 +1,110 @@
1568+/*
1569+ * Generic HDLC support routines for Linux
1570+ * HDLC Ethernet emulation support
1571+ *
1572+ * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl>
1573+ *
1574+ * This program is free software; you can redistribute it and/or modify it
1575+ * under the terms of version 2 of the GNU General Public License
1576+ * as published by the Free Software Foundation.
1577+ */
1578+
1579+#include <linux/config.h>
1580+#include <linux/module.h>
1581+#include <linux/kernel.h>
1582+#include <linux/slab.h>
1583+#include <linux/poll.h>
1584+#include <linux/errno.h>
1585+#include <linux/if_arp.h>
1586+#include <linux/init.h>
1587+#include <linux/skbuff.h>
1588+#include <linux/pkt_sched.h>
1589+#include <linux/random.h>
1590+#include <linux/inetdevice.h>
1591+#include <linux/lapb.h>
1592+#include <linux/rtnetlink.h>
1593+#include <linux/etherdevice.h>
1594+#include <linux/hdlc.h>
1595+
1596+
1597+static int eth_tx(struct sk_buff *skb, struct net_device *dev)
1598+{
1599+ int pad = ETH_ZLEN - skb->len;
1600+ if (pad > 0) { /* Pad the frame with zeros */
1601+ int len = skb->len;
1602+ if (skb_tailroom(skb) < pad)
1603+ if (pskb_expand_head(skb, 0, pad, GFP_ATOMIC)) {
1604+ dev_to_hdlc(dev)->stats.tx_dropped++;
1605+ dev_kfree_skb(skb);
1606+ return 0;
1607+ }
1608+ skb_put(skb, pad);
1609+ memset(skb->data + len, 0, pad);
1610+ }
1611+ return dev_to_hdlc(dev)->xmit(skb, dev);
1612+}
1613+
1614+
1615+int hdlc_raw_eth_ioctl(hdlc_device *hdlc, struct ifreq *ifr)
1616+{
1617+ raw_hdlc_proto *raw_s = ifr->ifr_settings.ifs_ifsu.raw_hdlc;
1618+ const size_t size = sizeof(raw_hdlc_proto);
1619+ raw_hdlc_proto new_settings;
1620+ struct net_device *dev = hdlc_to_dev(hdlc);
1621+ int result;
1622+ void *old_ch_mtu;
1623+ int old_qlen;
1624+
1625+ switch (ifr->ifr_settings.type) {
1626+ case IF_GET_PROTO:
1627+ ifr->ifr_settings.type = IF_PROTO_HDLC_ETH;
1628+ if (ifr->ifr_settings.size < size) {
1629+ ifr->ifr_settings.size = size; /* data size wanted */
1630+ return -ENOBUFS;
1631+ }
1632+ if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size))
1633+ return -EFAULT;
1634+ return 0;
1635+
1636+ case IF_PROTO_HDLC_ETH:
1637+ if (!capable(CAP_NET_ADMIN))
1638+ return -EPERM;
1639+
1640+ if (dev->flags & IFF_UP)
1641+ return -EBUSY;
1642+
1643+ if (copy_from_user(&new_settings, raw_s, size))
1644+ return -EFAULT;
1645+
1646+ if (new_settings.encoding == ENCODING_DEFAULT)
1647+ new_settings.encoding = ENCODING_NRZ;
1648+
1649+ if (new_settings.parity == PARITY_DEFAULT)
1650+ new_settings.parity = PARITY_CRC16_PR1_CCITT;
1651+
1652+ result = hdlc->attach(hdlc, new_settings.encoding,
1653+ new_settings.parity);
1654+ if (result)
1655+ return result;
1656+
1657+ hdlc_proto_detach(hdlc);
1658+ memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size);
1659+
1660+ hdlc->open = NULL;
1661+ hdlc->stop = NULL;
1662+ hdlc->netif_rx = NULL;
1663+ hdlc->type_trans = eth_type_trans;
1664+ hdlc->proto = IF_PROTO_HDLC_ETH;
1665+ dev->hard_start_xmit = eth_tx;
1666+ old_ch_mtu = dev->change_mtu;
1667+ old_qlen = dev->tx_queue_len;
1668+ ether_setup(dev);
1669+ dev->change_mtu = old_ch_mtu;
1670+ dev->tx_queue_len = old_qlen;
1671+ memcpy(dev->dev_addr, "\x00\x01", 2);
1672+ get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
1673+ return 0;
1674+ }
1675+
1676+ return -EINVAL;
1677+}
1678--- linux-2.4.orig/drivers/net/wan/hd6457x.c 2003-07-29 23:25:03.000000000 +0200
1679+++ linux-2.4/drivers/net/wan/hd6457x.c 2003-07-29 23:32:44.000000000 +0200
1680@@ -1,16 +1,29 @@
1681 /*
1682 * Hitachi SCA HD64570 and HD64572 common driver for Linux
1683 *
1684- * Copyright (C) 1998-2000 Krzysztof Halasa <khc@pm.waw.pl>
1685+ * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
1686 *
1687 * This program is free software; you can redistribute it and/or modify it
1688- * under the terms of the GNU General Public License as published by
1689- * the Free Software Foundation; either version 2 of the License, or
1690- * (at your option) any later version.
1691+ * under the terms of version 2 of the GNU General Public License
1692+ * as published by the Free Software Foundation.
1693 *
1694 * Sources of information:
1695 * Hitachi HD64570 SCA User's Manual
1696 * Hitachi HD64572 SCA-II User's Manual
1697+ *
1698+ * We use the following SCA memory map:
1699+ *
1700+ * Packet buffer descriptor rings - starting from winbase or win0base:
1701+ * rx_ring_buffers * sizeof(pkt_desc) = logical channel #0 RX ring
1702+ * tx_ring_buffers * sizeof(pkt_desc) = logical channel #0 TX ring
1703+ * rx_ring_buffers * sizeof(pkt_desc) = logical channel #1 RX ring (if used)
1704+ * tx_ring_buffers * sizeof(pkt_desc) = logical channel #1 TX ring (if used)
1705+ *
1706+ * Packet data buffers - starting from winbase + buff_offset:
1707+ * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers
1708+ * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers
1709+ * rx_ring_buffers * HDLC_MAX_MRU = logical channel #0 RX buffers (if used)
1710+ * tx_ring_buffers * HDLC_MAX_MRU = logical channel #0 TX buffers (if used)
1711 */
1712
1713 #include <linux/module.h>
1714@@ -42,8 +55,6 @@
1715 #error Either hd64570.h or hd64572.h must be included
1716 #endif
1717
1718-static char sca_version[]="1.09";
1719-
1720 #define get_msci(port) (phy_node(port) ? MSCI1_OFFSET : MSCI0_OFFSET)
1721 #define get_dmac_rx(port) (phy_node(port) ? DMAC1RX_OFFSET : DMAC0RX_OFFSET)
1722 #define get_dmac_tx(port) (phy_node(port) ? DMAC1TX_OFFSET : DMAC0TX_OFFSET)
1723@@ -116,24 +127,35 @@
1724
1725
1726
1727-static inline u8 next_desc(port_t *port, u8 desc)
1728+static inline u16 next_desc(port_t *port, u16 desc, int transmit)
1729+{
1730+ return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers
1731+ : port_to_card(port)->rx_ring_buffers);
1732+}
1733+
1734+
1735+
1736+static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit)
1737 {
1738- return (desc + 1) % port_to_card(port)->ring_buffers;
1739+ u16 rx_buffs = port_to_card(port)->rx_ring_buffers;
1740+ u16 tx_buffs = port_to_card(port)->tx_ring_buffers;
1741+
1742+ desc %= (transmit ? tx_buffs : rx_buffs); // called with "X + 1" etc.
1743+ return log_node(port) * (rx_buffs + tx_buffs) +
1744+ transmit * rx_buffs + desc;
1745 }
1746
1747
1748
1749-static inline u16 desc_offset(port_t *port, u8 desc, u8 transmit)
1750+static inline u16 desc_offset(port_t *port, u16 desc, int transmit)
1751 {
1752 /* Descriptor offset always fits in 16 bytes */
1753- u8 buffs = port_to_card(port)->ring_buffers;
1754- return ((log_node(port) * 2 + transmit) * buffs + (desc % buffs)) *
1755- sizeof(pkt_desc);
1756+ return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc);
1757 }
1758
1759
1760
1761-static inline pkt_desc* desc_address(port_t *port, u8 desc, u8 transmit)
1762+static inline pkt_desc* desc_address(port_t *port, u16 desc, int transmit)
1763 {
1764 #ifdef PAGE0_ALWAYS_MAPPED
1765 return (pkt_desc*)(win0base(port_to_card(port))
1766@@ -146,12 +168,10 @@
1767
1768
1769
1770-static inline u32 buffer_offset(port_t *port, u8 desc, u8 transmit)
1771+static inline u32 buffer_offset(port_t *port, u16 desc, int transmit)
1772 {
1773- u8 buffs = port_to_card(port)->ring_buffers;
1774 return port_to_card(port)->buff_offset +
1775- ((log_node(port) * 2 + transmit) * buffs + (desc % buffs)) *
1776- (u32)HDLC_MAX_MRU;
1777+ desc_abs_number(port, desc, transmit) * (u32)HDLC_MAX_MRU;
1778 }
1779
1780
1781@@ -159,8 +179,7 @@
1782 static void sca_init_sync_port(port_t *port)
1783 {
1784 card_t *card = port_to_card(port);
1785- u8 transmit, i;
1786- u16 dmac, buffs = card->ring_buffers;
1787+ int transmit, i;
1788
1789 port->rxin = 0;
1790 port->txin = 0;
1791@@ -171,6 +190,10 @@
1792 #endif
1793
1794 for (transmit = 0; transmit < 2; transmit++) {
1795+ u16 dmac = transmit ? get_dmac_tx(port) : get_dmac_rx(port);
1796+ u16 buffs = transmit ? card->tx_ring_buffers
1797+ : card->rx_ring_buffers;
1798+
1799 for (i = 0; i < buffs; i++) {
1800 pkt_desc* desc = desc_address(port, i, transmit);
1801 u16 chain_off = desc_offset(port, i + 1, transmit);
1802@@ -182,7 +205,6 @@
1803 writeb(0, &desc->stat);
1804 }
1805
1806- dmac = transmit ? get_dmac_tx(port) : get_dmac_rx(port);
1807 /* DMA disable - to halt state */
1808 sca_out(0, transmit ? DSR_TX(phy_node(port)) :
1809 DSR_RX(phy_node(port)), card);
1810@@ -247,7 +269,7 @@
1811
1812
1813
1814-static inline void sca_rx(card_t *card, port_t *port, pkt_desc *desc, u8 rxin)
1815+static inline void sca_rx(card_t *card, port_t *port, pkt_desc *desc, u16 rxin)
1816 {
1817 struct sk_buff *skb;
1818 u16 len;
1819@@ -294,7 +316,7 @@
1820 skb->mac.raw = skb->data;
1821 skb->dev = hdlc_to_dev(&port->hdlc);
1822 skb->dev->last_rx = jiffies;
1823- skb->protocol = htons(ETH_P_HDLC);
1824+ skb->protocol = hdlc_type_trans(skb, hdlc_to_dev(&port->hdlc));
1825 netif_rx(skb);
1826 }
1827
1828@@ -341,7 +363,7 @@
1829
1830 /* Set new error descriptor address */
1831 sca_outa(desc_off, dmac + EDAL, card);
1832- port->rxin = next_desc(port, port->rxin);
1833+ port->rxin = next_desc(port, port->rxin, 0);
1834 }
1835
1836 /* make sure RX DMA is enabled */
1837@@ -377,8 +399,7 @@
1838 port->hdlc.stats.tx_packets++;
1839 port->hdlc.stats.tx_bytes += readw(&desc->len);
1840 writeb(0, &desc->stat); /* Free descriptor */
1841- port->txlast = (port->txlast + 1) %
1842- port_to_card(port)->ring_buffers;
1843+ port->txlast = next_desc(port, port->txlast, 1);
1844 }
1845
1846 netif_wake_queue(hdlc_to_dev(&port->hdlc));
1847@@ -390,8 +411,6 @@
1848 static void sca_intr(int irq, void* dev_id, struct pt_regs *regs)
1849 {
1850 card_t *card = dev_id;
1851-/* Maximum events to handle at each interrupt - should I increase it? */
1852- int boguscnt = 4;
1853 int i;
1854 u8 stat;
1855
1856@@ -412,23 +431,12 @@
1857 if (stat & SCA_INTR_DMAC_TX(i))
1858 sca_tx_intr(port);
1859 }
1860-
1861- if (--boguscnt < 0) {
1862-#if 0
1863- printk(KERN_ERR "%s: too much work at "
1864- "interrupt\n",
1865- hdlc_to_name(&port->hdlc));
1866-#endif
1867- goto exit;
1868- }
1869 }
1870 }
1871
1872- exit:
1873 #ifndef ALL_PAGES_ALWAYS_MAPPED
1874 openwin(card, page); /* Restore original page */
1875 #endif
1876- return;
1877 }
1878
1879
1880@@ -436,7 +444,7 @@
1881 static void sca_set_port(port_t *port)
1882 {
1883 card_t* card = port_to_card(port);
1884- u8 msci = get_msci(port);
1885+ u16 msci = get_msci(port);
1886 u8 md2 = sca_in(msci + MD2, card);
1887 unsigned int tmc, br = 10, brv = 1024;
1888
1889@@ -496,7 +504,7 @@
1890 {
1891 port_t *port = hdlc_to_port(hdlc);
1892 card_t* card = port_to_card(port);
1893- u8 msci = get_msci(port);
1894+ u16 msci = get_msci(port);
1895 u8 md0, md2;
1896
1897 switch(port->encoding) {
1898@@ -517,7 +525,7 @@
1899 case PARITY_CRC16_PR0_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU_0; break;
1900 #else
1901 case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break;
1902-#endif
1903+#endif
1904 case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU; break;
1905 default: md0 = MD0_HDLC | MD0_CRC_NONE;
1906 }
1907@@ -566,7 +574,7 @@
1908 /* MSCI TX INT IRQ enable */
1909 sca_outl(IE0_TXINT | IE0_UDRN, msci + IE0, card);
1910 /* DMA & MSCI IRQ enable */
1911- sca_outl(sca_in(IER0, card) |
1912+ sca_outl(sca_inl(IER0, card) |
1913 (phy_node(port) ? 0x02006600 : 0x00020066), IER0, card);
1914 #endif
1915
1916@@ -614,7 +622,7 @@
1917 parity != PARITY_CRC16_PR0_CCITT &&
1918 #else
1919 parity != PARITY_CRC32_PR1_CCITT &&
1920-#endif
1921+#endif
1922 parity != PARITY_CRC16_PR1_CCITT)
1923 return -EINVAL;
1924
1925@@ -640,14 +648,13 @@
1926 openwin(card, 0);
1927 #endif
1928
1929- printk(KERN_ERR "RX ring: CDA=%u EDA=%u DSR=%02X in=%u "
1930- "%sactive",
1931+ printk(KERN_ERR "RX ring: CDA=%u EDA=%u DSR=%02X in=%u %sactive",
1932 sca_ina(get_dmac_rx(port) + CDAL, card),
1933 sca_ina(get_dmac_rx(port) + EDAL, card),
1934 sca_in(DSR_RX(phy_node(port)), card),
1935 port->rxin,
1936 sca_in(DSR_RX(phy_node(port)), card) & DSR_DE?"":"in");
1937- for (cnt = 0; cnt<port_to_card(port)->ring_buffers; cnt++)
1938+ for (cnt = 0; cnt < port_to_card(port)->rx_ring_buffers; cnt++)
1939 printk(" %02X",
1940 readb(&(desc_address(port, cnt, 0)->stat)));
1941
1942@@ -659,7 +666,7 @@
1943 port->txlast,
1944 sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in");
1945
1946- for (cnt = 0; cnt<port_to_card(port)->ring_buffers; cnt++)
1947+ for (cnt = 0; cnt < port_to_card(port)->tx_ring_buffers; cnt++)
1948 printk(" %02X",
1949 readb(&(desc_address(port, cnt, 1)->stat)));
1950 printk("\n");
1951@@ -751,7 +758,7 @@
1952 writeb(ST_TX_EOM, &desc->stat);
1953 dev->trans_start = jiffies;
1954
1955- port->txin = next_desc(port, port->txin);
1956+ port->txin = next_desc(port, port->txin, 1);
1957 sca_outa(desc_offset(port, port->txin, 1),
1958 get_dmac_tx(port) + EDAL, card);
1959
1960@@ -768,7 +775,49 @@
1961 }
1962
1963
1964-static void sca_init(card_t *card, int wait_states)
1965+
1966+#ifdef NEED_DETECT_RAM
1967+static u32 __devinit sca_detect_ram(card_t *card, u8 *rambase, u32 ramsize)
1968+{
1969+ /* Round RAM size to 32 bits, fill from end to start */
1970+ u32 i = ramsize &= ~3;
1971+
1972+#ifndef ALL_PAGES_ALWAYS_MAPPED
1973+ u32 size = winsize(card);
1974+
1975+ openwin(card, (i - 4) / size); /* select last window */
1976+#endif
1977+ do {
1978+ i -= 4;
1979+#ifndef ALL_PAGES_ALWAYS_MAPPED
1980+ if ((i + 4) % size == 0)
1981+ openwin(card, i / size);
1982+ writel(i ^ 0x12345678, rambase + i % size);
1983+#else
1984+ writel(i ^ 0x12345678, rambase + i);
1985+#endif
1986+ }while (i > 0);
1987+
1988+ for (i = 0; i < ramsize ; i += 4) {
1989+#ifndef ALL_PAGES_ALWAYS_MAPPED
1990+ if (i % size == 0)
1991+ openwin(card, i / size);
1992+
1993+ if (readl(rambase + i % size) != (i ^ 0x12345678))
1994+ break;
1995+#else
1996+ if (readl(rambase + i) != (i ^ 0x12345678))
1997+ break;
1998+#endif
1999+ }
2000+
2001+ return i;
2002+}
2003+#endif /* NEED_DETECT_RAM */
2004+
2005+
2006+
2007+static void __devinit sca_init(card_t *card, int wait_states)
2008 {
2009 sca_out(wait_states, WCRL, card); /* Wait Control */
2010 sca_out(wait_states, WCRM, card);
2011--- linux-2.4.orig/drivers/net/wan/n2.c 2003-07-29 23:25:03.000000000 +0200
2012+++ linux-2.4/drivers/net/wan/n2.c 2003-07-29 23:32:23.000000000 +0200
2013@@ -1,12 +1,11 @@
2014 /*
2015 * SDL Inc. RISCom/N2 synchronous serial card driver for Linux
2016 *
2017- * Copyright (C) 1998-2002 Krzysztof Halasa <khc@pm.waw.pl>
2018+ * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
2019 *
2020 * This program is free software; you can redistribute it and/or modify it
2021- * under the terms of the GNU General Public License as published by
2022- * the Free Software Foundation; either version 2 of the License, or
2023- * (at your option) any later version.
2024+ * under the terms of version 2 of the GNU General Public License
2025+ * as published by the Free Software Foundation.
2026 *
2027 * For information see http://hq.pm.waw.pl/hdlc/
2028 *
2029@@ -34,14 +33,21 @@
2030 #include "hd64570.h"
2031
2032
2033-static const char* version = "SDL RISCom/N2 driver version: 1.10";
2034+static const char* version = "SDL RISCom/N2 driver version: 1.14";
2035 static const char* devname = "RISCom/N2";
2036
2037 #define USE_WINDOWSIZE 16384
2038 #define USE_BUS16BITS 1
2039 #define CLOCK_BASE 9830400 /* 9.8304 MHz */
2040-
2041+#define MAX_PAGES 16 /* 16 RAM pages at max */
2042+#define MAX_RAM_SIZE 0x80000 /* 512 KB */
2043+#if MAX_RAM_SIZE > MAX_PAGES * USE_WINDOWSIZE
2044+#undef MAX_RAM_SIZE
2045+#define MAX_RAM_SIZE (MAX_PAGES * USE_WINDOWSIZE)
2046+#endif
2047 #define N2_IOPORTS 0x10
2048+#define NEED_DETECT_RAM
2049+#define MAX_TX_BUFFERS 10
2050
2051 static char *hw = NULL; /* pointer to hw=xxx command line string */
2052
2053@@ -86,16 +92,16 @@
2054 struct card_s *card;
2055 spinlock_t lock; /* TX lock */
2056 sync_serial_settings settings;
2057+ int valid; /* port enabled */
2058+ int rxpart; /* partial frame received, next frame invalid*/
2059 unsigned short encoding;
2060 unsigned short parity;
2061+ u16 rxin; /* rx ring buffer 'in' pointer */
2062+ u16 txin; /* tx ring buffer 'in' and 'last' pointers */
2063+ u16 txlast;
2064 u8 rxs, txs, tmc; /* SCA registers */
2065- u8 valid; /* port enabled */
2066 u8 phy_node; /* physical port # - 0 or 1 */
2067 u8 log_node; /* logical port # */
2068- u8 rxin; /* rx ring buffer 'in' pointer */
2069- u8 txin; /* tx ring buffer 'in' and 'last' pointers */
2070- u8 txlast;
2071- u8 rxpart; /* partial frame received, next frame invalid*/
2072 }port_t;
2073
2074
2075@@ -106,8 +112,9 @@
2076 u32 ram_size; /* number of bytes */
2077 u16 io; /* IO Base address */
2078 u16 buff_offset; /* offset of first buffer of first channel */
2079+ u16 rx_ring_buffers; /* number of buffers in a ring */
2080+ u16 tx_ring_buffers;
2081 u8 irq; /* IRQ (3-15) */
2082- u8 ring_buffers; /* number of buffers in a ring */
2083
2084 port_t ports[2];
2085 struct card_s *next_card;
2086@@ -216,7 +223,7 @@
2087 MOD_INC_USE_COUNT;
2088 mcr &= port->phy_node ? ~DTR_PORT1 : ~DTR_PORT0; /* set DTR ON */
2089 outb(mcr, io + N2_MCR);
2090-
2091+
2092 outb(inb(io + N2_PCR) | PCR_ENWIN, io + N2_PCR); /* open window */
2093 outb(inb(io + N2_PSR) | PSR_DMAEN, io + N2_PSR); /* enable dma */
2094 sca_open(hdlc);
2095@@ -297,62 +304,6 @@
2096
2097
2098
2099-static u8 n2_count_page(card_t *card)
2100-{
2101- u8 page;
2102- int i, bcount = USE_WINDOWSIZE, wcount = USE_WINDOWSIZE/2;
2103- u16 *dp = (u16*)card->winbase;
2104- u8 *bp = (u8*)card->winbase;
2105- u8 psr = inb(card->io + N2_PSR) & PSR_WINBITS;
2106-
2107-
2108- for (page = 0; page < 16; page++) {
2109- outb(psr | page, card->io + N2_PSR); /* select a page */
2110- writeb(page, dp);
2111- if (readb(dp) != page)
2112- break; /* If can't read back, no good memory */
2113-
2114- outb(psr, card->io + N2_PSR); /* goto page 0 */
2115- if (readb(dp))
2116- break; /* If page 0 changed, then wrapped around */
2117-
2118- outb(psr | page, card->io + N2_PSR); /* select page again */
2119-
2120- /* first do byte tests */
2121- for (i = 0; i < bcount; i++)
2122- writeb(i, bp + i);
2123- for (i = 0; i < bcount; i++)
2124- if (readb(bp + i) != (i & 0xff))
2125- return 0;
2126-
2127- for (i = 0; i < bcount; i++)
2128- writeb(~i, bp + i);
2129- for (i = 0; i < bcount; i++)
2130- if (readb(bp + i) != (~i & 0xff))
2131- return 0;
2132-
2133- /* next do 16-bit tests */
2134- for (i = 0; i < wcount; i++)
2135- writew(0x55AA, dp + i);
2136- for (i = 0; i < wcount; i++)
2137- if (readw(dp + i) != 0x55AA)
2138- return 0;
2139-
2140- for (i = 0; i < wcount; i++)
2141- writew(0xAA55, dp + i);
2142- for (i = 0; i < wcount; i++)
2143- if (readw(dp + i) != 0xAA55)
2144- return 0;
2145-
2146- for (i = 0; i < wcount; i++)
2147- writew(page, dp + i);
2148- }
2149-
2150- return page;
2151-}
2152-
2153-
2154-
2155 static void n2_destroy_card(card_t *card)
2156 {
2157 int cnt;
2158@@ -376,11 +327,12 @@
2159
2160
2161
2162-static int n2_run(unsigned long io, unsigned long irq, unsigned long winbase,
2163- long valid0, long valid1)
2164+static int __init n2_run(unsigned long io, unsigned long irq,
2165+ unsigned long winbase, long valid0, long valid1)
2166 {
2167 card_t *card;
2168 u8 cnt, pcr;
2169+ int i;
2170
2171 if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) {
2172 printk(KERN_ERR "n2: invalid I/O port value\n");
2173@@ -391,7 +343,7 @@
2174 printk(KERN_ERR "n2: invalid IRQ value\n");
2175 return -ENODEV;
2176 }
2177-
2178+
2179 if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) {
2180 printk(KERN_ERR "n2: invalid RAM value\n");
2181 return -ENODEV;
2182@@ -451,25 +403,27 @@
2183 pcr = PCR_ENWIN | PCR_VPM | (USE_BUS16BITS ? PCR_BUS16 : 0);
2184 outb(pcr, io + N2_PCR);
2185
2186- cnt = n2_count_page(card);
2187- if (!cnt) {
2188- printk(KERN_ERR "n2: memory test failed.\n");
2189- n2_destroy_card(card);
2190- return -EIO;
2191- }
2192+ card->ram_size = sca_detect_ram(card, card->winbase, MAX_RAM_SIZE);
2193
2194- card->ram_size = cnt * USE_WINDOWSIZE;
2195+ /* number of TX + RX buffers for one port */
2196+ i = card->ram_size / ((valid0 + valid1) * (sizeof(pkt_desc) +
2197+ HDLC_MAX_MRU));
2198
2199- /* 4 rings required for 2 ports, 2 rings for one port */
2200- card->ring_buffers = card->ram_size /
2201- ((valid0 + valid1) * 2 * (sizeof(pkt_desc) + HDLC_MAX_MRU));
2202+ card->tx_ring_buffers = min(i / 2, MAX_TX_BUFFERS);
2203+ card->rx_ring_buffers = i - card->tx_ring_buffers;
2204
2205- card->buff_offset = (valid0 + valid1) * 2 * (sizeof(pkt_desc))
2206- * card->ring_buffers;
2207+ card->buff_offset = (valid0 + valid1) * sizeof(pkt_desc) *
2208+ (card->tx_ring_buffers + card->rx_ring_buffers);
2209
2210 printk(KERN_DEBUG "n2: RISCom/N2 %u KB RAM, IRQ%u, "
2211- "using %u packets rings\n", card->ram_size / 1024, card->irq,
2212- card->ring_buffers);
2213+ "using %u TX + %u RX packets rings\n", card->ram_size / 1024,
2214+ card->irq, card->tx_ring_buffers, card->rx_ring_buffers);
2215+
2216+ if (card->tx_ring_buffers < 1) {
2217+ printk(KERN_ERR "n2: RAM test failed\n");
2218+ n2_destroy_card(card);
2219+ return -EIO;
2220+ }
2221
2222 pcr |= PCR_RUNSCA; /* run SCA */
2223 outb(pcr, io + N2_PCR);
2224@@ -531,7 +485,7 @@
2225 return -ENOSYS; /* no parameters specified, abort */
2226 }
2227
2228- printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version);
2229+ printk(KERN_INFO "%s\n", version);
2230
2231 do {
2232 unsigned long io, irq, ram;
2233@@ -558,7 +512,7 @@
2234 break;
2235 hw++;
2236 }
2237-
2238+
2239 if (!valid[0] && !valid[1])
2240 break; /* at least one port must be used */
2241
2242@@ -566,7 +520,7 @@
2243 n2_run(io, irq, ram, valid[0], valid[1]);
2244
2245 if (*hw == '\x0')
2246- return 0;
2247+ return first_card ? 0 : -ENOSYS;
2248 }while(*hw++ == ':');
2249
2250 printk(KERN_ERR "n2: invalid hardware parameters\n");
2251@@ -602,6 +556,6 @@
2252
2253 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
2254 MODULE_DESCRIPTION("RISCom/N2 serial port driver");
2255-MODULE_LICENSE("GPL");
2256+MODULE_LICENSE("GPL v2");
2257 MODULE_PARM(hw, "s"); /* hw=io,irq,ram,ports:io,irq,... */
2258 EXPORT_NO_SYMBOLS;
2259--- linux-2.4.orig/drivers/net/wan/c101.c 2003-07-29 23:25:03.000000000 +0200
2260+++ linux-2.4/drivers/net/wan/c101.c 2003-07-29 23:32:23.000000000 +0200
2261@@ -1,12 +1,11 @@
2262 /*
2263 * Moxa C101 synchronous serial card driver for Linux
2264 *
2265- * Copyright (C) 2000-2002 Krzysztof Halasa <khc@pm.waw.pl>
2266+ * Copyright (C) 2000-2003 Krzysztof Halasa <khc@pm.waw.pl>
2267 *
2268 * This program is free software; you can redistribute it and/or modify it
2269- * under the terms of the GNU General Public License as published by
2270- * the Free Software Foundation; either version 2 of the License, or
2271- * (at your option) any later version.
2272+ * under the terms of version 2 of the GNU General Public License
2273+ * as published by the Free Software Foundation.
2274 *
2275 * For information see http://hq.pm.waw.pl/hdlc/
2276 *
2277@@ -31,7 +30,7 @@
2278 #include "hd64570.h"
2279
2280
2281-static const char* version = "Moxa C101 driver version: 1.10";
2282+static const char* version = "Moxa C101 driver version: 1.14";
2283 static const char* devname = "C101";
2284
2285 #define C101_PAGE 0x1D00
2286@@ -41,6 +40,10 @@
2287 #define C101_MAPPED_RAM_SIZE 0x4000
2288
2289 #define RAM_SIZE (256 * 1024)
2290+#define TX_RING_BUFFERS 10
2291+#define RX_RING_BUFFERS ((RAM_SIZE - C101_WINDOW_SIZE) / \
2292+ (sizeof(pkt_desc) + HDLC_MAX_MRU) - TX_RING_BUFFERS)
2293+
2294 #define CLOCK_BASE 9830400 /* 9.8304 MHz */
2295 #define PAGE0_ALWAYS_MAPPED
2296
2297@@ -52,20 +55,20 @@
2298 spinlock_t lock; /* TX lock */
2299 u8 *win0base; /* ISA window base address */
2300 u32 phy_winbase; /* ISA physical base address */
2301- u16 buff_offset; /* offset of first buffer of first channel */
2302 sync_serial_settings settings;
2303+ int rxpart; /* partial frame received, next frame invalid*/
2304 unsigned short encoding;
2305 unsigned short parity;
2306+ u16 rx_ring_buffers; /* number of buffers in a ring */
2307+ u16 tx_ring_buffers;
2308+ u16 buff_offset; /* offset of first buffer of first channel */
2309+ u16 rxin; /* rx ring buffer 'in' pointer */
2310+ u16 txin; /* tx ring buffer 'in' and 'last' pointers */
2311+ u16 txlast;
2312 u8 rxs, txs, tmc; /* SCA registers */
2313 u8 irq; /* IRQ (3-15) */
2314- u8 ring_buffers; /* number of buffers in a ring */
2315 u8 page;
2316
2317- u8 rxin; /* rx ring buffer 'in' pointer */
2318- u8 txin; /* tx ring buffer 'in' and 'last' pointers */
2319- u8 txlast;
2320- u8 rxpart; /* partial frame received, next frame invalid*/
2321-
2322 struct card_s *next_card;
2323 }card_t;
2324
2325@@ -78,7 +81,12 @@
2326 #define sca_in(reg, card) readb((card)->win0base + C101_SCA + (reg))
2327 #define sca_out(value, reg, card) writeb(value, (card)->win0base + C101_SCA + (reg))
2328 #define sca_inw(reg, card) readw((card)->win0base + C101_SCA + (reg))
2329-#define sca_outw(value, reg, card) writew(value, (card)->win0base + C101_SCA + (reg))
2330+
2331+/* EDA address register must be set in EDAL, EDAH order - 8 bit ISA bus */
2332+#define sca_outw(value, reg, card) do { \
2333+ writeb(value & 0xFF, (card)->win0base + C101_SCA + (reg)); \
2334+ writeb((value >> 8 ) & 0xFF, (card)->win0base + C101_SCA + (reg+1));\
2335+} while(0)
2336
2337 #define port_to_card(port) (port)
2338 #define log_node(port) (0)
2339@@ -229,6 +237,8 @@
2340
2341 static void c101_destroy_card(card_t *card)
2342 {
2343+ readb(card->win0base + C101_PAGE); /* Resets SCA? */
2344+
2345 if (card->irq)
2346 free_irq(card->irq, card);
2347
2348@@ -242,7 +252,7 @@
2349
2350
2351
2352-static int c101_run(unsigned long irq, unsigned long winbase)
2353+static int __init c101_run(unsigned long irq, unsigned long winbase)
2354 {
2355 struct net_device *dev;
2356 card_t *card;
2357@@ -285,9 +295,10 @@
2358 return -EBUSY;
2359 }
2360
2361- /* 2 rings required for 1 port */
2362- card->ring_buffers = (RAM_SIZE -C101_WINDOW_SIZE) / (2 * HDLC_MAX_MRU);
2363- printk(KERN_DEBUG "c101: using %u packets rings\n",card->ring_buffers);
2364+ card->tx_ring_buffers = TX_RING_BUFFERS;
2365+ card->rx_ring_buffers = RX_RING_BUFFERS;
2366+ printk(KERN_DEBUG "c101: using %u TX + %u RX packets rings\n",
2367+ card->tx_ring_buffers, card->rx_ring_buffers);
2368
2369 card->buff_offset = C101_WINDOW_SIZE; /* Bytes 1D00-1FFF reserved */
2370
2371@@ -337,7 +348,7 @@
2372 return -ENOSYS; /* no parameters specified, abort */
2373 }
2374
2375- printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version);
2376+ printk(KERN_INFO "%s\n", version);
2377
2378 do {
2379 unsigned long irq, ram;
2380@@ -352,7 +363,7 @@
2381 c101_run(irq, ram);
2382
2383 if (*hw == '\x0')
2384- return 0;
2385+ return first_card ? 0 : -ENOSYS;
2386 }while(*hw++ == ':');
2387
2388 printk(KERN_ERR "c101: invalid hardware parameters\n");
2389@@ -389,6 +400,6 @@
2390
2391 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
2392 MODULE_DESCRIPTION("Moxa C101 serial port driver");
2393-MODULE_LICENSE("GPL");
2394+MODULE_LICENSE("GPL v2");
2395 MODULE_PARM(hw, "s"); /* hw=irq,ram:irq,... */
2396 EXPORT_NO_SYMBOLS;
2397--- linux-2.4.orig/drivers/net/wan/farsync.c 2003-07-29 23:25:03.000000000 +0200
2398+++ linux-2.4/drivers/net/wan/farsync.c 2003-07-29 23:32:23.000000000 +0200
2399@@ -764,7 +764,7 @@
2400 /* Push upstream */
2401 skb->mac.raw = skb->data;
2402 skb->dev = hdlc_to_dev ( &port->hdlc );
2403- skb->protocol = htons ( ETH_P_HDLC );
2404+ skb->protocol = hdlc_type_trans(skb, skb->dev);
2405 netif_rx ( skb );
2406
2407 port_to_dev ( port )->last_rx = jiffies;
2408--- linux-2.4.orig/drivers/net/wan/dscc4.c 2003-07-29 23:25:03.000000000 +0200
2409+++ linux-2.4/drivers/net/wan/dscc4.c 2003-07-29 23:32:23.000000000 +0200
2410@@ -488,7 +488,7 @@
2411 dpriv->rx_skbuff[dirty] = skb;
2412 if (skb) {
2413 skb->dev = dev;
2414- skb->protocol = htons(ETH_P_HDLC);
2415+ skb->protocol = hdlc_type_trans(skb, dev);
2416 skb->mac.raw = skb->data;
2417 rx_fd->data = pci_map_single(dpriv->pci_priv->pdev, skb->data,
2418 len, PCI_DMA_FROMDEVICE);
2419--- linux-2.4.orig/Documentation/Configure.help 2003-07-29 23:24:56.000000000 +0200
2420+++ linux-2.4/Documentation/Configure.help 2003-07-29 23:32:23.000000000 +0200
2421@@ -9674,14 +9674,15 @@
2422 This driver supports the FarSync T-Series X.21 (and V.35/V.24) cards
2423 from FarSite Communications Ltd.
2424 Synchronous communication is supported on all ports at speeds up to
2425- 8Mb/s (128K on V.24) using synchronous PPP or Cisco HDLC.
2426+ 8Mb/s (128K on V.24) using synchronous PPP, Cisco HDLC, raw HDLC,
2427+ Frame Relay or X.25/LAPB.
2428
2429 If you want to compile this driver as a module ( = code which can be
2430 inserted in and removed from the running kernel whenever you want)
2431 say M here and read <file:Documentation/modules.txt>.
2432 The module will be called farsync.o and if you want the module to be
2433 automatically loaded when the interface is referenced then you
2434- should add "alias syncX farsync" to /etc/modules.conf for each
2435+ should add "alias hdlcX farsync" to /etc/modules.conf for each
2436 interface, where X is 0, 1, 2, ...
2437
2438 CONFIG_HDLC_DEBUG_PKT
2439@@ -10576,6 +10577,15 @@
2440
2441 If unsure, say N here.
2442
2443+Raw HDLC Ethernet device support
2444+CONFIG_HDLC_RAW_ETH
2445+ Say Y to this option if you want generic HDLC driver to support
2446+ raw HDLC Ethernet device emulation over WAN (Wide Area Network)
2447+ connections.
2448+ You will need it for Ethernet over HDLC bridges.
2449+
2450+ If unsure, say N here.
2451+
2452 Cisco HDLC support
2453 CONFIG_HDLC_CISCO
2454 Say Y to this option if you want generic HDLC driver to support
2455@@ -10590,13 +10600,6 @@
2456
2457 If unsure, say N here.
2458
2459-Frame-Relay bridging support
2460-CONFIG_HDLC_FR_BRIDGE
2461- Say Y to this option if you want generic HDLC driver to support
2462- bridging LAN frames over Frame-Relay links.
2463-
2464- If unsure, say N here.
2465-
2466 Synchronous Point-to-Point Protocol (PPP) support
2467 CONFIG_HDLC_PPP
2468 Say Y to this option if you want generic HDLC driver to support
2469@@ -10639,6 +10642,25 @@
2470
2471 If unsure, say N here.
2472
2473+CONFIG_HDLC_DEBUG_PKT
2474+ This option is for developers only - do NOT use on production
2475+ systems.
2476+
2477+CONFIG_HDLC_DEBUG_HARD_HEADER
2478+ This option is for developers only - do NOT use on production
2479+ systems.
2480+
2481+CONFIG_HDLC_DEBUG_ECN
2482+ This option is for developers only - do NOT use on production
2483+ systems.
2484+
2485+CONFIG_HDLC_DEBUG_RINGS
2486+ If you answer Y here you will be able to get a diagnostic dump of
2487+ port's TX and RX packet rings, using "sethdlc hdlcX private"
2488+ command. It does not affect normal operations.
2489+
2490+ If unsure, say Y here.
2491+
2492 Ethernet (10 or 100Mbit)
2493 CONFIG_NET_ETHERNET
2494 Ethernet (also called IEEE 802.3 or ISO 8802-2) is the most common
2495--- linux-2.4.orig/drivers/net/wan/Config.in 2003-07-29 23:25:03.000000000 +0200
2496+++ linux-2.4/drivers/net/wan/Config.in 2003-07-29 23:32:23.000000000 +0200
2497@@ -68,6 +68,7 @@
2498 tristate ' Generic HDLC layer' CONFIG_HDLC
2499 if [ "$CONFIG_HDLC" != "n" ]; then
2500 bool ' Raw HDLC support' CONFIG_HDLC_RAW
2501+ bool ' Raw HDLC Ethernet device support' CONFIG_HDLC_RAW_ETH
2502 bool ' Cisco HDLC support' CONFIG_HDLC_CISCO
2503 bool ' Frame Relay support' CONFIG_HDLC_FR
2504 bool ' Synchronous Point-to-Point Protocol (PPP) support' CONFIG_HDLC_PPP
This page took 0.350251 seconds and 4 git commands to generate.