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
4 -Generic HDLC layer for Linux kernel 2.4/2.5
6 Krzysztof Halasa <khc@pm.waw.pl>
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.
19 - PPP (uses syncppp.c),
20 - X.25 (uses X.25 routines).
22 - RISCom/N2 by SDL Communications Inc.
23 - and others, some not in the official kernel.
25 +Ethernet device emulation (using HDLC or Frame-Relay PVC) is compatible
26 +with IEEE 802.1Q (VLANs) and 802.1D (Ethernet bridging).
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:
33 sethdlc hdlc0 cisco interval 10 timeout 25
35 sethdlc hdlc0 rs232 clock ext
38 + sethdlc hdlc0 fr lmi ansi
39 + sethdlc hdlc0 create 99
41 + ifconfig pvc0 localIP pointopoint remoteIP
43 In Frame Relay mode, ifconfig master hdlc device up (without assigning
44 any IP address to it) before using pvc devices.
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
49 +* hdlc-eth - Ethernet device emulation using HDLC. Parity and encoding
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
56 n392 - error threshold - both user and network
57 n393 - monitored events count - both user and network
59 -* create | delete n - FR only - adds / deletes PVC interface with DLCI #n.
61 +* create n | delete n - adds / deletes PVC interface with DLCI #n.
62 + Newly created interface will be named pvc0, pvc1 etc.
64 +* create ether n | delete ether n - adds a device for Ethernet-bridged
65 + frames. The device will be named pvceth0, pvceth1 etc.
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):
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.
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
87 #include <linux/types.h> /* for "__kernel_caddr_t" et al */
88 #include <linux/socket.h> /* for "struct sockaddr" et al */
91 #include <linux/hdlc/ioctl.h>
93 /* Standard interface flags (netdevice->flags). */
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 */
101 /* For definitions see hdlc.h */
102 #define IF_PROTO_HDLC 0x2000 /* raw HDLC protocol */
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 */
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
119 fr_proto_pvc *fr_pvc;
120 + fr_proto_pvc_info *fr_pvc_info;
122 /* interface settings */
123 sync_serial_settings *sync;
127 #define IFHWADDRLEN 6
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
136 * Generic HDLC support routines for Linux
138 - * Copyright (C) 1999-2002 Krzysztof Halasa <khc@pm.waw.pl>
139 + * Copyright (C) 1999-2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
151 #include <linux/hdlc/ioctl.h>
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 */
157 #define MAXLEN_LMISTAT 20 /* max size of status enquiry frame */
159 @@ -145,17 +144,20 @@
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 */
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;
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. */
199 pvc_device *first_pvc;
203 struct timer_list timer;
210 u32 last_errors; /* last errors bit list */
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);
223 -static __inline__ struct net_device* pvc_to_dev(pvc_device *pvc)
225 - return &pvc->netdev;
229 static __inline__ pvc_device* dev_to_pvc(struct net_device *dev)
231 - return (pvc_device*)dev;
232 + return (pvc_device*)dev->priv;
240 -static __inline__ const char *pvc_to_name(pvc_device *pvc)
242 - return pvc_to_dev(pvc)->name;
246 -static __inline__ u16 netdev_dlci(struct net_device *dev)
248 - return ntohs(*(u16*)dev->dev_addr);
253 static __inline__ u16 q922_to_dlci(u8 *hdr)
255 return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
260 +static __inline__ unsigned short hdlc_type_trans(struct sk_buff *skb,
261 + struct net_device *dev)
263 + hdlc_device *hdlc = dev_to_hdlc(skb->dev);
264 + if (hdlc->type_trans)
265 + return hdlc->type_trans(skb, dev);
267 + return __constant_htons(ETH_P_HDLC);
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
275 } fr_proto_pvc; /* for creating/deleting FR PVCs */
279 + char master[IFNAMSIZ]; /* Name of master FRAD device */
280 +}fr_proto_pvc_info; /* for returning PVC information only */
283 unsigned int interval;
284 unsigned int timeout;
287 /* PPP doesn't need any info now - supply length = 0 to ioctl */
289 -union hdlc_settings {
290 - raw_hdlc_proto raw_hdlc;
293 - fr_proto_pvc fr_pvc;
296 -union line_settings {
297 - sync_serial_settings sync;
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
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
315 * Generic HDLC support routines for Linux
318 - * Copyright (C) 2000 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
319 + * Copyright (C) 2000 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
329 #include <linux/config.h>
331 data->par1 = htonl(par1);
332 data->par2 = htonl(par2);
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));
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;
348 +static unsigned short cisco_type_trans(struct sk_buff *skb,
349 + struct net_device *dev)
351 + hdlc_header *data = (hdlc_header*)skb->data;
353 + if (skb->len < sizeof(hdlc_header))
354 + return __constant_htons(ETH_P_HDLC);
356 + if (data->address != CISCO_MULTICAST &&
357 + data->address != CISCO_UNICAST)
358 + return __constant_htons(ETH_P_HDLC);
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;
367 + return __constant_htons(ETH_P_HDLC);
372 static void cisco_rx(struct sk_buff *skb)
374 hdlc_device *hdlc = dev_to_hdlc(skb->dev);
376 skb_pull(skb, sizeof(hdlc_header));
378 switch(ntohs(data->protocol)) {
382 - skb->protocol = data->protocol;
383 - skb->dev = hdlc_to_dev(hdlc);
388 /* Packet is not needed, drop it. */
389 dev_kfree_skb_any(skb);
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
401 * Generic HDLC support routines for Linux
402 * Frame Relay support
404 - * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
405 + * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
412 + * under the terms of version 2 of the GNU General Public License
413 + * as published by the Free Software Foundation.
416 + Theory of PVC state in DCE mode:
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
422 + (active) -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create"
423 + -> 1 when "PVC up" and (exist,new) = 1,0
426 #include <linux/config.h>
427 #include <linux/module.h>
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>
440 __inline__ pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
442 - pvc_device *pvc=hdlc->state.fr.first_pvc;
445 - if (netdev_dlci(&pvc->netdev) == dlci)
446 + pvc_device *pvc = hdlc->state.fr.first_pvc;
449 + if (pvc->dlci == dlci)
451 + if (pvc->dlci > dlci)
452 + return NULL; /* the listed is sorted */
460 +__inline__ pvc_device* add_pvc(hdlc_device *hdlc, u16 dlci)
462 + pvc_device *pvc, **pvc_p = &hdlc->state.fr.first_pvc;
465 + if ((*pvc_p)->dlci == dlci)
467 + if ((*pvc_p)->dlci > dlci)
468 + break; /* the listed is sorted */
469 + pvc_p = &(*pvc_p)->next;
472 + pvc = kmalloc(sizeof(pvc_device), GFP_ATOMIC);
476 + memset(pvc, 0, sizeof(pvc_device));
478 + pvc->master = hdlc;
479 + pvc->next = *pvc_p; /* Put it in the chain */
485 +__inline__ int pvc_is_used(pvc_device *pvc)
487 + return pvc->main != NULL || pvc->ether != NULL;
491 +__inline__ void delete_unused_pvcs(hdlc_device *hdlc)
493 + pvc_device **pvc_p = &hdlc->state.fr.first_pvc;
496 + if (!pvc_is_used(*pvc_p)) {
497 + pvc_device *pvc = *pvc_p;
498 + *pvc_p = pvc->next;
502 + pvc_p = &(*pvc_p)->next;
506 -__inline__ u16 status_to_dlci(hdlc_device *hdlc, u8 *status,
507 - int *active, int *new)
509 +__inline__ struct net_device** get_dev_p(pvc_device *pvc, int type)
511 - *new = (status[2] & 0x08);
512 - *active = (!*new && (status[2] & 0x02));
513 + if (type == ARPHRD_ETHER)
514 + return &pvc->ether;
520 +__inline__ u16 status_to_dlci(u8 *status, int *active, int *new)
522 + *new = (status[2] & 0x08) ? 1 : 0;
523 + *active = (status[2] & 0x02) ? 1 : 0;
525 return ((status[0] & 0x3F)<<4) | ((status[1] & 0x78)>>3);
529 -__inline__ void dlci_to_status(hdlc_device *hdlc, u16 dlci, u8 *status,
530 +__inline__ void dlci_to_status(u16 dlci, u8 *status,
533 status[0] = (dlci>>4) & 0x3F;
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)
543 + struct sk_buff *skb = *skb_p;
546 - daddr = dev->broadcast;
548 -#ifdef CONFIG_HDLC_DEBUG_HARD_HEADER
549 - printk(KERN_DEBUG "%s: fr_hard_header called\n", dev->name);
554 + switch(skb->protocol) {
555 + case __constant_ntohs(ETH_P_IP):
557 skb_push(skb, head_len);
558 skb->data[3] = NLPID_IP;
562 + case __constant_ntohs(ETH_P_IPV6):
564 skb_push(skb, head_len);
565 skb->data[3] = NLPID_IPV6;
569 + case __constant_ntohs(LMI_PROTO):
571 skb_push(skb, head_len);
572 skb->data[3] = LMI_PROTO;
575 + case __constant_ntohs(ETH_P_802_3):
577 + if (skb_headroom(skb) < head_len) {
578 + struct sk_buff *skb2 = skb_realloc_headroom(skb,
582 + dev_kfree_skb(skb);
583 + skb = *skb_p = skb2;
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 */
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;
607 - memcpy(skb->data, daddr, 2);
608 + dlci_to_q922(skb->data, dlci);
609 skb->data[2] = FR_UI;
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 */
620 - if (pvc->master->state.fr.settings.lmi != LMI_NONE)
621 - pvc->state.active = 0;
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;
628 - pvc->state.new = 0;
629 - pvc->master->state.fr.changed = 1;
630 + pvc->master->state.fr.dce_changed = 1;
635 @@ -139,38 +216,94 @@
636 static int pvc_close(struct net_device *dev)
638 pvc_device *pvc = dev_to_pvc(dev);
639 - pvc->state.active = pvc->state.new = 0;
640 - pvc->master->state.fr.changed = 1;
642 + if (--pvc->open_count == 0) {
643 + if (pvc->master->state.fr.settings.lmi == LMI_NONE)
644 + pvc->state.active = 0;
646 + if (pvc->master->state.fr.settings.dce) {
647 + pvc->master->state.fr.dce_changed = 1;
648 + pvc->state.active = 0;
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)
659 pvc_device *pvc = dev_to_pvc(dev);
660 + fr_proto_pvc_info info;
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);
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;
676 + ifr->ifr_settings.type = IF_PROTO_FR_PVC;
678 + if (ifr->ifr_settings.size < sizeof(info)) {
679 + /* data size wanted */
680 + ifr->ifr_settings.size = sizeof(info);
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)))
697 +__inline__ struct net_device_stats *pvc_get_stats(struct net_device *dev)
699 + return (struct net_device_stats *)
700 + ((char *)dev + sizeof(struct net_device));
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)
708 pvc_device *pvc = dev_to_pvc(dev);
709 - return &pvc->stats;
710 + struct net_device_stats *stats = pvc_get_stats(dev);
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,
720 + stats->tx_dropped++;
721 + dev_kfree_skb(skb);
725 + memset(skb->data + len, 0, pad);
727 + skb->protocol = __constant_htons(ETH_P_802_3);
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);
740 + stats->tx_dropped++;
741 + dev_kfree_skb(skb);
748 static inline void fr_log_dlci_active(pvc_device *pvc)
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),
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");
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));
776 @@ -224,12 +363,13 @@
777 skb = dev_alloc_skb(len);
779 printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n",
780 - hdlc_to_name(hdlc));
781 + hdlc_to_name(hdlc));
784 memset(skb->data, 0, len);
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);
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;
796 - if (hdlc->state.fr.reliable &&
797 - (pvc->netdev.flags & IFF_UP) &&
798 - !pvc->state.active &&
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);
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);
814 - dlci_to_status(hdlc, netdev_dlci(&pvc->netdev),
816 + dlci_to_status(pvc->dlci, data + i,
817 pvc->state.active, pvc->state.new);
822 skb->priority = TC_PRIO_CONTROL;
823 skb->dev = hdlc_to_dev(hdlc);
824 + skb->nh.raw = skb->data;
828 @@ -312,10 +457,11 @@
831 hdlc->state.fr.n391cnt = 0; /* Request full status */
832 - hdlc->state.fr.changed = 1;
833 + hdlc->state.fr.dce_changed = 1;
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;
846 - int reptype = -1, error;
847 + int reptype = -1, error, no_ram;
851 @@ -420,20 +566,18 @@
853 if (pvc->state.new) {
855 - pvc->state.active = 1;
856 - fr_log_dlci_active(pvc);
858 /* Tell DTE that new PVC is now active */
859 - hdlc->state.fr.changed = 1;
860 + hdlc->state.fr.dce_changed = 1;
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;
874 fr_lmi_send(hdlc, reptype == LMI_FULLREP ? 1 : 0);
875 @@ -449,13 +593,14 @@
876 pvc = hdlc->state.fr.first_pvc;
879 - pvc->state.deleted = pvc->state.active; /* mark active PVCs */
880 + pvc->state.deleted = 1;
885 while (skb->len >= i + 2 + stat_len) {
888 + unsigned int active, new;
890 if (skb->data[i] != ((hdlc->state.fr.settings.lmi == LMI_CCITT)
891 ? LMI_CCITT_PVCSTAT : LMI_PVCSTAT)) {
892 @@ -472,21 +617,28 @@
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);
900 + pvc = add_pvc(hdlc, dlci);
902 + if (!pvc && !no_ram) {
903 + printk(KERN_WARNING
904 + "%s: Memory squeeze on fr_lmi_recv()\n",
905 + hdlc_to_name(hdlc));
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);
922 - pvc->state.deleted = 0;
925 - printk(KERN_INFO "%s: new PVC available, DLCI=%u\n",
926 - hdlc_to_name(hdlc), dlci);
930 @@ -494,10 +646,10 @@
931 pvc = hdlc->state.fr.first_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;
944 u8 *data = skb->data;
947 + struct net_device *dev = NULL;
949 - if (skb->len<4 || fh->ea1 || data[2] != FR_UI)
950 + if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
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);
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);
967 + dev_kfree_skb_any(skb);
971 - pvc->stats.rx_packets++; /* PVC traffic */
972 - pvc->stats.rx_bytes += skb->len;
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");
982 pvc->state.fecn ^= 1;
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");
993 pvc->state.becn ^= 1;
996 - if (pvc->state.becn)
997 - pvc->stats.rx_compressed++;
999 - skb->dev = &pvc->netdev;
1001 if (data[3] == NLPID_IP) {
1002 skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
1004 skb->protocol = htons(ETH_P_IP);
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) */
1014 skb->protocol = htons(ETH_P_IPV6);
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));
1025 @@ -610,23 +745,39 @@
1027 case ETH_P_IP: /* a long variant */
1030 skb->protocol = htons(pid);
1033 + case 0x80C20007: /* bridged Ethernet frame */
1034 + if ((dev = pvc->ether) != NULL)
1035 + skb->protocol = eth_type_trans(skb, dev);
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);
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);
1053 - printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x\n",
1054 - hdlc_to_name(hdlc), data[3]);
1055 - dev_kfree_skb_any(skb);
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++;
1065 + dev_kfree_skb_any(skb);
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);
1084 - dev_close(&pvc->netdev); /* Shutdown all PVCs for this FRAD */
1085 + while(pvc) { /* Shutdown all PVCs for this FRAD */
1087 + dev_close(pvc->main);
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;
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)
1102 - pvc_device **pvc_p = &hdlc->state.fr.first_pvc;
1105 + pvc_device *pvc = NULL;
1106 + struct net_device *dev;
1108 + char * prefix = "pvc%d";
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";
1116 - if (netdev_dlci(&(*pvc_p)->netdev) == dlci)
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));
1125 - if (create) { /* Create PVC */
1126 - if (*pvc_p != NULL)
1129 - pvc = *pvc_p = kmalloc(sizeof(pvc_device), GFP_KERNEL);
1131 - printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1132 - hdlc_to_name(hdlc));
1135 - memset(pvc, 0, sizeof(pvc_device));
1136 + if (*get_dev_p(pvc, type))
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;
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;
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);
1158 - result = dev_alloc_name(&pvc->netdev, "pvc%d");
1165 - if (register_netdevice(&pvc->netdev) != 0) {
1170 + dev = kmalloc(sizeof(struct net_device) +
1171 + sizeof(struct net_device_stats), GFP_KERNEL);
1173 + printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1174 + hdlc_to_name(hdlc));
1175 + delete_unused_pvcs(hdlc);
1178 + memset(dev, 0, sizeof(struct net_device) +
1179 + sizeof(struct net_device_stats));
1181 - hdlc->state.fr.changed = 1;
1182 - hdlc->state.fr.pvc_count++;
1184 + if (type == ARPHRD_ETHER) {
1186 + memcpy(dev->dev_addr, "\x00\x01", 2);
1187 + get_random_bytes(dev->dev_addr + 2, ETH_ALEN - 2);
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);
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;
1206 + result = dev_alloc_name(dev, prefix);
1209 + delete_unused_pvcs(hdlc);
1213 + if (register_netdevice(dev) != 0) {
1215 + delete_unused_pvcs(hdlc);
1219 + *get_dev_p(pvc, type) = dev;
1221 + hdlc->state.fr.dce_changed = 1;
1222 + hdlc->state.fr.dce_pvc_count++;
1229 - if (*pvc_p == NULL) /* Delete PVC */
1230 +static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1233 + struct net_device *dev;
1235 + if ((pvc = find_pvc(hdlc, dlci)) == NULL)
1239 + if ((dev = *get_dev_p(pvc, type)) == NULL)
1242 - if (pvc->netdev.flags & IFF_UP)
1243 + if (dev->flags & IFF_UP)
1244 return -EBUSY; /* PVC in use */
1246 - hdlc->state.fr.changed = 1;
1247 - hdlc->state.fr.pvc_count--;
1248 - *pvc_p = pvc->next;
1249 - unregister_netdevice(&pvc->netdev);
1251 + unregister_netdevice(dev);
1253 + *get_dev_p(pvc, type) = NULL;
1255 + if (!pvc_is_used(pvc)) {
1256 + hdlc->state.fr.dce_pvc_count--;
1257 + hdlc->state.fr.dce_changed = 1;
1259 + delete_unused_pvcs(hdlc);
1263 @@ -763,14 +943,21 @@
1264 pvc_device *pvc = hdlc->state.fr.first_pvc;
1266 pvc_device *next = pvc->next;
1267 - unregister_netdev(&pvc->netdev);
1269 + unregister_netdevice(pvc->main);
1273 + unregister_netdevice(pvc->ether);
1274 + kfree(pvc->ether);
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;
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;
1295 memcpy(&hdlc->state.fr.settings, &new_settings, size);
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;
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))
1321 @@ -854,8 +1043,20 @@
1322 sizeof(fr_proto_pvc)))
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 */
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 */
1334 + result = ARPHRD_DLCI;
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);
1340 + return fr_del_pvc(hdlc, pvc.dlci, result);
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
1348 * Generic HDLC support routines for Linux
1350 - * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1351 + * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
1361 - * - this is work in progress
1362 - * - not heavily tested on SMP
1363 - * - currently supported:
1364 + * Currently supported:
1367 * * Frame Relay with ANSI or CCITT LMI (both user and network side)
1369 #include <linux/hdlc.h>
1372 -static const char* version = "HDLC support module revision 1.11";
1373 +static const char* version = "HDLC support module revision 1.14";
1376 static int hdlc_change_mtu(struct net_device *dev, int new_mtu)
1378 static int hdlc_rcv(struct sk_buff *skb, struct net_device *dev,
1379 struct packet_type *p)
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);
1386 + hdlc->stats.rx_dropped++; /* Shouldn't happen */
1387 + dev_kfree_skb(skb);
1393 #define hdlc_raw_ioctl(hdlc, ifr) -ENOSYS
1396 +#ifndef CONFIG_HDLC_RAW_ETH
1397 +#define hdlc_raw_eth_ioctl(hdlc, ifr) -ENOSYS
1400 #ifndef CONFIG_HDLC_PPP
1401 #define hdlc_ppp_ioctl(hdlc, ifr) -ENOSYS
1405 switch(ifr->ifr_settings.type) {
1407 + case IF_PROTO_HDLC_ETH:
1409 case IF_PROTO_CISCO:
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 @@
1421 void unregister_hdlc_device(hdlc_device *hdlc)
1424 hdlc_proto_detach(hdlc);
1426 - unregister_netdev(hdlc_to_dev(hdlc));
1427 + unregister_netdevice(hdlc_to_dev(hdlc));
1434 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1435 MODULE_DESCRIPTION("HDLC support module");
1436 -MODULE_LICENSE("GPL");
1437 +MODULE_LICENSE("GPL v2");
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
1444 * Generic HDLC support routines for Linux
1445 * Point-to-point protocol support
1447 - * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1448 + * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
1458 #include <linux/config.h>
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)
1467 - skb->protocol = htons(ETH_P_WAN_PPP);
1469 + return __constant_htons(ETH_P_WAN_PPP);
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
1486 * Generic HDLC support routines for Linux
1489 - * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1490 + * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
1500 #include <linux/config.h>
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
1512 * Generic HDLC support routines for Linux
1515 - * Copyright (C) 1999 - 2001 Krzysztof Halasa <khc@pm.waw.pl>
1516 + * Copyright (C) 1999 - 2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
1526 #include <linux/config.h>
1528 #include <linux/hdlc.h>
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)
1535 - skb->protocol = htons(ETH_P_IP);
1537 + return __constant_htons(ETH_P_IP);
1542 new_settings.encoding = ENCODING_NRZ;
1544 if (new_settings.parity == PARITY_DEFAULT)
1545 - new_settings.parity = PARITY_NONE;
1546 + new_settings.parity = PARITY_CRC16_PR1_CCITT;
1548 result = hdlc->attach(hdlc, new_settings.encoding,
1549 new_settings.parity);
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;
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
1569 + * Generic HDLC support routines for Linux
1570 + * HDLC Ethernet emulation support
1572 + * Copyright (C) 2002-2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
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>
1597 +static int eth_tx(struct sk_buff *skb, struct net_device *dev)
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);
1608 + skb_put(skb, pad);
1609 + memset(skb->data + len, 0, pad);
1611 + return dev_to_hdlc(dev)->xmit(skb, dev);
1615 +int hdlc_raw_eth_ioctl(hdlc_device *hdlc, struct ifreq *ifr)
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);
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 */
1632 + if (copy_to_user(raw_s, &hdlc->state.raw_hdlc.settings, size))
1636 + case IF_PROTO_HDLC_ETH:
1637 + if (!capable(CAP_NET_ADMIN))
1640 + if (dev->flags & IFF_UP)
1643 + if (copy_from_user(&new_settings, raw_s, size))
1646 + if (new_settings.encoding == ENCODING_DEFAULT)
1647 + new_settings.encoding = ENCODING_NRZ;
1649 + if (new_settings.parity == PARITY_DEFAULT)
1650 + new_settings.parity = PARITY_CRC16_PR1_CCITT;
1652 + result = hdlc->attach(hdlc, new_settings.encoding,
1653 + new_settings.parity);
1657 + hdlc_proto_detach(hdlc);
1658 + memcpy(&hdlc->state.raw_hdlc.settings, &new_settings, size);
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;
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);
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
1682 * Hitachi SCA HD64570 and HD64572 common driver for Linux
1684 - * Copyright (C) 1998-2000 Krzysztof Halasa <khc@pm.waw.pl>
1685 + * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
1694 * Sources of information:
1695 * Hitachi HD64570 SCA User's Manual
1696 * Hitachi HD64572 SCA-II User's Manual
1698 + * We use the following SCA memory map:
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)
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)
1713 #include <linux/module.h>
1715 #error Either hd64570.h or hd64572.h must be included
1718 -static char sca_version[]="1.09";
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 @@
1727 -static inline u8 next_desc(port_t *port, u8 desc)
1728 +static inline u16 next_desc(port_t *port, u16 desc, int transmit)
1730 + return (desc + 1) % (transmit ? port_to_card(port)->tx_ring_buffers
1731 + : port_to_card(port)->rx_ring_buffers);
1736 +static inline u16 desc_abs_number(port_t *port, u16 desc, int transmit)
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;
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;
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)
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)) *
1756 + return desc_abs_number(port, desc, transmit) * sizeof(pkt_desc);
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)
1764 #ifdef PAGE0_ALWAYS_MAPPED
1765 return (pkt_desc*)(win0base(port_to_card(port))
1766 @@ -146,12 +168,10 @@
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)
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;
1782 static void sca_init_sync_port(port_t *port)
1784 card_t *card = port_to_card(port);
1786 - u16 dmac, buffs = card->ring_buffers;
1791 @@ -171,6 +190,10 @@
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;
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);
1803 writeb(0, &desc->stat);
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);
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)
1817 struct sk_buff *skb;
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));
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);
1836 /* make sure RX DMA is enabled */
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);
1846 netif_wake_queue(hdlc_to_dev(&port->hdlc));
1848 static void sca_intr(int irq, void* dev_id, struct pt_regs *regs)
1850 card_t *card = dev_id;
1851 -/* Maximum events to handle at each interrupt - should I increase it? */
1856 @@ -412,23 +431,12 @@
1857 if (stat & SCA_INTR_DMAC_TX(i))
1861 - if (--boguscnt < 0) {
1863 - printk(KERN_ERR "%s: too much work at "
1865 - hdlc_to_name(&port->hdlc));
1873 #ifndef ALL_PAGES_ALWAYS_MAPPED
1874 openwin(card, page); /* Restore original page */
1881 static void sca_set_port(port_t *port)
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;
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);
1897 switch(port->encoding) {
1899 case PARITY_CRC16_PR0_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU_0; break;
1901 case PARITY_CRC32_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU32; break;
1904 case PARITY_CRC16_PR1_CCITT: md0 = MD0_HDLC | MD0_CRC_ITU; break;
1905 default: md0 = MD0_HDLC | MD0_CRC_NONE;
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);
1917 parity != PARITY_CRC16_PR0_CCITT &&
1919 parity != PARITY_CRC32_PR1_CCITT &&
1922 parity != PARITY_CRC16_PR1_CCITT)
1925 @@ -640,14 +648,13 @@
1929 - printk(KERN_ERR "RX ring: CDA=%u EDA=%u DSR=%02X in=%u "
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),
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++)
1940 readb(&(desc_address(port, cnt, 0)->stat)));
1944 sca_in(DSR_TX(phy_node(port)), card) & DSR_DE ? "" : "in");
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++)
1949 readb(&(desc_address(port, cnt, 1)->stat)));
1952 writeb(ST_TX_EOM, &desc->stat);
1953 dev->trans_start = jiffies;
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);
1960 @@ -768,7 +775,49 @@
1964 -static void sca_init(card_t *card, int wait_states)
1966 +#ifdef NEED_DETECT_RAM
1967 +static u32 __devinit sca_detect_ram(card_t *card, u8 *rambase, u32 ramsize)
1969 + /* Round RAM size to 32 bits, fill from end to start */
1970 + u32 i = ramsize &= ~3;
1972 +#ifndef ALL_PAGES_ALWAYS_MAPPED
1973 + u32 size = winsize(card);
1975 + openwin(card, (i - 4) / size); /* select last window */
1979 +#ifndef ALL_PAGES_ALWAYS_MAPPED
1980 + if ((i + 4) % size == 0)
1981 + openwin(card, i / size);
1982 + writel(i ^ 0x12345678, rambase + i % size);
1984 + writel(i ^ 0x12345678, rambase + i);
1988 + for (i = 0; i < ramsize ; i += 4) {
1989 +#ifndef ALL_PAGES_ALWAYS_MAPPED
1990 + if (i % size == 0)
1991 + openwin(card, i / size);
1993 + if (readl(rambase + i % size) != (i ^ 0x12345678))
1996 + if (readl(rambase + i) != (i ^ 0x12345678))
2003 +#endif /* NEED_DETECT_RAM */
2007 +static void __devinit sca_init(card_t *card, int wait_states)
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
2015 * SDL Inc. RISCom/N2 synchronous serial card driver for Linux
2017 - * Copyright (C) 1998-2002 Krzysztof Halasa <khc@pm.waw.pl>
2018 + * Copyright (C) 1998-2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
2027 * For information see http://hq.pm.waw.pl/hdlc/
2030 #include "hd64570.h"
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";
2037 #define USE_WINDOWSIZE 16384
2038 #define USE_BUS16BITS 1
2039 #define CLOCK_BASE 9830400 /* 9.8304 MHz */
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)
2047 #define N2_IOPORTS 0x10
2048 +#define NEED_DETECT_RAM
2049 +#define MAX_TX_BUFFERS 10
2051 static char *hw = NULL; /* pointer to hw=xxx command line string */
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 */
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 */
2071 - u8 rxpart; /* partial frame received, next frame invalid*/
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 */
2085 struct card_s *next_card;
2088 mcr &= port->phy_node ? ~DTR_PORT1 : ~DTR_PORT0; /* set DTR ON */
2089 outb(mcr, io + N2_MCR);
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 */
2095 @@ -297,62 +304,6 @@
2099 -static u8 n2_count_page(card_t *card)
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;
2108 - for (page = 0; page < 16; page++) {
2109 - outb(psr | page, card->io + N2_PSR); /* select a page */
2111 - if (readb(dp) != page)
2112 - break; /* If can't read back, no good memory */
2114 - outb(psr, card->io + N2_PSR); /* goto page 0 */
2116 - break; /* If page 0 changed, then wrapped around */
2118 - outb(psr | page, card->io + N2_PSR); /* select page again */
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))
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))
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)
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)
2146 - for (i = 0; i < wcount; i++)
2147 - writew(page, dp + i);
2155 static void n2_destroy_card(card_t *card)
2158 @@ -376,11 +327,12 @@
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)
2171 if (io < 0x200 || io > 0x3FF || (io % N2_IOPORTS) != 0) {
2172 printk(KERN_ERR "n2: invalid I/O port value\n");
2174 printk(KERN_ERR "n2: invalid IRQ value\n");
2179 if (winbase < 0xA0000 || winbase > 0xFFFFF || (winbase & 0xFFF) != 0) {
2180 printk(KERN_ERR "n2: invalid RAM value\n");
2182 @@ -451,25 +403,27 @@
2183 pcr = PCR_ENWIN | PCR_VPM | (USE_BUS16BITS ? PCR_BUS16 : 0);
2184 outb(pcr, io + N2_PCR);
2186 - cnt = n2_count_page(card);
2188 - printk(KERN_ERR "n2: memory test failed.\n");
2189 - n2_destroy_card(card);
2192 + card->ram_size = sca_detect_ram(card, card->winbase, MAX_RAM_SIZE);
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) +
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;
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);
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);
2216 + if (card->tx_ring_buffers < 1) {
2217 + printk(KERN_ERR "n2: RAM test failed\n");
2218 + n2_destroy_card(card);
2222 pcr |= PCR_RUNSCA; /* run SCA */
2223 outb(pcr, io + N2_PCR);
2225 return -ENOSYS; /* no parameters specified, abort */
2228 - printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version);
2229 + printk(KERN_INFO "%s\n", version);
2232 unsigned long io, irq, ram;
2239 if (!valid[0] && !valid[1])
2240 break; /* at least one port must be used */
2243 n2_run(io, irq, ram, valid[0], valid[1]);
2247 + return first_card ? 0 : -ENOSYS;
2248 }while(*hw++ == ':');
2250 printk(KERN_ERR "n2: invalid hardware parameters\n");
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,... */
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
2263 * Moxa C101 synchronous serial card driver for Linux
2265 - * Copyright (C) 2000-2002 Krzysztof Halasa <khc@pm.waw.pl>
2266 + * Copyright (C) 2000-2003 Krzysztof Halasa <khc@pm.waw.pl>
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.
2275 * For information see http://hq.pm.waw.pl/hdlc/
2278 #include "hd64570.h"
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";
2285 #define C101_PAGE 0x1D00
2287 #define C101_MAPPED_RAM_SIZE 0x4000
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)
2294 #define CLOCK_BASE 9830400 /* 9.8304 MHz */
2295 #define PAGE0_ALWAYS_MAPPED
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 */
2312 u8 rxs, txs, tmc; /* SCA registers */
2313 u8 irq; /* IRQ (3-15) */
2314 - u8 ring_buffers; /* number of buffers in a ring */
2317 - u8 rxin; /* rx ring buffer 'in' pointer */
2318 - u8 txin; /* tx ring buffer 'in' and 'last' pointers */
2320 - u8 rxpart; /* partial frame received, next frame invalid*/
2322 struct card_s *next_card;
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))
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));\
2337 #define port_to_card(port) (port)
2338 #define log_node(port) (0)
2341 static void c101_destroy_card(card_t *card)
2343 + readb(card->win0base + C101_PAGE); /* Resets SCA? */
2346 free_irq(card->irq, card);
2352 -static int c101_run(unsigned long irq, unsigned long winbase)
2353 +static int __init c101_run(unsigned long irq, unsigned long winbase)
2355 struct net_device *dev;
2357 @@ -285,9 +295,10 @@
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);
2369 card->buff_offset = C101_WINDOW_SIZE; /* Bytes 1D00-1FFF reserved */
2372 return -ENOSYS; /* no parameters specified, abort */
2375 - printk(KERN_INFO "%s (SCA-%s)\n", version, sca_version);
2376 + printk(KERN_INFO "%s\n", version);
2379 unsigned long irq, ram;
2385 + return first_card ? 0 : -ENOSYS;
2386 }while(*hw++ == ':');
2388 printk(KERN_ERR "c101: invalid hardware parameters\n");
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,... */
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
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);
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
2411 dpriv->rx_skbuff[dirty] = skb;
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.
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, ...
2438 CONFIG_HDLC_DEBUG_PKT
2439 @@ -10576,6 +10577,15 @@
2441 If unsure, say N here.
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)
2448 + You will need it for Ethernet over HDLC bridges.
2450 + If unsure, say N here.
2454 Say Y to this option if you want generic HDLC driver to support
2455 @@ -10590,13 +10600,6 @@
2457 If unsure, say N here.
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.
2464 - If unsure, say N here.
2466 Synchronous Point-to-Point Protocol (PPP) support
2468 Say Y to this option if you want generic HDLC driver to support
2469 @@ -10639,6 +10642,25 @@
2471 If unsure, say N here.
2473 +CONFIG_HDLC_DEBUG_PKT
2474 + This option is for developers only - do NOT use on production
2477 +CONFIG_HDLC_DEBUG_HARD_HEADER
2478 + This option is for developers only - do NOT use on production
2481 +CONFIG_HDLC_DEBUG_ECN
2482 + This option is for developers only - do NOT use on production
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.
2490 + If unsure, say Y here.
2492 Ethernet (10 or 100Mbit)
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
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