]> git.pld-linux.org Git - packages/kernel.git/blob - hdlc-2.4.21-1.14a.patch
- use depmod with path when checking deps
[packages/kernel.git] / hdlc-2.4.21-1.14a.patch
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.237241 seconds and 3 git commands to generate.