xref: /openbmc/linux/drivers/net/wan/hdlc_fr.c (revision 22246614)
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 
1094 	if ((pvc = add_pvc(frad, dlci)) == NULL) {
1095 		printk(KERN_WARNING "%s: Memory squeeze on fr_add_pvc()\n",
1096 		       frad->name);
1097 		return -ENOBUFS;
1098 	}
1099 
1100 	if (*get_dev_p(pvc, type))
1101 		return -EEXIST;
1102 
1103 	used = pvc_is_used(pvc);
1104 
1105 	if (type == ARPHRD_ETHER)
1106 		dev = alloc_netdev(sizeof(struct pvc_desc), "pvceth%d",
1107 				   ether_setup);
1108 	else
1109 		dev = alloc_netdev(sizeof(struct pvc_desc), "pvc%d", pvc_setup);
1110 
1111 	if (!dev) {
1112 		printk(KERN_WARNING "%s: Memory squeeze on fr_pvc()\n",
1113 		       frad->name);
1114 		delete_unused_pvcs(hdlc);
1115 		return -ENOBUFS;
1116 	}
1117 
1118 	if (type == ARPHRD_ETHER)
1119 		random_ether_addr(dev->dev_addr);
1120 	else {
1121 		*(__be16*)dev->dev_addr = htons(dlci);
1122 		dlci_to_q922(dev->broadcast, dlci);
1123 	}
1124 	dev->hard_start_xmit = pvc_xmit;
1125 	dev->get_stats = pvc_get_stats;
1126 	dev->open = pvc_open;
1127 	dev->stop = pvc_close;
1128 	dev->do_ioctl = pvc_ioctl;
1129 	dev->change_mtu = pvc_change_mtu;
1130 	dev->mtu = HDLC_MAX_MTU;
1131 	dev->tx_queue_len = 0;
1132 	pvcdev_to_desc(dev)->pvc = pvc;
1133 
1134 	result = dev_alloc_name(dev, dev->name);
1135 	if (result < 0) {
1136 		free_netdev(dev);
1137 		delete_unused_pvcs(hdlc);
1138 		return result;
1139 	}
1140 
1141 	if (register_netdevice(dev) != 0) {
1142 		free_netdev(dev);
1143 		delete_unused_pvcs(hdlc);
1144 		return -EIO;
1145 	}
1146 
1147 	dev->destructor = free_netdev;
1148 	*get_dev_p(pvc, type) = dev;
1149 	if (!used) {
1150 		state(hdlc)->dce_changed = 1;
1151 		state(hdlc)->dce_pvc_count++;
1152 	}
1153 	return 0;
1154 }
1155 
1156 
1157 
1158 static int fr_del_pvc(hdlc_device *hdlc, unsigned int dlci, int type)
1159 {
1160 	pvc_device *pvc;
1161 	struct net_device *dev;
1162 
1163 	if ((pvc = find_pvc(hdlc, dlci)) == NULL)
1164 		return -ENOENT;
1165 
1166 	if ((dev = *get_dev_p(pvc, type)) == NULL)
1167 		return -ENOENT;
1168 
1169 	if (dev->flags & IFF_UP)
1170 		return -EBUSY;		/* PVC in use */
1171 
1172 	unregister_netdevice(dev); /* the destructor will free_netdev(dev) */
1173 	*get_dev_p(pvc, type) = NULL;
1174 
1175 	if (!pvc_is_used(pvc)) {
1176 		state(hdlc)->dce_pvc_count--;
1177 		state(hdlc)->dce_changed = 1;
1178 	}
1179 	delete_unused_pvcs(hdlc);
1180 	return 0;
1181 }
1182 
1183 
1184 
1185 static void fr_destroy(struct net_device *frad)
1186 {
1187 	hdlc_device *hdlc = dev_to_hdlc(frad);
1188 	pvc_device *pvc = state(hdlc)->first_pvc;
1189 	state(hdlc)->first_pvc = NULL; /* All PVCs destroyed */
1190 	state(hdlc)->dce_pvc_count = 0;
1191 	state(hdlc)->dce_changed = 1;
1192 
1193 	while (pvc) {
1194 		pvc_device *next = pvc->next;
1195 		/* destructors will free_netdev() main and ether */
1196 		if (pvc->main)
1197 			unregister_netdevice(pvc->main);
1198 
1199 		if (pvc->ether)
1200 			unregister_netdevice(pvc->ether);
1201 
1202 		kfree(pvc);
1203 		pvc = next;
1204 	}
1205 }
1206 
1207 
1208 static struct hdlc_proto proto = {
1209 	.close		= fr_close,
1210 	.start		= fr_start,
1211 	.stop		= fr_stop,
1212 	.detach		= fr_destroy,
1213 	.ioctl		= fr_ioctl,
1214 	.netif_rx	= fr_rx,
1215 	.module		= THIS_MODULE,
1216 };
1217 
1218 
1219 static int fr_ioctl(struct net_device *dev, struct ifreq *ifr)
1220 {
1221 	fr_proto __user *fr_s = ifr->ifr_settings.ifs_ifsu.fr;
1222 	const size_t size = sizeof(fr_proto);
1223 	fr_proto new_settings;
1224 	hdlc_device *hdlc = dev_to_hdlc(dev);
1225 	fr_proto_pvc pvc;
1226 	int result;
1227 
1228 	switch (ifr->ifr_settings.type) {
1229 	case IF_GET_PROTO:
1230 		if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1231 			return -EINVAL;
1232 		ifr->ifr_settings.type = IF_PROTO_FR;
1233 		if (ifr->ifr_settings.size < size) {
1234 			ifr->ifr_settings.size = size; /* data size wanted */
1235 			return -ENOBUFS;
1236 		}
1237 		if (copy_to_user(fr_s, &state(hdlc)->settings, size))
1238 			return -EFAULT;
1239 		return 0;
1240 
1241 	case IF_PROTO_FR:
1242 		if(!capable(CAP_NET_ADMIN))
1243 			return -EPERM;
1244 
1245 		if(dev->flags & IFF_UP)
1246 			return -EBUSY;
1247 
1248 		if (copy_from_user(&new_settings, fr_s, size))
1249 			return -EFAULT;
1250 
1251 		if (new_settings.lmi == LMI_DEFAULT)
1252 			new_settings.lmi = LMI_ANSI;
1253 
1254 		if ((new_settings.lmi != LMI_NONE &&
1255 		     new_settings.lmi != LMI_ANSI &&
1256 		     new_settings.lmi != LMI_CCITT &&
1257 		     new_settings.lmi != LMI_CISCO) ||
1258 		    new_settings.t391 < 1 ||
1259 		    new_settings.t392 < 2 ||
1260 		    new_settings.n391 < 1 ||
1261 		    new_settings.n392 < 1 ||
1262 		    new_settings.n393 < new_settings.n392 ||
1263 		    new_settings.n393 > 32 ||
1264 		    (new_settings.dce != 0 &&
1265 		     new_settings.dce != 1))
1266 			return -EINVAL;
1267 
1268 		result=hdlc->attach(dev, ENCODING_NRZ,PARITY_CRC16_PR1_CCITT);
1269 		if (result)
1270 			return result;
1271 
1272 		if (dev_to_hdlc(dev)->proto != &proto) { /* Different proto */
1273 			result = attach_hdlc_protocol(dev, &proto,
1274 						      sizeof(struct frad_state));
1275 			if (result)
1276 				return result;
1277 			state(hdlc)->first_pvc = NULL;
1278 			state(hdlc)->dce_pvc_count = 0;
1279 		}
1280 		memcpy(&state(hdlc)->settings, &new_settings, size);
1281 
1282 		dev->hard_start_xmit = hdlc->xmit;
1283 		dev->type = ARPHRD_FRAD;
1284 		return 0;
1285 
1286 	case IF_PROTO_FR_ADD_PVC:
1287 	case IF_PROTO_FR_DEL_PVC:
1288 	case IF_PROTO_FR_ADD_ETH_PVC:
1289 	case IF_PROTO_FR_DEL_ETH_PVC:
1290 		if (dev_to_hdlc(dev)->proto != &proto) /* Different proto */
1291 			return -EINVAL;
1292 
1293 		if(!capable(CAP_NET_ADMIN))
1294 			return -EPERM;
1295 
1296 		if (copy_from_user(&pvc, ifr->ifr_settings.ifs_ifsu.fr_pvc,
1297 				   sizeof(fr_proto_pvc)))
1298 			return -EFAULT;
1299 
1300 		if (pvc.dlci <= 0 || pvc.dlci >= 1024)
1301 			return -EINVAL;	/* Only 10 bits, DLCI 0 reserved */
1302 
1303 		if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC ||
1304 		    ifr->ifr_settings.type == IF_PROTO_FR_DEL_ETH_PVC)
1305 			result = ARPHRD_ETHER; /* bridged Ethernet device */
1306 		else
1307 			result = ARPHRD_DLCI;
1308 
1309 		if (ifr->ifr_settings.type == IF_PROTO_FR_ADD_PVC ||
1310 		    ifr->ifr_settings.type == IF_PROTO_FR_ADD_ETH_PVC)
1311 			return fr_add_pvc(dev, pvc.dlci, result);
1312 		else
1313 			return fr_del_pvc(hdlc, pvc.dlci, result);
1314 	}
1315 
1316 	return -EINVAL;
1317 }
1318 
1319 
1320 static int __init mod_init(void)
1321 {
1322 	register_hdlc_protocol(&proto);
1323 	return 0;
1324 }
1325 
1326 
1327 static void __exit mod_exit(void)
1328 {
1329 	unregister_hdlc_protocol(&proto);
1330 }
1331 
1332 
1333 module_init(mod_init);
1334 module_exit(mod_exit);
1335 
1336 MODULE_AUTHOR("Krzysztof Halasa <khc@pm.waw.pl>");
1337 MODULE_DESCRIPTION("Frame-Relay protocol support for generic HDLC");
1338 MODULE_LICENSE("GPL v2");
1339