blob: de6be7181f0734966cdbe840ef923f9dd7ff4cd8 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/* $Id: isdn_net.c,v 1.1.2.2 2004/01/12 22:37:19 keil Exp $
2 *
3 * Linux ISDN subsystem, network interfaces and related functions (linklevel).
4 *
5 * Copyright 1994-1998 by Fritz Elfert (fritz@isdn4linux.de)
6 * Copyright 1995,96 by Thinking Objects Software GmbH Wuerzburg
7 * Copyright 1995,96 by Michael Hipp (Michael.Hipp@student.uni-tuebingen.de)
8 *
9 * This software may be used and distributed according to the terms
10 * of the GNU General Public License, incorporated herein by reference.
11 *
12 * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02
13 * guy@traverse.com.au
14 * Outgoing calls - looks for a 'V' in first char of dialed number
15 * Incoming calls - checks first character of eaz as follows:
16 * Numeric - accept DATA only - original functionality
17 * 'V' - accept VOICE (DOV) only
18 * 'B' - accept BOTH DATA and DOV types
19 *
20 * Jan 2001: fix CISCO HDLC Bjoern A. Zeeb <i4l@zabbadoz.net>
21 * for info on the protocol, see
22 * http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
23 */
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/isdn.h>
26#include <net/arp.h>
27#include <net/dst.h>
28#include <net/pkt_sched.h>
29#include <linux/inetdevice.h>
30#include "isdn_common.h"
31#include "isdn_net.h"
32#ifdef CONFIG_ISDN_PPP
33#include "isdn_ppp.h"
34#endif
35#ifdef CONFIG_ISDN_X25
36#include <linux/concap.h>
37#include "isdn_concap.h"
38#endif
39
40
41/*
42 * Outline of new tbusy handling:
43 *
44 * Old method, roughly spoken, consisted of setting tbusy when entering
45 * isdn_net_start_xmit() and at several other locations and clearing
46 * it from isdn_net_start_xmit() thread when sending was successful.
47 *
48 * With 2.3.x multithreaded network core, to prevent problems, tbusy should
49 * only be set by the isdn_net_start_xmit() thread and only when a tx-busy
50 * condition is detected. Other threads (in particular isdn_net_stat_callb())
51 * are only allowed to clear tbusy.
52 *
53 * -HE
54 */
55
56/*
57 * About SOFTNET:
58 * Most of the changes were pretty obvious and basically done by HE already.
59 *
60 * One problem of the isdn net device code is that is uses struct net_device
61 * for masters and slaves. However, only master interface are registered to
62 * the network layer, and therefore, it only makes sense to call netif_*
63 * functions on them.
64 *
65 * --KG
66 */
67
68/*
69 * Find out if the netdevice has been ifup-ed yet.
70 * For slaves, look at the corresponding master.
71 */
72static __inline__ int isdn_net_device_started(isdn_net_dev *n)
73{
74 isdn_net_local *lp = n->local;
75 struct net_device *dev;
76
77 if (lp->master)
78 dev = lp->master;
79 else
Karsten Keild62a38d2007-10-08 20:37:11 -070080 dev = n->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070081 return netif_running(dev);
82}
83
84/*
85 * wake up the network -> net_device queue.
86 * For slaves, wake the corresponding master interface.
87 */
88static __inline__ void isdn_net_device_wake_queue(isdn_net_local *lp)
89{
90 if (lp->master)
91 netif_wake_queue(lp->master);
92 else
Karsten Keild62a38d2007-10-08 20:37:11 -070093 netif_wake_queue(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070094}
95
96/*
97 * stop the network -> net_device queue.
98 * For slaves, stop the corresponding master interface.
99 */
100static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp)
101{
102 if (lp->master)
103 netif_stop_queue(lp->master);
104 else
Karsten Keild62a38d2007-10-08 20:37:11 -0700105 netif_stop_queue(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700106}
107
108/*
109 * find out if the net_device which this lp belongs to (lp can be
110 * master or slave) is busy. It's busy iff all (master and slave)
111 * queues are busy
112 */
113static __inline__ int isdn_net_device_busy(isdn_net_local *lp)
114{
115 isdn_net_local *nlp;
116 isdn_net_dev *nd;
117 unsigned long flags;
118
119 if (!isdn_net_lp_busy(lp))
120 return 0;
121
122 if (lp->master)
Wang Chen838361f2008-12-03 15:49:46 -0800123 nd = ISDN_MASTER_PRIV(lp)->netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700124 else
125 nd = lp->netdev;
126
127 spin_lock_irqsave(&nd->queue_lock, flags);
128 nlp = lp->next;
129 while (nlp != lp) {
130 if (!isdn_net_lp_busy(nlp)) {
131 spin_unlock_irqrestore(&nd->queue_lock, flags);
132 return 0;
133 }
134 nlp = nlp->next;
135 }
136 spin_unlock_irqrestore(&nd->queue_lock, flags);
137 return 1;
138}
139
140static __inline__ void isdn_net_inc_frame_cnt(isdn_net_local *lp)
141{
142 atomic_inc(&lp->frame_cnt);
143 if (isdn_net_device_busy(lp))
144 isdn_net_device_stop_queue(lp);
145}
146
147static __inline__ void isdn_net_dec_frame_cnt(isdn_net_local *lp)
148{
149 atomic_dec(&lp->frame_cnt);
150
151 if (!(isdn_net_device_busy(lp))) {
152 if (!skb_queue_empty(&lp->super_tx_queue)) {
153 schedule_work(&lp->tqueue);
154 } else {
155 isdn_net_device_wake_queue(lp);
156 }
157 }
158}
159
160static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
161{
162 atomic_set(&lp->frame_cnt, 0);
163}
164
165/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
166 * to be safe.
167 * For 2.3.x we push it up to 20 secs, because call establishment
168 * (in particular callback) may take such a long time, and we
169 * don't want confusing messages in the log. However, there is a slight
170 * possibility that this large timeout will break other things like MPPP,
171 * which might rely on the tx timeout. If so, we'll find out this way...
172 */
173
174#define ISDN_NET_TX_TIMEOUT (20*HZ)
175
176/* Prototypes */
177
Adrian Bunk3e206b02005-06-25 14:58:35 -0700178static int isdn_net_force_dial_lp(isdn_net_local *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700179static int isdn_net_start_xmit(struct sk_buff *, struct net_device *);
180
181static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
182static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
183
184char *isdn_net_revision = "$Revision: 1.1.2.2 $";
185
186 /*
187 * Code for raw-networking over ISDN
188 */
189
190static void
191isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
192{
193 if(skb) {
194
195 u_short proto = ntohs(skb->protocol);
196
197 printk(KERN_DEBUG "isdn_net: %s: %s, signalling dst_link_failure %s\n",
198 dev->name,
199 (reason != NULL) ? reason : "unknown",
200 (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
201
202 dst_link_failure(skb);
203 }
204 else { /* dial not triggered by rawIP packet */
205 printk(KERN_DEBUG "isdn_net: %s: %s\n",
206 dev->name,
207 (reason != NULL) ? reason : "reason unknown");
208 }
209}
210
211static void
212isdn_net_reset(struct net_device *dev)
213{
214#ifdef CONFIG_ISDN_X25
215 struct concap_device_ops * dops =
Wang Chen838361f2008-12-03 15:49:46 -0800216 ((isdn_net_local *) netdev_priv(dev))->dops;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700217 struct concap_proto * cprot =
Wang Chen838361f2008-12-03 15:49:46 -0800218 ((isdn_net_local *) netdev_priv(dev))->netdev->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219#endif
220#ifdef CONFIG_ISDN_X25
221 if( cprot && cprot -> pops && dops )
222 cprot -> pops -> restart ( cprot, dev, dops );
223#endif
224}
225
226/* Open/initialize the board. */
227static int
228isdn_net_open(struct net_device *dev)
229{
230 int i;
231 struct net_device *p;
232 struct in_device *in_dev;
233
234 /* moved here from isdn_net_reset, because only the master has an
235 interface associated which is supposed to be started. BTW:
236 we need to call netif_start_queue, not netif_wake_queue here */
237 netif_start_queue(dev);
238
239 isdn_net_reset(dev);
240 /* Fill in the MAC-level header (not needed, but for compatibility... */
241 for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
242 dev->dev_addr[i] = 0xfc;
243 if ((in_dev = dev->ip_ptr) != NULL) {
244 /*
245 * Any address will do - we take the first
246 */
247 struct in_ifaddr *ifa = in_dev->ifa_list;
248 if (ifa != NULL)
249 memcpy(dev->dev_addr+2, &ifa->ifa_local, 4);
250 }
251
252 /* If this interface has slaves, start them also */
Wang Chen838361f2008-12-03 15:49:46 -0800253 p = MASTER_TO_SLAVE(dev);
254 if (p) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700255 while (p) {
256 isdn_net_reset(p);
Wang Chen838361f2008-12-03 15:49:46 -0800257 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700258 }
259 }
260 isdn_lock_drivers();
261 return 0;
262}
263
264/*
265 * Assign an ISDN-channel to a net-interface
266 */
267static void
268isdn_net_bind_channel(isdn_net_local * lp, int idx)
269{
270 lp->flags |= ISDN_NET_CONNECTED;
271 lp->isdn_device = dev->drvmap[idx];
272 lp->isdn_channel = dev->chanmap[idx];
273 dev->rx_netdev[idx] = lp->netdev;
274 dev->st_netdev[idx] = lp->netdev;
275}
276
277/*
278 * unbind a net-interface (resets interface after an error)
279 */
280static void
281isdn_net_unbind_channel(isdn_net_local * lp)
282{
283 skb_queue_purge(&lp->super_tx_queue);
284
285 if (!lp->master) { /* reset only master device */
286 /* Moral equivalent of dev_purge_queues():
287 BEWARE! This chunk of code cannot be called from hardware
288 interrupt handler. I hope it is true. --ANK
289 */
David S. Miller5aa70992008-07-08 22:59:10 -0700290 qdisc_reset_all_tx(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700291 }
292 lp->dialstate = 0;
293 dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
294 dev->st_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
Paul Bollebae58432009-01-14 14:41:00 -0800295 if (lp->isdn_device != -1 && lp->isdn_channel != -1)
296 isdn_free_channel(lp->isdn_device, lp->isdn_channel,
297 ISDN_USAGE_NET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 lp->flags &= ~ISDN_NET_CONNECTED;
299 lp->isdn_device = -1;
300 lp->isdn_channel = -1;
301}
302
303/*
304 * Perform auto-hangup and cps-calculation for net-interfaces.
305 *
306 * auto-hangup:
307 * Increment idle-counter (this counter is reset on any incoming or
308 * outgoing packet), if counter exceeds configured limit either do a
309 * hangup immediately or - if configured - wait until just before the next
310 * charge-info.
311 *
312 * cps-calculation (needed for dynamic channel-bundling):
313 * Since this function is called every second, simply reset the
314 * byte-counter of the interface after copying it to the cps-variable.
315 */
Adrian Bunk3e206b02005-06-25 14:58:35 -0700316static unsigned long last_jiffies = -HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700317
318void
319isdn_net_autohup(void)
320{
321 isdn_net_dev *p = dev->netdev;
322 int anymore;
323
324 anymore = 0;
325 while (p) {
326 isdn_net_local *l = p->local;
327 if (jiffies == last_jiffies)
328 l->cps = l->transcount;
329 else
330 l->cps = (l->transcount * HZ) / (jiffies - last_jiffies);
331 l->transcount = 0;
332 if (dev->net_verbose > 3)
Karsten Keilfaca94f2007-10-15 02:11:44 -0700333 printk(KERN_DEBUG "%s: %d bogocps\n", p->dev->name, l->cps);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700334 if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
335 anymore = 1;
336 l->huptimer++;
337 /*
338 * if there is some dialmode where timeout-hangup
339 * should _not_ be done, check for that here
340 */
341 if ((l->onhtime) &&
342 (l->huptimer > l->onhtime))
343 {
344 if (l->hupflags & ISDN_MANCHARGE &&
345 l->hupflags & ISDN_CHARGEHUP) {
346 while (time_after(jiffies, l->chargetime + l->chargeint))
347 l->chargetime += l->chargeint;
348 if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ))
349 if (l->outgoing || l->hupflags & ISDN_INHUP)
Karsten Keild62a38d2007-10-08 20:37:11 -0700350 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700351 } else if (l->outgoing) {
352 if (l->hupflags & ISDN_CHARGEHUP) {
353 if (l->hupflags & ISDN_WAITCHARGE) {
354 printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700355 p->dev->name, l->hupflags);
Karsten Keild62a38d2007-10-08 20:37:11 -0700356 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700357 } else if (time_after(jiffies, l->chargetime + l->chargeint)) {
358 printk(KERN_DEBUG
359 "isdn_net: %s: chtime = %lu, chint = %d\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700360 p->dev->name, l->chargetime, l->chargeint);
Karsten Keild62a38d2007-10-08 20:37:11 -0700361 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700362 }
363 } else
Karsten Keild62a38d2007-10-08 20:37:11 -0700364 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365 } else if (l->hupflags & ISDN_INHUP)
Karsten Keild62a38d2007-10-08 20:37:11 -0700366 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 }
368
369 if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
Karsten Keild62a38d2007-10-08 20:37:11 -0700370 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371 break;
372 }
373 }
374 p = (isdn_net_dev *) p->next;
375 }
376 last_jiffies = jiffies;
377 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
378}
379
380static void isdn_net_lp_disconnected(isdn_net_local *lp)
381{
382 isdn_net_rm_from_bundle(lp);
383}
384
385/*
386 * Handle status-messages from ISDN-interfacecard.
387 * This function is called from within the main-status-dispatcher
388 * isdn_status_callback, which itself is called from the low-level driver.
389 * Return: 1 = Event handled, 0 = not for us or unknown Event.
390 */
391int
392isdn_net_stat_callback(int idx, isdn_ctrl *c)
393{
394 isdn_net_dev *p = dev->st_netdev[idx];
395 int cmd = c->command;
396
397 if (p) {
398 isdn_net_local *lp = p->local;
399#ifdef CONFIG_ISDN_X25
400 struct concap_proto *cprot = lp->netdev->cprot;
401 struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;
402#endif
403 switch (cmd) {
404 case ISDN_STAT_BSENT:
405 /* A packet has successfully been sent out */
406 if ((lp->flags & ISDN_NET_CONNECTED) &&
407 (!lp->dialstate)) {
408 isdn_net_dec_frame_cnt(lp);
409 lp->stats.tx_packets++;
410 lp->stats.tx_bytes += c->parm.length;
411 }
412 return 1;
413 case ISDN_STAT_DCONN:
414 /* D-Channel is up */
415 switch (lp->dialstate) {
416 case 4:
417 case 7:
418 case 8:
419 lp->dialstate++;
420 return 1;
421 case 12:
422 lp->dialstate = 5;
423 return 1;
424 }
425 break;
426 case ISDN_STAT_DHUP:
427 /* Either D-Channel-hangup or error during dialout */
428#ifdef CONFIG_ISDN_X25
429 /* If we are not connencted then dialing had
430 failed. If there are generic encap protocol
431 receiver routines signal the closure of
432 the link*/
433
434 if( !(lp->flags & ISDN_NET_CONNECTED)
435 && pops && pops -> disconn_ind )
436 pops -> disconn_ind(cprot);
437#endif /* CONFIG_ISDN_X25 */
438 if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
439 if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
440 isdn_net_ciscohdlck_disconnected(lp);
441#ifdef CONFIG_ISDN_PPP
442 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
443 isdn_ppp_free(lp);
444#endif
445 isdn_net_lp_disconnected(lp);
446 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
Karsten Keilfaca94f2007-10-15 02:11:44 -0700447 printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
448 printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 lp->charge);
450 isdn_net_unbind_channel(lp);
451 return 1;
452 }
453 break;
454#ifdef CONFIG_ISDN_X25
455 case ISDN_STAT_BHUP:
456 /* B-Channel-hangup */
457 /* try if there are generic encap protocol
458 receiver routines and signal the closure of
459 the link */
460 if( pops && pops -> disconn_ind ){
461 pops -> disconn_ind(cprot);
462 return 1;
463 }
464 break;
465#endif /* CONFIG_ISDN_X25 */
466 case ISDN_STAT_BCONN:
467 /* B-Channel is up */
468 isdn_net_zero_frame_cnt(lp);
469 switch (lp->dialstate) {
470 case 5:
471 case 6:
472 case 7:
473 case 8:
474 case 9:
475 case 10:
476 case 12:
477 if (lp->dialstate <= 6) {
478 dev->usage[idx] |= ISDN_USAGE_OUTGOING;
479 isdn_info_update();
480 } else
481 dev->rx_netdev[idx] = p;
482 lp->dialstate = 0;
483 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
484 if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
485 isdn_net_ciscohdlck_connected(lp);
486 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
487 if (lp->master) { /* is lp a slave? */
Wang Chen838361f2008-12-03 15:49:46 -0800488 isdn_net_dev *nd = ISDN_MASTER_PRIV(lp)->netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700489 isdn_net_add_to_bundle(nd, lp);
490 }
491 }
Karsten Keilfaca94f2007-10-15 02:11:44 -0700492 printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700493 /* If first Chargeinfo comes before B-Channel connect,
494 * we correct the timestamp here.
495 */
496 lp->chargetime = jiffies;
497
498 /* reset dial-timeout */
499 lp->dialstarted = 0;
500 lp->dialwait_timer = 0;
501
502#ifdef CONFIG_ISDN_PPP
503 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
504 isdn_ppp_wakeup_daemon(lp);
505#endif
506#ifdef CONFIG_ISDN_X25
507 /* try if there are generic concap receiver routines */
508 if( pops )
509 if( pops->connect_ind)
510 pops->connect_ind(cprot);
511#endif /* CONFIG_ISDN_X25 */
512 /* ppp needs to do negotiations first */
513 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
514 isdn_net_device_wake_queue(lp);
515 return 1;
516 }
517 break;
518 case ISDN_STAT_NODCH:
519 /* No D-Channel avail. */
520 if (lp->dialstate == 4) {
521 lp->dialstate--;
522 return 1;
523 }
524 break;
525 case ISDN_STAT_CINF:
526 /* Charge-info from TelCo. Calculate interval between
527 * charge-infos and set timestamp for last info for
528 * usage by isdn_net_autohup()
529 */
530 lp->charge++;
531 if (lp->hupflags & ISDN_HAVECHARGE) {
532 lp->hupflags &= ~ISDN_WAITCHARGE;
533 lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
534 }
535 if (lp->hupflags & ISDN_WAITCHARGE)
536 lp->hupflags |= ISDN_HAVECHARGE;
537 lp->chargetime = jiffies;
538 printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700539 p->dev->name, lp->chargetime);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700540 return 1;
541 }
542 }
543 return 0;
544}
545
546/*
547 * Perform dialout for net-interfaces and timeout-handling for
548 * D-Channel-up and B-Channel-up Messages.
549 * This function is initially called from within isdn_net_start_xmit() or
550 * or isdn_net_find_icall() after initializing the dialstate for an
551 * interface. If further calls are needed, the function schedules itself
552 * for a timer-callback via isdn_timer_function().
553 * The dialstate is also affected by incoming status-messages from
554 * the ISDN-Channel which are handled in isdn_net_stat_callback() above.
555 */
556void
557isdn_net_dial(void)
558{
559 isdn_net_dev *p = dev->netdev;
560 int anymore = 0;
561 int i;
562 isdn_ctrl cmd;
563 u_char *phone_number;
564
565 while (p) {
566 isdn_net_local *lp = p->local;
567
568#ifdef ISDN_DEBUG_NET_DIAL
569 if (lp->dialstate)
Karsten Keilfaca94f2007-10-15 02:11:44 -0700570 printk(KERN_DEBUG "%s: dialstate=%d\n", p->dev->name, lp->dialstate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571#endif
572 switch (lp->dialstate) {
573 case 0:
574 /* Nothing to do for this interface */
575 break;
576 case 1:
577 /* Initiate dialout. Set phone-number-pointer to first number
578 * of interface.
579 */
580 lp->dial = lp->phone[1];
581 if (!lp->dial) {
582 printk(KERN_WARNING "%s: phone number deleted?\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700583 p->dev->name);
Karsten Keild62a38d2007-10-08 20:37:11 -0700584 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 break;
586 }
587 anymore = 1;
588
589 if(lp->dialtimeout > 0)
590 if(lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
591 lp->dialstarted = jiffies;
592 lp->dialwait_timer = 0;
593 }
594
595 lp->dialstate++;
596 /* Fall through */
597 case 2:
598 /* Prepare dialing. Clear EAZ, then set EAZ. */
599 cmd.driver = lp->isdn_device;
600 cmd.arg = lp->isdn_channel;
601 cmd.command = ISDN_CMD_CLREAZ;
602 isdn_command(&cmd);
603 sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
604 cmd.command = ISDN_CMD_SETEAZ;
605 isdn_command(&cmd);
606 lp->dialretry = 0;
607 anymore = 1;
608 lp->dialstate++;
609 /* Fall through */
610 case 3:
611 /* Setup interface, dial current phone-number, switch to next number.
612 * If list of phone-numbers is exhausted, increment
613 * retry-counter.
614 */
615 if(dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
616 char *s;
617 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
618 s = "dial suppressed: isdn system stopped";
619 else
620 s = "dial suppressed: dialmode `off'";
Karsten Keild62a38d2007-10-08 20:37:11 -0700621 isdn_net_unreachable(p->dev, NULL, s);
622 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700623 break;
624 }
625 cmd.driver = lp->isdn_device;
626 cmd.command = ISDN_CMD_SETL2;
627 cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
628 isdn_command(&cmd);
629 cmd.driver = lp->isdn_device;
630 cmd.command = ISDN_CMD_SETL3;
631 cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
632 isdn_command(&cmd);
633 cmd.driver = lp->isdn_device;
634 cmd.arg = lp->isdn_channel;
635 if (!lp->dial) {
636 printk(KERN_WARNING "%s: phone number deleted?\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700637 p->dev->name);
Karsten Keild62a38d2007-10-08 20:37:11 -0700638 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700639 break;
640 }
641 if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
642 lp->dialstate = 4;
Karsten Keilfaca94f2007-10-15 02:11:44 -0700643 printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700644 } else {
645 if(lp->dialtimeout > 0)
646 if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
647 lp->dialwait_timer = jiffies + lp->dialwait;
648 lp->dialstarted = 0;
Karsten Keild62a38d2007-10-08 20:37:11 -0700649 isdn_net_unreachable(p->dev, NULL, "dial: timed out");
650 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700651 break;
652 }
653
654 cmd.driver = lp->isdn_device;
655 cmd.command = ISDN_CMD_DIAL;
656 cmd.parm.setup.si2 = 0;
657
658 /* check for DOV */
659 phone_number = lp->dial->num;
660 if ((*phone_number == 'v') ||
661 (*phone_number == 'V')) { /* DOV call */
662 cmd.parm.setup.si1 = 1;
663 } else { /* DATA call */
664 cmd.parm.setup.si1 = 7;
665 }
666
667 strcpy(cmd.parm.setup.phone, phone_number);
668 /*
669 * Switch to next number or back to start if at end of list.
670 */
671 if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
672 lp->dial = lp->phone[1];
673 lp->dialretry++;
674
675 if (lp->dialretry > lp->dialmax) {
676 if (lp->dialtimeout == 0) {
677 lp->dialwait_timer = jiffies + lp->dialwait;
678 lp->dialstarted = 0;
Karsten Keild62a38d2007-10-08 20:37:11 -0700679 isdn_net_unreachable(p->dev, NULL, "dial: tried all numbers dialmax times");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700680 }
Karsten Keild62a38d2007-10-08 20:37:11 -0700681 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 break;
683 }
684 }
685 sprintf(cmd.parm.setup.eazmsn, "%s",
686 isdn_map_eaz2msn(lp->msn, cmd.driver));
687 i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
688 if (i >= 0) {
689 strcpy(dev->num[i], cmd.parm.setup.phone);
690 dev->usage[i] |= ISDN_USAGE_OUTGOING;
691 isdn_info_update();
692 }
Karsten Keilfaca94f2007-10-15 02:11:44 -0700693 printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 lp->dialretry, cmd.parm.setup.phone,
695 (cmd.parm.setup.si1 == 1) ? "DOV" : "");
696 lp->dtimer = 0;
697#ifdef ISDN_DEBUG_NET_DIAL
698 printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
699 lp->isdn_channel);
700#endif
701 isdn_command(&cmd);
702 }
703 lp->huptimer = 0;
704 lp->outgoing = 1;
705 if (lp->chargeint) {
706 lp->hupflags |= ISDN_HAVECHARGE;
707 lp->hupflags &= ~ISDN_WAITCHARGE;
708 } else {
709 lp->hupflags |= ISDN_WAITCHARGE;
710 lp->hupflags &= ~ISDN_HAVECHARGE;
711 }
712 anymore = 1;
713 lp->dialstate =
714 (lp->cbdelay &&
715 (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
716 break;
717 case 4:
718 /* Wait for D-Channel-connect.
719 * If timeout, switch back to state 3.
720 * Dialmax-handling moved to state 3.
721 */
722 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
723 lp->dialstate = 3;
724 anymore = 1;
725 break;
726 case 5:
727 /* Got D-Channel-Connect, send B-Channel-request */
728 cmd.driver = lp->isdn_device;
729 cmd.arg = lp->isdn_channel;
730 cmd.command = ISDN_CMD_ACCEPTB;
731 anymore = 1;
732 lp->dtimer = 0;
733 lp->dialstate++;
734 isdn_command(&cmd);
735 break;
736 case 6:
737 /* Wait for B- or D-Channel-connect. If timeout,
738 * switch back to state 3.
739 */
740#ifdef ISDN_DEBUG_NET_DIAL
741 printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);
742#endif
743 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
744 lp->dialstate = 3;
745 anymore = 1;
746 break;
747 case 7:
748 /* Got incoming Call, setup L2 and L3 protocols,
749 * then wait for D-Channel-connect
750 */
751#ifdef ISDN_DEBUG_NET_DIAL
752 printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
753#endif
754 cmd.driver = lp->isdn_device;
755 cmd.command = ISDN_CMD_SETL2;
756 cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
757 isdn_command(&cmd);
758 cmd.driver = lp->isdn_device;
759 cmd.command = ISDN_CMD_SETL3;
760 cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
761 isdn_command(&cmd);
762 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)
Karsten Keild62a38d2007-10-08 20:37:11 -0700763 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700764 else {
765 anymore = 1;
766 lp->dialstate++;
767 }
768 break;
769 case 9:
770 /* Got incoming D-Channel-Connect, send B-Channel-request */
771 cmd.driver = lp->isdn_device;
772 cmd.arg = lp->isdn_channel;
773 cmd.command = ISDN_CMD_ACCEPTB;
774 isdn_command(&cmd);
775 anymore = 1;
776 lp->dtimer = 0;
777 lp->dialstate++;
778 break;
779 case 8:
780 case 10:
781 /* Wait for B- or D-channel-connect */
782#ifdef ISDN_DEBUG_NET_DIAL
783 printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
784#endif
785 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
Karsten Keild62a38d2007-10-08 20:37:11 -0700786 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700787 else
788 anymore = 1;
789 break;
790 case 11:
791 /* Callback Delay */
792 if (lp->dtimer++ > lp->cbdelay)
793 lp->dialstate = 1;
794 anymore = 1;
795 break;
796 case 12:
797 /* Remote does callback. Hangup after cbdelay, then wait for incoming
798 * call (in state 4).
799 */
800 if (lp->dtimer++ > lp->cbdelay)
801 {
Karsten Keilfaca94f2007-10-15 02:11:44 -0700802 printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700803 lp->dtimer = 0;
804 lp->dialstate = 4;
805 cmd.driver = lp->isdn_device;
806 cmd.command = ISDN_CMD_HANGUP;
807 cmd.arg = lp->isdn_channel;
808 isdn_command(&cmd);
809 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
810 }
811 anymore = 1;
812 break;
813 default:
814 printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700815 lp->dialstate, p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700816 }
817 p = (isdn_net_dev *) p->next;
818 }
819 isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);
820}
821
822/*
823 * Perform hangup for a net-interface.
824 */
825void
826isdn_net_hangup(struct net_device *d)
827{
Wang Chen838361f2008-12-03 15:49:46 -0800828 isdn_net_local *lp = (isdn_net_local *) netdev_priv(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700829 isdn_ctrl cmd;
830#ifdef CONFIG_ISDN_X25
831 struct concap_proto *cprot = lp->netdev->cprot;
832 struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;
833#endif
834
835 if (lp->flags & ISDN_NET_CONNECTED) {
836 if (lp->slave != NULL) {
Wang Chen838361f2008-12-03 15:49:46 -0800837 isdn_net_local *slp = ISDN_SLAVE_PRIV(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700838 if (slp->flags & ISDN_NET_CONNECTED) {
839 printk(KERN_INFO
840 "isdn_net: hang up slave %s before %s\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700841 lp->slave->name, d->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700842 isdn_net_hangup(lp->slave);
843 }
844 }
Karsten Keilfaca94f2007-10-15 02:11:44 -0700845 printk(KERN_INFO "isdn_net: local hangup %s\n", d->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700846#ifdef CONFIG_ISDN_PPP
847 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
848 isdn_ppp_free(lp);
849#endif
850 isdn_net_lp_disconnected(lp);
851#ifdef CONFIG_ISDN_X25
852 /* try if there are generic encap protocol
853 receiver routines and signal the closure of
854 the link */
855 if( pops && pops -> disconn_ind )
856 pops -> disconn_ind(cprot);
857#endif /* CONFIG_ISDN_X25 */
858
859 cmd.driver = lp->isdn_device;
860 cmd.command = ISDN_CMD_HANGUP;
861 cmd.arg = lp->isdn_channel;
862 isdn_command(&cmd);
Karsten Keilfaca94f2007-10-15 02:11:44 -0700863 printk(KERN_INFO "%s: Chargesum is %d\n", d->name, lp->charge);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700864 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
865 }
866 isdn_net_unbind_channel(lp);
867}
868
869typedef struct {
Harvey Harrisonc19d0362008-11-20 04:10:51 -0800870 __be16 source;
871 __be16 dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700872} ip_ports;
873
874static void
875isdn_net_log_skb(struct sk_buff * skb, isdn_net_local * lp)
876{
Arnaldo Carvalho de Melod56f90a2007-04-10 20:50:43 -0700877 /* hopefully, this was set correctly */
878 const u_char *p = skb_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700879 unsigned short proto = ntohs(skb->protocol);
880 int data_ofs;
881 ip_ports *ipp;
882 char addinfo[100];
883
884 addinfo[0] = '\0';
885 /* This check stolen from 2.1.72 dev_queue_xmit_nit() */
Arnaldo Carvalho de Melo27a884d2007-04-19 20:29:13 -0700886 if (p < skb->data || skb->network_header >= skb->tail) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700887 /* fall back to old isdn_net_log_packet method() */
888 char * buf = skb->data;
889
Karsten Keilfaca94f2007-10-15 02:11:44 -0700890 printk(KERN_DEBUG "isdn_net: protocol %04x is buggy, dev %s\n", skb->protocol, lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891 p = buf;
892 proto = ETH_P_IP;
893 switch (lp->p_encap) {
894 case ISDN_NET_ENCAP_IPTYP:
Harvey Harrison00bcd522008-11-13 22:41:29 -0800895 proto = ntohs(*(__be16 *)&buf[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896 p = &buf[2];
897 break;
898 case ISDN_NET_ENCAP_ETHER:
Harvey Harrison00bcd522008-11-13 22:41:29 -0800899 proto = ntohs(*(__be16 *)&buf[12]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700900 p = &buf[14];
901 break;
902 case ISDN_NET_ENCAP_CISCOHDLC:
Harvey Harrison00bcd522008-11-13 22:41:29 -0800903 proto = ntohs(*(__be16 *)&buf[2]);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700904 p = &buf[4];
905 break;
906#ifdef CONFIG_ISDN_PPP
907 case ISDN_NET_ENCAP_SYNCPPP:
908 proto = ntohs(skb->protocol);
909 p = &buf[IPPP_MAX_HEADER];
910 break;
911#endif
912 }
913 }
914 data_ofs = ((p[0] & 15) * 4);
915 switch (proto) {
916 case ETH_P_IP:
917 switch (p[9]) {
918 case 1:
919 strcpy(addinfo, " ICMP");
920 break;
921 case 2:
922 strcpy(addinfo, " IGMP");
923 break;
924 case 4:
925 strcpy(addinfo, " IPIP");
926 break;
927 case 6:
928 ipp = (ip_ports *) (&p[data_ofs]);
929 sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
930 ntohs(ipp->dest));
931 break;
932 case 8:
933 strcpy(addinfo, " EGP");
934 break;
935 case 12:
936 strcpy(addinfo, " PUP");
937 break;
938 case 17:
939 ipp = (ip_ports *) (&p[data_ofs]);
940 sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
941 ntohs(ipp->dest));
942 break;
943 case 22:
944 strcpy(addinfo, " IDP");
945 break;
946 }
Harvey Harrison00bcd522008-11-13 22:41:29 -0800947 printk(KERN_INFO "OPEN: %pI4 -> %pI4%s\n",
948 p + 12, p + 16, addinfo);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700949 break;
950 case ETH_P_ARP:
Harvey Harrison00bcd522008-11-13 22:41:29 -0800951 printk(KERN_INFO "OPEN: ARP %pI4 -> *.*.*.* ?%pI4\n",
952 p + 14, p + 24);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700953 break;
954 }
955}
956
957/*
958 * this function is used to send supervisory data, i.e. data which was
959 * not received from the network layer, but e.g. frames from ipppd, CCP
960 * reset frames etc.
961 */
962void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
963{
964 if (in_irq()) {
965 // we can't grab the lock from irq context,
966 // so we just queue the packet
967 skb_queue_tail(&lp->super_tx_queue, skb);
968 schedule_work(&lp->tqueue);
969 return;
970 }
971
972 spin_lock_bh(&lp->xmit_lock);
973 if (!isdn_net_lp_busy(lp)) {
974 isdn_net_writebuf_skb(lp, skb);
975 } else {
976 skb_queue_tail(&lp->super_tx_queue, skb);
977 }
978 spin_unlock_bh(&lp->xmit_lock);
979}
980
981/*
982 * called from tq_immediate
983 */
David Howellsc4028952006-11-22 14:57:56 +0000984static void isdn_net_softint(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700985{
David Howellsc4028952006-11-22 14:57:56 +0000986 isdn_net_local *lp = container_of(work, isdn_net_local, tqueue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987 struct sk_buff *skb;
988
989 spin_lock_bh(&lp->xmit_lock);
990 while (!isdn_net_lp_busy(lp)) {
991 skb = skb_dequeue(&lp->super_tx_queue);
992 if (!skb)
993 break;
994 isdn_net_writebuf_skb(lp, skb);
995 }
996 spin_unlock_bh(&lp->xmit_lock);
997}
998
999/*
1000 * all frames sent from the (net) LL to a HL driver should go via this function
1001 * it's serialized by the caller holding the lp->xmit_lock spinlock
1002 */
1003void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
1004{
1005 int ret;
1006 int len = skb->len; /* save len */
1007
1008 /* before obtaining the lock the caller should have checked that
1009 the lp isn't busy */
1010 if (isdn_net_lp_busy(lp)) {
1011 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1012 goto error;
1013 }
1014
1015 if (!(lp->flags & ISDN_NET_CONNECTED)) {
1016 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1017 goto error;
1018 }
1019 ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
1020 if (ret != len) {
1021 /* we should never get here */
Karsten Keilfaca94f2007-10-15 02:11:44 -07001022 printk(KERN_WARNING "%s: HL driver queue full\n", lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023 goto error;
1024 }
1025
1026 lp->transcount += len;
1027 isdn_net_inc_frame_cnt(lp);
1028 return;
1029
1030 error:
1031 dev_kfree_skb(skb);
1032 lp->stats.tx_errors++;
1033
1034}
1035
1036
1037/*
1038 * Helper function for isdn_net_start_xmit.
1039 * When called, the connection is already established.
1040 * Based on cps-calculation, check if device is overloaded.
1041 * If so, and if a slave exists, trigger dialing for it.
1042 * If any slave is online, deliver packets using a simple round robin
1043 * scheme.
1044 *
1045 * Return: 0 on success, !0 on failure.
1046 */
1047
1048static int
1049isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
1050{
1051 isdn_net_dev *nd;
1052 isdn_net_local *slp;
Wang Chen838361f2008-12-03 15:49:46 -08001053 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 int retv = 0;
1055
Wang Chen838361f2008-12-03 15:49:46 -08001056 if (((isdn_net_local *) netdev_priv(ndev))->master) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1058 dev_kfree_skb(skb);
1059 return 0;
1060 }
1061
1062 /* For the other encaps the header has already been built */
1063#ifdef CONFIG_ISDN_PPP
1064 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1065 return isdn_ppp_xmit(skb, ndev);
1066 }
1067#endif
Wang Chen838361f2008-12-03 15:49:46 -08001068 nd = ((isdn_net_local *) netdev_priv(ndev))->netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001069 lp = isdn_net_get_locked_lp(nd);
1070 if (!lp) {
1071 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
1072 return 1;
1073 }
1074 /* we have our lp locked from now on */
1075
1076 /* Reset hangup-timeout */
1077 lp->huptimer = 0; // FIXME?
1078 isdn_net_writebuf_skb(lp, skb);
1079 spin_unlock_bh(&lp->xmit_lock);
1080
1081 /* the following stuff is here for backwards compatibility.
1082 * in future, start-up and hangup of slaves (based on current load)
1083 * should move to userspace and get based on an overall cps
1084 * calculation
1085 */
1086 if (lp->cps > lp->triggercps) {
1087 if (lp->slave) {
1088 if (!lp->sqfull) {
1089 /* First time overload: set timestamp only */
1090 lp->sqfull = 1;
1091 lp->sqfull_stamp = jiffies;
1092 } else {
1093 /* subsequent overload: if slavedelay exceeded, start dialing */
1094 if (time_after(jiffies, lp->sqfull_stamp + lp->slavedelay)) {
Wang Chen838361f2008-12-03 15:49:46 -08001095 slp = ISDN_SLAVE_PRIV(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 if (!(slp->flags & ISDN_NET_CONNECTED)) {
Wang Chen838361f2008-12-03 15:49:46 -08001097 isdn_net_force_dial_lp(ISDN_SLAVE_PRIV(lp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 }
1099 }
1100 }
1101 }
1102 } else {
1103 if (lp->sqfull && time_after(jiffies, lp->sqfull_stamp + lp->slavedelay + (10 * HZ))) {
1104 lp->sqfull = 0;
1105 }
1106 /* this is a hack to allow auto-hangup for slaves on moderate loads */
1107 nd->queue = nd->local;
1108 }
1109
1110 return retv;
1111
1112}
1113
1114static void
1115isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
1116{
Wang Chen838361f2008-12-03 15:49:46 -08001117 isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001118 if (!skb)
1119 return;
1120 if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03001121 const int pullsize = skb_network_offset(skb) - ETH_HLEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001122 if (pullsize > 0) {
1123 printk(KERN_DEBUG "isdn_net: Pull junk %d\n", pullsize);
1124 skb_pull(skb, pullsize);
1125 }
1126 }
1127}
1128
1129
Adrian Bunk3e206b02005-06-25 14:58:35 -07001130static void isdn_net_tx_timeout(struct net_device * ndev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001131{
Wang Chen838361f2008-12-03 15:49:46 -08001132 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133
1134 printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
1135 if (!lp->dialstate){
1136 lp->stats.tx_errors++;
1137 /*
1138 * There is a certain probability that this currently
1139 * works at all because if we always wake up the interface,
1140 * then upper layer will try to send the next packet
1141 * immediately. And then, the old clean_up logic in the
1142 * driver will hopefully continue to work as it used to do.
1143 *
1144 * This is rather primitive right know, we better should
1145 * clean internal queues here, in particular for multilink and
1146 * ppp, and reset HL driver's channel, too. --HE
1147 *
1148 * actually, this may not matter at all, because ISDN hardware
1149 * should not see transmitter hangs at all IMO
1150 * changed KERN_DEBUG to KERN_WARNING to find out if this is
1151 * ever called --KG
1152 */
1153 }
1154 ndev->trans_start = jiffies;
1155 netif_wake_queue(ndev);
1156}
1157
1158/*
1159 * Try sending a packet.
1160 * If this interface isn't connected to a ISDN-Channel, find a free channel,
1161 * and start dialing.
1162 */
1163static int
1164isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1165{
Wang Chen838361f2008-12-03 15:49:46 -08001166 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001167#ifdef CONFIG_ISDN_X25
1168 struct concap_proto * cprot = lp -> netdev -> cprot;
1169/* At this point hard_start_xmit() passes control to the encapsulation
1170 protocol (if present).
1171 For X.25 auto-dialing is completly bypassed because:
1172 - It does not conform with the semantics of a reliable datalink
1173 service as needed by X.25 PLP.
1174 - I don't want that the interface starts dialing when the network layer
1175 sends a message which requests to disconnect the lapb link (or if it
1176 sends any other message not resulting in data transmission).
1177 Instead, dialing will be initiated by the encapsulation protocol entity
1178 when a dl_establish request is received from the upper layer.
1179*/
1180 if (cprot && cprot -> pops) {
1181 int ret = cprot -> pops -> encap_and_xmit ( cprot , skb);
1182
1183 if (ret)
1184 netif_stop_queue(ndev);
1185 return ret;
1186 } else
1187#endif
1188 /* auto-dialing xmit function */
1189 {
1190#ifdef ISDN_DEBUG_NET_DUMP
1191 u_char *buf;
1192#endif
1193 isdn_net_adjust_hdr(skb, ndev);
1194#ifdef ISDN_DEBUG_NET_DUMP
1195 buf = skb->data;
1196 isdn_dumppkt("S:", buf, skb->len, 40);
1197#endif
1198
1199 if (!(lp->flags & ISDN_NET_CONNECTED)) {
1200 int chi;
1201 /* only do autodial if allowed by config */
1202 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
1203 isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
1204 dev_kfree_skb(skb);
1205 return 0;
1206 }
1207 if (lp->phone[1]) {
1208 ulong flags;
1209
1210 if(lp->dialwait_timer <= 0)
1211 if(lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
1212 lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
1213
1214 if(lp->dialwait_timer > 0) {
1215 if(time_before(jiffies, lp->dialwait_timer)) {
1216 isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
1217 dev_kfree_skb(skb);
1218 return 0;
1219 } else
1220 lp->dialwait_timer = 0;
1221 }
1222 /* Grab a free ISDN-Channel */
1223 spin_lock_irqsave(&dev->lock, flags);
1224 if (((chi =
1225 isdn_get_free_channel(
1226 ISDN_USAGE_NET,
1227 lp->l2_proto,
1228 lp->l3_proto,
1229 lp->pre_device,
1230 lp->pre_channel,
1231 lp->msn)
1232 ) < 0) &&
1233 ((chi =
1234 isdn_get_free_channel(
1235 ISDN_USAGE_NET,
1236 lp->l2_proto,
1237 lp->l3_proto,
1238 lp->pre_device,
1239 lp->pre_channel^1,
1240 lp->msn)
1241 ) < 0)) {
1242 spin_unlock_irqrestore(&dev->lock, flags);
1243 isdn_net_unreachable(ndev, skb,
1244 "No channel");
1245 dev_kfree_skb(skb);
1246 return 0;
1247 }
1248 /* Log packet, which triggered dialing */
1249 if (dev->net_verbose)
1250 isdn_net_log_skb(skb, lp);
1251 lp->dialstate = 1;
1252 /* Connect interface with channel */
1253 isdn_net_bind_channel(lp, chi);
1254#ifdef CONFIG_ISDN_PPP
1255 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1256 /* no 'first_skb' handling for syncPPP */
1257 if (isdn_ppp_bind(lp) < 0) {
1258 dev_kfree_skb(skb);
1259 isdn_net_unbind_channel(lp);
1260 spin_unlock_irqrestore(&dev->lock, flags);
1261 return 0; /* STN (skb to nirvana) ;) */
1262 }
1263#ifdef CONFIG_IPPP_FILTER
1264 if (isdn_ppp_autodial_filter(skb, lp)) {
1265 isdn_ppp_free(lp);
1266 isdn_net_unbind_channel(lp);
1267 spin_unlock_irqrestore(&dev->lock, flags);
1268 isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
1269 dev_kfree_skb(skb);
1270 return 0;
1271 }
1272#endif
1273 spin_unlock_irqrestore(&dev->lock, flags);
1274 isdn_net_dial(); /* Initiate dialing */
1275 netif_stop_queue(ndev);
1276 return 1; /* let upper layer requeue skb packet */
1277 }
1278#endif
1279 /* Initiate dialing */
1280 spin_unlock_irqrestore(&dev->lock, flags);
1281 isdn_net_dial();
1282 isdn_net_device_stop_queue(lp);
1283 return 1;
1284 } else {
1285 isdn_net_unreachable(ndev, skb,
1286 "No phone number");
1287 dev_kfree_skb(skb);
1288 return 0;
1289 }
1290 } else {
1291 /* Device is connected to an ISDN channel */
1292 ndev->trans_start = jiffies;
1293 if (!lp->dialstate) {
1294 /* ISDN connection is established, try sending */
1295 int ret;
1296 ret = (isdn_net_xmit(ndev, skb));
1297 if(ret) netif_stop_queue(ndev);
1298 return ret;
1299 } else
1300 netif_stop_queue(ndev);
1301 }
1302 }
1303 return 1;
1304}
1305
1306/*
1307 * Shutdown a net-interface.
1308 */
1309static int
1310isdn_net_close(struct net_device *dev)
1311{
1312 struct net_device *p;
1313#ifdef CONFIG_ISDN_X25
1314 struct concap_proto * cprot =
Wang Chen838361f2008-12-03 15:49:46 -08001315 ((isdn_net_local *) netdev_priv(dev))->netdev->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001316 /* printk(KERN_DEBUG "isdn_net_close %s\n" , dev-> name ); */
1317#endif
1318
1319#ifdef CONFIG_ISDN_X25
1320 if( cprot && cprot -> pops ) cprot -> pops -> close( cprot );
1321#endif
1322 netif_stop_queue(dev);
Wang Chen838361f2008-12-03 15:49:46 -08001323 p = MASTER_TO_SLAVE(dev);
1324 if (p) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001325 /* If this interface has slaves, stop them also */
1326 while (p) {
1327#ifdef CONFIG_ISDN_X25
Wang Chen838361f2008-12-03 15:49:46 -08001328 cprot = ((isdn_net_local *) netdev_priv(p))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001329 -> netdev -> cprot;
1330 if( cprot && cprot -> pops )
1331 cprot -> pops -> close( cprot );
1332#endif
1333 isdn_net_hangup(p);
Wang Chen838361f2008-12-03 15:49:46 -08001334 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001335 }
1336 }
1337 isdn_net_hangup(dev);
1338 isdn_unlock_drivers();
1339 return 0;
1340}
1341
1342/*
1343 * Get statistics
1344 */
1345static struct net_device_stats *
1346isdn_net_get_stats(struct net_device *dev)
1347{
Wang Chen838361f2008-12-03 15:49:46 -08001348 isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349 return &lp->stats;
1350}
1351
1352/* This is simply a copy from std. eth.c EXCEPT we pull ETH_HLEN
1353 * instead of dev->hard_header_len off. This is done because the
1354 * lowlevel-driver has already pulled off its stuff when we get
1355 * here and this routine only gets called with p_encap == ETHER.
1356 * Determine the packet's protocol ID. The rule here is that we
1357 * assume 802.3 if the type field is short enough to be a length.
1358 * This is normal practice and works for any 'now in use' protocol.
1359 */
1360
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001361static __be16
Linus Torvalds1da177e2005-04-16 15:20:36 -07001362isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev)
1363{
1364 struct ethhdr *eth;
1365 unsigned char *rawp;
1366
Arnaldo Carvalho de Melo459a98e2007-03-19 15:30:44 -07001367 skb_reset_mac_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368 skb_pull(skb, ETH_HLEN);
1369 eth = eth_hdr(skb);
1370
1371 if (*eth->h_dest & 1) {
1372 if (memcmp(eth->h_dest, dev->broadcast, ETH_ALEN) == 0)
1373 skb->pkt_type = PACKET_BROADCAST;
1374 else
1375 skb->pkt_type = PACKET_MULTICAST;
1376 }
1377 /*
1378 * This ALLMULTI check should be redundant by 1.4
1379 * so don't forget to remove it.
1380 */
1381
1382 else if (dev->flags & (IFF_PROMISC /*| IFF_ALLMULTI*/)) {
1383 if (memcmp(eth->h_dest, dev->dev_addr, ETH_ALEN))
1384 skb->pkt_type = PACKET_OTHERHOST;
1385 }
1386 if (ntohs(eth->h_proto) >= 1536)
1387 return eth->h_proto;
1388
1389 rawp = skb->data;
1390
1391 /*
1392 * This is a magic hack to spot IPX packets. Older Novell breaks
1393 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
1394 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
1395 * won't work for fault tolerant netware but does for the rest.
1396 */
1397 if (*(unsigned short *) rawp == 0xFFFF)
1398 return htons(ETH_P_802_3);
1399 /*
1400 * Real 802.2 LLC
1401 */
1402 return htons(ETH_P_802_2);
1403}
1404
1405
1406/*
1407 * CISCO HDLC keepalive specific stuff
1408 */
1409static struct sk_buff*
1410isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
1411{
1412 unsigned short hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
1413 struct sk_buff *skb;
1414
1415 skb = alloc_skb(hl + len, GFP_ATOMIC);
1416 if (skb)
1417 skb_reserve(skb, hl);
1418 else
1419 printk("isdn out of mem at %s:%d!\n", __FILE__, __LINE__);
1420 return skb;
1421}
1422
1423/* cisco hdlck device private ioctls */
Adrian Bunk3e206b02005-06-25 14:58:35 -07001424static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001425isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1426{
Wang Chen838361f2008-12-03 15:49:46 -08001427 isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001428 unsigned long len = 0;
1429 unsigned long expires = 0;
1430 int tmp = 0;
1431 int period = lp->cisco_keepalive_period;
1432 s8 debserint = lp->cisco_debserint;
1433 int rc = 0;
1434
1435 if (lp->p_encap != ISDN_NET_ENCAP_CISCOHDLCK)
1436 return -EINVAL;
1437
1438 switch (cmd) {
1439 /* get/set keepalive period */
1440 case SIOCGKEEPPERIOD:
1441 len = (unsigned long)sizeof(lp->cisco_keepalive_period);
1442 if (copy_to_user(ifr->ifr_data,
1443 &lp->cisco_keepalive_period, len))
1444 rc = -EFAULT;
1445 break;
1446 case SIOCSKEEPPERIOD:
1447 tmp = lp->cisco_keepalive_period;
1448 len = (unsigned long)sizeof(lp->cisco_keepalive_period);
1449 if (copy_from_user(&period, ifr->ifr_data, len))
1450 rc = -EFAULT;
1451 if ((period > 0) && (period <= 32767))
1452 lp->cisco_keepalive_period = period;
1453 else
1454 rc = -EINVAL;
1455 if (!rc && (tmp != lp->cisco_keepalive_period)) {
1456 expires = (unsigned long)(jiffies +
1457 lp->cisco_keepalive_period * HZ);
1458 mod_timer(&lp->cisco_timer, expires);
1459 printk(KERN_INFO "%s: Keepalive period set "
1460 "to %d seconds.\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001461 dev->name, lp->cisco_keepalive_period);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001462 }
1463 break;
1464
1465 /* get/set debugging */
1466 case SIOCGDEBSERINT:
1467 len = (unsigned long)sizeof(lp->cisco_debserint);
1468 if (copy_to_user(ifr->ifr_data,
1469 &lp->cisco_debserint, len))
1470 rc = -EFAULT;
1471 break;
1472 case SIOCSDEBSERINT:
1473 len = (unsigned long)sizeof(lp->cisco_debserint);
1474 if (copy_from_user(&debserint,
1475 ifr->ifr_data, len))
1476 rc = -EFAULT;
1477 if ((debserint >= 0) && (debserint <= 64))
1478 lp->cisco_debserint = debserint;
1479 else
1480 rc = -EINVAL;
1481 break;
1482
1483 default:
1484 rc = -EINVAL;
1485 break;
1486 }
1487 return (rc);
1488}
1489
Stephen Hemmingerd7005552009-01-07 18:04:17 -08001490
1491static int isdn_net_ioctl(struct net_device *dev,
1492 struct ifreq *ifr, int cmd)
1493{
1494 isdn_net_local *lp = (isdn_net_local *) netdev_priv(dev);
1495
1496 switch (lp->p_encap) {
1497#ifdef CONFIG_ISDN_PPP
1498 case ISDN_NET_ENCAP_SYNCPPP:
1499 return isdn_ppp_dev_ioctl(dev, ifr, cmd);
1500#endif
1501 case ISDN_NET_ENCAP_CISCOHDLCK:
1502 return isdn_ciscohdlck_dev_ioctl(dev, ifr, cmd);
1503 default:
1504 return -EINVAL;
1505 }
1506}
1507
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508/* called via cisco_timer.function */
1509static void
1510isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
1511{
1512 isdn_net_local *lp = (isdn_net_local *) data;
1513 struct sk_buff *skb;
1514 unsigned char *p;
1515 unsigned long last_cisco_myseq = lp->cisco_myseq;
1516 int myseq_diff = 0;
1517
1518 if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate) {
1519 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1520 return;
1521 }
1522 lp->cisco_myseq++;
1523
1524 myseq_diff = (lp->cisco_myseq - lp->cisco_mineseen);
1525 if ((lp->cisco_line_state) && ((myseq_diff >= 3)||(myseq_diff <= -3))) {
1526 /* line up -> down */
1527 lp->cisco_line_state = 0;
1528 printk (KERN_WARNING
1529 "UPDOWN: Line protocol on Interface %s,"
Karsten Keilfaca94f2007-10-15 02:11:44 -07001530 " changed state to down\n", lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531 /* should stop routing higher-level data accross */
1532 } else if ((!lp->cisco_line_state) &&
1533 (myseq_diff >= 0) && (myseq_diff <= 2)) {
1534 /* line down -> up */
1535 lp->cisco_line_state = 1;
1536 printk (KERN_WARNING
1537 "UPDOWN: Line protocol on Interface %s,"
Karsten Keilfaca94f2007-10-15 02:11:44 -07001538 " changed state to up\n", lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001539 /* restart routing higher-level data accross */
1540 }
1541
1542 if (lp->cisco_debserint)
1543 printk (KERN_DEBUG "%s: HDLC "
1544 "myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001545 lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 ((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
1547 lp->cisco_yourseq,
1548 ((lp->cisco_line_state) ? "line up" : "line down"));
1549
1550 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1551 if (!skb)
1552 return;
1553
1554 p = skb_put(skb, 4 + 14);
1555
1556 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001557 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1558 *(u8 *)(p + 1) = CISCO_CTRL;
1559 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560
1561 /* slarp keepalive */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001562 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
1563 *(__be32 *)(p + 8) = cpu_to_be32(lp->cisco_myseq);
1564 *(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
1565 *(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliablity, always 0xffff
1566 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567
1568 isdn_net_write_super(lp, skb);
1569
1570 lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
1571
1572 add_timer(&lp->cisco_timer);
1573}
1574
1575static void
1576isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
1577{
1578 struct sk_buff *skb;
1579 unsigned char *p;
1580
1581 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1582 if (!skb)
1583 return;
1584
1585 p = skb_put(skb, 4 + 14);
1586
1587 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001588 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1589 *(u8 *)(p + 1) = CISCO_CTRL;
1590 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001591
1592 /* slarp request */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001593 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_REQUEST);
1594 *(__be32 *)(p + 8) = cpu_to_be32(0); // address
1595 *(__be32 *)(p + 12) = cpu_to_be32(0); // netmask
1596 *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
1597 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001598
1599 isdn_net_write_super(lp, skb);
1600}
1601
1602static void
1603isdn_net_ciscohdlck_connected(isdn_net_local *lp)
1604{
1605 lp->cisco_myseq = 0;
1606 lp->cisco_mineseen = 0;
1607 lp->cisco_yourseq = 0;
1608 lp->cisco_keepalive_period = ISDN_TIMER_KEEPINT;
1609 lp->cisco_last_slarp_in = 0;
1610 lp->cisco_line_state = 0;
1611 lp->cisco_debserint = 0;
1612
1613 /* send slarp request because interface/seq.no.s reset */
1614 isdn_net_ciscohdlck_slarp_send_request(lp);
1615
1616 init_timer(&lp->cisco_timer);
1617 lp->cisco_timer.data = (unsigned long) lp;
1618 lp->cisco_timer.function = isdn_net_ciscohdlck_slarp_send_keepalive;
1619 lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
1620 add_timer(&lp->cisco_timer);
1621}
1622
1623static void
1624isdn_net_ciscohdlck_disconnected(isdn_net_local *lp)
1625{
1626 del_timer(&lp->cisco_timer);
1627}
1628
1629static void
1630isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
1631{
1632 struct sk_buff *skb;
1633 unsigned char *p;
1634 struct in_device *in_dev = NULL;
Al Viroa144ea42006-09-28 18:00:55 -07001635 __be32 addr = 0; /* local ipv4 address */
1636 __be32 mask = 0; /* local netmask */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001637
Karsten Keild62a38d2007-10-08 20:37:11 -07001638 if ((in_dev = lp->netdev->dev->ip_ptr) != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639 /* take primary(first) address of interface */
1640 struct in_ifaddr *ifa = in_dev->ifa_list;
1641 if (ifa != NULL) {
1642 addr = ifa->ifa_local;
1643 mask = ifa->ifa_mask;
1644 }
1645 }
1646
1647 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1648 if (!skb)
1649 return;
1650
1651 p = skb_put(skb, 4 + 14);
1652
1653 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001654 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1655 *(u8 *)(p + 1) = CISCO_CTRL;
1656 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001657
1658 /* slarp reply, send own ip/netmask; if values are nonsense remote
1659 * should think we are unable to provide it with an address via SLARP */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001660 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_REPLY);
David S. Miller198d6ba2008-11-18 23:38:23 -08001661 *(__be32 *)(p + 8) = addr; // address
1662 *(__be32 *)(p + 12) = mask; // netmask
Harvey Harrison00bcd522008-11-13 22:41:29 -08001663 *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
1664 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665
1666 isdn_net_write_super(lp, skb);
1667}
1668
1669static void
1670isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
1671{
1672 unsigned char *p;
1673 int period;
1674 u32 code;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001675 u32 my_seq;
1676 u32 your_seq;
1677 __be32 local;
1678 __be32 *addr, *mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001679 u16 unused;
1680
1681 if (skb->len < 14)
1682 return;
1683
1684 p = skb->data;
Harvey Harrison00bcd522008-11-13 22:41:29 -08001685 code = be32_to_cpup((__be32 *)p);
1686 p += 4;
1687
Linus Torvalds1da177e2005-04-16 15:20:36 -07001688 switch (code) {
1689 case CISCO_SLARP_REQUEST:
1690 lp->cisco_yourseq = 0;
1691 isdn_net_ciscohdlck_slarp_send_reply(lp);
1692 break;
1693 case CISCO_SLARP_REPLY:
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001694 addr = (__be32 *)p;
1695 mask = (__be32 *)(p + 4);
1696 if (*mask != cpu_to_be32(0xfffffffc))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001697 goto slarp_reply_out;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001698 if ((*addr & cpu_to_be32(3)) == cpu_to_be32(0) ||
1699 (*addr & cpu_to_be32(3)) == cpu_to_be32(3))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001700 goto slarp_reply_out;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001701 local = *addr ^ cpu_to_be32(3);
1702 printk(KERN_INFO "%s: got slarp reply: remote ip: %pI4, local ip: %pI4 mask: %pI4\n",
1703 lp->netdev->dev->name, addr, &local, mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001704 break;
1705 slarp_reply_out:
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001706 printk(KERN_INFO "%s: got invalid slarp reply (%pI4/%pI4) - ignored\n",
1707 lp->netdev->dev->name, addr, mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001708 break;
1709 case CISCO_SLARP_KEEPALIVE:
1710 period = (int)((jiffies - lp->cisco_last_slarp_in
1711 + HZ/2 - 1) / HZ);
1712 if (lp->cisco_debserint &&
1713 (period != lp->cisco_keepalive_period) &&
1714 lp->cisco_last_slarp_in) {
1715 printk(KERN_DEBUG "%s: Keepalive period mismatch - "
1716 "is %d but should be %d.\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001717 lp->netdev->dev->name, period,
1718 lp->cisco_keepalive_period);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001719 }
1720 lp->cisco_last_slarp_in = jiffies;
Harvey Harrison00bcd522008-11-13 22:41:29 -08001721 my_seq = be32_to_cpup((__be32 *)(p + 0));
1722 your_seq = be32_to_cpup((__be32 *)(p + 4));
1723 unused = be16_to_cpup((__be16 *)(p + 8));
1724 p += 10;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001725 lp->cisco_yourseq = my_seq;
1726 lp->cisco_mineseen = your_seq;
1727 break;
1728 }
1729}
1730
1731static void
1732isdn_net_ciscohdlck_receive(isdn_net_local *lp, struct sk_buff *skb)
1733{
1734 unsigned char *p;
1735 u8 addr;
1736 u8 ctrl;
1737 u16 type;
1738
1739 if (skb->len < 4)
1740 goto out_free;
1741
1742 p = skb->data;
Harvey Harrison00bcd522008-11-13 22:41:29 -08001743 addr = *(u8 *)(p + 0);
1744 ctrl = *(u8 *)(p + 1);
1745 type = be16_to_cpup((__be16 *)(p + 2));
1746 p += 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001747 skb_pull(skb, 4);
1748
1749 if (addr != CISCO_ADDR_UNICAST && addr != CISCO_ADDR_BROADCAST) {
1750 printk(KERN_WARNING "%s: Unknown Cisco addr 0x%02x\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001751 lp->netdev->dev->name, addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001752 goto out_free;
1753 }
1754 if (ctrl != CISCO_CTRL) {
1755 printk(KERN_WARNING "%s: Unknown Cisco ctrl 0x%02x\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001756 lp->netdev->dev->name, ctrl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001757 goto out_free;
1758 }
1759
1760 switch (type) {
1761 case CISCO_TYPE_SLARP:
1762 isdn_net_ciscohdlck_slarp_in(lp, skb);
1763 goto out_free;
1764 case CISCO_TYPE_CDP:
1765 if (lp->cisco_debserint)
1766 printk(KERN_DEBUG "%s: Received CDP packet. use "
Karsten Keilfaca94f2007-10-15 02:11:44 -07001767 "\"no cdp enable\" on cisco.\n",
1768 lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001769 goto out_free;
1770 default:
1771 /* no special cisco protocol */
1772 skb->protocol = htons(type);
1773 netif_rx(skb);
1774 return;
1775 }
1776
1777 out_free:
1778 kfree_skb(skb);
1779}
1780
1781/*
1782 * Got a packet from ISDN-Channel.
1783 */
1784static void
1785isdn_net_receive(struct net_device *ndev, struct sk_buff *skb)
1786{
Wang Chen838361f2008-12-03 15:49:46 -08001787 isdn_net_local *lp = (isdn_net_local *) netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 isdn_net_local *olp = lp; /* original 'lp' */
1789#ifdef CONFIG_ISDN_X25
1790 struct concap_proto *cprot = lp -> netdev -> cprot;
1791#endif
1792 lp->transcount += skb->len;
1793
1794 lp->stats.rx_packets++;
1795 lp->stats.rx_bytes += skb->len;
1796 if (lp->master) {
1797 /* Bundling: If device is a slave-device, deliver to master, also
1798 * handle master's statistics and hangup-timeout
1799 */
1800 ndev = lp->master;
Wang Chen838361f2008-12-03 15:49:46 -08001801 lp = (isdn_net_local *) netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001802 lp->stats.rx_packets++;
1803 lp->stats.rx_bytes += skb->len;
1804 }
1805 skb->dev = ndev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001806 skb->pkt_type = PACKET_HOST;
Arnaldo Carvalho de Melo459a98e2007-03-19 15:30:44 -07001807 skb_reset_mac_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001808#ifdef ISDN_DEBUG_NET_DUMP
1809 isdn_dumppkt("R:", skb->data, skb->len, 40);
1810#endif
1811 switch (lp->p_encap) {
1812 case ISDN_NET_ENCAP_ETHER:
1813 /* Ethernet over ISDN */
1814 olp->huptimer = 0;
1815 lp->huptimer = 0;
1816 skb->protocol = isdn_net_type_trans(skb, ndev);
1817 break;
1818 case ISDN_NET_ENCAP_UIHDLC:
1819 /* HDLC with UI-frame (for ispa with -h1 option) */
1820 olp->huptimer = 0;
1821 lp->huptimer = 0;
1822 skb_pull(skb, 2);
1823 /* Fall through */
1824 case ISDN_NET_ENCAP_RAWIP:
1825 /* RAW-IP without MAC-Header */
1826 olp->huptimer = 0;
1827 lp->huptimer = 0;
1828 skb->protocol = htons(ETH_P_IP);
1829 break;
1830 case ISDN_NET_ENCAP_CISCOHDLCK:
1831 isdn_net_ciscohdlck_receive(lp, skb);
1832 return;
1833 case ISDN_NET_ENCAP_CISCOHDLC:
1834 /* CISCO-HDLC IP with type field and fake I-frame-header */
1835 skb_pull(skb, 2);
1836 /* Fall through */
1837 case ISDN_NET_ENCAP_IPTYP:
1838 /* IP with type field */
1839 olp->huptimer = 0;
1840 lp->huptimer = 0;
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001841 skb->protocol = *(__be16 *)&(skb->data[0]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001842 skb_pull(skb, 2);
1843 if (*(unsigned short *) skb->data == 0xFFFF)
1844 skb->protocol = htons(ETH_P_802_3);
1845 break;
1846#ifdef CONFIG_ISDN_PPP
1847 case ISDN_NET_ENCAP_SYNCPPP:
1848 /* huptimer is done in isdn_ppp_push_higher */
1849 isdn_ppp_receive(lp->netdev, olp, skb);
1850 return;
1851#endif
1852
1853 default:
1854#ifdef CONFIG_ISDN_X25
1855 /* try if there are generic sync_device receiver routines */
1856 if(cprot) if(cprot -> pops)
1857 if( cprot -> pops -> data_ind){
1858 cprot -> pops -> data_ind(cprot,skb);
1859 return;
1860 };
1861#endif /* CONFIG_ISDN_X25 */
1862 printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07001863 lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001864 kfree_skb(skb);
1865 return;
1866 }
1867
1868 netif_rx(skb);
1869 return;
1870}
1871
1872/*
1873 * A packet arrived via ISDN. Search interface-chain for a corresponding
1874 * interface. If found, deliver packet to receiver-function and return 1,
1875 * else return 0.
1876 */
1877int
1878isdn_net_rcv_skb(int idx, struct sk_buff *skb)
1879{
1880 isdn_net_dev *p = dev->rx_netdev[idx];
1881
1882 if (p) {
1883 isdn_net_local *lp = p->local;
1884 if ((lp->flags & ISDN_NET_CONNECTED) &&
1885 (!lp->dialstate)) {
Karsten Keild62a38d2007-10-08 20:37:11 -07001886 isdn_net_receive(p->dev, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001887 return 1;
1888 }
1889 }
1890 return 0;
1891}
1892
Linus Torvalds1da177e2005-04-16 15:20:36 -07001893/*
1894 * build an header
1895 * depends on encaps that is being used.
1896 */
1897
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001898static int isdn_net_header(struct sk_buff *skb, struct net_device *dev,
1899 unsigned short type,
1900 const void *daddr, const void *saddr, unsigned plen)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001901{
Wang Chen838361f2008-12-03 15:49:46 -08001902 isdn_net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 unsigned char *p;
1904 ushort len = 0;
1905
1906 switch (lp->p_encap) {
1907 case ISDN_NET_ENCAP_ETHER:
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001908 len = eth_header(skb, dev, type, daddr, saddr, plen);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001909 break;
1910#ifdef CONFIG_ISDN_PPP
1911 case ISDN_NET_ENCAP_SYNCPPP:
1912 /* stick on a fake header to keep fragmentation code happy. */
1913 len = IPPP_MAX_HEADER;
1914 skb_push(skb,len);
1915 break;
1916#endif
1917 case ISDN_NET_ENCAP_RAWIP:
1918 printk(KERN_WARNING "isdn_net_header called with RAW_IP!\n");
1919 len = 0;
1920 break;
1921 case ISDN_NET_ENCAP_IPTYP:
1922 /* ethernet type field */
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001923 *((__be16 *)skb_push(skb, 2)) = htons(type);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924 len = 2;
1925 break;
1926 case ISDN_NET_ENCAP_UIHDLC:
1927 /* HDLC with UI-Frames (for ispa with -h1 option) */
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001928 *((__be16 *)skb_push(skb, 2)) = htons(0x0103);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929 len = 2;
1930 break;
1931 case ISDN_NET_ENCAP_CISCOHDLC:
1932 case ISDN_NET_ENCAP_CISCOHDLCK:
1933 p = skb_push(skb, 4);
Harvey Harrison00bcd522008-11-13 22:41:29 -08001934 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1935 *(u8 *)(p + 1) = CISCO_CTRL;
1936 *(__be16 *)(p + 2) = cpu_to_be16(type);
1937 p += 4;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001938 len = 4;
1939 break;
1940#ifdef CONFIG_ISDN_X25
1941 default:
1942 /* try if there are generic concap protocol routines */
1943 if( lp-> netdev -> cprot ){
1944 printk(KERN_WARNING "isdn_net_header called with concap_proto!\n");
1945 len = 0;
1946 break;
1947 }
1948 break;
1949#endif /* CONFIG_ISDN_X25 */
1950 }
1951 return len;
1952}
1953
1954/* We don't need to send arp, because we have point-to-point connections. */
1955static int
1956isdn_net_rebuild_header(struct sk_buff *skb)
1957{
1958 struct net_device *dev = skb->dev;
Wang Chen838361f2008-12-03 15:49:46 -08001959 isdn_net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960 int ret = 0;
1961
1962 if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
1963 struct ethhdr *eth = (struct ethhdr *) skb->data;
1964
1965 /*
1966 * Only ARP/IP is currently supported
1967 */
1968
1969 if (eth->h_proto != htons(ETH_P_IP)) {
1970 printk(KERN_WARNING
1971 "isdn_net: %s don't know how to resolve type %d addresses?\n",
1972 dev->name, (int) eth->h_proto);
1973 memcpy(eth->h_source, dev->dev_addr, dev->addr_len);
1974 return 0;
1975 }
1976 /*
1977 * Try to get ARP to resolve the header.
1978 */
1979#ifdef CONFIG_INET
1980 ret = arp_find(eth->h_dest, skb);
1981#endif
1982 }
1983 return ret;
1984}
1985
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001986static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh)
1987{
1988 const struct net_device *dev = neigh->dev;
Wang Chen838361f2008-12-03 15:49:46 -08001989 isdn_net_local *lp = netdev_priv(dev);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001990
1991 if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
1992 return eth_header_cache(neigh, hh);
1993 return -1;
1994}
1995
1996static void isdn_header_cache_update(struct hh_cache *hh,
1997 const struct net_device *dev,
1998 const unsigned char *haddr)
1999{
Wang Chen838361f2008-12-03 15:49:46 -08002000 isdn_net_local *lp = netdev_priv(dev);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002001 if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
Harvey Harrisonc19d0362008-11-20 04:10:51 -08002002 eth_header_cache_update(hh, dev, haddr);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002003}
2004
2005static const struct header_ops isdn_header_ops = {
2006 .create = isdn_net_header,
2007 .rebuild = isdn_net_rebuild_header,
2008 .cache = isdn_header_cache,
2009 .cache_update = isdn_header_cache_update,
2010};
2011
Linus Torvalds1da177e2005-04-16 15:20:36 -07002012/*
2013 * Interface-setup. (just after registering a new interface)
2014 */
2015static int
2016isdn_net_init(struct net_device *ndev)
2017{
2018 ushort max_hlhdr_len = 0;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002019 int drvidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002020
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 /*
2022 * up till binding we ask the protocol layer to reserve as much
2023 * as we might need for HL layer
2024 */
2025
2026 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
2027 if (dev->drv[drvidx])
2028 if (max_hlhdr_len < dev->drv[drvidx]->interface->hl_hdrlen)
2029 max_hlhdr_len = dev->drv[drvidx]->interface->hl_hdrlen;
2030
2031 ndev->hard_header_len = ETH_HLEN + max_hlhdr_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002032 return 0;
2033}
2034
2035static void
2036isdn_net_swapbind(int drvidx)
2037{
2038 isdn_net_dev *p;
2039
2040#ifdef ISDN_DEBUG_NET_ICALL
2041 printk(KERN_DEBUG "n_fi: swapping ch of %d\n", drvidx);
2042#endif
2043 p = dev->netdev;
2044 while (p) {
2045 if (p->local->pre_device == drvidx)
2046 switch (p->local->pre_channel) {
2047 case 0:
2048 p->local->pre_channel = 1;
2049 break;
2050 case 1:
2051 p->local->pre_channel = 0;
2052 break;
2053 }
2054 p = (isdn_net_dev *) p->next;
2055 }
2056}
2057
2058static void
2059isdn_net_swap_usage(int i1, int i2)
2060{
2061 int u1 = dev->usage[i1] & ISDN_USAGE_EXCLUSIVE;
2062 int u2 = dev->usage[i2] & ISDN_USAGE_EXCLUSIVE;
2063
2064#ifdef ISDN_DEBUG_NET_ICALL
2065 printk(KERN_DEBUG "n_fi: usage of %d and %d\n", i1, i2);
2066#endif
2067 dev->usage[i1] &= ~ISDN_USAGE_EXCLUSIVE;
2068 dev->usage[i1] |= u2;
2069 dev->usage[i2] &= ~ISDN_USAGE_EXCLUSIVE;
2070 dev->usage[i2] |= u1;
2071 isdn_info_update();
2072}
2073
2074/*
2075 * An incoming call-request has arrived.
2076 * Search the interface-chain for an appropriate interface.
2077 * If found, connect the interface to the ISDN-channel and initiate
2078 * D- and B-Channel-setup. If secure-flag is set, accept only
2079 * configured phone-numbers. If callback-flag is set, initiate
2080 * callback-dialing.
2081 *
2082 * Return-Value: 0 = No appropriate interface for this call.
2083 * 1 = Call accepted
2084 * 2 = Reject call, wait cbdelay, then call back
2085 * 3 = Reject call
2086 * 4 = Wait cbdelay, then call back
2087 * 5 = No appropriate interface for this call,
2088 * would eventually match if CID was longer.
2089 */
2090
2091int
2092isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
2093{
2094 char *eaz;
2095 int si1;
2096 int si2;
2097 int ematch;
2098 int wret;
2099 int swapped;
2100 int sidx = 0;
2101 u_long flags;
2102 isdn_net_dev *p;
2103 isdn_net_phone *n;
Karsten Keil0f138642007-11-22 12:43:13 +01002104 char nr[ISDN_MSNLEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105 char *my_eaz;
2106
2107 /* Search name in netdev-chain */
2108 if (!setup->phone[0]) {
2109 nr[0] = '0';
2110 nr[1] = '\0';
2111 printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
2112 } else
Karsten Keil0f138642007-11-22 12:43:13 +01002113 strlcpy(nr, setup->phone, ISDN_MSNLEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002114 si1 = (int) setup->si1;
2115 si2 = (int) setup->si2;
2116 if (!setup->eazmsn[0]) {
2117 printk(KERN_WARNING "isdn_net: Incoming call without CPN, assuming '0'\n");
2118 eaz = "0";
2119 } else
2120 eaz = setup->eazmsn;
2121 if (dev->net_verbose > 1)
2122 printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
2123 /* Accept DATA and VOICE calls at this stage
2124 * local eaz is checked later for allowed call types
2125 */
2126 if ((si1 != 7) && (si1 != 1)) {
2127 if (dev->net_verbose > 1)
2128 printk(KERN_INFO "isdn_net: Service-Indicator not 1 or 7, ignored\n");
2129 return 0;
2130 }
2131 n = (isdn_net_phone *) 0;
2132 p = dev->netdev;
2133 ematch = wret = swapped = 0;
2134#ifdef ISDN_DEBUG_NET_ICALL
2135 printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
2136 dev->usage[idx]);
2137#endif
2138 while (p) {
2139 int matchret;
2140 isdn_net_local *lp = p->local;
2141
2142 /* If last check has triggered as binding-swap, revert it */
2143 switch (swapped) {
2144 case 2:
2145 isdn_net_swap_usage(idx, sidx);
2146 /* fall through */
2147 case 1:
2148 isdn_net_swapbind(di);
2149 break;
2150 }
2151 swapped = 0;
2152 /* check acceptable call types for DOV */
2153 my_eaz = isdn_map_eaz2msn(lp->msn, di);
2154 if (si1 == 1) { /* it's a DOV call, check if we allow it */
2155 if (*my_eaz == 'v' || *my_eaz == 'V' ||
2156 *my_eaz == 'b' || *my_eaz == 'B')
2157 my_eaz++; /* skip to allow a match */
2158 else
2159 my_eaz = NULL; /* force non match */
2160 } else { /* it's a DATA call, check if we allow it */
2161 if (*my_eaz == 'b' || *my_eaz == 'B')
2162 my_eaz++; /* skip to allow a match */
2163 }
2164 if (my_eaz)
2165 matchret = isdn_msncmp(eaz, my_eaz);
2166 else
2167 matchret = 1;
2168 if (!matchret)
2169 ematch = 1;
2170
2171 /* Remember if more numbers eventually can match */
2172 if (matchret > wret)
2173 wret = matchret;
2174#ifdef ISDN_DEBUG_NET_ICALL
2175 printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002176 p->dev->name, lp->msn, lp->flags, lp->dialstate);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002177#endif
2178 if ((!matchret) && /* EAZ is matching */
2179 (((!(lp->flags & ISDN_NET_CONNECTED)) && /* but not connected */
2180 (USG_NONE(dev->usage[idx]))) || /* and ch. unused or */
2181 ((((lp->dialstate == 4) || (lp->dialstate == 12)) && /* if dialing */
2182 (!(lp->flags & ISDN_NET_CALLBACK))) /* but no callback */
2183 )))
2184 {
2185#ifdef ISDN_DEBUG_NET_ICALL
2186 printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
2187 lp->pre_device, lp->pre_channel);
2188#endif
2189 if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
2190 if ((lp->pre_channel != ch) ||
2191 (lp->pre_device != di)) {
2192 /* Here we got a problem:
2193 * If using an ICN-Card, an incoming call is always signaled on
2194 * on the first channel of the card, if both channels are
2195 * down. However this channel may be bound exclusive. If the
2196 * second channel is free, this call should be accepted.
2197 * The solution is horribly but it runs, so what:
2198 * We exchange the exclusive bindings of the two channels, the
2199 * corresponding variables in the interface-structs.
2200 */
2201 if (ch == 0) {
2202 sidx = isdn_dc2minor(di, 1);
2203#ifdef ISDN_DEBUG_NET_ICALL
2204 printk(KERN_DEBUG "n_fi: ch is 0\n");
2205#endif
2206 if (USG_NONE(dev->usage[sidx])) {
2207 /* Second Channel is free, now see if it is bound
2208 * exclusive too. */
2209 if (dev->usage[sidx] & ISDN_USAGE_EXCLUSIVE) {
2210#ifdef ISDN_DEBUG_NET_ICALL
2211 printk(KERN_DEBUG "n_fi: 2nd channel is down and bound\n");
2212#endif
2213 /* Yes, swap bindings only, if the original
2214 * binding is bound to channel 1 of this driver */
2215 if ((lp->pre_device == di) &&
2216 (lp->pre_channel == 1)) {
2217 isdn_net_swapbind(di);
2218 swapped = 1;
2219 } else {
2220 /* ... else iterate next device */
2221 p = (isdn_net_dev *) p->next;
2222 continue;
2223 }
2224 } else {
2225#ifdef ISDN_DEBUG_NET_ICALL
2226 printk(KERN_DEBUG "n_fi: 2nd channel is down and unbound\n");
2227#endif
2228 /* No, swap always and swap excl-usage also */
2229 isdn_net_swap_usage(idx, sidx);
2230 isdn_net_swapbind(di);
2231 swapped = 2;
2232 }
2233 /* Now check for exclusive binding again */
2234#ifdef ISDN_DEBUG_NET_ICALL
2235 printk(KERN_DEBUG "n_fi: final check\n");
2236#endif
2237 if ((dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) &&
2238 ((lp->pre_channel != ch) ||
2239 (lp->pre_device != di))) {
2240#ifdef ISDN_DEBUG_NET_ICALL
2241 printk(KERN_DEBUG "n_fi: final check failed\n");
2242#endif
2243 p = (isdn_net_dev *) p->next;
2244 continue;
2245 }
2246 }
2247 } else {
2248 /* We are already on the second channel, so nothing to do */
2249#ifdef ISDN_DEBUG_NET_ICALL
2250 printk(KERN_DEBUG "n_fi: already on 2nd channel\n");
2251#endif
2252 }
2253 }
2254 }
2255#ifdef ISDN_DEBUG_NET_ICALL
2256 printk(KERN_DEBUG "n_fi: match2\n");
2257#endif
2258 n = lp->phone[0];
2259 if (lp->flags & ISDN_NET_SECURE) {
2260 while (n) {
2261 if (!isdn_msncmp(nr, n->num))
2262 break;
2263 n = (isdn_net_phone *) n->next;
2264 }
2265 }
2266 if (n || (!(lp->flags & ISDN_NET_SECURE))) {
2267#ifdef ISDN_DEBUG_NET_ICALL
2268 printk(KERN_DEBUG "n_fi: match3\n");
2269#endif
2270 /* matching interface found */
2271
2272 /*
2273 * Is the state STOPPED?
2274 * If so, no dialin is allowed,
2275 * so reject actively.
2276 * */
2277 if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
2278 printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002279 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002280 return 3;
2281 }
2282 /*
2283 * Is the interface up?
2284 * If not, reject the call actively.
2285 */
2286 if (!isdn_net_device_started(p)) {
2287 printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002288 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002289 return 3;
2290 }
2291 /* Interface is up, now see if it's a slave. If so, see if
2292 * it's master and parent slave is online. If not, reject the call.
2293 */
2294 if (lp->master) {
Wang Chen838361f2008-12-03 15:49:46 -08002295 isdn_net_local *mlp = ISDN_MASTER_PRIV(lp);
Karsten Keilfaca94f2007-10-15 02:11:44 -07002296 printk(KERN_DEBUG "ICALLslv: %s\n", p->dev->name);
2297 printk(KERN_DEBUG "master=%s\n", lp->master->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002298 if (mlp->flags & ISDN_NET_CONNECTED) {
2299 printk(KERN_DEBUG "master online\n");
2300 /* Master is online, find parent-slave (master if first slave) */
2301 while (mlp->slave) {
Wang Chen838361f2008-12-03 15:49:46 -08002302 if (ISDN_SLAVE_PRIV(mlp) == lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 break;
Wang Chen838361f2008-12-03 15:49:46 -08002304 mlp = ISDN_SLAVE_PRIV(mlp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305 }
2306 } else
2307 printk(KERN_DEBUG "master offline\n");
2308 /* Found parent, if it's offline iterate next device */
2309 printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
2310 if (!(mlp->flags & ISDN_NET_CONNECTED)) {
2311 p = (isdn_net_dev *) p->next;
2312 continue;
2313 }
2314 }
2315 if (lp->flags & ISDN_NET_CALLBACK) {
2316 int chi;
2317 /*
2318 * Is the state MANUAL?
2319 * If so, no callback can be made,
2320 * so reject actively.
2321 * */
2322 if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
2323 printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002324 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 return 3;
2326 }
2327 printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002328 p->dev->name, nr, eaz);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 if (lp->phone[1]) {
2330 /* Grab a free ISDN-Channel */
2331 spin_lock_irqsave(&dev->lock, flags);
2332 if ((chi =
2333 isdn_get_free_channel(
2334 ISDN_USAGE_NET,
2335 lp->l2_proto,
2336 lp->l3_proto,
2337 lp->pre_device,
2338 lp->pre_channel,
2339 lp->msn)
2340 ) < 0) {
2341
Karsten Keilfaca94f2007-10-15 02:11:44 -07002342 printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n",
2343 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344 spin_unlock_irqrestore(&dev->lock, flags);
2345 return 0;
2346 }
2347 /* Setup dialstate. */
2348 lp->dtimer = 0;
2349 lp->dialstate = 11;
2350 /* Connect interface with channel */
2351 isdn_net_bind_channel(lp, chi);
2352#ifdef CONFIG_ISDN_PPP
2353 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2354 if (isdn_ppp_bind(lp) < 0) {
2355 spin_unlock_irqrestore(&dev->lock, flags);
2356 isdn_net_unbind_channel(lp);
2357 return 0;
2358 }
2359#endif
2360 spin_unlock_irqrestore(&dev->lock, flags);
2361 /* Initiate dialing by returning 2 or 4 */
2362 return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
2363 } else
Karsten Keilfaca94f2007-10-15 02:11:44 -07002364 printk(KERN_WARNING "isdn_net: %s: No phone number\n",
2365 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002366 return 0;
2367 } else {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002368 printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
2369 p->dev->name, nr, eaz);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002370 /* if this interface is dialing, it does it probably on a different
2371 device, so free this device */
2372 if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
2373#ifdef CONFIG_ISDN_PPP
2374 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2375 isdn_ppp_free(lp);
2376#endif
2377 isdn_net_lp_disconnected(lp);
2378 isdn_free_channel(lp->isdn_device, lp->isdn_channel,
2379 ISDN_USAGE_NET);
2380 }
2381 spin_lock_irqsave(&dev->lock, flags);
2382 dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
2383 dev->usage[idx] |= ISDN_USAGE_NET;
2384 strcpy(dev->num[idx], nr);
2385 isdn_info_update();
2386 dev->st_netdev[idx] = lp->netdev;
2387 lp->isdn_device = di;
2388 lp->isdn_channel = ch;
2389 lp->ppp_slot = -1;
2390 lp->flags |= ISDN_NET_CONNECTED;
2391 lp->dialstate = 7;
2392 lp->dtimer = 0;
2393 lp->outgoing = 0;
2394 lp->huptimer = 0;
2395 lp->hupflags |= ISDN_WAITCHARGE;
2396 lp->hupflags &= ~ISDN_HAVECHARGE;
2397#ifdef CONFIG_ISDN_PPP
2398 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
2399 if (isdn_ppp_bind(lp) < 0) {
2400 isdn_net_unbind_channel(lp);
2401 spin_unlock_irqrestore(&dev->lock, flags);
2402 return 0;
2403 }
2404 }
2405#endif
2406 spin_unlock_irqrestore(&dev->lock, flags);
2407 return 1;
2408 }
2409 }
2410 }
2411 p = (isdn_net_dev *) p->next;
2412 }
2413 /* If none of configured EAZ/MSN matched and not verbose, be silent */
2414 if (!ematch || dev->net_verbose)
2415 printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
2416 return (wret == 2)?5:0;
2417}
2418
2419/*
2420 * Search list of net-interfaces for an interface with given name.
2421 */
2422isdn_net_dev *
2423isdn_net_findif(char *name)
2424{
2425 isdn_net_dev *p = dev->netdev;
2426
2427 while (p) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002428 if (!strcmp(p->dev->name, name))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002429 return p;
2430 p = (isdn_net_dev *) p->next;
2431 }
2432 return (isdn_net_dev *) NULL;
2433}
2434
2435/*
2436 * Force a net-interface to dial out.
2437 * This is called from the userlevel-routine below or
2438 * from isdn_net_start_xmit().
2439 */
Adrian Bunk3e206b02005-06-25 14:58:35 -07002440static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07002441isdn_net_force_dial_lp(isdn_net_local * lp)
2442{
2443 if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
2444 int chi;
2445 if (lp->phone[1]) {
2446 ulong flags;
2447
2448 /* Grab a free ISDN-Channel */
2449 spin_lock_irqsave(&dev->lock, flags);
2450 if ((chi = isdn_get_free_channel(
2451 ISDN_USAGE_NET,
2452 lp->l2_proto,
2453 lp->l3_proto,
2454 lp->pre_device,
2455 lp->pre_channel,
2456 lp->msn)) < 0) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002457 printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n",
2458 lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002459 spin_unlock_irqrestore(&dev->lock, flags);
2460 return -EAGAIN;
2461 }
2462 lp->dialstate = 1;
2463 /* Connect interface with channel */
2464 isdn_net_bind_channel(lp, chi);
2465#ifdef CONFIG_ISDN_PPP
2466 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2467 if (isdn_ppp_bind(lp) < 0) {
2468 isdn_net_unbind_channel(lp);
2469 spin_unlock_irqrestore(&dev->lock, flags);
2470 return -EAGAIN;
2471 }
2472#endif
2473 /* Initiate dialing */
2474 spin_unlock_irqrestore(&dev->lock, flags);
2475 isdn_net_dial();
2476 return 0;
2477 } else
2478 return -EINVAL;
2479 } else
2480 return -EBUSY;
2481}
2482
2483/*
2484 * This is called from certain upper protocol layers (multilink ppp
2485 * and x25iface encapsulation module) that want to initiate dialing
2486 * themselves.
2487 */
2488int
2489isdn_net_dial_req(isdn_net_local * lp)
2490{
2491 /* is there a better error code? */
2492 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) return -EBUSY;
2493
2494 return isdn_net_force_dial_lp(lp);
2495}
2496
2497/*
2498 * Force a net-interface to dial out.
2499 * This is always called from within userspace (ISDN_IOCTL_NET_DIAL).
2500 */
2501int
2502isdn_net_force_dial(char *name)
2503{
2504 isdn_net_dev *p = isdn_net_findif(name);
2505
2506 if (!p)
2507 return -ENODEV;
2508 return (isdn_net_force_dial_lp(p->local));
2509}
2510
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002511/* The ISDN-specific entries in the device structure. */
2512static const struct net_device_ops isdn_netdev_ops = {
2513 .ndo_init = isdn_net_init,
2514 .ndo_open = isdn_net_open,
2515 .ndo_stop = isdn_net_close,
2516 .ndo_do_ioctl = isdn_net_ioctl,
2517
2518 .ndo_validate_addr = NULL,
2519 .ndo_start_xmit = isdn_net_start_xmit,
2520 .ndo_get_stats = isdn_net_get_stats,
2521 .ndo_tx_timeout = isdn_net_tx_timeout,
2522};
2523
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524/*
Karsten Keild62a38d2007-10-08 20:37:11 -07002525 * Helper for alloc_netdev()
2526 */
2527static void _isdn_setup(struct net_device *dev)
2528{
Wang Chen838361f2008-12-03 15:49:46 -08002529 isdn_net_local *lp = netdev_priv(dev);
Karsten Keild62a38d2007-10-08 20:37:11 -07002530
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002531 ether_setup(dev);
2532
Karsten Keild62a38d2007-10-08 20:37:11 -07002533 dev->flags = IFF_NOARP | IFF_POINTOPOINT;
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002534 /* Setup the generic properties */
2535 dev->mtu = 1500;
2536 dev->flags = IFF_NOARP|IFF_POINTOPOINT;
2537 dev->type = ARPHRD_ETHER;
2538 dev->addr_len = ETH_ALEN;
2539 dev->header_ops = NULL;
2540 dev->netdev_ops = &isdn_netdev_ops;
2541
2542 /* for clients with MPPP maybe higher values better */
2543 dev->tx_queue_len = 30;
2544
Karsten Keild62a38d2007-10-08 20:37:11 -07002545 lp->p_encap = ISDN_NET_ENCAP_RAWIP;
2546 lp->magic = ISDN_NET_MAGIC;
2547 lp->last = lp;
2548 lp->next = lp;
2549 lp->isdn_device = -1;
2550 lp->isdn_channel = -1;
2551 lp->pre_device = -1;
2552 lp->pre_channel = -1;
2553 lp->exclusive = -1;
2554 lp->ppp_slot = -1;
2555 lp->pppbind = -1;
2556 skb_queue_head_init(&lp->super_tx_queue);
2557 lp->l2_proto = ISDN_PROTO_L2_X75I;
2558 lp->l3_proto = ISDN_PROTO_L3_TRANS;
2559 lp->triggercps = 6000;
2560 lp->slavedelay = 10 * HZ;
2561 lp->hupflags = ISDN_INHUP; /* Do hangup even on incoming calls */
2562 lp->onhtime = 10; /* Default hangup-time for saving costs */
2563 lp->dialmax = 1;
2564 /* Hangup before Callback, manual dial */
2565 lp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;
2566 lp->cbdelay = 25; /* Wait 5 secs before Callback */
2567 lp->dialtimeout = -1; /* Infinite Dial-Timeout */
2568 lp->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
2569 lp->dialstarted = 0; /* Jiffies of last dial-start */
2570 lp->dialwait_timer = 0; /* Jiffies of earliest next dial-start */
2571}
2572
2573/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002574 * Allocate a new network-interface and initialize its data structures.
2575 */
2576char *
2577isdn_net_new(char *name, struct net_device *master)
2578{
2579 isdn_net_dev *netdev;
2580
2581 /* Avoid creating an existing interface */
2582 if (isdn_net_findif(name)) {
2583 printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
2584 return NULL;
2585 }
Karsten Keild62a38d2007-10-08 20:37:11 -07002586 if (name == NULL)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002587 return NULL;
Burman Yan41f96932006-12-08 02:39:35 -08002588 if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002589 printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
2590 return NULL;
2591 }
Karsten Keild62a38d2007-10-08 20:37:11 -07002592 netdev->dev = alloc_netdev(sizeof(isdn_net_local), name, _isdn_setup);
2593 if (!netdev->dev) {
2594 printk(KERN_WARNING "isdn_net: Could not allocate network device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 kfree(netdev);
2596 return NULL;
2597 }
Wang Chen838361f2008-12-03 15:49:46 -08002598 netdev->local = netdev_priv(netdev->dev);
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002599
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 if (master) {
2601 /* Device shall be a slave */
Wang Chen838361f2008-12-03 15:49:46 -08002602 struct net_device *p = MASTER_TO_SLAVE(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002603 struct net_device *q = master;
2604
2605 netdev->local->master = master;
2606 /* Put device at end of slave-chain */
2607 while (p) {
2608 q = p;
Wang Chen838361f2008-12-03 15:49:46 -08002609 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002610 }
Wang Chen838361f2008-12-03 15:49:46 -08002611 MASTER_TO_SLAVE(q) = netdev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002612 } else {
2613 /* Device shall be a master */
2614 /*
2615 * Watchdog timer (currently) for master only.
2616 */
Karsten Keild62a38d2007-10-08 20:37:11 -07002617 netdev->dev->watchdog_timeo = ISDN_NET_TX_TIMEOUT;
2618 if (register_netdev(netdev->dev) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002619 printk(KERN_WARNING "isdn_net: Could not register net-device\n");
Karsten Keild62a38d2007-10-08 20:37:11 -07002620 free_netdev(netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002621 kfree(netdev);
2622 return NULL;
2623 }
2624 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002625 netdev->queue = netdev->local;
2626 spin_lock_init(&netdev->queue_lock);
2627
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 netdev->local->netdev = netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002629
David Howellsc4028952006-11-22 14:57:56 +00002630 INIT_WORK(&netdev->local->tqueue, isdn_net_softint);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002631 spin_lock_init(&netdev->local->xmit_lock);
2632
Linus Torvalds1da177e2005-04-16 15:20:36 -07002633 /* Put into to netdev-chain */
2634 netdev->next = (void *) dev->netdev;
2635 dev->netdev = netdev;
Karsten Keild62a38d2007-10-08 20:37:11 -07002636 return netdev->dev->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002637}
2638
2639char *
2640isdn_net_newslave(char *parm)
2641{
2642 char *p = strchr(parm, ',');
2643 isdn_net_dev *n;
2644 char newname[10];
2645
2646 if (p) {
2647 /* Slave-Name MUST not be empty */
2648 if (!strlen(p + 1))
2649 return NULL;
2650 strcpy(newname, p + 1);
2651 *p = 0;
2652 /* Master must already exist */
2653 if (!(n = isdn_net_findif(parm)))
2654 return NULL;
2655 /* Master must be a real interface, not a slave */
2656 if (n->local->master)
2657 return NULL;
2658 /* Master must not be started yet */
2659 if (isdn_net_device_started(n))
2660 return NULL;
Karsten Keild62a38d2007-10-08 20:37:11 -07002661 return (isdn_net_new(newname, n->dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 }
2663 return NULL;
2664}
2665
2666/*
2667 * Set interface-parameters.
2668 * Always set all parameters, so the user-level application is responsible
2669 * for not overwriting existing setups. It has to get the current
2670 * setup first, if only selected parameters are to be changed.
2671 */
2672int
2673isdn_net_setcfg(isdn_net_ioctl_cfg * cfg)
2674{
2675 isdn_net_dev *p = isdn_net_findif(cfg->name);
2676 ulong features;
2677 int i;
2678 int drvidx;
2679 int chidx;
2680 char drvid[25];
2681
2682 if (p) {
2683 isdn_net_local *lp = p->local;
2684
2685 /* See if any registered driver supports the features we want */
2686 features = ((1 << cfg->l2_proto) << ISDN_FEATURE_L2_SHIFT) |
2687 ((1 << cfg->l3_proto) << ISDN_FEATURE_L3_SHIFT);
2688 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2689 if (dev->drv[i])
2690 if ((dev->drv[i]->interface->features & features) == features)
2691 break;
2692 if (i == ISDN_MAX_DRIVERS) {
2693 printk(KERN_WARNING "isdn_net: No driver with selected features\n");
2694 return -ENODEV;
2695 }
2696 if (lp->p_encap != cfg->p_encap){
2697#ifdef CONFIG_ISDN_X25
2698 struct concap_proto * cprot = p -> cprot;
2699#endif
2700 if (isdn_net_device_started(p)) {
2701 printk(KERN_WARNING "%s: cannot change encap when if is up\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002702 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002703 return -EBUSY;
2704 }
2705#ifdef CONFIG_ISDN_X25
2706 if( cprot && cprot -> pops )
2707 cprot -> pops -> proto_del ( cprot );
2708 p -> cprot = NULL;
2709 lp -> dops = NULL;
2710 /* ... , prepare for configuration of new one ... */
2711 switch ( cfg -> p_encap ){
2712 case ISDN_NET_ENCAP_X25IFACE:
2713 lp -> dops = &isdn_concap_reliable_dl_dops;
2714 }
2715 /* ... and allocate new one ... */
2716 p -> cprot = isdn_concap_new( cfg -> p_encap );
2717 /* p -> cprot == NULL now if p_encap is not supported
2718 by means of the concap_proto mechanism */
2719 /* the protocol is not configured yet; this will
2720 happen later when isdn_net_reset() is called */
2721#endif
2722 }
2723 switch ( cfg->p_encap ) {
2724 case ISDN_NET_ENCAP_SYNCPPP:
2725#ifndef CONFIG_ISDN_PPP
2726 printk(KERN_WARNING "%s: SyncPPP support not configured\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002727 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002728 return -EINVAL;
2729#else
Karsten Keild62a38d2007-10-08 20:37:11 -07002730 p->dev->type = ARPHRD_PPP; /* change ARP type */
2731 p->dev->addr_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002732#endif
2733 break;
2734 case ISDN_NET_ENCAP_X25IFACE:
2735#ifndef CONFIG_ISDN_X25
2736 printk(KERN_WARNING "%s: isdn-x25 support not configured\n",
Denis V. Lunevc749b012007-10-15 12:52:20 -07002737 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002738 return -EINVAL;
2739#else
Karsten Keild62a38d2007-10-08 20:37:11 -07002740 p->dev->type = ARPHRD_X25; /* change ARP type */
2741 p->dev->addr_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002742#endif
2743 break;
2744 case ISDN_NET_ENCAP_CISCOHDLCK:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002745 break;
2746 default:
2747 if( cfg->p_encap >= 0 &&
2748 cfg->p_encap <= ISDN_NET_ENCAP_MAX_ENCAP )
2749 break;
2750 printk(KERN_WARNING
2751 "%s: encapsulation protocol %d not supported\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002752 p->dev->name, cfg->p_encap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002753 return -EINVAL;
2754 }
2755 if (strlen(cfg->drvid)) {
2756 /* A bind has been requested ... */
2757 char *c,
2758 *e;
2759
2760 drvidx = -1;
2761 chidx = -1;
2762 strcpy(drvid, cfg->drvid);
2763 if ((c = strchr(drvid, ','))) {
2764 /* The channel-number is appended to the driver-Id with a comma */
2765 chidx = (int) simple_strtoul(c + 1, &e, 10);
2766 if (e == c)
2767 chidx = -1;
2768 *c = '\0';
2769 }
2770 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2771 /* Lookup driver-Id in array */
2772 if (!(strcmp(dev->drvid[i], drvid))) {
2773 drvidx = i;
2774 break;
2775 }
2776 if ((drvidx == -1) || (chidx == -1))
2777 /* Either driver-Id or channel-number invalid */
2778 return -ENODEV;
2779 } else {
2780 /* Parameters are valid, so get them */
2781 drvidx = lp->pre_device;
2782 chidx = lp->pre_channel;
2783 }
2784 if (cfg->exclusive > 0) {
2785 unsigned long flags;
2786
2787 /* If binding is exclusive, try to grab the channel */
2788 spin_lock_irqsave(&dev->lock, flags);
2789 if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
2790 lp->l2_proto, lp->l3_proto, drvidx,
2791 chidx, lp->msn)) < 0) {
2792 /* Grab failed, because desired channel is in use */
2793 lp->exclusive = -1;
2794 spin_unlock_irqrestore(&dev->lock, flags);
2795 return -EBUSY;
2796 }
2797 /* All went ok, so update isdninfo */
2798 dev->usage[i] = ISDN_USAGE_EXCLUSIVE;
2799 isdn_info_update();
2800 spin_unlock_irqrestore(&dev->lock, flags);
2801 lp->exclusive = i;
2802 } else {
2803 /* Non-exclusive binding or unbind. */
2804 lp->exclusive = -1;
2805 if ((lp->pre_device != -1) && (cfg->exclusive == -1)) {
2806 isdn_unexclusive_channel(lp->pre_device, lp->pre_channel);
2807 isdn_free_channel(lp->pre_device, lp->pre_channel, ISDN_USAGE_NET);
2808 drvidx = -1;
2809 chidx = -1;
2810 }
2811 }
Karsten Keil0f138642007-11-22 12:43:13 +01002812 strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 lp->pre_device = drvidx;
2814 lp->pre_channel = chidx;
2815 lp->onhtime = cfg->onhtime;
2816 lp->charge = cfg->charge;
2817 lp->l2_proto = cfg->l2_proto;
2818 lp->l3_proto = cfg->l3_proto;
2819 lp->cbdelay = cfg->cbdelay;
2820 lp->dialmax = cfg->dialmax;
2821 lp->triggercps = cfg->triggercps;
2822 lp->slavedelay = cfg->slavedelay * HZ;
2823 lp->pppbind = cfg->pppbind;
2824 lp->dialtimeout = cfg->dialtimeout >= 0 ? cfg->dialtimeout * HZ : -1;
2825 lp->dialwait = cfg->dialwait * HZ;
2826 if (cfg->secure)
2827 lp->flags |= ISDN_NET_SECURE;
2828 else
2829 lp->flags &= ~ISDN_NET_SECURE;
2830 if (cfg->cbhup)
2831 lp->flags |= ISDN_NET_CBHUP;
2832 else
2833 lp->flags &= ~ISDN_NET_CBHUP;
2834 switch (cfg->callback) {
2835 case 0:
2836 lp->flags &= ~(ISDN_NET_CALLBACK | ISDN_NET_CBOUT);
2837 break;
2838 case 1:
2839 lp->flags |= ISDN_NET_CALLBACK;
2840 lp->flags &= ~ISDN_NET_CBOUT;
2841 break;
2842 case 2:
2843 lp->flags |= ISDN_NET_CBOUT;
2844 lp->flags &= ~ISDN_NET_CALLBACK;
2845 break;
2846 }
2847 lp->flags &= ~ISDN_NET_DIALMODE_MASK; /* first all bits off */
2848 if (cfg->dialmode && !(cfg->dialmode & ISDN_NET_DIALMODE_MASK)) {
2849 /* old isdnctrl version, where only 0 or 1 is given */
2850 printk(KERN_WARNING
2851 "Old isdnctrl version detected! Please update.\n");
2852 lp->flags |= ISDN_NET_DM_OFF; /* turn on `off' bit */
2853 }
2854 else {
2855 lp->flags |= cfg->dialmode; /* turn on selected bits */
2856 }
2857 if (cfg->chargehup)
2858 lp->hupflags |= ISDN_CHARGEHUP;
2859 else
2860 lp->hupflags &= ~ISDN_CHARGEHUP;
2861 if (cfg->ihup)
2862 lp->hupflags |= ISDN_INHUP;
2863 else
2864 lp->hupflags &= ~ISDN_INHUP;
2865 if (cfg->chargeint > 10) {
2866 lp->hupflags |= ISDN_CHARGEHUP | ISDN_HAVECHARGE | ISDN_MANCHARGE;
2867 lp->chargeint = cfg->chargeint * HZ;
2868 }
2869 if (cfg->p_encap != lp->p_encap) {
2870 if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
Karsten Keild62a38d2007-10-08 20:37:11 -07002871 p->dev->header_ops = NULL;
2872 p->dev->flags = IFF_NOARP|IFF_POINTOPOINT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002873 } else {
Karsten Keild62a38d2007-10-08 20:37:11 -07002874 p->dev->header_ops = &isdn_header_ops;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002875 if (cfg->p_encap == ISDN_NET_ENCAP_ETHER)
Karsten Keild62a38d2007-10-08 20:37:11 -07002876 p->dev->flags = IFF_BROADCAST | IFF_MULTICAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002877 else
Karsten Keild62a38d2007-10-08 20:37:11 -07002878 p->dev->flags = IFF_NOARP|IFF_POINTOPOINT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002879 }
2880 }
2881 lp->p_encap = cfg->p_encap;
2882 return 0;
2883 }
2884 return -ENODEV;
2885}
2886
2887/*
2888 * Perform get-interface-parameters.ioctl
2889 */
2890int
2891isdn_net_getcfg(isdn_net_ioctl_cfg * cfg)
2892{
2893 isdn_net_dev *p = isdn_net_findif(cfg->name);
2894
2895 if (p) {
2896 isdn_net_local *lp = p->local;
2897
2898 strcpy(cfg->eaz, lp->msn);
2899 cfg->exclusive = lp->exclusive;
2900 if (lp->pre_device >= 0) {
2901 sprintf(cfg->drvid, "%s,%d", dev->drvid[lp->pre_device],
2902 lp->pre_channel);
2903 } else
2904 cfg->drvid[0] = '\0';
2905 cfg->onhtime = lp->onhtime;
2906 cfg->charge = lp->charge;
2907 cfg->l2_proto = lp->l2_proto;
2908 cfg->l3_proto = lp->l3_proto;
2909 cfg->p_encap = lp->p_encap;
2910 cfg->secure = (lp->flags & ISDN_NET_SECURE) ? 1 : 0;
2911 cfg->callback = 0;
2912 if (lp->flags & ISDN_NET_CALLBACK)
2913 cfg->callback = 1;
2914 if (lp->flags & ISDN_NET_CBOUT)
2915 cfg->callback = 2;
2916 cfg->cbhup = (lp->flags & ISDN_NET_CBHUP) ? 1 : 0;
2917 cfg->dialmode = lp->flags & ISDN_NET_DIALMODE_MASK;
2918 cfg->chargehup = (lp->hupflags & 4) ? 1 : 0;
2919 cfg->ihup = (lp->hupflags & 8) ? 1 : 0;
2920 cfg->cbdelay = lp->cbdelay;
2921 cfg->dialmax = lp->dialmax;
2922 cfg->triggercps = lp->triggercps;
2923 cfg->slavedelay = lp->slavedelay / HZ;
2924 cfg->chargeint = (lp->hupflags & ISDN_CHARGEHUP) ?
2925 (lp->chargeint / HZ) : 0;
2926 cfg->pppbind = lp->pppbind;
2927 cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
2928 cfg->dialwait = lp->dialwait / HZ;
Karsten Keilfaca94f2007-10-15 02:11:44 -07002929 if (lp->slave) {
2930 if (strlen(lp->slave->name) > 8)
2931 strcpy(cfg->slave, "too-long");
2932 else
2933 strcpy(cfg->slave, lp->slave->name);
2934 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002935 cfg->slave[0] = '\0';
Karsten Keilfaca94f2007-10-15 02:11:44 -07002936 if (lp->master) {
2937 if (strlen(lp->master->name) > 8)
2938 strcpy(cfg->master, "too-long");
2939 strcpy(cfg->master, lp->master->name);
2940 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002941 cfg->master[0] = '\0';
2942 return 0;
2943 }
2944 return -ENODEV;
2945}
2946
2947/*
2948 * Add a phone-number to an interface.
2949 */
2950int
2951isdn_net_addphone(isdn_net_ioctl_phone * phone)
2952{
2953 isdn_net_dev *p = isdn_net_findif(phone->name);
2954 isdn_net_phone *n;
2955
2956 if (p) {
Robert P. J. Day5cbded52006-12-13 00:35:56 -08002957 if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002958 return -ENOMEM;
Karsten Keil0f138642007-11-22 12:43:13 +01002959 strlcpy(n->num, phone->phone, sizeof(n->num));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002960 n->next = p->local->phone[phone->outgoing & 1];
2961 p->local->phone[phone->outgoing & 1] = n;
2962 return 0;
2963 }
2964 return -ENODEV;
2965}
2966
2967/*
2968 * Copy a string of all phone-numbers of an interface to user space.
2969 * This might sleep and must be called with the isdn semaphore down.
2970 */
2971int
2972isdn_net_getphones(isdn_net_ioctl_phone * phone, char __user *phones)
2973{
2974 isdn_net_dev *p = isdn_net_findif(phone->name);
2975 int inout = phone->outgoing & 1;
2976 int more = 0;
2977 int count = 0;
2978 isdn_net_phone *n;
2979
2980 if (!p)
2981 return -ENODEV;
2982 inout &= 1;
2983 for (n = p->local->phone[inout]; n; n = n->next) {
2984 if (more) {
2985 put_user(' ', phones++);
2986 count++;
2987 }
2988 if (copy_to_user(phones, n->num, strlen(n->num) + 1)) {
2989 return -EFAULT;
2990 }
2991 phones += strlen(n->num);
2992 count += strlen(n->num);
2993 more = 1;
2994 }
2995 put_user(0, phones);
2996 count++;
2997 return count;
2998}
2999
3000/*
3001 * Copy a string containing the peer's phone number of a connected interface
3002 * to user space.
3003 */
3004int
3005isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
3006{
3007 isdn_net_dev *p = isdn_net_findif(phone->name);
3008 int ch, dv, idx;
3009
Karsten Keilfaca94f2007-10-15 02:11:44 -07003010 if (!p)
3011 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 /*
3013 * Theoretical race: while this executes, the remote number might
3014 * become invalid (hang up) or change (new connection), resulting
3015 * in (partially) wrong number copied to user. This race
3016 * currently ignored.
3017 */
3018 ch = p->local->isdn_channel;
3019 dv = p->local->isdn_device;
Karsten Keilfaca94f2007-10-15 02:11:44 -07003020 if(ch < 0 && dv < 0)
3021 return -ENOTCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022 idx = isdn_dc2minor(dv, ch);
Karsten Keilfaca94f2007-10-15 02:11:44 -07003023 if (idx <0 )
3024 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003025 /* for pre-bound channels, we need this extra check */
Karsten Keilfaca94f2007-10-15 02:11:44 -07003026 if (strncmp(dev->num[idx], "???", 3) == 0)
3027 return -ENOTCONN;
3028 strncpy(phone->phone, dev->num[idx], ISDN_MSNLEN);
3029 phone->outgoing = USG_OUTGOING(dev->usage[idx]);
3030 if (copy_to_user(peer, phone, sizeof(*peer)))
3031 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003032 return 0;
3033}
3034/*
3035 * Delete a phone-number from an interface.
3036 */
3037int
3038isdn_net_delphone(isdn_net_ioctl_phone * phone)
3039{
3040 isdn_net_dev *p = isdn_net_findif(phone->name);
3041 int inout = phone->outgoing & 1;
3042 isdn_net_phone *n;
3043 isdn_net_phone *m;
3044
3045 if (p) {
3046 n = p->local->phone[inout];
3047 m = NULL;
3048 while (n) {
3049 if (!strcmp(n->num, phone->phone)) {
3050 if (p->local->dial == n)
3051 p->local->dial = n->next;
3052 if (m)
3053 m->next = n->next;
3054 else
3055 p->local->phone[inout] = n->next;
3056 kfree(n);
3057 return 0;
3058 }
3059 m = n;
3060 n = (isdn_net_phone *) n->next;
3061 }
3062 return -EINVAL;
3063 }
3064 return -ENODEV;
3065}
3066
3067/*
3068 * Delete all phone-numbers of an interface.
3069 */
3070static int
3071isdn_net_rmallphone(isdn_net_dev * p)
3072{
3073 isdn_net_phone *n;
3074 isdn_net_phone *m;
3075 int i;
3076
3077 for (i = 0; i < 2; i++) {
3078 n = p->local->phone[i];
3079 while (n) {
3080 m = n->next;
3081 kfree(n);
3082 n = m;
3083 }
3084 p->local->phone[i] = NULL;
3085 }
3086 p->local->dial = NULL;
3087 return 0;
3088}
3089
3090/*
3091 * Force a hangup of a network-interface.
3092 */
3093int
3094isdn_net_force_hangup(char *name)
3095{
3096 isdn_net_dev *p = isdn_net_findif(name);
3097 struct net_device *q;
3098
3099 if (p) {
3100 if (p->local->isdn_device < 0)
3101 return 1;
3102 q = p->local->slave;
3103 /* If this interface has slaves, do a hangup for them also. */
3104 while (q) {
3105 isdn_net_hangup(q);
Wang Chen838361f2008-12-03 15:49:46 -08003106 q = MASTER_TO_SLAVE(q);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 }
Karsten Keild62a38d2007-10-08 20:37:11 -07003108 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003109 return 0;
3110 }
3111 return -ENODEV;
3112}
3113
3114/*
3115 * Helper-function for isdn_net_rm: Do the real work.
3116 */
3117static int
3118isdn_net_realrm(isdn_net_dev * p, isdn_net_dev * q)
3119{
3120 u_long flags;
3121
3122 if (isdn_net_device_started(p)) {
3123 return -EBUSY;
3124 }
3125#ifdef CONFIG_ISDN_X25
3126 if( p -> cprot && p -> cprot -> pops )
3127 p -> cprot -> pops -> proto_del ( p -> cprot );
3128#endif
3129 /* Free all phone-entries */
3130 isdn_net_rmallphone(p);
3131 /* If interface is bound exclusive, free channel-usage */
3132 if (p->local->exclusive != -1)
3133 isdn_unexclusive_channel(p->local->pre_device, p->local->pre_channel);
3134 if (p->local->master) {
3135 /* It's a slave-device, so update master's slave-pointer if necessary */
Wang Chen838361f2008-12-03 15:49:46 -08003136 if (((isdn_net_local *) ISDN_MASTER_PRIV(p->local))->slave ==
3137 p->dev)
3138 ((isdn_net_local *)ISDN_MASTER_PRIV(p->local))->slave =
3139 p->local->slave;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 } else {
3141 /* Unregister only if it's a master-device */
Karsten Keild62a38d2007-10-08 20:37:11 -07003142 unregister_netdev(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003143 }
3144 /* Unlink device from chain */
3145 spin_lock_irqsave(&dev->lock, flags);
3146 if (q)
3147 q->next = p->next;
3148 else
3149 dev->netdev = p->next;
3150 if (p->local->slave) {
3151 /* If this interface has a slave, remove it also */
Karsten Keilfaca94f2007-10-15 02:11:44 -07003152 char *slavename = p->local->slave->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003153 isdn_net_dev *n = dev->netdev;
3154 q = NULL;
3155 while (n) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07003156 if (!strcmp(n->dev->name, slavename)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157 spin_unlock_irqrestore(&dev->lock, flags);
3158 isdn_net_realrm(n, q);
3159 spin_lock_irqsave(&dev->lock, flags);
3160 break;
3161 }
3162 q = n;
Karsten Keilfaca94f2007-10-15 02:11:44 -07003163 n = (isdn_net_dev *)n->next;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164 }
3165 }
3166 spin_unlock_irqrestore(&dev->lock, flags);
3167 /* If no more net-devices remain, disable auto-hangup timer */
3168 if (dev->netdev == NULL)
3169 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
Karsten Keild62a38d2007-10-08 20:37:11 -07003170 free_netdev(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003171 kfree(p);
3172
3173 return 0;
3174}
3175
3176/*
3177 * Remove a single network-interface.
3178 */
3179int
3180isdn_net_rm(char *name)
3181{
3182 u_long flags;
3183 isdn_net_dev *p;
3184 isdn_net_dev *q;
3185
3186 /* Search name in netdev-chain */
3187 spin_lock_irqsave(&dev->lock, flags);
3188 p = dev->netdev;
3189 q = NULL;
3190 while (p) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07003191 if (!strcmp(p->dev->name, name)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 spin_unlock_irqrestore(&dev->lock, flags);
3193 return (isdn_net_realrm(p, q));
3194 }
3195 q = p;
3196 p = (isdn_net_dev *) p->next;
3197 }
3198 spin_unlock_irqrestore(&dev->lock, flags);
3199 /* If no more net-devices remain, disable auto-hangup timer */
3200 if (dev->netdev == NULL)
3201 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
3202 return -ENODEV;
3203}
3204
3205/*
3206 * Remove all network-interfaces
3207 */
3208int
3209isdn_net_rmall(void)
3210{
3211 u_long flags;
3212 int ret;
3213
3214 /* Walk through netdev-chain */
3215 spin_lock_irqsave(&dev->lock, flags);
3216 while (dev->netdev) {
3217 if (!dev->netdev->local->master) {
3218 /* Remove master-devices only, slaves get removed with their master */
3219 spin_unlock_irqrestore(&dev->lock, flags);
3220 if ((ret = isdn_net_realrm(dev->netdev, NULL))) {
3221 return ret;
3222 }
3223 spin_lock_irqsave(&dev->lock, flags);
3224 }
3225 }
3226 dev->netdev = NULL;
3227 spin_unlock_irqrestore(&dev->lock, flags);
3228 return 0;
3229}