]> pilppa.org Git - linux-2.6-omap-h63xx.git/blob - drivers/net/wan/hdlc_fr.c
Merge branches 'release' and 'hp-cid' into release
[linux-2.6-omap-h63xx.git] / drivers / net / wan / hdlc_fr.c
1 /*
2  * Generic HDLC support routines for Linux
3  * Frame Relay support
4  *
5  * Copyright (C) 1999 - 2006 Krzysztof Halasa <khc@pm.waw.pl>
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License
9  * as published by the Free Software Foundation.
10  *
11
12             Theory of PVC state
13
14  DCE mode:
15
16  (exist,new) -> 0,0 when "PVC create" or if "link unreliable"
17          0,x -> 1,1 if "link reliable" when sending FULL STATUS
18          1,1 -> 1,0 if received FULL STATUS ACK
19
20  (active)    -> 0 when "ifconfig PVC down" or "link unreliable" or "PVC create"
21              -> 1 when "PVC up" and (exist,new) = 1,0
22
23  DTE mode:
24  (exist,new,active) = FULL STATUS if "link reliable"
25                     = 0, 0, 0 if "link unreliable"
26  No LMI:
27  active = open and "link reliable"
28  exist = new = not used
29
30  CCITT LMI: ITU-T Q.933 Annex A
31  ANSI LMI: ANSI T1.617 Annex D
32  CISCO LMI: the original, aka "Gang of Four" LMI
33
34 */
35
36 #include <linux/module.h>
37 #include <linux/kernel.h>
38 #include <linux/slab.h>
39 #include <linux/poll.h>
40 #include <linux/errno.h>
41 #include <linux/if_arp.h>
42 #include <linux/init.h>
43 #include <linux/skbuff.h>
44 #include <linux/pkt_sched.h>
45 #include <linux/inetdevice.h>
46 #include <linux/lapb.h>
47 #include <linux/rtnetlink.h>
48 #include <linux/etherdevice.h>
49 #include <linux/hdlc.h>
50
51 #undef DEBUG_PKT
52 #undef DEBUG_ECN
53 #undef DEBUG_LINK
54 #undef DEBUG_PROTO
55 #undef DEBUG_PVC
56
57 #define FR_UI                   0x03
58 #define FR_PAD                  0x00
59
60 #define NLPID_IP                0xCC
61 #define NLPID_IPV6              0x8E
62 #define NLPID_SNAP              0x80
63 #define NLPID_PAD               0x00
64 #define NLPID_CCITT_ANSI_LMI    0x08
65 #define NLPID_CISCO_LMI         0x09
66
67
68 #define LMI_CCITT_ANSI_DLCI        0 /* LMI DLCI */
69 #define LMI_CISCO_DLCI          1023
70
71 #define LMI_CALLREF             0x00 /* Call Reference */
72 #define LMI_ANSI_LOCKSHIFT      0x95 /* ANSI locking shift */
73 #define LMI_ANSI_CISCO_REPTYPE  0x01 /* report type */
74 #define LMI_CCITT_REPTYPE       0x51
75 #define LMI_ANSI_CISCO_ALIVE    0x03 /* keep alive */
76 #define LMI_CCITT_ALIVE         0x53
77 #define LMI_ANSI_CISCO_PVCSTAT  0x07 /* PVC status */
78 #define LMI_CCITT_PVCSTAT       0x57
79
80 #define LMI_FULLREP             0x00 /* full report  */
81 #define LMI_INTEGRITY           0x01 /* link integrity report */
82 #define LMI_SINGLE              0x02 /* single PVC report */
83
84 #define LMI_STATUS_ENQUIRY      0x75
85 #define LMI_STATUS              0x7D /* reply */
86
87 #define LMI_REPT_LEN               1 /* report type element length */
88 #define LMI_INTEG_LEN              2 /* link integrity element length */
89
90 #define LMI_CCITT_CISCO_LENGTH    13 /* LMI frame lengths */
91 #define LMI_ANSI_LENGTH           14
92
93
94 typedef struct {
95 #if defined(__LITTLE_ENDIAN_BITFIELD)
96         unsigned ea1:   1;
97         unsigned cr:    1;
98         unsigned dlcih: 6;
99   
100         unsigned ea2:   1;
101         unsigned de:    1;
102         unsigned becn:  1;
103         unsigned fecn:  1;
104         unsigned dlcil: 4;
105 #else
106         unsigned dlcih: 6;
107         unsigned cr:    1;
108         unsigned ea1:   1;
109
110         unsigned dlcil: 4;
111         unsigned fecn:  1;
112         unsigned becn:  1;
113         unsigned de:    1;
114         unsigned ea2:   1;
115 #endif
116 }__attribute__ ((packed)) fr_hdr;
117
118
119 typedef struct pvc_device_struct {
120         struct net_device *frad;
121         struct net_device *main;
122         struct net_device *ether;       /* bridged Ethernet interface   */
123         struct pvc_device_struct *next; /* Sorted in ascending DLCI order */
124         int dlci;
125         int open_count;
126
127         struct {
128                 unsigned int new: 1;
129                 unsigned int active: 1;
130                 unsigned int exist: 1;
131                 unsigned int deleted: 1;
132                 unsigned int fecn: 1;
133                 unsigned int becn: 1;
134                 unsigned int bandwidth; /* Cisco LMI reporting only */
135         }state;
136 }pvc_device;
137
138 struct pvc_desc {
139         struct net_device_stats stats;
140         pvc_device *pvc;
141 };
142
143 struct frad_state {
144         fr_proto settings;
145         pvc_device *first_pvc;
146         int dce_pvc_count;
147
148         struct timer_list timer;
149         unsigned long last_poll;
150         int reliable;
151         int dce_changed;
152         int request;
153         int fullrep_sent;
154         u32 last_errors; /* last errors bit list */
155         u8 n391cnt;
156         u8 txseq; /* TX sequence number */
157         u8 rxseq; /* RX sequence number */
158 };
159
160
161 static int fr_ioctl(struct net_device *dev, struct ifreq *ifr);
162
163
164 static inline u16 q922_to_dlci(u8 *hdr)
165 {
166         return ((hdr[0] & 0xFC) << 2) | ((hdr[1] & 0xF0) >> 4);
167 }
168
169
170 static inline void dlci_to_q922(u8 *hdr, u16 dlci)
171 {
172         hdr[0] = (dlci >> 2) & 0xFC;
173         hdr[1] = ((dlci << 4) & 0xF0) | 0x01;
174 }
175
176
177 static inline struct frad_state* state(hdlc_device *hdlc)
178 {
179         return(struct frad_state *)(hdlc->state);
180 }
181
182 static inline struct pvc_desc* pvcdev_to_desc(struct net_device *dev)
183 {
184         return dev->priv;
185 }
186
187 static inline struct net_device_stats* pvc_get_stats(struct net_device *dev)
188 {
189         return &pvcdev_to_desc(dev)->stats;
190 }
191
192 static inline pvc_device* find_pvc(hdlc_device *hdlc, u16 dlci)
193 {
194         pvc_device *pvc = state(hdlc)->first_pvc;
195
196         while (pvc) {
197                 if (pvc->dlci == dlci)
198                         return pvc;
199                 if (pvc->dlci > dlci)
200                         return NULL; /* the listed is sorted */
201                 pvc = pvc->next;
202         }
203
204         return NULL;
205 }
206
207
208 static pvc_device* add_pvc(struct net_device *dev, u16 dlci)
209 {
210         hdlc_device *hdlc = dev_to_hdlc(dev);
211         pvc_device *pvc, **pvc_p = &state(hdlc)->first_pvc;
212
213         while (*pvc_p) {
214                 if ((*pvc_p)->dlci == dlci)
215                         return *pvc_p;
216                 if ((*pvc_p)->dlci > dlci)
217                         break;  /* the list is sorted */
218                 pvc_p = &(*pvc_p)->next;
219         }
220
221         pvc = kzalloc(sizeof(pvc_device), GFP_ATOMIC);
222 #ifdef DEBUG_PVC
223         printk(KERN_DEBUG "add_pvc: allocated pvc %p, frad %p\n", pvc, dev);
224 #endif
225         if (!pvc)
226                 return NULL;
227
228         pvc->dlci = dlci;
229         pvc->frad = dev;
230         pvc->next = *pvc_p;     /* Put it in the chain */
231         *pvc_p = pvc;
232         return pvc;
233 }
234
235
236 static inline int pvc_is_used(pvc_device *pvc)
237 {
238         return pvc->main || pvc->ether;
239 }
240
241
242 static inline void pvc_carrier(int on, pvc_device *pvc)
243 {
244         if (on) {
245                 if (pvc->main)
246                         if (!netif_carrier_ok(pvc->main))
247                                 netif_carrier_on(pvc->main);
248                 if (pvc->ether)
249                         if (!netif_carrier_ok(pvc->ether))
250                                 netif_carrier_on(pvc->ether);
251         } else {
252                 if (pvc->main)
253                         if (netif_carrier_ok(pvc->main))
254                                 netif_carrier_off(pvc->main);
255                 if (pvc->ether)
256                         if (netif_carrier_ok(pvc->ether))
257                                 netif_carrier_off(pvc->ether);
258         }
259 }
260
261
262 static inline void delete_unused_pvcs(hdlc_device *hdlc)
263 {
264         pvc_device **pvc_p = &state(hdlc)->first_pvc;
265
266         while (*pvc_p) {
267                 if (!pvc_is_used(*pvc_p)) {
268                         pvc_device *pvc = *pvc_p;
269 #ifdef DEBUG_PVC
270                         printk(KERN_DEBUG "freeing unused pvc: %p\n", pvc);
271 #endif
272                         *pvc_p = pvc->next;
273                         kfree(pvc);
274                         continue;
275                 }
276                 pvc_p = &(*pvc_p)->next;
277         }
278 }
279
280
281 static inline struct net_device** get_dev_p(pvc_device *pvc, int type)
282 {
283         if (type == ARPHRD_ETHER)
284                 return &pvc->ether;
285         else
286                 return &pvc->main;
287 }
288
289
290 static int fr_hard_header(struct sk_buff **skb_p, u16 dlci)
291 {
292         u16 head_len;
293         struct sk_buff *skb = *skb_p;
294
295         switch (skb->protocol) {
296         case __constant_htons(NLPID_CCITT_ANSI_LMI):
297                 head_len = 4;
298                 skb_push(skb, head_len);
299                 skb->data[3] = NLPID_CCITT_ANSI_LMI;
300                 break;
301
302         case __constant_htons(NLPID_CISCO_LMI):
303                 head_len = 4;
304                 skb_push(skb, head_len);
305                 skb->data[3] = NLPID_CISCO_LMI;
306                 break;
307
308         case __constant_htons(ETH_P_IP):
309                 head_len = 4;
310                 skb_push(skb, head_len);
311                 skb->data[3] = NLPID_IP;
312                 break;
313
314         case __constant_htons(ETH_P_IPV6):
315                 head_len = 4;
316                 skb_push(skb, head_len);
317                 skb->data[3] = NLPID_IPV6;
318                 break;
319
320         case __constant_htons(ETH_P_802_3):
321                 head_len = 10;
322                 if (skb_headroom(skb) < head_len) {
323                         struct sk_buff *skb2 = skb_realloc_headroom(skb,
324                                                                     head_len);
325                         if (!skb2)
326                                 return -ENOBUFS;
327                         dev_kfree_skb(skb);
328                         skb = *skb_p = skb2;
329                 }
330                 skb_push(skb, head_len);
331                 skb->data[3] = FR_PAD;
332                 skb->data[4] = NLPID_SNAP;
333                 skb->data[5] = FR_PAD;
334                 skb->data[6] = 0x80;
335                 skb->data[7] = 0xC2;
336                 skb->data[8] = 0x00;
337                 skb->data[9] = 0x07; /* bridged Ethernet frame w/out FCS */
338                 break;
339
340         default:
341                 head_len = 10;
342                 skb_push(skb, head_len);
343                 skb->data[3] = FR_PAD;
344                 skb->data[4] = NLPID_SNAP;
345                 skb->data[5] = FR_PAD;
346                 skb->data[6] = FR_PAD;
347                 skb->data[7] = FR_PAD;
348                 *(__be16*)(skb->data + 8) = skb->protocol;
349         }
350
351         dlci_to_q922(skb->data, dlci);
352         skb->data[2] = FR_UI;
353         return 0;
354 }
355
356
357
358 static int pvc_open(struct net_device *dev)
359 {
360         pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
361
362         if ((pvc->frad->flags & IFF_UP) == 0)
363                 return -EIO;  /* Frad must be UP in order to activate PVC */
364
365         if (pvc->open_count++ == 0) {
366                 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
367                 if (state(hdlc)->settings.lmi == LMI_NONE)
368                         pvc->state.active = netif_carrier_ok(pvc->frad);
369
370                 pvc_carrier(pvc->state.active, pvc);
371                 state(hdlc)->dce_changed = 1;
372         }
373         return 0;
374 }
375
376
377
378 static int pvc_close(struct net_device *dev)
379 {
380         pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
381
382         if (--pvc->open_count == 0) {
383                 hdlc_device *hdlc = dev_to_hdlc(pvc->frad);
384                 if (state(hdlc)->settings.lmi == LMI_NONE)
385                         pvc->state.active = 0;
386
387                 if (state(hdlc)->settings.dce) {
388                         state(hdlc)->dce_changed = 1;
389                         pvc->state.active = 0;
390                 }
391         }
392         return 0;
393 }
394
395
396
397 static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
398 {
399         pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
400         fr_proto_pvc_info info;
401
402         if (ifr->ifr_settings.type == IF_GET_PROTO) {
403                 if (dev->type == ARPHRD_ETHER)
404                         ifr->ifr_settings.type = IF_PROTO_FR_ETH_PVC;
405                 else
406                         ifr->ifr_settings.type = IF_PROTO_FR_PVC;
407
408                 if (ifr->ifr_settings.size < sizeof(info)) {
409                         /* data size wanted */
410                         ifr->ifr_settings.size = sizeof(info);
411                         return -ENOBUFS;
412                 }
413
414                 info.dlci = pvc->dlci;
415                 memcpy(info.master, pvc->frad->name, IFNAMSIZ);
416                 if (copy_to_user(ifr->ifr_settings.ifs_ifsu.fr_pvc_info,
417                                  &info, sizeof(info)))
418                         return -EFAULT;
419                 return 0;
420         }
421
422         return -EINVAL;
423 }
424
425 static int pvc_xmit(struct sk_buff *skb, struct net_device *dev)
426 {
427         pvc_device *pvc = pvcdev_to_desc(dev)->pvc;
428         struct net_device_stats *stats = pvc_get_stats(dev);
429
430         if (pvc->state.active) {
431                 if (dev->type == ARPHRD_ETHER) {
432                         int pad = ETH_ZLEN - skb->len;
433                         if (pad > 0) { /* Pad the frame with zeros */
434                                 int len = skb->len;
435                                 if (skb_tailroom(skb) < pad)
436                                         if (pskb_expand_head(skb, 0, pad,
437                                                              GFP_ATOMIC)) {
438                                                 stats->tx_dropped++;
439                                                 dev_kfree_skb(skb);
440                                                 return 0;
441                                         }
442                                 skb_put(skb, pad);
443                                 memset(skb->data + len, 0, pad);
444                         }
445                         skb->protocol = __constant_htons(ETH_P_802_3);
446                 }
447                 if (!fr_hard_header(&skb, pvc->dlci)) {
448                         stats->tx_bytes += skb->len;
449                         stats->tx_packets++;
450                         if (pvc->state.fecn) /* TX Congestion counter */
451                                 stats->tx_compressed++;
452                         skb->dev = pvc->frad;
453                         dev_queue_xmit(skb);
454                         return 0;
455                 }
456         }
457
458         stats->tx_dropped++;
459         dev_kfree_skb(skb);
460         return 0;
461 }
462
463
464
465 static int pvc_change_mtu(struct net_device *dev, int new_mtu)
466 {
467         if ((new_mtu < 68) || (new_mtu > HDLC_MAX_MTU))
468                 return -EINVAL;
469         dev->mtu = new_mtu;
470         return 0;
471 }
472
473
474
475 static inline void fr_log_dlci_active(pvc_device *pvc)
476 {
477         printk(KERN_INFO "%s: DLCI %d [%s%s%s]%s %s\n",
478                pvc->frad->name,
479                pvc->dlci,
480                pvc->main ? pvc->main->name : "",
481                pvc->main && pvc->ether ? " " : "",
482                pvc->ether ? pvc->ether->name : "",
483                pvc->state.new ? " new" : "",
484                !pvc->state.exist ? "deleted" :
485                pvc->state.active ? "active" : "inactive");
486 }
487
488
489
490 static inline u8 fr_lmi_nextseq(u8 x)
491 {
492         x++;
493         return x ? x : 1;
494 }
495
496
497 static void fr_lmi_send(struct net_device *dev, int fullrep)
498 {
499         hdlc_device *hdlc = dev_to_hdlc(dev);
500         struct sk_buff *skb;
501         pvc_device *pvc = state(hdlc)->first_pvc;
502         int lmi = state(hdlc)->settings.lmi;
503         int dce = state(hdlc)->settings.dce;
504         int len = lmi == LMI_ANSI ? LMI_ANSI_LENGTH : LMI_CCITT_CISCO_LENGTH;
505         int stat_len = (lmi == LMI_CISCO) ? 6 : 3;
506         u8 *data;
507         int i = 0;
508
509         if (dce && fullrep) {
510                 len += state(hdlc)->dce_pvc_count * (2 + stat_len);
511                 if (len > HDLC_MAX_MRU) {
512                         printk(KERN_WARNING "%s: Too many PVCs while sending "
513                                "LMI full report\n", dev->name);
514                         return;
515                 }
516         }
517
518         skb = dev_alloc_skb(len);
519         if (!skb) {
520                 printk(KERN_WARNING "%s: Memory squeeze on fr_lmi_send()\n",
521                        dev->name);
522                 return;
523         }
524         memset(skb->data, 0, len);
525         skb_reserve(skb, 4);
526         if (lmi == LMI_CISCO) {
527                 skb->protocol = __constant_htons(NLPID_CISCO_LMI);
528                 fr_hard_header(&skb, LMI_CISCO_DLCI);
529         } else {
530                 skb->protocol = __constant_htons(NLPID_CCITT_ANSI_LMI);
531                 fr_hard_header(&skb, LMI_CCITT_ANSI_DLCI);
532         }
533         data = skb_tail_pointer(skb);
534         data[i++] = LMI_CALLREF;
535         data[i++] = dce ? LMI_STATUS : LMI_STATUS_ENQUIRY;
536         if (lmi == LMI_ANSI)
537                 data[i++] = LMI_ANSI_LOCKSHIFT;
538         data[i++] = lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
539                 LMI_ANSI_CISCO_REPTYPE;
540         data[i++] = LMI_REPT_LEN;
541         data[i++] = fullrep ? LMI_FULLREP : LMI_INTEGRITY;
542         data[i++] = lmi == LMI_CCITT ? LMI_CCITT_ALIVE : LMI_ANSI_CISCO_ALIVE;
543         data[i++] = LMI_INTEG_LEN;
544         data[i++] = state(hdlc)->txseq =
545                 fr_lmi_nextseq(state(hdlc)->txseq);
546         data[i++] = state(hdlc)->rxseq;
547
548         if (dce && fullrep) {
549                 while (pvc) {
550                         data[i++] = lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
551                                 LMI_ANSI_CISCO_PVCSTAT;
552                         data[i++] = stat_len;
553
554                         /* LMI start/restart */
555                         if (state(hdlc)->reliable && !pvc->state.exist) {
556                                 pvc->state.exist = pvc->state.new = 1;
557                                 fr_log_dlci_active(pvc);
558                         }
559
560                         /* ifconfig PVC up */
561                         if (pvc->open_count && !pvc->state.active &&
562                             pvc->state.exist && !pvc->state.new) {
563                                 pvc_carrier(1, pvc);
564                                 pvc->state.active = 1;
565                                 fr_log_dlci_active(pvc);
566                         }
567
568                         if (lmi == LMI_CISCO) {
569                                 data[i] = pvc->dlci >> 8;
570                                 data[i + 1] = pvc->dlci & 0xFF;
571                         } else {
572                                 data[i] = (pvc->dlci >> 4) & 0x3F;
573                                 data[i + 1] = ((pvc->dlci << 3) & 0x78) | 0x80;
574                                 data[i + 2] = 0x80;
575                         }
576
577                         if (pvc->state.new)
578                                 data[i + 2] |= 0x08;
579                         else if (pvc->state.active)
580                                 data[i + 2] |= 0x02;
581
582                         i += stat_len;
583                         pvc = pvc->next;
584                 }
585         }
586
587         skb_put(skb, i);
588         skb->priority = TC_PRIO_CONTROL;
589         skb->dev = dev;
590         skb_reset_network_header(skb);
591
592         dev_queue_xmit(skb);
593 }
594
595
596
597 static void fr_set_link_state(int reliable, struct net_device *dev)
598 {
599         hdlc_device *hdlc = dev_to_hdlc(dev);
600         pvc_device *pvc = state(hdlc)->first_pvc;
601
602         state(hdlc)->reliable = reliable;
603         if (reliable) {
604                 netif_dormant_off(dev);
605                 state(hdlc)->n391cnt = 0; /* Request full status */
606                 state(hdlc)->dce_changed = 1;
607
608                 if (state(hdlc)->settings.lmi == LMI_NONE) {
609                         while (pvc) {   /* Activate all PVCs */
610                                 pvc_carrier(1, pvc);
611                                 pvc->state.exist = pvc->state.active = 1;
612                                 pvc->state.new = 0;
613                                 pvc = pvc->next;
614                         }
615                 }
616         } else {
617                 netif_dormant_on(dev);
618                 while (pvc) {           /* Deactivate all PVCs */
619                         pvc_carrier(0, pvc);
620                         pvc->state.exist = pvc->state.active = 0;
621                         pvc->state.new = 0;
622                         if (!state(hdlc)->settings.dce)
623                                 pvc->state.bandwidth = 0;
624                         pvc = pvc->next;
625                 }
626         }
627 }
628
629
630 static void fr_timer(unsigned long arg)
631 {
632         struct net_device *dev = (struct net_device *)arg;
633         hdlc_device *hdlc = dev_to_hdlc(dev);
634         int i, cnt = 0, reliable;
635         u32 list;
636
637         if (state(hdlc)->settings.dce) {
638                 reliable = state(hdlc)->request &&
639                         time_before(jiffies, state(hdlc)->last_poll +
640                                     state(hdlc)->settings.t392 * HZ);
641                 state(hdlc)->request = 0;
642         } else {
643                 state(hdlc)->last_errors <<= 1; /* Shift the list */
644                 if (state(hdlc)->request) {
645                         if (state(hdlc)->reliable)
646                                 printk(KERN_INFO "%s: No LMI status reply "
647                                        "received\n", dev->name);
648                         state(hdlc)->last_errors |= 1;
649                 }
650
651                 list = state(hdlc)->last_errors;
652                 for (i = 0; i < state(hdlc)->settings.n393; i++, list >>= 1)
653                         cnt += (list & 1);      /* errors count */
654
655                 reliable = (cnt < state(hdlc)->settings.n392);
656         }
657
658         if (state(hdlc)->reliable != reliable) {
659                 printk(KERN_INFO "%s: Link %sreliable\n", dev->name,
660                        reliable ? "" : "un");
661                 fr_set_link_state(reliable, dev);
662         }
663
664         if (state(hdlc)->settings.dce)
665                 state(hdlc)->timer.expires = jiffies +
666                         state(hdlc)->settings.t392 * HZ;
667         else {
668                 if (state(hdlc)->n391cnt)
669                         state(hdlc)->n391cnt--;
670
671                 fr_lmi_send(dev, state(hdlc)->n391cnt == 0);
672
673                 state(hdlc)->last_poll = jiffies;
674                 state(hdlc)->request = 1;
675                 state(hdlc)->timer.expires = jiffies +
676                         state(hdlc)->settings.t391 * HZ;
677         }
678
679         state(hdlc)->timer.function = fr_timer;
680         state(hdlc)->timer.data = arg;
681         add_timer(&state(hdlc)->timer);
682 }
683
684
685 static int fr_lmi_recv(struct net_device *dev, struct sk_buff *skb)
686 {
687         hdlc_device *hdlc = dev_to_hdlc(dev);
688         pvc_device *pvc;
689         u8 rxseq, txseq;
690         int lmi = state(hdlc)->settings.lmi;
691         int dce = state(hdlc)->settings.dce;
692         int stat_len = (lmi == LMI_CISCO) ? 6 : 3, reptype, error, no_ram, i;
693
694         if (skb->len < (lmi == LMI_ANSI ? LMI_ANSI_LENGTH :
695                         LMI_CCITT_CISCO_LENGTH)) {
696                 printk(KERN_INFO "%s: Short LMI frame\n", dev->name);
697                 return 1;
698         }
699
700         if (skb->data[3] != (lmi == LMI_CISCO ? NLPID_CISCO_LMI :
701                              NLPID_CCITT_ANSI_LMI)) {
702                 printk(KERN_INFO "%s: Received non-LMI frame with LMI DLCI\n",
703                        dev->name);
704                 return 1;
705         }
706
707         if (skb->data[4] != LMI_CALLREF) {
708                 printk(KERN_INFO "%s: Invalid LMI Call reference (0x%02X)\n",
709                        dev->name, skb->data[4]);
710                 return 1;
711         }
712
713         if (skb->data[5] != (dce ? LMI_STATUS_ENQUIRY : LMI_STATUS)) {
714                 printk(KERN_INFO "%s: Invalid LMI Message type (0x%02X)\n",
715                        dev->name, skb->data[5]);
716                 return 1;
717         }
718
719         if (lmi == LMI_ANSI) {
720                 if (skb->data[6] != LMI_ANSI_LOCKSHIFT) {
721                         printk(KERN_INFO "%s: Not ANSI locking shift in LMI"
722                                " message (0x%02X)\n", dev->name, skb->data[6]);
723                         return 1;
724                 }
725                 i = 7;
726         } else
727                 i = 6;
728
729         if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_REPTYPE :
730                              LMI_ANSI_CISCO_REPTYPE)) {
731                 printk(KERN_INFO "%s: Not an LMI Report type IE (0x%02X)\n",
732                        dev->name, skb->data[i]);
733                 return 1;
734         }
735
736         if (skb->data[++i] != LMI_REPT_LEN) {
737                 printk(KERN_INFO "%s: Invalid LMI Report type IE length"
738                        " (%u)\n", dev->name, skb->data[i]);
739                 return 1;
740         }
741
742         reptype = skb->data[++i];
743         if (reptype != LMI_INTEGRITY && reptype != LMI_FULLREP) {
744                 printk(KERN_INFO "%s: Unsupported LMI Report type (0x%02X)\n",
745                        dev->name, reptype);
746                 return 1;
747         }
748
749         if (skb->data[++i] != (lmi == LMI_CCITT ? LMI_CCITT_ALIVE :
750                                LMI_ANSI_CISCO_ALIVE)) {
751                 printk(KERN_INFO "%s: Not an LMI Link integrity verification"
752                        " IE (0x%02X)\n", dev->name, skb->data[i]);
753                 return 1;
754         }
755
756         if (skb->data[++i] != LMI_INTEG_LEN) {
757                 printk(KERN_INFO "%s: Invalid LMI Link integrity verification"
758                        " IE length (%u)\n", dev->name, skb->data[i]);
759                 return 1;
760         }
761         i++;
762
763         state(hdlc)->rxseq = skb->data[i++]; /* TX sequence from peer */
764         rxseq = skb->data[i++]; /* Should confirm our sequence */
765
766         txseq = state(hdlc)->txseq;
767
768         if (dce)
769                 state(hdlc)->last_poll = jiffies;
770
771         error = 0;
772         if (!state(hdlc)->reliable)
773                 error = 1;
774
775         if (rxseq == 0 || rxseq != txseq) { /* Ask for full report next time */
776                 state(hdlc)->n391cnt = 0;
777                 error = 1;
778         }
779
780         if (dce) {
781                 if (state(hdlc)->fullrep_sent && !error) {
782 /* Stop sending full report - the last one has been confirmed by DTE */
783                         state(hdlc)->fullrep_sent = 0;
784                         pvc = state(hdlc)->first_pvc;
785                         while (pvc) {
786                                 if (pvc->state.new) {
787                                         pvc->state.new = 0;
788
789 /* Tell DTE that new PVC is now active */
790                                         state(hdlc)->dce_changed = 1;
791                                 }
792                                 pvc = pvc->next;
793                         }
794                 }
795
796                 if (state(hdlc)->dce_changed) {
797                         reptype = LMI_FULLREP;
798                         state(hdlc)->fullrep_sent = 1;
799                         state(hdlc)->dce_changed = 0;
800                 }
801
802                 state(hdlc)->request = 1; /* got request */
803                 fr_lmi_send(dev, reptype == LMI_FULLREP ? 1 : 0);
804                 return 0;
805         }
806
807         /* DTE */
808
809         state(hdlc)->request = 0; /* got response, no request pending */
810
811         if (error)
812                 return 0;
813
814         if (reptype != LMI_FULLREP)
815                 return 0;
816
817         pvc = state(hdlc)->first_pvc;
818
819         while (pvc) {
820                 pvc->state.deleted = 1;
821                 pvc = pvc->next;
822         }
823
824         no_ram = 0;
825         while (skb->len >= i + 2 + stat_len) {
826                 u16 dlci;
827                 u32 bw;
828                 unsigned int active, new;
829
830                 if (skb->data[i] != (lmi == LMI_CCITT ? LMI_CCITT_PVCSTAT :
831                                        LMI_ANSI_CISCO_PVCSTAT)) {
832                         printk(KERN_INFO "%s: Not an LMI PVC status IE"
833                                " (0x%02X)\n", dev->name, skb->data[i]);
834                         return 1;
835                 }
836
837                 if (skb->data[++i] != stat_len) {
838                         printk(KERN_INFO "%s: Invalid LMI PVC status IE length"
839                                " (%u)\n", dev->name, skb->data[i]);
840                         return 1;
841                 }
842                 i++;
843
844                 new = !! (skb->data[i + 2] & 0x08);
845                 active = !! (skb->data[i + 2] & 0x02);
846                 if (lmi == LMI_CISCO) {
847                         dlci = (skb->data[i] << 8) | skb->data[i + 1];
848                         bw = (skb->data[i + 3] << 16) |
849                                 (skb->data[i + 4] << 8) |
850                                 (skb->data[i + 5]);
851                 } else {
852                         dlci = ((skb->data[i] & 0x3F) << 4) |
853                                 ((skb->data[i + 1] & 0x78) >> 3);
854                         bw = 0;
855                 }
856
857                 pvc = add_pvc(dev, dlci);
858
859                 if (!pvc && !no_ram) {
860                         printk(KERN_WARNING
861                                "%s: Memory squeeze on fr_lmi_recv()\n",
862                                dev->name);
863                         no_ram = 1;
864                 }
865
866                 if (pvc) {
867                         pvc->state.exist = 1;
868                         pvc->state.deleted = 0;
869                         if (active != pvc->state.active ||
870                             new != pvc->state.new ||
871                             bw != pvc->state.bandwidth ||
872                             !pvc->state.exist) {
873                                 pvc->state.new = new;
874                                 pvc->state.active = active;
875                                 pvc->state.bandwidth = bw;
876                                 pvc_carrier(active, pvc);
877                                 fr_log_dlci_active(pvc);
878                         }
879                 }
880
881                 i += stat_len;
882         }
883
884         pvc = state(hdlc)->first_pvc;
885
886         while (pvc) {
887                 if (pvc->state.deleted && pvc->state.exist) {
888                         pvc_carrier(0, pvc);
889                         pvc->state.active = pvc->state.new = 0;
890                         pvc->state.exist = 0;
891                         pvc->state.bandwidth = 0;
892                         fr_log_dlci_active(pvc);
893                 }
894                 pvc = pvc->next;
895         }
896
897         /* Next full report after N391 polls */
898         state(hdlc)->n391cnt = state(hdlc)->settings.n391;
899
900         return 0;
901 }
902
903
904 static int fr_rx(struct sk_buff *skb)
905 {
906         struct net_device *frad = skb->dev;
907         hdlc_device *hdlc = dev_to_hdlc(frad);
908         fr_hdr *fh = (fr_hdr*)skb->data;
909         u8 *data = skb->data;
910         u16 dlci;
911         pvc_device *pvc;
912         struct net_device *dev = NULL;
913
914         if (skb->len <= 4 || fh->ea1 || data[2] != FR_UI)
915                 goto rx_error;
916
917         dlci = q922_to_dlci(skb->data);
918
919         if ((dlci == LMI_CCITT_ANSI_DLCI &&
920              (state(hdlc)->settings.lmi == LMI_ANSI ||
921               state(hdlc)->settings.lmi == LMI_CCITT)) ||
922             (dlci == LMI_CISCO_DLCI &&
923              state(hdlc)->settings.lmi == LMI_CISCO)) {
924                 if (fr_lmi_recv(frad, skb))
925                         goto rx_error;
926                 dev_kfree_skb_any(skb);
927                 return NET_RX_SUCCESS;
928         }
929
930         pvc = find_pvc(hdlc, dlci);
931         if (!pvc) {
932 #ifdef DEBUG_PKT
933                 printk(KERN_INFO "%s: No PVC for received frame's DLCI %d\n",
934                        frad->name, dlci);
935 #endif
936                 dev_kfree_skb_any(skb);
937                 return NET_RX_DROP;
938         }
939
940         if (pvc->state.fecn != fh->fecn) {
941 #ifdef DEBUG_ECN
942                 printk(KERN_DEBUG "%s: DLCI %d FECN O%s\n", frad->name,
943                        dlci, fh->fecn ? "N" : "FF");
944 #endif
945                 pvc->state.fecn ^= 1;
946         }
947
948         if (pvc->state.becn != fh->becn) {
949 #ifdef DEBUG_ECN
950                 printk(KERN_DEBUG "%s: DLCI %d BECN O%s\n", frad->name,
951                        dlci, fh->becn ? "N" : "FF");
952 #endif
953                 pvc->state.becn ^= 1;
954         }
955
956
957         if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL) {
958                 dev_to_hdlc(frad)->stats.rx_dropped++;
959                 return NET_RX_DROP;
960         }
961
962         if (data[3] == NLPID_IP) {
963                 skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
964                 dev = pvc->main;
965                 skb->protocol = htons(ETH_P_IP);
966
967         } else if (data[3] == NLPID_IPV6) {
968                 skb_pull(skb, 4); /* Remove 4-byte header (hdr, UI, NLPID) */
969                 dev = pvc->main;
970                 skb->protocol = htons(ETH_P_IPV6);
971
972         } else if (skb->len > 10 && data[3] == FR_PAD &&
973                    data[4] == NLPID_SNAP && data[5] == FR_PAD) {
974                 u16 oui = ntohs(*(__be16*)(data + 6));
975                 u16 pid = ntohs(*(__be16*)(data + 8));
976                 skb_pull(skb, 10);
977
978                 switch ((((u32)oui) << 16) | pid) {
979                 case ETH_P_ARP: /* routed frame with SNAP */
980                 case ETH_P_IPX:
981                 case ETH_P_IP:  /* a long variant */
982                 case ETH_P_IPV6:
983                         dev = pvc->main;
984                         skb->protocol = htons(pid);
985                         break;
986
987                 case 0x80C20007: /* bridged Ethernet frame */
988                         if ((dev = pvc->ether) != NULL)
989                                 skb->protocol = eth_type_trans(skb, dev);
990                         break;
991
992                 default:
993                         printk(KERN_INFO "%s: Unsupported protocol, OUI=%x "
994                                "PID=%x\n", frad->name, oui, pid);
995                         dev_kfree_skb_any(skb);
996                         return NET_RX_DROP;
997                 }
998         } else {
999                 printk(KERN_INFO "%s: Unsupported protocol, NLPID=%x "
1000                        "length = %i\n", frad->name, data[3], skb->len);
1001                 dev_kfree_skb_any(skb);
1002                 return NET_RX_DROP;
1003         }
1004
1005         if (dev) {
1006                 struct net_device_stats *stats = pvc_get_stats(dev);
1007                 stats->rx_packets++; /* PVC traffic */
1008                 stats->rx_bytes += skb->len;
1009                 if (pvc->state.becn)
1010                         stats->rx_compressed++;
1011                 netif_rx(skb);
1012                 return NET_RX_SUCCESS;
1013         } else {
1014                 dev_kfree_skb_any(skb);
1015                 return NET_RX_DROP;
1016         }
1017
1018  rx_error:
1019         dev_to_hdlc(frad)->stats.rx_errors++; /* Mark error */
1020         dev_kfree_skb_any(skb);
1021         return NET_RX_DROP;
1022 }
1023
1024
1025
1026 static void fr_start(struct net_device *dev)
1027 {
1028         hdlc_device *hdlc = dev_to_hdlc(dev);
1029 #ifdef DEBUG_LINK
1030         printk(KERN_DEBUG "fr_start\n");
1031 #endif
1032         if (state(hdlc)->settings.lmi != LMI_NONE) {
1033                 state(hdlc)->reliable = 0;
1034                 state(hdlc)->dce_changed = 1;
1035                 state(hdlc)->request = 0;
1036                 state(hdlc)->fullrep_sent = 0;
1037                 state(hdlc)->last_errors = 0xFFFFFFFF;
1038                 state(hdlc)->n391cnt = 0;
1039                 state(hdlc)->txseq = state(hdlc)->rxseq = 0;
1040
1041                 init_timer(&state(hdlc)->timer);
1042                 /* First poll after 1 s */
1043                 state(hdlc)->timer.expires = jiffies + HZ;
1044                 state(hdlc)->timer.function = fr_timer;
1045                 state(hdlc)->timer.data = (unsigned long)dev;
1046                 add_timer(&state(hdlc)->timer);
1047         } else
1048                 fr_set_link_state(1, dev);
1049 }
1050
1051
1052 static void fr_stop(struct net_device *dev)
1053 {
1054         hdlc_device *hdlc = dev_to_hdlc(dev);
1055 #ifdef DEBUG_LINK
1056         printk(KERN_DEBUG "fr_stop\n");
1057 #endif
1058         if (state(hdlc)->settings.lmi != LMI_NONE)
1059                 del_timer_sync(&state(hdlc)->timer);
1060         fr_set_link_state(0, dev);
1061 }
1062
1063
1064 static void fr_close(struct net_device *dev)
1065 {
1066         hdlc_device *hdlc = dev_to_hdlc(dev);
1067         pvc_device *pvc = state(hdlc)->first_pvc;
1068
1069         while (pvc) {           /* Shutdown all PVCs for this FRAD */
1070                 if (pvc->main)
1071                         dev_close(pvc->main);
1072                 if (pvc->ether)
1073                         dev_close(pvc->ether);
1074                 pvc = pvc->next;
1075         }
1076 }
1077
1078
1079 static void pvc_setup(struct net_device *dev)
1080 {
1081         dev->type = ARPHRD_DLCI;
1082         dev->flags = IFF_POINTOPOINT;
1083         dev->hard_header_len = 10;
1084         dev->addr_len = 2;
1085 }
1086
1087 static int fr_add_pvc(struct net_device *frad, unsigned int dlci, int type)
1088 {
1089         hdlc_device *hdlc = dev_to_hdlc(frad);
1090         pvc_device *pvc = NULL;
1091         struct net_device *dev;
1092         int result, used;
1093         char * prefix = "pvc%d";
1094
1095         if (type == ARPHRD_ETHER)
1096                 prefix = "pvceth%d";
1097
1098         if ((pvc = add_pvc(frad, dlci)) == NULL) {
1099                 printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
1100                        frad->name);
1101                 return -ENOBUFS;
1102         }
1103
1104         if (*get_dev_p(pvc, type))
1105                 return -EEXIST;
1106
1107         used = pvc_is_used(pvc);
1108
1109         if (type == ARPHRD_ETHER)
1110                 dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d",
1111                                    ether_setup);
1112         else
1113                 dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup);
1114
1115         if (!dev) {
1116                 printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1117                        frad->name);
1118                 delete_unused_pvcs(hdlc);
1119                 return -ENOBUFS;
1120         }
1121
1122         if (type == ARPHRD_ETHER)
1123                 random_ether_addr(dev->dev_addr);
1124         else {
1125                 *(__be16*)dev->dev_addr = htons(dlci);
1126                 dlci_to_q922(dev->broadcast, dlci);
1127         }
1128         dev->hard_start_xmit = pvc_xmit;
1129         dev->get_stats = pvc_get_stats;
1130         dev->open = pvc_open;
1131         dev->stop = pvc_close;
1132         dev->do_ioctl = pvc_ioctl;
1133         dev->change_mtu = pvc_change_mtu;
1134         dev->mtu = HDLC_MAX_MTU;
1135         dev->tx_queue_len = 0;
1136         pvcdev_to_desc(dev)->pvc = pvc;
1137
1138         result = dev_alloc_name(dev, dev->name);
1139         if (result < 0) {
1140                 free_netdev(dev);
1141                 delete_unused_pvcs(hdlc);
1142                 return result;
1143         }
1144
1145         if (register_netdevice(dev) != 0) {
1146                 free_netdev(dev);
1147                 delete_unused_pvcs(hdlc);
1148                 return -EIO;
1149         }
1150
1151         dev->destructor = free_netdev;
1152         *get_dev_p(pvc, type) = dev;
1153         if (!used) {
1154                 state(hdlc)->dce_changed = 1;
1155                 state(hdlc)->dce_pvc_count++;
1156         }
1157         return 0;
1158 }
1159
1160
1161
1162 static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1163 {
1164         pvc_device *pvc;
1165         struct net_device *dev;
1166
1167         if ((pvc = find_pvc(hdlc, dlci)) == NULL)
1168                 return -ENOENT;
1169
1170         if ((dev = *get_dev_p(pvc, type)) == NULL)
1171                 return -ENOENT;
1172
1173         if (dev->flags & IFF_UP)
1174                 return -EBUSY;          /* PVC in use */
1175
1176         unregister_netdevice(dev); /* the destructor will free_netdev(dev) */
1177         *get_dev_p(pvc, type) = NULL;
1178
1179         if (!pvc_is_used(pvc)) {
1180                 state(hdlc)->dce_pvc_count--;
1181                 state(hdlc)->dce_changed = 1;
1182         }
1183         delete_unused_pvcs(hdlc);
1184         return 0;
1185 }
1186
1187
1188
1189 static void fr_destroy(struct net_device *frad)
1190 {
1191         hdlc_device *hdlc = dev_to_hdlc(frad);
1192         pvc_device *pvc = state(hdlc)->first_pvc;
1193         state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */
1194         state(hdlc)->dce_pvc_count = 0;
1195         state(hdlc)->dce_changed = 1;
1196
1197         while (pvc) {
1198                 pvc_device *next = pvc->next;
1199                 /* destructors will free_netdev() main and ether */
1200                 if (pvc->main)
1201                         unregister_netdevice(pvc->main);
1202
1203                 if (pvc->ether)
1204                         unregister_netdevice(pvc->ether);
1205
1206                 kfree(pvc);
1207                 pvc = next;
1208         }
1209 }
1210
1211
1212 static struct hdlc_proto proto = {
1213         .close          = fr_close,
1214         .start          = fr_start,
1215         .stop           = fr_stop,
1216         .detach         = fr_destroy,
1217         .ioctl          = fr_ioctl,
1218         .netif_rx       = fr_rx,
1219         .module         = THIS_MODULE,
1220 };
1221
1222
1223 static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1224 {
1225         fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
1226         const size_t size = sizeof(fr_proto);
1227         fr_proto new_settings;
1228         hdlc_device *hdlc = dev_to_hdlc(dev);
1229         fr_proto_pvc pvc;
1230         int result;
1231
1232         switch (ifr->ifr_settings.type) {
1233         case IF_GET_PROTO:
1234                 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1235                         return -EINVAL;
1236                 ifr->ifr_settings.type = IF_PROTO_FR;
1237                 if (ifr->ifr_settings.size < size) {
1238                         ifr->ifr_settings.size = size; /* data size wanted */
1239                         return -ENOBUFS;
1240                 }
1241                 if (copy_to_user(fr_s, &state(hdlc)->settings, size))
1242                         return -EFAULT;
1243                 return 0;
1244
1245         case IF_PROTO_FR:
1246                 if(!capable(CAP_NET_ADMIN))
1247                         return -EPERM;
1248
1249                 if(dev->flags & IFF_UP)
1250                         return -EBUSY;
1251
1252                 if (copy_from_user(&new_settings, fr_s, size))
1253                         return -EFAULT;
1254
1255                 if (new_settings.lmi == LMI_DEFAULT)
1256                         new_settings.lmi = LMI_ANSI;
1257
1258                 if ((new_settings.lmi != LMI_NONE &&
1259                      new_settings.lmi != LMI_ANSI &&
1260                      new_settings.lmi != LMI_CCITT &&
1261                      new_settings.lmi != LMI_CISCO) ||
1262                     new_settings.t391 < 1 ||
1263                     new_settings.t392 < 2 ||
1264                     new_settings.n391 < 1 ||
1265                     new_settings.n392 < 1 ||
1266                     new_settings.n393 < new_settings.n392 ||
1267                     new_settings.n393 > 32 ||
1268                     (new_settings.dce != 0 &&
1269                      new_settings.dce != 1))
1270                         return -EINVAL;
1271
1272                 result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
1273                 if (result)
1274                         return result;
1275
1276                 if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
1277                         result = attach_hdlc_protocol(dev, &proto,
1278                                                       sizeof(struct frad_state));
1279                         if (result)
1280                                 return result;
1281                         state(hdlc)->first_pvc = NULL;
1282                         state(hdlc)->dce_pvc_count = 0;
1283                 }
1284                 memcpy(&state(hdlc)->settings, &new_settings, size);
1285
1286                 dev->hard_start_xmit = hdlc->xmit;
1287                 dev->type = ARPHRD_FRAD;
1288                 return 0;
1289
1290         case IF_PROTO_FR_ADD_PVC:
1291         case IF_PROTO_FR_DEL_PVC:
1292         case IF_PROTO_FR_ADD_ETH_PVC:
1293         case IF_PROTO_FR_DEL_ETH_PVC:
1294                 if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1295                         return -EINVAL;
1296
1297                 if(!capable(CAP_NET_ADMIN))
1298                         return -EPERM;
1299
1300                 if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc,
1301                                    sizeof(fr_proto_pvc)))
1302                         return -EFAULT;
1303
1304                 if (pvc.dlci <= 0 || pvc.dlci >= 1024)
1305                         return -EINVAL; /* Only 10 bits, DLCI 0 reserved */
1306
1307                 if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC ||
1308                     ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC)
1309                         result = ARPHRD_ETHER; /* bridged Ethernet device */
1310                 else
1311                         result = ARPHRD_DLCI;
1312
1313                 if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC ||
1314                     ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC)
1315                         return fr_add_pvc(dev, pvc.dlci, result);
1316                 else
1317                         return fr_del_pvc(hdlc, pvc.dlci, result);
1318         }
1319
1320         return -EINVAL;
1321 }
1322
1323
1324 static int __init mod_init(void)
1325 {
1326         register_hdlc_protocol(&proto);
1327         return 0;
1328 }
1329
1330
1331 static void __exit mod_exit(void)
1332 {
1333         unregister_hdlc_protocol(&proto);
1334 }
1335
1336
1337 module_init(mod_init);
1338 module_exit(mod_exit);
1339
1340 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1341 MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
1342 MODULE_LICENSE("GPL v2");