blob: f63a110b7bcb2d2257869484bd9b894d94b9b5d2 [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 *
Joe Perches475be4d2012-02-19 19:52:38 -080012 * Data Over Voice (DOV) support added - Guy Ellis 23-Mar-02
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 * 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>
Joe Perches475be4d2012-02-19 19:52:38 -080021 * for info on the protocol, see
Linus Torvalds1da177e2005-04-16 15:20:36 -070022 * http://i4l.zabbadoz.net/i4l/cisco-hdlc.txt
23 */
24
Linus Torvalds1da177e2005-04-16 15:20:36 -070025#include <linux/isdn.h>
Tejun Heo5a0e3ad2010-03-24 17:04:11 +090026#include <linux/slab.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <net/arp.h>
28#include <net/dst.h>
29#include <net/pkt_sched.h>
30#include <linux/inetdevice.h>
31#include "isdn_common.h"
32#include "isdn_net.h"
33#ifdef CONFIG_ISDN_PPP
34#include "isdn_ppp.h"
35#endif
36#ifdef CONFIG_ISDN_X25
37#include <linux/concap.h>
38#include "isdn_concap.h"
39#endif
40
41
42/*
Joe Perches475be4d2012-02-19 19:52:38 -080043 * Outline of new tbusy handling:
Linus Torvalds1da177e2005-04-16 15:20:36 -070044 *
45 * Old method, roughly spoken, consisted of setting tbusy when entering
46 * isdn_net_start_xmit() and at several other locations and clearing
47 * it from isdn_net_start_xmit() thread when sending was successful.
48 *
49 * With 2.3.x multithreaded network core, to prevent problems, tbusy should
50 * only be set by the isdn_net_start_xmit() thread and only when a tx-busy
51 * condition is detected. Other threads (in particular isdn_net_stat_callb())
52 * are only allowed to clear tbusy.
53 *
54 * -HE
55 */
56
57/*
58 * About SOFTNET:
59 * Most of the changes were pretty obvious and basically done by HE already.
60 *
Geert Uytterhoeven3c7f3092015-03-03 11:58:08 +010061 * One problem of the isdn net device code is that it uses struct net_device
Joe Perches475be4d2012-02-19 19:52:38 -080062 * for masters and slaves. However, only master interface are registered to
63 * the network layer, and therefore, it only makes sense to call netif_*
Linus Torvalds1da177e2005-04-16 15:20:36 -070064 * functions on them.
65 *
66 * --KG
67 */
68
Joe Perches475be4d2012-02-19 19:52:38 -080069/*
Linus Torvalds1da177e2005-04-16 15:20:36 -070070 * Find out if the netdevice has been ifup-ed yet.
71 * For slaves, look at the corresponding master.
72 */
73static __inline__ int isdn_net_device_started(isdn_net_dev *n)
74{
75 isdn_net_local *lp = n->local;
76 struct net_device *dev;
Joe Perches475be4d2012-02-19 19:52:38 -080077
78 if (lp->master)
Linus Torvalds1da177e2005-04-16 15:20:36 -070079 dev = lp->master;
80 else
Karsten Keild62a38d2007-10-08 20:37:11 -070081 dev = n->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -070082 return netif_running(dev);
83}
84
85/*
86 * wake up the network -> net_device queue.
87 * For slaves, wake the corresponding master interface.
88 */
89static __inline__ void isdn_net_device_wake_queue(isdn_net_local *lp)
90{
Joe Perches475be4d2012-02-19 19:52:38 -080091 if (lp->master)
Linus Torvalds1da177e2005-04-16 15:20:36 -070092 netif_wake_queue(lp->master);
93 else
Karsten Keild62a38d2007-10-08 20:37:11 -070094 netif_wake_queue(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -070095}
96
97/*
98 * stop the network -> net_device queue.
99 * For slaves, stop the corresponding master interface.
100 */
101static __inline__ void isdn_net_device_stop_queue(isdn_net_local *lp)
102{
103 if (lp->master)
104 netif_stop_queue(lp->master);
105 else
Karsten Keild62a38d2007-10-08 20:37:11 -0700106 netif_stop_queue(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700107}
108
109/*
110 * find out if the net_device which this lp belongs to (lp can be
Joe Perches475be4d2012-02-19 19:52:38 -0800111 * master or slave) is busy. It's busy iff all (master and slave)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112 * queues are busy
113 */
114static __inline__ int isdn_net_device_busy(isdn_net_local *lp)
115{
116 isdn_net_local *nlp;
117 isdn_net_dev *nd;
118 unsigned long flags;
119
120 if (!isdn_net_lp_busy(lp))
121 return 0;
122
123 if (lp->master)
Wang Chen838361f2008-12-03 15:49:46 -0800124 nd = ISDN_MASTER_PRIV(lp)->netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700125 else
126 nd = lp->netdev;
Joe Perches475be4d2012-02-19 19:52:38 -0800127
Linus Torvalds1da177e2005-04-16 15:20:36 -0700128 spin_lock_irqsave(&nd->queue_lock, flags);
129 nlp = lp->next;
130 while (nlp != lp) {
131 if (!isdn_net_lp_busy(nlp)) {
132 spin_unlock_irqrestore(&nd->queue_lock, flags);
133 return 0;
134 }
135 nlp = nlp->next;
136 }
137 spin_unlock_irqrestore(&nd->queue_lock, flags);
138 return 1;
139}
140
141static __inline__ void isdn_net_inc_frame_cnt(isdn_net_local *lp)
142{
143 atomic_inc(&lp->frame_cnt);
144 if (isdn_net_device_busy(lp))
145 isdn_net_device_stop_queue(lp);
146}
147
148static __inline__ void isdn_net_dec_frame_cnt(isdn_net_local *lp)
149{
150 atomic_dec(&lp->frame_cnt);
151
152 if (!(isdn_net_device_busy(lp))) {
153 if (!skb_queue_empty(&lp->super_tx_queue)) {
154 schedule_work(&lp->tqueue);
155 } else {
156 isdn_net_device_wake_queue(lp);
157 }
Joe Perches475be4d2012-02-19 19:52:38 -0800158 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700159}
160
161static __inline__ void isdn_net_zero_frame_cnt(isdn_net_local *lp)
162{
163 atomic_set(&lp->frame_cnt, 0);
164}
165
Joe Perches475be4d2012-02-19 19:52:38 -0800166/* For 2.2.x we leave the transmitter busy timeout at 2 secs, just
Linus Torvalds1da177e2005-04-16 15:20:36 -0700167 * to be safe.
168 * For 2.3.x we push it up to 20 secs, because call establishment
Joe Perches475be4d2012-02-19 19:52:38 -0800169 * (in particular callback) may take such a long time, and we
Linus Torvalds1da177e2005-04-16 15:20:36 -0700170 * don't want confusing messages in the log. However, there is a slight
171 * possibility that this large timeout will break other things like MPPP,
172 * which might rely on the tx timeout. If so, we'll find out this way...
173 */
174
Joe Perches475be4d2012-02-19 19:52:38 -0800175#define ISDN_NET_TX_TIMEOUT (20 * HZ)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700176
177/* Prototypes */
178
Adrian Bunk3e206b02005-06-25 14:58:35 -0700179static int isdn_net_force_dial_lp(isdn_net_local *);
Stephen Hemminger8b62ff22009-08-31 19:50:44 +0000180static netdev_tx_t isdn_net_start_xmit(struct sk_buff *,
Joe Perches475be4d2012-02-19 19:52:38 -0800181 struct net_device *);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700182
183static void isdn_net_ciscohdlck_connected(isdn_net_local *lp);
184static void isdn_net_ciscohdlck_disconnected(isdn_net_local *lp);
185
186char *isdn_net_revision = "$Revision: 1.1.2.2 $";
187
Joe Perches475be4d2012-02-19 19:52:38 -0800188/*
189 * Code for raw-networking over ISDN
190 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700191
192static void
193isdn_net_unreachable(struct net_device *dev, struct sk_buff *skb, char *reason)
194{
Joe Perches475be4d2012-02-19 19:52:38 -0800195 if (skb) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700196
197 u_short proto = ntohs(skb->protocol);
198
199 printk(KERN_DEBUG "isdn_net: %s: %s, signalling dst_link_failure %s\n",
200 dev->name,
201 (reason != NULL) ? reason : "unknown",
202 (proto != ETH_P_IP) ? "Protocol != ETH_P_IP" : "");
Joe Perches475be4d2012-02-19 19:52:38 -0800203
Linus Torvalds1da177e2005-04-16 15:20:36 -0700204 dst_link_failure(skb);
205 }
206 else { /* dial not triggered by rawIP packet */
207 printk(KERN_DEBUG "isdn_net: %s: %s\n",
Joe Perches475be4d2012-02-19 19:52:38 -0800208 dev->name,
209 (reason != NULL) ? reason : "reason unknown");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 }
211}
212
213static void
214isdn_net_reset(struct net_device *dev)
215{
216#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -0800217 struct concap_device_ops *dops =
218 ((isdn_net_local *)netdev_priv(dev))->dops;
219 struct concap_proto *cprot =
220 ((isdn_net_local *)netdev_priv(dev))->netdev->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700221#endif
222#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -0800223 if (cprot && cprot->pops && dops)
224 cprot->pops->restart(cprot, dev, dops);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700225#endif
226}
227
228/* Open/initialize the board. */
229static int
230isdn_net_open(struct net_device *dev)
231{
232 int i;
233 struct net_device *p;
234 struct in_device *in_dev;
235
236 /* moved here from isdn_net_reset, because only the master has an
237 interface associated which is supposed to be started. BTW:
238 we need to call netif_start_queue, not netif_wake_queue here */
239 netif_start_queue(dev);
240
241 isdn_net_reset(dev);
242 /* Fill in the MAC-level header (not needed, but for compatibility... */
243 for (i = 0; i < ETH_ALEN - sizeof(u32); i++)
244 dev->dev_addr[i] = 0xfc;
245 if ((in_dev = dev->ip_ptr) != NULL) {
246 /*
247 * Any address will do - we take the first
248 */
249 struct in_ifaddr *ifa = in_dev->ifa_list;
250 if (ifa != NULL)
Joe Perches475be4d2012-02-19 19:52:38 -0800251 memcpy(dev->dev_addr + 2, &ifa->ifa_local, 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 }
253
254 /* If this interface has slaves, start them also */
Wang Chen838361f2008-12-03 15:49:46 -0800255 p = MASTER_TO_SLAVE(dev);
256 if (p) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700257 while (p) {
258 isdn_net_reset(p);
Wang Chen838361f2008-12-03 15:49:46 -0800259 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700260 }
261 }
262 isdn_lock_drivers();
263 return 0;
264}
265
266/*
267 * Assign an ISDN-channel to a net-interface
268 */
269static void
Joe Perches475be4d2012-02-19 19:52:38 -0800270isdn_net_bind_channel(isdn_net_local *lp, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271{
272 lp->flags |= ISDN_NET_CONNECTED;
273 lp->isdn_device = dev->drvmap[idx];
274 lp->isdn_channel = dev->chanmap[idx];
275 dev->rx_netdev[idx] = lp->netdev;
276 dev->st_netdev[idx] = lp->netdev;
277}
278
279/*
280 * unbind a net-interface (resets interface after an error)
281 */
282static void
Joe Perches475be4d2012-02-19 19:52:38 -0800283isdn_net_unbind_channel(isdn_net_local *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700284{
285 skb_queue_purge(&lp->super_tx_queue);
286
287 if (!lp->master) { /* reset only master device */
288 /* Moral equivalent of dev_purge_queues():
289 BEWARE! This chunk of code cannot be called from hardware
290 interrupt handler. I hope it is true. --ANK
Joe Perches475be4d2012-02-19 19:52:38 -0800291 */
David S. Miller5aa70992008-07-08 22:59:10 -0700292 qdisc_reset_all_tx(lp->netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700293 }
294 lp->dialstate = 0;
295 dev->rx_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
296 dev->st_netdev[isdn_dc2minor(lp->isdn_device, lp->isdn_channel)] = NULL;
Paul Bollebae58432009-01-14 14:41:00 -0800297 if (lp->isdn_device != -1 && lp->isdn_channel != -1)
298 isdn_free_channel(lp->isdn_device, lp->isdn_channel,
299 ISDN_USAGE_NET);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700300 lp->flags &= ~ISDN_NET_CONNECTED;
301 lp->isdn_device = -1;
302 lp->isdn_channel = -1;
303}
304
305/*
306 * Perform auto-hangup and cps-calculation for net-interfaces.
307 *
308 * auto-hangup:
309 * Increment idle-counter (this counter is reset on any incoming or
310 * outgoing packet), if counter exceeds configured limit either do a
311 * hangup immediately or - if configured - wait until just before the next
312 * charge-info.
313 *
314 * cps-calculation (needed for dynamic channel-bundling):
315 * Since this function is called every second, simply reset the
316 * byte-counter of the interface after copying it to the cps-variable.
317 */
Adrian Bunk3e206b02005-06-25 14:58:35 -0700318static unsigned long last_jiffies = -HZ;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700319
320void
321isdn_net_autohup(void)
322{
323 isdn_net_dev *p = dev->netdev;
324 int anymore;
325
326 anymore = 0;
327 while (p) {
328 isdn_net_local *l = p->local;
329 if (jiffies == last_jiffies)
330 l->cps = l->transcount;
331 else
332 l->cps = (l->transcount * HZ) / (jiffies - last_jiffies);
333 l->transcount = 0;
334 if (dev->net_verbose > 3)
Karsten Keilfaca94f2007-10-15 02:11:44 -0700335 printk(KERN_DEBUG "%s: %d bogocps\n", p->dev->name, l->cps);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700336 if ((l->flags & ISDN_NET_CONNECTED) && (!l->dialstate)) {
337 anymore = 1;
338 l->huptimer++;
339 /*
340 * if there is some dialmode where timeout-hangup
341 * should _not_ be done, check for that here
342 */
343 if ((l->onhtime) &&
344 (l->huptimer > l->onhtime))
345 {
346 if (l->hupflags & ISDN_MANCHARGE &&
347 l->hupflags & ISDN_CHARGEHUP) {
348 while (time_after(jiffies, l->chargetime + l->chargeint))
349 l->chargetime += l->chargeint;
350 if (time_after(jiffies, l->chargetime + l->chargeint - 2 * HZ))
351 if (l->outgoing || l->hupflags & ISDN_INHUP)
Karsten Keild62a38d2007-10-08 20:37:11 -0700352 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700353 } else if (l->outgoing) {
354 if (l->hupflags & ISDN_CHARGEHUP) {
355 if (l->hupflags & ISDN_WAITCHARGE) {
356 printk(KERN_DEBUG "isdn_net: Hupflags of %s are %X\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700357 p->dev->name, l->hupflags);
Karsten Keild62a38d2007-10-08 20:37:11 -0700358 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700359 } else if (time_after(jiffies, l->chargetime + l->chargeint)) {
360 printk(KERN_DEBUG
361 "isdn_net: %s: chtime = %lu, chint = %d\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -0700362 p->dev->name, l->chargetime, l->chargeint);
Karsten Keild62a38d2007-10-08 20:37:11 -0700363 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700364 }
365 } else
Karsten Keild62a38d2007-10-08 20:37:11 -0700366 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700367 } else if (l->hupflags & ISDN_INHUP)
Karsten Keild62a38d2007-10-08 20:37:11 -0700368 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700369 }
370
Joe Perches475be4d2012-02-19 19:52:38 -0800371 if (dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*l) == ISDN_NET_DM_OFF)) {
Karsten Keild62a38d2007-10-08 20:37:11 -0700372 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700373 break;
374 }
375 }
376 p = (isdn_net_dev *) p->next;
377 }
378 last_jiffies = jiffies;
379 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, anymore);
380}
381
382static void isdn_net_lp_disconnected(isdn_net_local *lp)
383{
384 isdn_net_rm_from_bundle(lp);
385}
386
387/*
388 * Handle status-messages from ISDN-interfacecard.
389 * This function is called from within the main-status-dispatcher
390 * isdn_status_callback, which itself is called from the low-level driver.
391 * Return: 1 = Event handled, 0 = not for us or unknown Event.
392 */
393int
394isdn_net_stat_callback(int idx, isdn_ctrl *c)
395{
396 isdn_net_dev *p = dev->st_netdev[idx];
397 int cmd = c->command;
398
399 if (p) {
400 isdn_net_local *lp = p->local;
401#ifdef CONFIG_ISDN_X25
402 struct concap_proto *cprot = lp->netdev->cprot;
403 struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;
404#endif
405 switch (cmd) {
Joe Perches475be4d2012-02-19 19:52:38 -0800406 case ISDN_STAT_BSENT:
407 /* A packet has successfully been sent out */
408 if ((lp->flags & ISDN_NET_CONNECTED) &&
409 (!lp->dialstate)) {
410 isdn_net_dec_frame_cnt(lp);
411 lp->stats.tx_packets++;
412 lp->stats.tx_bytes += c->parm.length;
413 }
414 return 1;
415 case ISDN_STAT_DCONN:
416 /* D-Channel is up */
417 switch (lp->dialstate) {
418 case 4:
419 case 7:
420 case 8:
421 lp->dialstate++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700422 return 1;
Joe Perches475be4d2012-02-19 19:52:38 -0800423 case 12:
424 lp->dialstate = 5;
425 return 1;
426 }
427 break;
428 case ISDN_STAT_DHUP:
429 /* Either D-Channel-hangup or error during dialout */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700430#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -0800431 /* If we are not connencted then dialing had
432 failed. If there are generic encap protocol
433 receiver routines signal the closure of
434 the link*/
Linus Torvalds1da177e2005-04-16 15:20:36 -0700435
Joe Perches475be4d2012-02-19 19:52:38 -0800436 if (!(lp->flags & ISDN_NET_CONNECTED)
437 && pops && pops->disconn_ind)
438 pops->disconn_ind(cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439#endif /* CONFIG_ISDN_X25 */
Joe Perches475be4d2012-02-19 19:52:38 -0800440 if ((!lp->dialstate) && (lp->flags & ISDN_NET_CONNECTED)) {
441 if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
442 isdn_net_ciscohdlck_disconnected(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700443#ifdef CONFIG_ISDN_PPP
Joe Perches475be4d2012-02-19 19:52:38 -0800444 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
445 isdn_ppp_free(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700446#endif
Joe Perches475be4d2012-02-19 19:52:38 -0800447 isdn_net_lp_disconnected(lp);
448 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
449 printk(KERN_INFO "%s: remote hangup\n", p->dev->name);
450 printk(KERN_INFO "%s: Chargesum is %d\n", p->dev->name,
451 lp->charge);
452 isdn_net_unbind_channel(lp);
453 return 1;
454 }
455 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -0800457 case ISDN_STAT_BHUP:
458 /* B-Channel-hangup */
459 /* try if there are generic encap protocol
460 receiver routines and signal the closure of
461 the link */
462 if (pops && pops->disconn_ind) {
463 pops->disconn_ind(cprot);
464 return 1;
465 }
466 break;
467#endif /* CONFIG_ISDN_X25 */
468 case ISDN_STAT_BCONN:
469 /* B-Channel is up */
470 isdn_net_zero_frame_cnt(lp);
471 switch (lp->dialstate) {
472 case 5:
473 case 6:
474 case 7:
475 case 8:
476 case 9:
477 case 10:
478 case 12:
479 if (lp->dialstate <= 6) {
480 dev->usage[idx] |= ISDN_USAGE_OUTGOING;
481 isdn_info_update();
482 } else
483 dev->rx_netdev[idx] = p;
484 lp->dialstate = 0;
485 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 1);
486 if (lp->p_encap == ISDN_NET_ENCAP_CISCOHDLCK)
487 isdn_net_ciscohdlck_connected(lp);
488 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP) {
489 if (lp->master) { /* is lp a slave? */
490 isdn_net_dev *nd = ISDN_MASTER_PRIV(lp)->netdev;
491 isdn_net_add_to_bundle(nd, lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 }
Joe Perches475be4d2012-02-19 19:52:38 -0800493 }
494 printk(KERN_INFO "isdn_net: %s connected\n", p->dev->name);
495 /* If first Chargeinfo comes before B-Channel connect,
496 * we correct the timestamp here.
497 */
498 lp->chargetime = jiffies;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700499
Joe Perches475be4d2012-02-19 19:52:38 -0800500 /* reset dial-timeout */
501 lp->dialstarted = 0;
502 lp->dialwait_timer = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700503
504#ifdef CONFIG_ISDN_PPP
Joe Perches475be4d2012-02-19 19:52:38 -0800505 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
506 isdn_ppp_wakeup_daemon(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700507#endif
508#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -0800509 /* try if there are generic concap receiver routines */
510 if (pops)
511 if (pops->connect_ind)
512 pops->connect_ind(cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700513#endif /* CONFIG_ISDN_X25 */
Joe Perches475be4d2012-02-19 19:52:38 -0800514 /* ppp needs to do negotiations first */
515 if (lp->p_encap != ISDN_NET_ENCAP_SYNCPPP)
516 isdn_net_device_wake_queue(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700517 return 1;
Joe Perches475be4d2012-02-19 19:52:38 -0800518 }
519 break;
520 case ISDN_STAT_NODCH:
521 /* No D-Channel avail. */
522 if (lp->dialstate == 4) {
523 lp->dialstate--;
524 return 1;
525 }
526 break;
527 case ISDN_STAT_CINF:
528 /* Charge-info from TelCo. Calculate interval between
529 * charge-infos and set timestamp for last info for
530 * usage by isdn_net_autohup()
531 */
532 lp->charge++;
533 if (lp->hupflags & ISDN_HAVECHARGE) {
534 lp->hupflags &= ~ISDN_WAITCHARGE;
535 lp->chargeint = jiffies - lp->chargetime - (2 * HZ);
536 }
537 if (lp->hupflags & ISDN_WAITCHARGE)
538 lp->hupflags |= ISDN_HAVECHARGE;
539 lp->chargetime = jiffies;
540 printk(KERN_DEBUG "isdn_net: Got CINF chargetime of %s now %lu\n",
541 p->dev->name, lp->chargetime);
542 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 }
544 }
545 return 0;
546}
547
548/*
549 * Perform dialout for net-interfaces and timeout-handling for
550 * D-Channel-up and B-Channel-up Messages.
551 * This function is initially called from within isdn_net_start_xmit() or
552 * or isdn_net_find_icall() after initializing the dialstate for an
553 * interface. If further calls are needed, the function schedules itself
554 * for a timer-callback via isdn_timer_function().
555 * The dialstate is also affected by incoming status-messages from
556 * the ISDN-Channel which are handled in isdn_net_stat_callback() above.
557 */
558void
559isdn_net_dial(void)
560{
561 isdn_net_dev *p = dev->netdev;
562 int anymore = 0;
563 int i;
564 isdn_ctrl cmd;
Joe Perches475be4d2012-02-19 19:52:38 -0800565 u_char *phone_number;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566
567 while (p) {
568 isdn_net_local *lp = p->local;
569
570#ifdef ISDN_DEBUG_NET_DIAL
571 if (lp->dialstate)
Karsten Keilfaca94f2007-10-15 02:11:44 -0700572 printk(KERN_DEBUG "%s: dialstate=%d\n", p->dev->name, lp->dialstate);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700573#endif
574 switch (lp->dialstate) {
Joe Perches475be4d2012-02-19 19:52:38 -0800575 case 0:
576 /* Nothing to do for this interface */
577 break;
578 case 1:
579 /* Initiate dialout. Set phone-number-pointer to first number
580 * of interface.
581 */
582 lp->dial = lp->phone[1];
583 if (!lp->dial) {
584 printk(KERN_WARNING "%s: phone number deleted?\n",
585 p->dev->name);
586 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700587 break;
Joe Perches475be4d2012-02-19 19:52:38 -0800588 }
589 anymore = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700590
Joe Perches475be4d2012-02-19 19:52:38 -0800591 if (lp->dialtimeout > 0)
592 if (lp->dialstarted == 0 || time_after(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait)) {
593 lp->dialstarted = jiffies;
594 lp->dialwait_timer = 0;
595 }
596
597 lp->dialstate++;
598 /* Fall through */
599 case 2:
600 /* Prepare dialing. Clear EAZ, then set EAZ. */
601 cmd.driver = lp->isdn_device;
602 cmd.arg = lp->isdn_channel;
603 cmd.command = ISDN_CMD_CLREAZ;
604 isdn_command(&cmd);
605 sprintf(cmd.parm.num, "%s", isdn_map_eaz2msn(lp->msn, cmd.driver));
606 cmd.command = ISDN_CMD_SETEAZ;
607 isdn_command(&cmd);
608 lp->dialretry = 0;
609 anymore = 1;
610 lp->dialstate++;
611 /* Fall through */
612 case 3:
613 /* Setup interface, dial current phone-number, switch to next number.
614 * If list of phone-numbers is exhausted, increment
615 * retry-counter.
616 */
617 if (dev->global_flags & ISDN_GLOBAL_STOPPED || (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF)) {
618 char *s;
619 if (dev->global_flags & ISDN_GLOBAL_STOPPED)
620 s = "dial suppressed: isdn system stopped";
621 else
622 s = "dial suppressed: dialmode `off'";
623 isdn_net_unreachable(p->dev, NULL, s);
624 isdn_net_hangup(p->dev);
625 break;
626 }
627 cmd.driver = lp->isdn_device;
628 cmd.command = ISDN_CMD_SETL2;
629 cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
630 isdn_command(&cmd);
631 cmd.driver = lp->isdn_device;
632 cmd.command = ISDN_CMD_SETL3;
633 cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
634 isdn_command(&cmd);
635 cmd.driver = lp->isdn_device;
636 cmd.arg = lp->isdn_channel;
637 if (!lp->dial) {
638 printk(KERN_WARNING "%s: phone number deleted?\n",
639 p->dev->name);
640 isdn_net_hangup(p->dev);
641 break;
642 }
643 if (!strncmp(lp->dial->num, "LEASED", strlen("LEASED"))) {
644 lp->dialstate = 4;
645 printk(KERN_INFO "%s: Open leased line ...\n", p->dev->name);
646 } else {
647 if (lp->dialtimeout > 0)
648 if (time_after(jiffies, lp->dialstarted + lp->dialtimeout)) {
649 lp->dialwait_timer = jiffies + lp->dialwait;
650 lp->dialstarted = 0;
651 isdn_net_unreachable(p->dev, NULL, "dial: timed out");
652 isdn_net_hangup(p->dev);
653 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700654 }
655
Linus Torvalds1da177e2005-04-16 15:20:36 -0700656 cmd.driver = lp->isdn_device;
Joe Perches475be4d2012-02-19 19:52:38 -0800657 cmd.command = ISDN_CMD_DIAL;
658 cmd.parm.setup.si2 = 0;
659
660 /* check for DOV */
661 phone_number = lp->dial->num;
662 if ((*phone_number == 'v') ||
663 (*phone_number == 'V')) { /* DOV call */
664 cmd.parm.setup.si1 = 1;
665 } else { /* DATA call */
666 cmd.parm.setup.si1 = 7;
667 }
668
669 strcpy(cmd.parm.setup.phone, phone_number);
670 /*
671 * Switch to next number or back to start if at end of list.
Linus Torvalds1da177e2005-04-16 15:20:36 -0700672 */
Joe Perches475be4d2012-02-19 19:52:38 -0800673 if (!(lp->dial = (isdn_net_phone *) lp->dial->next)) {
674 lp->dial = lp->phone[1];
675 lp->dialretry++;
676
677 if (lp->dialretry > lp->dialmax) {
678 if (lp->dialtimeout == 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700679 lp->dialwait_timer = jiffies + lp->dialwait;
680 lp->dialstarted = 0;
Joe Perches475be4d2012-02-19 19:52:38 -0800681 isdn_net_unreachable(p->dev, NULL, "dial: tried all numbers dialmax times");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 }
Joe Perches475be4d2012-02-19 19:52:38 -0800683 isdn_net_hangup(p->dev);
684 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700685 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700686 }
Joe Perches475be4d2012-02-19 19:52:38 -0800687 sprintf(cmd.parm.setup.eazmsn, "%s",
688 isdn_map_eaz2msn(lp->msn, cmd.driver));
689 i = isdn_dc2minor(lp->isdn_device, lp->isdn_channel);
690 if (i >= 0) {
691 strcpy(dev->num[i], cmd.parm.setup.phone);
692 dev->usage[i] |= ISDN_USAGE_OUTGOING;
693 isdn_info_update();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700694 }
Joe Perches475be4d2012-02-19 19:52:38 -0800695 printk(KERN_INFO "%s: dialing %d %s... %s\n", p->dev->name,
696 lp->dialretry, cmd.parm.setup.phone,
697 (cmd.parm.setup.si1 == 1) ? "DOV" : "");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700698 lp->dtimer = 0;
Joe Perches475be4d2012-02-19 19:52:38 -0800699#ifdef ISDN_DEBUG_NET_DIAL
700 printk(KERN_DEBUG "dial: d=%d c=%d\n", lp->isdn_device,
701 lp->isdn_channel);
702#endif
703 isdn_command(&cmd);
704 }
705 lp->huptimer = 0;
706 lp->outgoing = 1;
707 if (lp->chargeint) {
708 lp->hupflags |= ISDN_HAVECHARGE;
709 lp->hupflags &= ~ISDN_WAITCHARGE;
710 } else {
711 lp->hupflags |= ISDN_WAITCHARGE;
712 lp->hupflags &= ~ISDN_HAVECHARGE;
713 }
714 anymore = 1;
715 lp->dialstate =
716 (lp->cbdelay &&
717 (lp->flags & ISDN_NET_CBOUT)) ? 12 : 4;
718 break;
719 case 4:
720 /* Wait for D-Channel-connect.
721 * If timeout, switch back to state 3.
722 * Dialmax-handling moved to state 3.
723 */
724 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
725 lp->dialstate = 3;
726 anymore = 1;
727 break;
728 case 5:
729 /* Got D-Channel-Connect, send B-Channel-request */
730 cmd.driver = lp->isdn_device;
731 cmd.arg = lp->isdn_channel;
732 cmd.command = ISDN_CMD_ACCEPTB;
733 anymore = 1;
734 lp->dtimer = 0;
735 lp->dialstate++;
736 isdn_command(&cmd);
737 break;
738 case 6:
739 /* Wait for B- or D-Channel-connect. If timeout,
740 * switch back to state 3.
741 */
742#ifdef ISDN_DEBUG_NET_DIAL
743 printk(KERN_DEBUG "dialtimer2: %d\n", lp->dtimer);
744#endif
745 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
746 lp->dialstate = 3;
747 anymore = 1;
748 break;
749 case 7:
750 /* Got incoming Call, setup L2 and L3 protocols,
751 * then wait for D-Channel-connect
752 */
753#ifdef ISDN_DEBUG_NET_DIAL
754 printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
755#endif
756 cmd.driver = lp->isdn_device;
757 cmd.command = ISDN_CMD_SETL2;
758 cmd.arg = lp->isdn_channel + (lp->l2_proto << 8);
759 isdn_command(&cmd);
760 cmd.driver = lp->isdn_device;
761 cmd.command = ISDN_CMD_SETL3;
762 cmd.arg = lp->isdn_channel + (lp->l3_proto << 8);
763 isdn_command(&cmd);
764 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT15)
765 isdn_net_hangup(p->dev);
766 else {
767 anymore = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700768 lp->dialstate++;
Joe Perches475be4d2012-02-19 19:52:38 -0800769 }
770 break;
771 case 9:
772 /* Got incoming D-Channel-Connect, send B-Channel-request */
773 cmd.driver = lp->isdn_device;
774 cmd.arg = lp->isdn_channel;
775 cmd.command = ISDN_CMD_ACCEPTB;
776 isdn_command(&cmd);
777 anymore = 1;
778 lp->dtimer = 0;
779 lp->dialstate++;
780 break;
781 case 8:
782 case 10:
783 /* Wait for B- or D-channel-connect */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700784#ifdef ISDN_DEBUG_NET_DIAL
Joe Perches475be4d2012-02-19 19:52:38 -0800785 printk(KERN_DEBUG "dialtimer4: %d\n", lp->dtimer);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700786#endif
Joe Perches475be4d2012-02-19 19:52:38 -0800787 if (lp->dtimer++ > ISDN_TIMER_DTIMEOUT10)
788 isdn_net_hangup(p->dev);
789 else
Linus Torvalds1da177e2005-04-16 15:20:36 -0700790 anymore = 1;
Joe Perches475be4d2012-02-19 19:52:38 -0800791 break;
792 case 11:
793 /* Callback Delay */
794 if (lp->dtimer++ > lp->cbdelay)
795 lp->dialstate = 1;
796 anymore = 1;
797 break;
798 case 12:
799 /* Remote does callback. Hangup after cbdelay, then wait for incoming
800 * call (in state 4).
801 */
802 if (lp->dtimer++ > lp->cbdelay)
803 {
804 printk(KERN_INFO "%s: hangup waiting for callback ...\n", p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700805 lp->dtimer = 0;
Joe Perches475be4d2012-02-19 19:52:38 -0800806 lp->dialstate = 4;
807 cmd.driver = lp->isdn_device;
808 cmd.command = ISDN_CMD_HANGUP;
809 cmd.arg = lp->isdn_channel;
810 isdn_command(&cmd);
811 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
812 }
813 anymore = 1;
814 break;
815 default:
816 printk(KERN_WARNING "isdn_net: Illegal dialstate %d for device %s\n",
817 lp->dialstate, p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700818 }
819 p = (isdn_net_dev *) p->next;
820 }
821 isdn_timer_ctrl(ISDN_TIMER_NETDIAL, anymore);
822}
823
824/*
825 * Perform hangup for a net-interface.
826 */
827void
828isdn_net_hangup(struct net_device *d)
829{
Joe Perchesa17531f2010-11-15 11:12:24 +0000830 isdn_net_local *lp = netdev_priv(d);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700831 isdn_ctrl cmd;
832#ifdef CONFIG_ISDN_X25
833 struct concap_proto *cprot = lp->netdev->cprot;
834 struct concap_proto_ops *pops = cprot ? cprot->pops : NULL;
835#endif
836
837 if (lp->flags & ISDN_NET_CONNECTED) {
838 if (lp->slave != NULL) {
Wang Chen838361f2008-12-03 15:49:46 -0800839 isdn_net_local *slp = ISDN_SLAVE_PRIV(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 if (slp->flags & ISDN_NET_CONNECTED) {
841 printk(KERN_INFO
Joe Perches475be4d2012-02-19 19:52:38 -0800842 "isdn_net: hang up slave %s before %s\n",
843 lp->slave->name, d->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700844 isdn_net_hangup(lp->slave);
845 }
846 }
Karsten Keilfaca94f2007-10-15 02:11:44 -0700847 printk(KERN_INFO "isdn_net: local hangup %s\n", d->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700848#ifdef CONFIG_ISDN_PPP
849 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
850 isdn_ppp_free(lp);
851#endif
852 isdn_net_lp_disconnected(lp);
853#ifdef CONFIG_ISDN_X25
854 /* try if there are generic encap protocol
855 receiver routines and signal the closure of
856 the link */
Joe Perches475be4d2012-02-19 19:52:38 -0800857 if (pops && pops->disconn_ind)
858 pops->disconn_ind(cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700859#endif /* CONFIG_ISDN_X25 */
860
861 cmd.driver = lp->isdn_device;
862 cmd.command = ISDN_CMD_HANGUP;
863 cmd.arg = lp->isdn_channel;
864 isdn_command(&cmd);
Karsten Keilfaca94f2007-10-15 02:11:44 -0700865 printk(KERN_INFO "%s: Chargesum is %d\n", d->name, lp->charge);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700866 isdn_all_eaz(lp->isdn_device, lp->isdn_channel);
867 }
868 isdn_net_unbind_channel(lp);
869}
870
871typedef struct {
Harvey Harrisonc19d0362008-11-20 04:10:51 -0800872 __be16 source;
873 __be16 dest;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874} ip_ports;
875
876static void
Joe Perches475be4d2012-02-19 19:52:38 -0800877isdn_net_log_skb(struct sk_buff *skb, isdn_net_local *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700878{
Arnaldo Carvalho de Melod56f90a2007-04-10 20:50:43 -0700879 /* hopefully, this was set correctly */
880 const u_char *p = skb_network_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700881 unsigned short proto = ntohs(skb->protocol);
882 int data_ofs;
883 ip_ports *ipp;
884 char addinfo[100];
885
886 addinfo[0] = '\0';
887 /* This check stolen from 2.1.72 dev_queue_xmit_nit() */
Simon Horman25b6e142013-05-28 20:34:23 +0000888 if (p < skb->data || skb_network_header(skb) >= skb_tail_pointer(skb)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700889 /* fall back to old isdn_net_log_packet method() */
Joe Perches475be4d2012-02-19 19:52:38 -0800890 char *buf = skb->data;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700891
Karsten Keilfaca94f2007-10-15 02:11:44 -0700892 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 -0700893 p = buf;
894 proto = ETH_P_IP;
895 switch (lp->p_encap) {
Joe Perches475be4d2012-02-19 19:52:38 -0800896 case ISDN_NET_ENCAP_IPTYP:
897 proto = ntohs(*(__be16 *)&buf[0]);
898 p = &buf[2];
899 break;
900 case ISDN_NET_ENCAP_ETHER:
901 proto = ntohs(*(__be16 *)&buf[12]);
902 p = &buf[14];
903 break;
904 case ISDN_NET_ENCAP_CISCOHDLC:
905 proto = ntohs(*(__be16 *)&buf[2]);
906 p = &buf[4];
907 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908#ifdef CONFIG_ISDN_PPP
Joe Perches475be4d2012-02-19 19:52:38 -0800909 case ISDN_NET_ENCAP_SYNCPPP:
910 proto = ntohs(skb->protocol);
911 p = &buf[IPPP_MAX_HEADER];
912 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700913#endif
914 }
915 }
916 data_ofs = ((p[0] & 15) * 4);
917 switch (proto) {
Joe Perches475be4d2012-02-19 19:52:38 -0800918 case ETH_P_IP:
919 switch (p[9]) {
920 case 1:
921 strcpy(addinfo, " ICMP");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700922 break;
Joe Perches475be4d2012-02-19 19:52:38 -0800923 case 2:
924 strcpy(addinfo, " IGMP");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700925 break;
Joe Perches475be4d2012-02-19 19:52:38 -0800926 case 4:
927 strcpy(addinfo, " IPIP");
928 break;
929 case 6:
930 ipp = (ip_ports *) (&p[data_ofs]);
931 sprintf(addinfo, " TCP, port: %d -> %d", ntohs(ipp->source),
932 ntohs(ipp->dest));
933 break;
934 case 8:
935 strcpy(addinfo, " EGP");
936 break;
937 case 12:
938 strcpy(addinfo, " PUP");
939 break;
940 case 17:
941 ipp = (ip_ports *) (&p[data_ofs]);
942 sprintf(addinfo, " UDP, port: %d -> %d", ntohs(ipp->source),
943 ntohs(ipp->dest));
944 break;
945 case 22:
946 strcpy(addinfo, " IDP");
947 break;
948 }
949 printk(KERN_INFO "OPEN: %pI4 -> %pI4%s\n",
950 p + 12, p + 16, addinfo);
951 break;
952 case ETH_P_ARP:
953 printk(KERN_INFO "OPEN: ARP %pI4 -> *.*.*.* ?%pI4\n",
954 p + 14, p + 24);
955 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 }
957}
958
959/*
960 * this function is used to send supervisory data, i.e. data which was
961 * not received from the network layer, but e.g. frames from ipppd, CCP
962 * reset frames etc.
963 */
964void isdn_net_write_super(isdn_net_local *lp, struct sk_buff *skb)
965{
966 if (in_irq()) {
Joe Perches475be4d2012-02-19 19:52:38 -0800967 // we can't grab the lock from irq context,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700968 // so we just queue the packet
969 skb_queue_tail(&lp->super_tx_queue, skb);
970 schedule_work(&lp->tqueue);
971 return;
972 }
973
974 spin_lock_bh(&lp->xmit_lock);
975 if (!isdn_net_lp_busy(lp)) {
976 isdn_net_writebuf_skb(lp, skb);
977 } else {
978 skb_queue_tail(&lp->super_tx_queue, skb);
979 }
980 spin_unlock_bh(&lp->xmit_lock);
981}
982
983/*
984 * called from tq_immediate
985 */
David Howellsc4028952006-11-22 14:57:56 +0000986static void isdn_net_softint(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700987{
David Howellsc4028952006-11-22 14:57:56 +0000988 isdn_net_local *lp = container_of(work, isdn_net_local, tqueue);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700989 struct sk_buff *skb;
990
991 spin_lock_bh(&lp->xmit_lock);
992 while (!isdn_net_lp_busy(lp)) {
993 skb = skb_dequeue(&lp->super_tx_queue);
994 if (!skb)
995 break;
Joe Perches475be4d2012-02-19 19:52:38 -0800996 isdn_net_writebuf_skb(lp, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700997 }
998 spin_unlock_bh(&lp->xmit_lock);
999}
1000
Joe Perches475be4d2012-02-19 19:52:38 -08001001/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001002 * all frames sent from the (net) LL to a HL driver should go via this function
1003 * it's serialized by the caller holding the lp->xmit_lock spinlock
1004 */
1005void isdn_net_writebuf_skb(isdn_net_local *lp, struct sk_buff *skb)
1006{
1007 int ret;
1008 int len = skb->len; /* save len */
1009
1010 /* before obtaining the lock the caller should have checked that
1011 the lp isn't busy */
1012 if (isdn_net_lp_busy(lp)) {
1013 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1014 goto error;
1015 }
1016
1017 if (!(lp->flags & ISDN_NET_CONNECTED)) {
1018 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1019 goto error;
1020 }
1021 ret = isdn_writebuf_skb_stub(lp->isdn_device, lp->isdn_channel, 1, skb);
1022 if (ret != len) {
1023 /* we should never get here */
Karsten Keilfaca94f2007-10-15 02:11:44 -07001024 printk(KERN_WARNING "%s: HL driver queue full\n", lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001025 goto error;
1026 }
Joe Perches475be4d2012-02-19 19:52:38 -08001027
Linus Torvalds1da177e2005-04-16 15:20:36 -07001028 lp->transcount += len;
1029 isdn_net_inc_frame_cnt(lp);
1030 return;
1031
Joe Perches475be4d2012-02-19 19:52:38 -08001032error:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 dev_kfree_skb(skb);
1034 lp->stats.tx_errors++;
1035
1036}
1037
1038
1039/*
1040 * Helper function for isdn_net_start_xmit.
1041 * When called, the connection is already established.
1042 * Based on cps-calculation, check if device is overloaded.
1043 * If so, and if a slave exists, trigger dialing for it.
1044 * If any slave is online, deliver packets using a simple round robin
1045 * scheme.
1046 *
1047 * Return: 0 on success, !0 on failure.
1048 */
1049
1050static int
1051isdn_net_xmit(struct net_device *ndev, struct sk_buff *skb)
1052{
1053 isdn_net_dev *nd;
1054 isdn_net_local *slp;
Joe Perchesa17531f2010-11-15 11:12:24 +00001055 isdn_net_local *lp = netdev_priv(ndev);
Patrick McHardyec634fe2009-07-05 19:23:38 -07001056 int retv = NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001057
Wang Chen838361f2008-12-03 15:49:46 -08001058 if (((isdn_net_local *) netdev_priv(ndev))->master) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1060 dev_kfree_skb(skb);
Patrick McHardyec634fe2009-07-05 19:23:38 -07001061 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001062 }
1063
1064 /* For the other encaps the header has already been built */
1065#ifdef CONFIG_ISDN_PPP
1066 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1067 return isdn_ppp_xmit(skb, ndev);
1068 }
1069#endif
Wang Chen838361f2008-12-03 15:49:46 -08001070 nd = ((isdn_net_local *) netdev_priv(ndev))->netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001071 lp = isdn_net_get_locked_lp(nd);
1072 if (!lp) {
1073 printk(KERN_WARNING "%s: all channels busy - requeuing!\n", ndev->name);
Patrick McHardy5b548142009-06-12 06:22:29 +00001074 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001075 }
1076 /* we have our lp locked from now on */
1077
1078 /* Reset hangup-timeout */
1079 lp->huptimer = 0; // FIXME?
1080 isdn_net_writebuf_skb(lp, skb);
1081 spin_unlock_bh(&lp->xmit_lock);
1082
1083 /* the following stuff is here for backwards compatibility.
1084 * in future, start-up and hangup of slaves (based on current load)
1085 * should move to userspace and get based on an overall cps
1086 * calculation
1087 */
1088 if (lp->cps > lp->triggercps) {
1089 if (lp->slave) {
1090 if (!lp->sqfull) {
1091 /* First time overload: set timestamp only */
1092 lp->sqfull = 1;
1093 lp->sqfull_stamp = jiffies;
1094 } else {
1095 /* subsequent overload: if slavedelay exceeded, start dialing */
1096 if (time_after(jiffies, lp->sqfull_stamp + lp->slavedelay)) {
Wang Chen838361f2008-12-03 15:49:46 -08001097 slp = ISDN_SLAVE_PRIV(lp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001098 if (!(slp->flags & ISDN_NET_CONNECTED)) {
Wang Chen838361f2008-12-03 15:49:46 -08001099 isdn_net_force_dial_lp(ISDN_SLAVE_PRIV(lp));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001100 }
1101 }
1102 }
1103 }
1104 } else {
1105 if (lp->sqfull && time_after(jiffies, lp->sqfull_stamp + lp->slavedelay + (10 * HZ))) {
1106 lp->sqfull = 0;
1107 }
1108 /* this is a hack to allow auto-hangup for slaves on moderate loads */
1109 nd->queue = nd->local;
1110 }
1111
1112 return retv;
1113
1114}
1115
1116static void
1117isdn_net_adjust_hdr(struct sk_buff *skb, struct net_device *dev)
1118{
Joe Perchesa17531f2010-11-15 11:12:24 +00001119 isdn_net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001120 if (!skb)
1121 return;
1122 if (lp->p_encap == ISDN_NET_ENCAP_ETHER) {
Arnaldo Carvalho de Melobbe735e2007-03-10 22:16:10 -03001123 const int pullsize = skb_network_offset(skb) - ETH_HLEN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001124 if (pullsize > 0) {
1125 printk(KERN_DEBUG "isdn_net: Pull junk %d\n", pullsize);
1126 skb_pull(skb, pullsize);
1127 }
1128 }
1129}
1130
1131
Joe Perches475be4d2012-02-19 19:52:38 -08001132static void isdn_net_tx_timeout(struct net_device *ndev)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133{
Joe Perchesa17531f2010-11-15 11:12:24 +00001134 isdn_net_local *lp = netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001135
1136 printk(KERN_WARNING "isdn_tx_timeout dev %s dialstate %d\n", ndev->name, lp->dialstate);
Joe Perches475be4d2012-02-19 19:52:38 -08001137 if (!lp->dialstate) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001138 lp->stats.tx_errors++;
Joe Perches475be4d2012-02-19 19:52:38 -08001139 /*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140 * There is a certain probability that this currently
1141 * works at all because if we always wake up the interface,
1142 * then upper layer will try to send the next packet
1143 * immediately. And then, the old clean_up logic in the
1144 * driver will hopefully continue to work as it used to do.
1145 *
1146 * This is rather primitive right know, we better should
1147 * clean internal queues here, in particular for multilink and
1148 * ppp, and reset HL driver's channel, too. --HE
1149 *
1150 * actually, this may not matter at all, because ISDN hardware
1151 * should not see transmitter hangs at all IMO
Joe Perches475be4d2012-02-19 19:52:38 -08001152 * changed KERN_DEBUG to KERN_WARNING to find out if this is
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 * ever called --KG
1154 */
1155 }
Florian Westphal860e9532016-05-03 16:33:13 +02001156 netif_trans_update(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001157 netif_wake_queue(ndev);
1158}
1159
1160/*
1161 * Try sending a packet.
1162 * If this interface isn't connected to a ISDN-Channel, find a free channel,
1163 * and start dialing.
1164 */
Stephen Hemminger8b62ff22009-08-31 19:50:44 +00001165static netdev_tx_t
Linus Torvalds1da177e2005-04-16 15:20:36 -07001166isdn_net_start_xmit(struct sk_buff *skb, struct net_device *ndev)
1167{
Joe Perchesa17531f2010-11-15 11:12:24 +00001168 isdn_net_local *lp = netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001170 struct concap_proto *cprot = lp->netdev->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171/* At this point hard_start_xmit() passes control to the encapsulation
1172 protocol (if present).
1173 For X.25 auto-dialing is completly bypassed because:
1174 - It does not conform with the semantics of a reliable datalink
Joe Perches475be4d2012-02-19 19:52:38 -08001175 service as needed by X.25 PLP.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001176 - I don't want that the interface starts dialing when the network layer
Joe Perches475be4d2012-02-19 19:52:38 -08001177 sends a message which requests to disconnect the lapb link (or if it
1178 sends any other message not resulting in data transmission).
Linus Torvalds1da177e2005-04-16 15:20:36 -07001179 Instead, dialing will be initiated by the encapsulation protocol entity
1180 when a dl_establish request is received from the upper layer.
1181*/
Joe Perches475be4d2012-02-19 19:52:38 -08001182 if (cprot && cprot->pops) {
1183 int ret = cprot->pops->encap_and_xmit(cprot, skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184
1185 if (ret)
1186 netif_stop_queue(ndev);
1187 return ret;
1188 } else
1189#endif
Joe Perches475be4d2012-02-19 19:52:38 -08001190 /* auto-dialing xmit function */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001191 {
1192#ifdef ISDN_DEBUG_NET_DUMP
1193 u_char *buf;
1194#endif
1195 isdn_net_adjust_hdr(skb, ndev);
1196#ifdef ISDN_DEBUG_NET_DUMP
1197 buf = skb->data;
1198 isdn_dumppkt("S:", buf, skb->len, 40);
1199#endif
1200
1201 if (!(lp->flags & ISDN_NET_CONNECTED)) {
1202 int chi;
1203 /* only do autodial if allowed by config */
1204 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) {
1205 isdn_net_unreachable(ndev, skb, "dial rejected: interface not in dialmode `auto'");
1206 dev_kfree_skb(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001207 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001208 }
1209 if (lp->phone[1]) {
1210 ulong flags;
1211
Joe Perches475be4d2012-02-19 19:52:38 -08001212 if (lp->dialwait_timer <= 0)
1213 if (lp->dialstarted > 0 && lp->dialtimeout > 0 && time_before(jiffies, lp->dialstarted + lp->dialtimeout + lp->dialwait))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 lp->dialwait_timer = lp->dialstarted + lp->dialtimeout + lp->dialwait;
1215
Joe Perches475be4d2012-02-19 19:52:38 -08001216 if (lp->dialwait_timer > 0) {
1217 if (time_before(jiffies, lp->dialwait_timer)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 isdn_net_unreachable(ndev, skb, "dial rejected: retry-time not reached");
1219 dev_kfree_skb(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001220 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001221 } else
1222 lp->dialwait_timer = 0;
1223 }
1224 /* Grab a free ISDN-Channel */
1225 spin_lock_irqsave(&dev->lock, flags);
1226 if (((chi =
Joe Perches475be4d2012-02-19 19:52:38 -08001227 isdn_get_free_channel(
1228 ISDN_USAGE_NET,
1229 lp->l2_proto,
1230 lp->l3_proto,
1231 lp->pre_device,
1232 lp->pre_channel,
1233 lp->msn)
1234 ) < 0) &&
1235 ((chi =
1236 isdn_get_free_channel(
1237 ISDN_USAGE_NET,
1238 lp->l2_proto,
1239 lp->l3_proto,
1240 lp->pre_device,
1241 lp->pre_channel^1,
1242 lp->msn)
1243 ) < 0)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001244 spin_unlock_irqrestore(&dev->lock, flags);
1245 isdn_net_unreachable(ndev, skb,
Joe Perches475be4d2012-02-19 19:52:38 -08001246 "No channel");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001247 dev_kfree_skb(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001248 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 }
1250 /* Log packet, which triggered dialing */
1251 if (dev->net_verbose)
1252 isdn_net_log_skb(skb, lp);
1253 lp->dialstate = 1;
1254 /* Connect interface with channel */
1255 isdn_net_bind_channel(lp, chi);
1256#ifdef CONFIG_ISDN_PPP
1257 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
1258 /* no 'first_skb' handling for syncPPP */
1259 if (isdn_ppp_bind(lp) < 0) {
1260 dev_kfree_skb(skb);
1261 isdn_net_unbind_channel(lp);
1262 spin_unlock_irqrestore(&dev->lock, flags);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001263 return NETDEV_TX_OK; /* STN (skb to nirvana) ;) */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001264 }
1265#ifdef CONFIG_IPPP_FILTER
1266 if (isdn_ppp_autodial_filter(skb, lp)) {
1267 isdn_ppp_free(lp);
1268 isdn_net_unbind_channel(lp);
1269 spin_unlock_irqrestore(&dev->lock, flags);
1270 isdn_net_unreachable(ndev, skb, "dial rejected: packet filtered");
1271 dev_kfree_skb(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001272 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001273 }
1274#endif
1275 spin_unlock_irqrestore(&dev->lock, flags);
1276 isdn_net_dial(); /* Initiate dialing */
1277 netif_stop_queue(ndev);
Patrick McHardy5b548142009-06-12 06:22:29 +00001278 return NETDEV_TX_BUSY; /* let upper layer requeue skb packet */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 }
1280#endif
1281 /* Initiate dialing */
1282 spin_unlock_irqrestore(&dev->lock, flags);
1283 isdn_net_dial();
1284 isdn_net_device_stop_queue(lp);
Patrick McHardy5b548142009-06-12 06:22:29 +00001285 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001286 } else {
1287 isdn_net_unreachable(ndev, skb,
1288 "No phone number");
1289 dev_kfree_skb(skb);
Patrick McHardy6ed10652009-06-23 06:03:08 +00001290 return NETDEV_TX_OK;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001291 }
1292 } else {
Joe Perches475be4d2012-02-19 19:52:38 -08001293 /* Device is connected to an ISDN channel */
Florian Westphal860e9532016-05-03 16:33:13 +02001294 netif_trans_update(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001295 if (!lp->dialstate) {
1296 /* ISDN connection is established, try sending */
1297 int ret;
1298 ret = (isdn_net_xmit(ndev, skb));
Joe Perches475be4d2012-02-19 19:52:38 -08001299 if (ret) netif_stop_queue(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 return ret;
1301 } else
1302 netif_stop_queue(ndev);
1303 }
1304 }
Patrick McHardyd77eeb72009-06-15 23:33:24 +00001305 return NETDEV_TX_BUSY;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306}
1307
1308/*
1309 * Shutdown a net-interface.
1310 */
1311static int
1312isdn_net_close(struct net_device *dev)
1313{
1314 struct net_device *p;
1315#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001316 struct concap_proto *cprot =
1317 ((isdn_net_local *)netdev_priv(dev))->netdev->cprot;
1318 /* printk(KERN_DEBUG "isdn_net_close %s\n" , dev-> name); */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001319#endif
1320
1321#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001322 if (cprot && cprot->pops) cprot->pops->close(cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323#endif
1324 netif_stop_queue(dev);
Wang Chen838361f2008-12-03 15:49:46 -08001325 p = MASTER_TO_SLAVE(dev);
1326 if (p) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327 /* If this interface has slaves, stop them also */
1328 while (p) {
1329#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001330 cprot = ((isdn_net_local *)netdev_priv(p))
1331 ->netdev->cprot;
1332 if (cprot && cprot->pops)
1333 cprot->pops->close(cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001334#endif
1335 isdn_net_hangup(p);
Wang Chen838361f2008-12-03 15:49:46 -08001336 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338 }
1339 isdn_net_hangup(dev);
1340 isdn_unlock_drivers();
1341 return 0;
1342}
1343
1344/*
1345 * Get statistics
1346 */
1347static struct net_device_stats *
1348isdn_net_get_stats(struct net_device *dev)
1349{
Joe Perchesa17531f2010-11-15 11:12:24 +00001350 isdn_net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001351 return &lp->stats;
1352}
1353
1354/* This is simply a copy from std. eth.c EXCEPT we pull ETH_HLEN
1355 * instead of dev->hard_header_len off. This is done because the
1356 * lowlevel-driver has already pulled off its stuff when we get
1357 * here and this routine only gets called with p_encap == ETHER.
1358 * Determine the packet's protocol ID. The rule here is that we
1359 * assume 802.3 if the type field is short enough to be a length.
1360 * This is normal practice and works for any 'now in use' protocol.
1361 */
1362
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001363static __be16
Linus Torvalds1da177e2005-04-16 15:20:36 -07001364isdn_net_type_trans(struct sk_buff *skb, struct net_device *dev)
1365{
1366 struct ethhdr *eth;
1367 unsigned char *rawp;
1368
Arnaldo Carvalho de Melo459a98e2007-03-19 15:30:44 -07001369 skb_reset_mac_header(skb);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 skb_pull(skb, ETH_HLEN);
1371 eth = eth_hdr(skb);
1372
1373 if (*eth->h_dest & 1) {
dingtianhong48f045b2013-12-26 19:41:05 +08001374 if (ether_addr_equal(eth->h_dest, dev->broadcast))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 skb->pkt_type = PACKET_BROADCAST;
1376 else
1377 skb->pkt_type = PACKET_MULTICAST;
1378 }
1379 /*
1380 * This ALLMULTI check should be redundant by 1.4
1381 * so don't forget to remove it.
1382 */
1383
1384 else if (dev->flags & (IFF_PROMISC /*| IFF_ALLMULTI*/)) {
dingtianhong48f045b2013-12-26 19:41:05 +08001385 if (!ether_addr_equal(eth->h_dest, dev->dev_addr))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001386 skb->pkt_type = PACKET_OTHERHOST;
1387 }
Simon Hormane5c5d222013-03-28 13:38:25 +09001388 if (ntohs(eth->h_proto) >= ETH_P_802_3_MIN)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001389 return eth->h_proto;
1390
1391 rawp = skb->data;
1392
1393 /*
1394 * This is a magic hack to spot IPX packets. Older Novell breaks
1395 * the protocol design and runs IPX over 802.3 without an 802.2 LLC
1396 * layer. We look for FFFF which isn't a used 802.2 SSAP/DSAP. This
1397 * won't work for fault tolerant netware but does for the rest.
1398 */
1399 if (*(unsigned short *) rawp == 0xFFFF)
1400 return htons(ETH_P_802_3);
1401 /*
1402 * Real 802.2 LLC
1403 */
1404 return htons(ETH_P_802_2);
1405}
1406
1407
Joe Perches475be4d2012-02-19 19:52:38 -08001408/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 * CISCO HDLC keepalive specific stuff
1410 */
1411static struct sk_buff*
1412isdn_net_ciscohdlck_alloc_skb(isdn_net_local *lp, int len)
1413{
1414 unsigned short hl = dev->drv[lp->isdn_device]->interface->hl_hdrlen;
1415 struct sk_buff *skb;
1416
1417 skb = alloc_skb(hl + len, GFP_ATOMIC);
1418 if (skb)
1419 skb_reserve(skb, hl);
Joe Perches475be4d2012-02-19 19:52:38 -08001420 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001421 printk("isdn out of mem at %s:%d!\n", __FILE__, __LINE__);
1422 return skb;
1423}
1424
1425/* cisco hdlck device private ioctls */
Adrian Bunk3e206b02005-06-25 14:58:35 -07001426static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001427isdn_ciscohdlck_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
1428{
Joe Perchesa17531f2010-11-15 11:12:24 +00001429 isdn_net_local *lp = netdev_priv(dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001430 unsigned long len = 0;
1431 unsigned long expires = 0;
1432 int tmp = 0;
1433 int period = lp->cisco_keepalive_period;
1434 s8 debserint = lp->cisco_debserint;
1435 int rc = 0;
1436
1437 if (lp->p_encap != ISDN_NET_ENCAP_CISCOHDLCK)
1438 return -EINVAL;
1439
1440 switch (cmd) {
1441 /* get/set keepalive period */
Joe Perches475be4d2012-02-19 19:52:38 -08001442 case SIOCGKEEPPERIOD:
1443 len = (unsigned long)sizeof(lp->cisco_keepalive_period);
1444 if (copy_to_user(ifr->ifr_data,
1445 &lp->cisco_keepalive_period, len))
1446 rc = -EFAULT;
1447 break;
1448 case SIOCSKEEPPERIOD:
1449 tmp = lp->cisco_keepalive_period;
1450 len = (unsigned long)sizeof(lp->cisco_keepalive_period);
1451 if (copy_from_user(&period, ifr->ifr_data, len))
1452 rc = -EFAULT;
1453 if ((period > 0) && (period <= 32767))
1454 lp->cisco_keepalive_period = period;
1455 else
1456 rc = -EINVAL;
1457 if (!rc && (tmp != lp->cisco_keepalive_period)) {
1458 expires = (unsigned long)(jiffies +
1459 lp->cisco_keepalive_period * HZ);
1460 mod_timer(&lp->cisco_timer, expires);
1461 printk(KERN_INFO "%s: Keepalive period set "
1462 "to %d seconds.\n",
1463 dev->name, lp->cisco_keepalive_period);
1464 }
1465 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001466
1467 /* get/set debugging */
Joe Perches475be4d2012-02-19 19:52:38 -08001468 case SIOCGDEBSERINT:
1469 len = (unsigned long)sizeof(lp->cisco_debserint);
1470 if (copy_to_user(ifr->ifr_data,
1471 &lp->cisco_debserint, len))
1472 rc = -EFAULT;
1473 break;
1474 case SIOCSDEBSERINT:
1475 len = (unsigned long)sizeof(lp->cisco_debserint);
1476 if (copy_from_user(&debserint,
1477 ifr->ifr_data, len))
1478 rc = -EFAULT;
1479 if ((debserint >= 0) && (debserint <= 64))
1480 lp->cisco_debserint = debserint;
1481 else
Linus Torvalds1da177e2005-04-16 15:20:36 -07001482 rc = -EINVAL;
Joe Perches475be4d2012-02-19 19:52:38 -08001483 break;
1484
1485 default:
1486 rc = -EINVAL;
1487 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001488 }
1489 return (rc);
1490}
1491
Stephen Hemmingerd7005552009-01-07 18:04:17 -08001492
1493static int isdn_net_ioctl(struct net_device *dev,
1494 struct ifreq *ifr, int cmd)
1495{
Joe Perchesa17531f2010-11-15 11:12:24 +00001496 isdn_net_local *lp = netdev_priv(dev);
Stephen Hemmingerd7005552009-01-07 18:04:17 -08001497
1498 switch (lp->p_encap) {
1499#ifdef CONFIG_ISDN_PPP
1500 case ISDN_NET_ENCAP_SYNCPPP:
1501 return isdn_ppp_dev_ioctl(dev, ifr, cmd);
1502#endif
1503 case ISDN_NET_ENCAP_CISCOHDLCK:
1504 return isdn_ciscohdlck_dev_ioctl(dev, ifr, cmd);
1505 default:
1506 return -EINVAL;
1507 }
1508}
1509
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510/* called via cisco_timer.function */
1511static void
1512isdn_net_ciscohdlck_slarp_send_keepalive(unsigned long data)
1513{
1514 isdn_net_local *lp = (isdn_net_local *) data;
1515 struct sk_buff *skb;
1516 unsigned char *p;
1517 unsigned long last_cisco_myseq = lp->cisco_myseq;
1518 int myseq_diff = 0;
1519
1520 if (!(lp->flags & ISDN_NET_CONNECTED) || lp->dialstate) {
1521 printk("isdn BUG at %s:%d!\n", __FILE__, __LINE__);
1522 return;
1523 }
1524 lp->cisco_myseq++;
1525
1526 myseq_diff = (lp->cisco_myseq - lp->cisco_mineseen);
Joe Perches475be4d2012-02-19 19:52:38 -08001527 if ((lp->cisco_line_state) && ((myseq_diff >= 3) || (myseq_diff <= -3))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001528 /* line up -> down */
1529 lp->cisco_line_state = 0;
Joe Perches475be4d2012-02-19 19:52:38 -08001530 printk(KERN_WARNING
1531 "UPDOWN: Line protocol on Interface %s,"
1532 " changed state to down\n", lp->netdev->dev->name);
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001533 /* should stop routing higher-level data across */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001534 } else if ((!lp->cisco_line_state) &&
Joe Perches475be4d2012-02-19 19:52:38 -08001535 (myseq_diff >= 0) && (myseq_diff <= 2)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536 /* line down -> up */
1537 lp->cisco_line_state = 1;
Joe Perches475be4d2012-02-19 19:52:38 -08001538 printk(KERN_WARNING
1539 "UPDOWN: Line protocol on Interface %s,"
1540 " changed state to up\n", lp->netdev->dev->name);
Lucas De Marchi25985ed2011-03-30 22:57:33 -03001541 /* restart routing higher-level data across */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 }
1543
1544 if (lp->cisco_debserint)
Joe Perches475be4d2012-02-19 19:52:38 -08001545 printk(KERN_DEBUG "%s: HDLC "
1546 "myseq %lu, mineseen %lu%c, yourseen %lu, %s\n",
1547 lp->netdev->dev->name, last_cisco_myseq, lp->cisco_mineseen,
1548 ((last_cisco_myseq == lp->cisco_mineseen) ? '*' : 040),
1549 lp->cisco_yourseq,
1550 ((lp->cisco_line_state) ? "line up" : "line down"));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551
1552 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1553 if (!skb)
1554 return;
1555
1556 p = skb_put(skb, 4 + 14);
1557
1558 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001559 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1560 *(u8 *)(p + 1) = CISCO_CTRL;
1561 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562
1563 /* slarp keepalive */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001564 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_KEEPALIVE);
1565 *(__be32 *)(p + 8) = cpu_to_be32(lp->cisco_myseq);
1566 *(__be32 *)(p + 12) = cpu_to_be32(lp->cisco_yourseq);
Dirk Hohndel06fe9fb2009-09-28 21:43:57 -04001567 *(__be16 *)(p + 16) = cpu_to_be16(0xffff); // reliability, always 0xffff
Harvey Harrison00bcd522008-11-13 22:41:29 -08001568 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001569
1570 isdn_net_write_super(lp, skb);
1571
1572 lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
Joe Perches475be4d2012-02-19 19:52:38 -08001573
Linus Torvalds1da177e2005-04-16 15:20:36 -07001574 add_timer(&lp->cisco_timer);
1575}
1576
1577static void
1578isdn_net_ciscohdlck_slarp_send_request(isdn_net_local *lp)
1579{
1580 struct sk_buff *skb;
1581 unsigned char *p;
1582
1583 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1584 if (!skb)
1585 return;
1586
1587 p = skb_put(skb, 4 + 14);
1588
1589 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001590 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1591 *(u8 *)(p + 1) = CISCO_CTRL;
1592 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001593
1594 /* slarp request */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001595 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_REQUEST);
1596 *(__be32 *)(p + 8) = cpu_to_be32(0); // address
1597 *(__be32 *)(p + 12) = cpu_to_be32(0); // netmask
1598 *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
1599 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001600
1601 isdn_net_write_super(lp, skb);
1602}
1603
Joe Perches475be4d2012-02-19 19:52:38 -08001604static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07001605isdn_net_ciscohdlck_connected(isdn_net_local *lp)
1606{
1607 lp->cisco_myseq = 0;
1608 lp->cisco_mineseen = 0;
1609 lp->cisco_yourseq = 0;
1610 lp->cisco_keepalive_period = ISDN_TIMER_KEEPINT;
1611 lp->cisco_last_slarp_in = 0;
1612 lp->cisco_line_state = 0;
1613 lp->cisco_debserint = 0;
1614
1615 /* send slarp request because interface/seq.no.s reset */
1616 isdn_net_ciscohdlck_slarp_send_request(lp);
1617
1618 init_timer(&lp->cisco_timer);
1619 lp->cisco_timer.data = (unsigned long) lp;
1620 lp->cisco_timer.function = isdn_net_ciscohdlck_slarp_send_keepalive;
1621 lp->cisco_timer.expires = jiffies + lp->cisco_keepalive_period * HZ;
1622 add_timer(&lp->cisco_timer);
1623}
1624
Joe Perches475be4d2012-02-19 19:52:38 -08001625static void
Linus Torvalds1da177e2005-04-16 15:20:36 -07001626isdn_net_ciscohdlck_disconnected(isdn_net_local *lp)
1627{
1628 del_timer(&lp->cisco_timer);
1629}
1630
1631static void
1632isdn_net_ciscohdlck_slarp_send_reply(isdn_net_local *lp)
1633{
1634 struct sk_buff *skb;
1635 unsigned char *p;
1636 struct in_device *in_dev = NULL;
Al Viroa144ea42006-09-28 18:00:55 -07001637 __be32 addr = 0; /* local ipv4 address */
1638 __be32 mask = 0; /* local netmask */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001639
Karsten Keild62a38d2007-10-08 20:37:11 -07001640 if ((in_dev = lp->netdev->dev->ip_ptr) != NULL) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001641 /* take primary(first) address of interface */
1642 struct in_ifaddr *ifa = in_dev->ifa_list;
1643 if (ifa != NULL) {
1644 addr = ifa->ifa_local;
1645 mask = ifa->ifa_mask;
1646 }
1647 }
1648
1649 skb = isdn_net_ciscohdlck_alloc_skb(lp, 4 + 14);
1650 if (!skb)
1651 return;
1652
1653 p = skb_put(skb, 4 + 14);
1654
1655 /* cisco header */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001656 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1657 *(u8 *)(p + 1) = CISCO_CTRL;
1658 *(__be16 *)(p + 2) = cpu_to_be16(CISCO_TYPE_SLARP);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001659
1660 /* slarp reply, send own ip/netmask; if values are nonsense remote
1661 * should think we are unable to provide it with an address via SLARP */
Harvey Harrison00bcd522008-11-13 22:41:29 -08001662 *(__be32 *)(p + 4) = cpu_to_be32(CISCO_SLARP_REPLY);
David S. Miller198d6ba2008-11-18 23:38:23 -08001663 *(__be32 *)(p + 8) = addr; // address
1664 *(__be32 *)(p + 12) = mask; // netmask
Harvey Harrison00bcd522008-11-13 22:41:29 -08001665 *(__be16 *)(p + 16) = cpu_to_be16(0); // unused
1666 p += 18;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001667
1668 isdn_net_write_super(lp, skb);
1669}
1670
1671static void
1672isdn_net_ciscohdlck_slarp_in(isdn_net_local *lp, struct sk_buff *skb)
1673{
1674 unsigned char *p;
1675 int period;
1676 u32 code;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001677 u32 my_seq;
1678 u32 your_seq;
1679 __be32 local;
1680 __be32 *addr, *mask;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001681
1682 if (skb->len < 14)
1683 return;
1684
1685 p = skb->data;
Harvey Harrison00bcd522008-11-13 22:41:29 -08001686 code = be32_to_cpup((__be32 *)p);
1687 p += 4;
1688
Linus Torvalds1da177e2005-04-16 15:20:36 -07001689 switch (code) {
1690 case CISCO_SLARP_REQUEST:
1691 lp->cisco_yourseq = 0;
1692 isdn_net_ciscohdlck_slarp_send_reply(lp);
1693 break;
1694 case CISCO_SLARP_REPLY:
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001695 addr = (__be32 *)p;
1696 mask = (__be32 *)(p + 4);
1697 if (*mask != cpu_to_be32(0xfffffffc))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001698 goto slarp_reply_out;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001699 if ((*addr & cpu_to_be32(3)) == cpu_to_be32(0) ||
1700 (*addr & cpu_to_be32(3)) == cpu_to_be32(3))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001701 goto slarp_reply_out;
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001702 local = *addr ^ cpu_to_be32(3);
1703 printk(KERN_INFO "%s: got slarp reply: remote ip: %pI4, local ip: %pI4 mask: %pI4\n",
1704 lp->netdev->dev->name, addr, &local, mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001705 break;
Joe Perches475be4d2012-02-19 19:52:38 -08001706 slarp_reply_out:
Harvey Harrison8cf14e32008-10-29 22:43:33 -07001707 printk(KERN_INFO "%s: got invalid slarp reply (%pI4/%pI4) - ignored\n",
1708 lp->netdev->dev->name, addr, mask);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709 break;
1710 case CISCO_SLARP_KEEPALIVE:
1711 period = (int)((jiffies - lp->cisco_last_slarp_in
Joe Perches475be4d2012-02-19 19:52:38 -08001712 + HZ / 2 - 1) / HZ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001713 if (lp->cisco_debserint &&
Joe Perches475be4d2012-02-19 19:52:38 -08001714 (period != lp->cisco_keepalive_period) &&
1715 lp->cisco_last_slarp_in) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001716 printk(KERN_DEBUG "%s: Keepalive period mismatch - "
Joe Perches475be4d2012-02-19 19:52:38 -08001717 "is %d but should be %d.\n",
1718 lp->netdev->dev->name, period,
1719 lp->cisco_keepalive_period);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001720 }
1721 lp->cisco_last_slarp_in = jiffies;
Harvey Harrison00bcd522008-11-13 22:41:29 -08001722 my_seq = be32_to_cpup((__be32 *)(p + 0));
1723 your_seq = be32_to_cpup((__be32 *)(p + 4));
Harvey Harrison00bcd522008-11-13 22:41:29 -08001724 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;
Joe Perches475be4d2012-02-19 19:52:38 -08001735 u8 addr;
1736 u8 ctrl;
1737 u16 type;
1738
Linus Torvalds1da177e2005-04-16 15:20:36 -07001739 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);
Joe Perches475be4d2012-02-19 19:52:38 -08001748
Linus Torvalds1da177e2005-04-16 15:20:36 -07001749 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 "
Joe Perches475be4d2012-02-19 19:52:38 -08001767 "\"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
Joe Perches475be4d2012-02-19 19:52:38 -08001777out_free:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001778 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{
Joe Perchesa17531f2010-11-15 11:12:24 +00001787 isdn_net_local *lp = netdev_priv(ndev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001788 isdn_net_local *olp = lp; /* original 'lp' */
1789#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001790 struct concap_proto *cprot = lp->netdev->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001791#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;
Joe Perchesa17531f2010-11-15 11:12:24 +00001801 lp = 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) {
Joe Perches475be4d2012-02-19 19:52:38 -08001812 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;
1841 skb->protocol = *(__be16 *)&(skb->data[0]);
1842 skb_pull(skb, 2);
1843 if (*(unsigned short *) skb->data == 0xFFFF)
1844 skb->protocol = htons(ETH_P_802_3);
1845 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001846#ifdef CONFIG_ISDN_PPP
Joe Perches475be4d2012-02-19 19:52:38 -08001847 case ISDN_NET_ENCAP_SYNCPPP:
1848 /* huptimer is done in isdn_ppp_push_higher */
1849 isdn_ppp_receive(lp->netdev, olp, skb);
1850 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001851#endif
1852
Joe Perches475be4d2012-02-19 19:52:38 -08001853 default:
Linus Torvalds1da177e2005-04-16 15:20:36 -07001854#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08001855 /* 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 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07001861#endif /* CONFIG_ISDN_X25 */
Joe Perches475be4d2012-02-19 19:52:38 -08001862 printk(KERN_WARNING "%s: unknown encapsulation, dropping\n",
1863 lp->netdev->dev->name);
1864 kfree_skb(skb);
1865 return;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001866 }
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;
Dan Carpenter5a46e0f2012-02-09 00:46:47 +00001904 int len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001905
1906 switch (lp->p_encap) {
Joe Perches475be4d2012-02-19 19:52:38 -08001907 case ISDN_NET_ENCAP_ETHER:
1908 len = eth_header(skb, dev, type, daddr, saddr, plen);
1909 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910#ifdef CONFIG_ISDN_PPP
Joe Perches475be4d2012-02-19 19:52:38 -08001911 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;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001916#endif
Joe Perches475be4d2012-02-19 19:52:38 -08001917 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 */
1923 *((__be16 *)skb_push(skb, 2)) = htons(type);
1924 len = 2;
1925 break;
1926 case ISDN_NET_ENCAP_UIHDLC:
1927 /* HDLC with UI-Frames (for ispa with -h1 option) */
1928 *((__be16 *)skb_push(skb, 2)) = htons(0x0103);
1929 len = 2;
1930 break;
1931 case ISDN_NET_ENCAP_CISCOHDLC:
1932 case ISDN_NET_ENCAP_CISCOHDLCK:
1933 p = skb_push(skb, 4);
1934 *(u8 *)(p + 0) = CISCO_ADDR_UNICAST;
1935 *(u8 *)(p + 1) = CISCO_CTRL;
1936 *(__be16 *)(p + 2) = cpu_to_be16(type);
1937 p += 4;
1938 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");
Linus Torvalds1da177e2005-04-16 15:20:36 -07001945 len = 0;
1946 break;
Joe Perches475be4d2012-02-19 19:52:38 -08001947 }
1948 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001949#endif /* CONFIG_ISDN_X25 */
1950 }
1951 return len;
1952}
1953
David S. Millere69dd332011-07-12 23:28:12 -07001954static int isdn_header_cache(const struct neighbour *neigh, struct hh_cache *hh,
1955 __be16 type)
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001956{
1957 const struct net_device *dev = neigh->dev;
Wang Chen838361f2008-12-03 15:49:46 -08001958 isdn_net_local *lp = netdev_priv(dev);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001959
1960 if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
David S. Millere69dd332011-07-12 23:28:12 -07001961 return eth_header_cache(neigh, hh, type);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001962 return -1;
1963}
1964
1965static void isdn_header_cache_update(struct hh_cache *hh,
1966 const struct net_device *dev,
1967 const unsigned char *haddr)
1968{
Wang Chen838361f2008-12-03 15:49:46 -08001969 isdn_net_local *lp = netdev_priv(dev);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001970 if (lp->p_encap == ISDN_NET_ENCAP_ETHER)
Harvey Harrisonc19d0362008-11-20 04:10:51 -08001971 eth_header_cache_update(hh, dev, haddr);
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001972}
1973
1974static const struct header_ops isdn_header_ops = {
1975 .create = isdn_net_header,
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001976 .cache = isdn_header_cache,
1977 .cache_update = isdn_header_cache_update,
1978};
1979
Linus Torvalds1da177e2005-04-16 15:20:36 -07001980/*
1981 * Interface-setup. (just after registering a new interface)
1982 */
1983static int
1984isdn_net_init(struct net_device *ndev)
1985{
1986 ushort max_hlhdr_len = 0;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07001987 int drvidx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988
Linus Torvalds1da177e2005-04-16 15:20:36 -07001989 /*
1990 * up till binding we ask the protocol layer to reserve as much
1991 * as we might need for HL layer
1992 */
1993
1994 for (drvidx = 0; drvidx < ISDN_MAX_DRIVERS; drvidx++)
1995 if (dev->drv[drvidx])
1996 if (max_hlhdr_len < dev->drv[drvidx]->interface->hl_hdrlen)
1997 max_hlhdr_len = dev->drv[drvidx]->interface->hl_hdrlen;
1998
1999 ndev->hard_header_len = ETH_HLEN + max_hlhdr_len;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002000 return 0;
2001}
2002
2003static void
2004isdn_net_swapbind(int drvidx)
2005{
2006 isdn_net_dev *p;
2007
2008#ifdef ISDN_DEBUG_NET_ICALL
2009 printk(KERN_DEBUG "n_fi: swapping ch of %d\n", drvidx);
2010#endif
2011 p = dev->netdev;
2012 while (p) {
2013 if (p->local->pre_device == drvidx)
2014 switch (p->local->pre_channel) {
Joe Perches475be4d2012-02-19 19:52:38 -08002015 case 0:
2016 p->local->pre_channel = 1;
2017 break;
2018 case 1:
2019 p->local->pre_channel = 0;
2020 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002021 }
2022 p = (isdn_net_dev *) p->next;
2023 }
2024}
2025
2026static void
2027isdn_net_swap_usage(int i1, int i2)
2028{
2029 int u1 = dev->usage[i1] & ISDN_USAGE_EXCLUSIVE;
2030 int u2 = dev->usage[i2] & ISDN_USAGE_EXCLUSIVE;
2031
2032#ifdef ISDN_DEBUG_NET_ICALL
2033 printk(KERN_DEBUG "n_fi: usage of %d and %d\n", i1, i2);
2034#endif
2035 dev->usage[i1] &= ~ISDN_USAGE_EXCLUSIVE;
2036 dev->usage[i1] |= u2;
2037 dev->usage[i2] &= ~ISDN_USAGE_EXCLUSIVE;
2038 dev->usage[i2] |= u1;
2039 isdn_info_update();
2040}
2041
2042/*
2043 * An incoming call-request has arrived.
2044 * Search the interface-chain for an appropriate interface.
2045 * If found, connect the interface to the ISDN-channel and initiate
2046 * D- and B-Channel-setup. If secure-flag is set, accept only
2047 * configured phone-numbers. If callback-flag is set, initiate
2048 * callback-dialing.
2049 *
2050 * Return-Value: 0 = No appropriate interface for this call.
2051 * 1 = Call accepted
2052 * 2 = Reject call, wait cbdelay, then call back
2053 * 3 = Reject call
2054 * 4 = Wait cbdelay, then call back
2055 * 5 = No appropriate interface for this call,
2056 * would eventually match if CID was longer.
2057 */
2058
2059int
2060isdn_net_find_icall(int di, int ch, int idx, setup_parm *setup)
2061{
2062 char *eaz;
2063 int si1;
2064 int si2;
2065 int ematch;
2066 int wret;
2067 int swapped;
2068 int sidx = 0;
2069 u_long flags;
2070 isdn_net_dev *p;
2071 isdn_net_phone *n;
Karsten Keil0f138642007-11-22 12:43:13 +01002072 char nr[ISDN_MSNLEN];
Linus Torvalds1da177e2005-04-16 15:20:36 -07002073 char *my_eaz;
2074
2075 /* Search name in netdev-chain */
2076 if (!setup->phone[0]) {
2077 nr[0] = '0';
2078 nr[1] = '\0';
2079 printk(KERN_INFO "isdn_net: Incoming call without OAD, assuming '0'\n");
2080 } else
Karsten Keil0f138642007-11-22 12:43:13 +01002081 strlcpy(nr, setup->phone, ISDN_MSNLEN);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002082 si1 = (int) setup->si1;
2083 si2 = (int) setup->si2;
2084 if (!setup->eazmsn[0]) {
2085 printk(KERN_WARNING "isdn_net: Incoming call without CPN, assuming '0'\n");
2086 eaz = "0";
2087 } else
2088 eaz = setup->eazmsn;
2089 if (dev->net_verbose > 1)
2090 printk(KERN_INFO "isdn_net: call from %s,%d,%d -> %s\n", nr, si1, si2, eaz);
2091 /* Accept DATA and VOICE calls at this stage
2092 * local eaz is checked later for allowed call types
2093 */
2094 if ((si1 != 7) && (si1 != 1)) {
2095 if (dev->net_verbose > 1)
2096 printk(KERN_INFO "isdn_net: Service-Indicator not 1 or 7, ignored\n");
2097 return 0;
2098 }
2099 n = (isdn_net_phone *) 0;
2100 p = dev->netdev;
2101 ematch = wret = swapped = 0;
2102#ifdef ISDN_DEBUG_NET_ICALL
2103 printk(KERN_DEBUG "n_fi: di=%d ch=%d idx=%d usg=%d\n", di, ch, idx,
Joe Perches475be4d2012-02-19 19:52:38 -08002104 dev->usage[idx]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002105#endif
2106 while (p) {
2107 int matchret;
2108 isdn_net_local *lp = p->local;
2109
2110 /* If last check has triggered as binding-swap, revert it */
2111 switch (swapped) {
Joe Perches475be4d2012-02-19 19:52:38 -08002112 case 2:
2113 isdn_net_swap_usage(idx, sidx);
2114 /* fall through */
2115 case 1:
2116 isdn_net_swapbind(di);
2117 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002118 }
2119 swapped = 0;
Joe Perches475be4d2012-02-19 19:52:38 -08002120 /* check acceptable call types for DOV */
2121 my_eaz = isdn_map_eaz2msn(lp->msn, di);
2122 if (si1 == 1) { /* it's a DOV call, check if we allow it */
2123 if (*my_eaz == 'v' || *my_eaz == 'V' ||
Linus Torvalds1da177e2005-04-16 15:20:36 -07002124 *my_eaz == 'b' || *my_eaz == 'B')
Joe Perches475be4d2012-02-19 19:52:38 -08002125 my_eaz++; /* skip to allow a match */
2126 else
2127 my_eaz = NULL; /* force non match */
2128 } else { /* it's a DATA call, check if we allow it */
2129 if (*my_eaz == 'b' || *my_eaz == 'B')
2130 my_eaz++; /* skip to allow a match */
2131 }
2132 if (my_eaz)
2133 matchret = isdn_msncmp(eaz, my_eaz);
2134 else
2135 matchret = 1;
2136 if (!matchret)
2137 ematch = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002138
2139 /* Remember if more numbers eventually can match */
2140 if (matchret > wret)
2141 wret = matchret;
2142#ifdef ISDN_DEBUG_NET_ICALL
2143 printk(KERN_DEBUG "n_fi: if='%s', l.msn=%s, l.flags=%d, l.dstate=%d\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002144 p->dev->name, lp->msn, lp->flags, lp->dialstate);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002145#endif
2146 if ((!matchret) && /* EAZ is matching */
2147 (((!(lp->flags & ISDN_NET_CONNECTED)) && /* but not connected */
2148 (USG_NONE(dev->usage[idx]))) || /* and ch. unused or */
2149 ((((lp->dialstate == 4) || (lp->dialstate == 12)) && /* if dialing */
2150 (!(lp->flags & ISDN_NET_CALLBACK))) /* but no callback */
Joe Perches475be4d2012-02-19 19:52:38 -08002151 )))
2152 {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002153#ifdef ISDN_DEBUG_NET_ICALL
2154 printk(KERN_DEBUG "n_fi: match1, pdev=%d pch=%d\n",
2155 lp->pre_device, lp->pre_channel);
2156#endif
2157 if (dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) {
2158 if ((lp->pre_channel != ch) ||
2159 (lp->pre_device != di)) {
2160 /* Here we got a problem:
2161 * If using an ICN-Card, an incoming call is always signaled on
2162 * on the first channel of the card, if both channels are
2163 * down. However this channel may be bound exclusive. If the
2164 * second channel is free, this call should be accepted.
2165 * The solution is horribly but it runs, so what:
2166 * We exchange the exclusive bindings of the two channels, the
2167 * corresponding variables in the interface-structs.
2168 */
2169 if (ch == 0) {
2170 sidx = isdn_dc2minor(di, 1);
2171#ifdef ISDN_DEBUG_NET_ICALL
2172 printk(KERN_DEBUG "n_fi: ch is 0\n");
2173#endif
2174 if (USG_NONE(dev->usage[sidx])) {
2175 /* Second Channel is free, now see if it is bound
2176 * exclusive too. */
2177 if (dev->usage[sidx] & ISDN_USAGE_EXCLUSIVE) {
2178#ifdef ISDN_DEBUG_NET_ICALL
2179 printk(KERN_DEBUG "n_fi: 2nd channel is down and bound\n");
2180#endif
2181 /* Yes, swap bindings only, if the original
2182 * binding is bound to channel 1 of this driver */
2183 if ((lp->pre_device == di) &&
2184 (lp->pre_channel == 1)) {
2185 isdn_net_swapbind(di);
2186 swapped = 1;
2187 } else {
2188 /* ... else iterate next device */
2189 p = (isdn_net_dev *) p->next;
2190 continue;
2191 }
2192 } else {
2193#ifdef ISDN_DEBUG_NET_ICALL
2194 printk(KERN_DEBUG "n_fi: 2nd channel is down and unbound\n");
2195#endif
2196 /* No, swap always and swap excl-usage also */
2197 isdn_net_swap_usage(idx, sidx);
2198 isdn_net_swapbind(di);
2199 swapped = 2;
2200 }
2201 /* Now check for exclusive binding again */
2202#ifdef ISDN_DEBUG_NET_ICALL
2203 printk(KERN_DEBUG "n_fi: final check\n");
2204#endif
2205 if ((dev->usage[idx] & ISDN_USAGE_EXCLUSIVE) &&
2206 ((lp->pre_channel != ch) ||
2207 (lp->pre_device != di))) {
2208#ifdef ISDN_DEBUG_NET_ICALL
2209 printk(KERN_DEBUG "n_fi: final check failed\n");
2210#endif
2211 p = (isdn_net_dev *) p->next;
2212 continue;
2213 }
2214 }
2215 } else {
2216 /* We are already on the second channel, so nothing to do */
2217#ifdef ISDN_DEBUG_NET_ICALL
2218 printk(KERN_DEBUG "n_fi: already on 2nd channel\n");
2219#endif
2220 }
2221 }
2222 }
2223#ifdef ISDN_DEBUG_NET_ICALL
2224 printk(KERN_DEBUG "n_fi: match2\n");
2225#endif
2226 n = lp->phone[0];
2227 if (lp->flags & ISDN_NET_SECURE) {
2228 while (n) {
2229 if (!isdn_msncmp(nr, n->num))
2230 break;
2231 n = (isdn_net_phone *) n->next;
2232 }
2233 }
2234 if (n || (!(lp->flags & ISDN_NET_SECURE))) {
2235#ifdef ISDN_DEBUG_NET_ICALL
2236 printk(KERN_DEBUG "n_fi: match3\n");
2237#endif
2238 /* matching interface found */
2239
2240 /*
2241 * Is the state STOPPED?
2242 * If so, no dialin is allowed,
2243 * so reject actively.
2244 * */
2245 if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
2246 printk(KERN_INFO "incoming call, interface %s `stopped' -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002247 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 return 3;
2249 }
2250 /*
2251 * Is the interface up?
2252 * If not, reject the call actively.
2253 */
2254 if (!isdn_net_device_started(p)) {
2255 printk(KERN_INFO "%s: incoming call, interface down -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002256 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002257 return 3;
2258 }
2259 /* Interface is up, now see if it's a slave. If so, see if
2260 * it's master and parent slave is online. If not, reject the call.
2261 */
2262 if (lp->master) {
Wang Chen838361f2008-12-03 15:49:46 -08002263 isdn_net_local *mlp = ISDN_MASTER_PRIV(lp);
Karsten Keilfaca94f2007-10-15 02:11:44 -07002264 printk(KERN_DEBUG "ICALLslv: %s\n", p->dev->name);
2265 printk(KERN_DEBUG "master=%s\n", lp->master->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002266 if (mlp->flags & ISDN_NET_CONNECTED) {
2267 printk(KERN_DEBUG "master online\n");
2268 /* Master is online, find parent-slave (master if first slave) */
2269 while (mlp->slave) {
Wang Chen838361f2008-12-03 15:49:46 -08002270 if (ISDN_SLAVE_PRIV(mlp) == lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002271 break;
Wang Chen838361f2008-12-03 15:49:46 -08002272 mlp = ISDN_SLAVE_PRIV(mlp);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002273 }
2274 } else
2275 printk(KERN_DEBUG "master offline\n");
2276 /* Found parent, if it's offline iterate next device */
2277 printk(KERN_DEBUG "mlpf: %d\n", mlp->flags & ISDN_NET_CONNECTED);
2278 if (!(mlp->flags & ISDN_NET_CONNECTED)) {
2279 p = (isdn_net_dev *) p->next;
2280 continue;
2281 }
Joe Perches475be4d2012-02-19 19:52:38 -08002282 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002283 if (lp->flags & ISDN_NET_CALLBACK) {
2284 int chi;
2285 /*
2286 * Is the state MANUAL?
2287 * If so, no callback can be made,
2288 * so reject actively.
2289 * */
2290 if (ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_OFF) {
2291 printk(KERN_INFO "incoming call for callback, interface %s `off' -> rejected\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002292 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002293 return 3;
2294 }
2295 printk(KERN_DEBUG "%s: call from %s -> %s, start callback\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002296 p->dev->name, nr, eaz);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002297 if (lp->phone[1]) {
2298 /* Grab a free ISDN-Channel */
2299 spin_lock_irqsave(&dev->lock, flags);
Joe Perches475be4d2012-02-19 19:52:38 -08002300 if ((chi =
2301 isdn_get_free_channel(
2302 ISDN_USAGE_NET,
2303 lp->l2_proto,
2304 lp->l3_proto,
2305 lp->pre_device,
2306 lp->pre_channel,
2307 lp->msn)
2308 ) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002309
Karsten Keilfaca94f2007-10-15 02:11:44 -07002310 printk(KERN_WARNING "isdn_net_find_icall: No channel for %s\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002311 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 spin_unlock_irqrestore(&dev->lock, flags);
2313 return 0;
2314 }
2315 /* Setup dialstate. */
2316 lp->dtimer = 0;
2317 lp->dialstate = 11;
2318 /* Connect interface with channel */
2319 isdn_net_bind_channel(lp, chi);
2320#ifdef CONFIG_ISDN_PPP
2321 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2322 if (isdn_ppp_bind(lp) < 0) {
2323 spin_unlock_irqrestore(&dev->lock, flags);
2324 isdn_net_unbind_channel(lp);
2325 return 0;
2326 }
2327#endif
2328 spin_unlock_irqrestore(&dev->lock, flags);
2329 /* Initiate dialing by returning 2 or 4 */
2330 return (lp->flags & ISDN_NET_CBHUP) ? 2 : 4;
2331 } else
Karsten Keilfaca94f2007-10-15 02:11:44 -07002332 printk(KERN_WARNING "isdn_net: %s: No phone number\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002333 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002334 return 0;
2335 } else {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002336 printk(KERN_DEBUG "%s: call from %s -> %s accepted\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002337 p->dev->name, nr, eaz);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 /* if this interface is dialing, it does it probably on a different
2339 device, so free this device */
2340 if ((lp->dialstate == 4) || (lp->dialstate == 12)) {
2341#ifdef CONFIG_ISDN_PPP
2342 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2343 isdn_ppp_free(lp);
2344#endif
2345 isdn_net_lp_disconnected(lp);
2346 isdn_free_channel(lp->isdn_device, lp->isdn_channel,
Joe Perches475be4d2012-02-19 19:52:38 -08002347 ISDN_USAGE_NET);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348 }
2349 spin_lock_irqsave(&dev->lock, flags);
2350 dev->usage[idx] &= ISDN_USAGE_EXCLUSIVE;
2351 dev->usage[idx] |= ISDN_USAGE_NET;
2352 strcpy(dev->num[idx], nr);
2353 isdn_info_update();
2354 dev->st_netdev[idx] = lp->netdev;
2355 lp->isdn_device = di;
2356 lp->isdn_channel = ch;
2357 lp->ppp_slot = -1;
2358 lp->flags |= ISDN_NET_CONNECTED;
2359 lp->dialstate = 7;
2360 lp->dtimer = 0;
2361 lp->outgoing = 0;
2362 lp->huptimer = 0;
2363 lp->hupflags |= ISDN_WAITCHARGE;
2364 lp->hupflags &= ~ISDN_HAVECHARGE;
2365#ifdef CONFIG_ISDN_PPP
2366 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP) {
2367 if (isdn_ppp_bind(lp) < 0) {
2368 isdn_net_unbind_channel(lp);
2369 spin_unlock_irqrestore(&dev->lock, flags);
2370 return 0;
2371 }
2372 }
2373#endif
2374 spin_unlock_irqrestore(&dev->lock, flags);
2375 return 1;
2376 }
2377 }
2378 }
2379 p = (isdn_net_dev *) p->next;
2380 }
2381 /* If none of configured EAZ/MSN matched and not verbose, be silent */
2382 if (!ematch || dev->net_verbose)
2383 printk(KERN_INFO "isdn_net: call from %s -> %d %s ignored\n", nr, di, eaz);
Joe Perches475be4d2012-02-19 19:52:38 -08002384 return (wret == 2) ? 5 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002385}
2386
2387/*
2388 * Search list of net-interfaces for an interface with given name.
2389 */
2390isdn_net_dev *
2391isdn_net_findif(char *name)
2392{
2393 isdn_net_dev *p = dev->netdev;
2394
2395 while (p) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002396 if (!strcmp(p->dev->name, name))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002397 return p;
2398 p = (isdn_net_dev *) p->next;
2399 }
2400 return (isdn_net_dev *) NULL;
2401}
2402
2403/*
2404 * Force a net-interface to dial out.
2405 * This is called from the userlevel-routine below or
2406 * from isdn_net_start_xmit().
2407 */
Adrian Bunk3e206b02005-06-25 14:58:35 -07002408static int
Joe Perches475be4d2012-02-19 19:52:38 -08002409isdn_net_force_dial_lp(isdn_net_local *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002410{
2411 if ((!(lp->flags & ISDN_NET_CONNECTED)) && !lp->dialstate) {
2412 int chi;
2413 if (lp->phone[1]) {
2414 ulong flags;
2415
2416 /* Grab a free ISDN-Channel */
2417 spin_lock_irqsave(&dev->lock, flags);
2418 if ((chi = isdn_get_free_channel(
Joe Perches475be4d2012-02-19 19:52:38 -08002419 ISDN_USAGE_NET,
2420 lp->l2_proto,
2421 lp->l3_proto,
2422 lp->pre_device,
2423 lp->pre_channel,
2424 lp->msn)) < 0) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07002425 printk(KERN_WARNING "isdn_net_force_dial: No channel for %s\n",
Joe Perches475be4d2012-02-19 19:52:38 -08002426 lp->netdev->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427 spin_unlock_irqrestore(&dev->lock, flags);
2428 return -EAGAIN;
2429 }
2430 lp->dialstate = 1;
2431 /* Connect interface with channel */
2432 isdn_net_bind_channel(lp, chi);
2433#ifdef CONFIG_ISDN_PPP
2434 if (lp->p_encap == ISDN_NET_ENCAP_SYNCPPP)
2435 if (isdn_ppp_bind(lp) < 0) {
2436 isdn_net_unbind_channel(lp);
2437 spin_unlock_irqrestore(&dev->lock, flags);
2438 return -EAGAIN;
2439 }
2440#endif
2441 /* Initiate dialing */
2442 spin_unlock_irqrestore(&dev->lock, flags);
2443 isdn_net_dial();
2444 return 0;
2445 } else
2446 return -EINVAL;
2447 } else
2448 return -EBUSY;
2449}
2450
2451/*
2452 * This is called from certain upper protocol layers (multilink ppp
2453 * and x25iface encapsulation module) that want to initiate dialing
2454 * themselves.
2455 */
2456int
Joe Perches475be4d2012-02-19 19:52:38 -08002457isdn_net_dial_req(isdn_net_local *lp)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002458{
2459 /* is there a better error code? */
2460 if (!(ISDN_NET_DIALMODE(*lp) == ISDN_NET_DM_AUTO)) return -EBUSY;
2461
2462 return isdn_net_force_dial_lp(lp);
2463}
2464
2465/*
2466 * Force a net-interface to dial out.
2467 * This is always called from within userspace (ISDN_IOCTL_NET_DIAL).
2468 */
2469int
2470isdn_net_force_dial(char *name)
2471{
2472 isdn_net_dev *p = isdn_net_findif(name);
2473
2474 if (!p)
2475 return -ENODEV;
2476 return (isdn_net_force_dial_lp(p->local));
2477}
2478
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002479/* The ISDN-specific entries in the device structure. */
2480static const struct net_device_ops isdn_netdev_ops = {
2481 .ndo_init = isdn_net_init,
2482 .ndo_open = isdn_net_open,
2483 .ndo_stop = isdn_net_close,
2484 .ndo_do_ioctl = isdn_net_ioctl,
2485
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002486 .ndo_start_xmit = isdn_net_start_xmit,
2487 .ndo_get_stats = isdn_net_get_stats,
2488 .ndo_tx_timeout = isdn_net_tx_timeout,
2489};
2490
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491/*
Karsten Keild62a38d2007-10-08 20:37:11 -07002492 * Helper for alloc_netdev()
2493 */
2494static void _isdn_setup(struct net_device *dev)
2495{
Wang Chen838361f2008-12-03 15:49:46 -08002496 isdn_net_local *lp = netdev_priv(dev);
Karsten Keild62a38d2007-10-08 20:37:11 -07002497
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002498 ether_setup(dev);
2499
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002500 /* Setup the generic properties */
Joe Perches475be4d2012-02-19 19:52:38 -08002501 dev->flags = IFF_NOARP | IFF_POINTOPOINT;
Neil Horman550fd082011-07-26 06:05:38 +00002502
2503 /* isdn prepends a header in the tx path, can't share skbs */
2504 dev->priv_flags &= ~IFF_TX_SKB_SHARING;
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002505 dev->header_ops = NULL;
2506 dev->netdev_ops = &isdn_netdev_ops;
2507
2508 /* for clients with MPPP maybe higher values better */
2509 dev->tx_queue_len = 30;
2510
Karsten Keild62a38d2007-10-08 20:37:11 -07002511 lp->p_encap = ISDN_NET_ENCAP_RAWIP;
2512 lp->magic = ISDN_NET_MAGIC;
2513 lp->last = lp;
2514 lp->next = lp;
2515 lp->isdn_device = -1;
2516 lp->isdn_channel = -1;
2517 lp->pre_device = -1;
2518 lp->pre_channel = -1;
2519 lp->exclusive = -1;
2520 lp->ppp_slot = -1;
2521 lp->pppbind = -1;
2522 skb_queue_head_init(&lp->super_tx_queue);
2523 lp->l2_proto = ISDN_PROTO_L2_X75I;
2524 lp->l3_proto = ISDN_PROTO_L3_TRANS;
2525 lp->triggercps = 6000;
2526 lp->slavedelay = 10 * HZ;
2527 lp->hupflags = ISDN_INHUP; /* Do hangup even on incoming calls */
2528 lp->onhtime = 10; /* Default hangup-time for saving costs */
2529 lp->dialmax = 1;
2530 /* Hangup before Callback, manual dial */
2531 lp->flags = ISDN_NET_CBHUP | ISDN_NET_DM_MANUAL;
2532 lp->cbdelay = 25; /* Wait 5 secs before Callback */
2533 lp->dialtimeout = -1; /* Infinite Dial-Timeout */
2534 lp->dialwait = 5 * HZ; /* Wait 5 sec. after failed dial */
2535 lp->dialstarted = 0; /* Jiffies of last dial-start */
2536 lp->dialwait_timer = 0; /* Jiffies of earliest next dial-start */
2537}
2538
2539/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002540 * Allocate a new network-interface and initialize its data structures.
2541 */
2542char *
2543isdn_net_new(char *name, struct net_device *master)
2544{
2545 isdn_net_dev *netdev;
2546
2547 /* Avoid creating an existing interface */
2548 if (isdn_net_findif(name)) {
2549 printk(KERN_WARNING "isdn_net: interface %s already exists\n", name);
2550 return NULL;
2551 }
Karsten Keild62a38d2007-10-08 20:37:11 -07002552 if (name == NULL)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002553 return NULL;
Burman Yan41f96932006-12-08 02:39:35 -08002554 if (!(netdev = kzalloc(sizeof(isdn_net_dev), GFP_KERNEL))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002555 printk(KERN_WARNING "isdn_net: Could not allocate net-device\n");
2556 return NULL;
2557 }
Tom Gundersenc835a672014-07-14 16:37:24 +02002558 netdev->dev = alloc_netdev(sizeof(isdn_net_local), name,
2559 NET_NAME_UNKNOWN, _isdn_setup);
Karsten Keild62a38d2007-10-08 20:37:11 -07002560 if (!netdev->dev) {
2561 printk(KERN_WARNING "isdn_net: Could not allocate network device\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002562 kfree(netdev);
2563 return NULL;
2564 }
Wang Chen838361f2008-12-03 15:49:46 -08002565 netdev->local = netdev_priv(netdev->dev);
Stephen Hemmingerd7005552009-01-07 18:04:17 -08002566
Linus Torvalds1da177e2005-04-16 15:20:36 -07002567 if (master) {
2568 /* Device shall be a slave */
Wang Chen838361f2008-12-03 15:49:46 -08002569 struct net_device *p = MASTER_TO_SLAVE(master);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 struct net_device *q = master;
2571
2572 netdev->local->master = master;
2573 /* Put device at end of slave-chain */
2574 while (p) {
2575 q = p;
Wang Chen838361f2008-12-03 15:49:46 -08002576 p = MASTER_TO_SLAVE(p);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002577 }
Wang Chen838361f2008-12-03 15:49:46 -08002578 MASTER_TO_SLAVE(q) = netdev->dev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002579 } else {
2580 /* Device shall be a master */
2581 /*
2582 * Watchdog timer (currently) for master only.
2583 */
Karsten Keild62a38d2007-10-08 20:37:11 -07002584 netdev->dev->watchdog_timeo = ISDN_NET_TX_TIMEOUT;
2585 if (register_netdev(netdev->dev) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002586 printk(KERN_WARNING "isdn_net: Could not register net-device\n");
Karsten Keild62a38d2007-10-08 20:37:11 -07002587 free_netdev(netdev->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002588 kfree(netdev);
2589 return NULL;
2590 }
2591 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002592 netdev->queue = netdev->local;
2593 spin_lock_init(&netdev->queue_lock);
2594
Linus Torvalds1da177e2005-04-16 15:20:36 -07002595 netdev->local->netdev = netdev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002596
David Howellsc4028952006-11-22 14:57:56 +00002597 INIT_WORK(&netdev->local->tqueue, isdn_net_softint);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002598 spin_lock_init(&netdev->local->xmit_lock);
2599
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 /* Put into to netdev-chain */
2601 netdev->next = (void *) dev->netdev;
2602 dev->netdev = netdev;
Karsten Keild62a38d2007-10-08 20:37:11 -07002603 return netdev->dev->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002604}
2605
2606char *
2607isdn_net_newslave(char *parm)
2608{
2609 char *p = strchr(parm, ',');
2610 isdn_net_dev *n;
2611 char newname[10];
2612
2613 if (p) {
Annie Cherkaev7b3a6672017-07-15 15:08:58 -06002614 /* Slave-Name MUST not be empty or overflow 'newname' */
2615 if (strscpy(newname, p + 1, sizeof(newname)) <= 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002616 return NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002617 *p = 0;
2618 /* Master must already exist */
2619 if (!(n = isdn_net_findif(parm)))
2620 return NULL;
2621 /* Master must be a real interface, not a slave */
2622 if (n->local->master)
2623 return NULL;
2624 /* Master must not be started yet */
Joe Perches475be4d2012-02-19 19:52:38 -08002625 if (isdn_net_device_started(n))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002626 return NULL;
Karsten Keild62a38d2007-10-08 20:37:11 -07002627 return (isdn_net_new(newname, n->dev));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 }
2629 return NULL;
2630}
2631
2632/*
2633 * Set interface-parameters.
2634 * Always set all parameters, so the user-level application is responsible
2635 * for not overwriting existing setups. It has to get the current
2636 * setup first, if only selected parameters are to be changed.
2637 */
2638int
Joe Perches475be4d2012-02-19 19:52:38 -08002639isdn_net_setcfg(isdn_net_ioctl_cfg *cfg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002640{
2641 isdn_net_dev *p = isdn_net_findif(cfg->name);
2642 ulong features;
2643 int i;
2644 int drvidx;
2645 int chidx;
2646 char drvid[25];
2647
2648 if (p) {
2649 isdn_net_local *lp = p->local;
2650
2651 /* See if any registered driver supports the features we want */
2652 features = ((1 << cfg->l2_proto) << ISDN_FEATURE_L2_SHIFT) |
2653 ((1 << cfg->l3_proto) << ISDN_FEATURE_L3_SHIFT);
2654 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2655 if (dev->drv[i])
2656 if ((dev->drv[i]->interface->features & features) == features)
2657 break;
2658 if (i == ISDN_MAX_DRIVERS) {
2659 printk(KERN_WARNING "isdn_net: No driver with selected features\n");
2660 return -ENODEV;
2661 }
Joe Perches475be4d2012-02-19 19:52:38 -08002662 if (lp->p_encap != cfg->p_encap) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002663#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08002664 struct concap_proto *cprot = p->cprot;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002665#endif
2666 if (isdn_net_device_started(p)) {
2667 printk(KERN_WARNING "%s: cannot change encap when if is up\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002668 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002669 return -EBUSY;
2670 }
2671#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08002672 if (cprot && cprot->pops)
2673 cprot->pops->proto_del(cprot);
2674 p->cprot = NULL;
2675 lp->dops = NULL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002676 /* ... , prepare for configuration of new one ... */
Joe Perches475be4d2012-02-19 19:52:38 -08002677 switch (cfg->p_encap) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002678 case ISDN_NET_ENCAP_X25IFACE:
Joe Perches475be4d2012-02-19 19:52:38 -08002679 lp->dops = &isdn_concap_reliable_dl_dops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002680 }
2681 /* ... and allocate new one ... */
Joe Perches475be4d2012-02-19 19:52:38 -08002682 p->cprot = isdn_concap_new(cfg->p_encap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002683 /* p -> cprot == NULL now if p_encap is not supported
2684 by means of the concap_proto mechanism */
2685 /* the protocol is not configured yet; this will
2686 happen later when isdn_net_reset() is called */
2687#endif
2688 }
Joe Perches475be4d2012-02-19 19:52:38 -08002689 switch (cfg->p_encap) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002690 case ISDN_NET_ENCAP_SYNCPPP:
2691#ifndef CONFIG_ISDN_PPP
2692 printk(KERN_WARNING "%s: SyncPPP support not configured\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002693 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002694 return -EINVAL;
2695#else
Karsten Keild62a38d2007-10-08 20:37:11 -07002696 p->dev->type = ARPHRD_PPP; /* change ARP type */
2697 p->dev->addr_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002698#endif
2699 break;
2700 case ISDN_NET_ENCAP_X25IFACE:
2701#ifndef CONFIG_ISDN_X25
2702 printk(KERN_WARNING "%s: isdn-x25 support not configured\n",
Denis V. Lunevc749b012007-10-15 12:52:20 -07002703 p->dev->name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002704 return -EINVAL;
2705#else
Karsten Keild62a38d2007-10-08 20:37:11 -07002706 p->dev->type = ARPHRD_X25; /* change ARP type */
2707 p->dev->addr_len = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708#endif
2709 break;
2710 case ISDN_NET_ENCAP_CISCOHDLCK:
Linus Torvalds1da177e2005-04-16 15:20:36 -07002711 break;
2712 default:
Joe Perches475be4d2012-02-19 19:52:38 -08002713 if (cfg->p_encap >= 0 &&
2714 cfg->p_encap <= ISDN_NET_ENCAP_MAX_ENCAP)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 break;
2716 printk(KERN_WARNING
2717 "%s: encapsulation protocol %d not supported\n",
Karsten Keilfaca94f2007-10-15 02:11:44 -07002718 p->dev->name, cfg->p_encap);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002719 return -EINVAL;
2720 }
2721 if (strlen(cfg->drvid)) {
2722 /* A bind has been requested ... */
2723 char *c,
Joe Perches475be4d2012-02-19 19:52:38 -08002724 *e;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002725
Dan Carpenter5dc55032011-11-24 02:42:09 +00002726 if (strnlen(cfg->drvid, sizeof(cfg->drvid)) ==
Joe Perches475be4d2012-02-19 19:52:38 -08002727 sizeof(cfg->drvid))
Dan Carpenter5dc55032011-11-24 02:42:09 +00002728 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002729 drvidx = -1;
2730 chidx = -1;
2731 strcpy(drvid, cfg->drvid);
2732 if ((c = strchr(drvid, ','))) {
2733 /* The channel-number is appended to the driver-Id with a comma */
2734 chidx = (int) simple_strtoul(c + 1, &e, 10);
2735 if (e == c)
2736 chidx = -1;
2737 *c = '\0';
2738 }
2739 for (i = 0; i < ISDN_MAX_DRIVERS; i++)
2740 /* Lookup driver-Id in array */
2741 if (!(strcmp(dev->drvid[i], drvid))) {
2742 drvidx = i;
2743 break;
2744 }
2745 if ((drvidx == -1) || (chidx == -1))
2746 /* Either driver-Id or channel-number invalid */
2747 return -ENODEV;
2748 } else {
2749 /* Parameters are valid, so get them */
2750 drvidx = lp->pre_device;
2751 chidx = lp->pre_channel;
2752 }
2753 if (cfg->exclusive > 0) {
2754 unsigned long flags;
2755
2756 /* If binding is exclusive, try to grab the channel */
2757 spin_lock_irqsave(&dev->lock, flags);
2758 if ((i = isdn_get_free_channel(ISDN_USAGE_NET,
Joe Perches475be4d2012-02-19 19:52:38 -08002759 lp->l2_proto, lp->l3_proto, drvidx,
2760 chidx, lp->msn)) < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002761 /* Grab failed, because desired channel is in use */
2762 lp->exclusive = -1;
2763 spin_unlock_irqrestore(&dev->lock, flags);
2764 return -EBUSY;
2765 }
2766 /* All went ok, so update isdninfo */
2767 dev->usage[i] = ISDN_USAGE_EXCLUSIVE;
2768 isdn_info_update();
2769 spin_unlock_irqrestore(&dev->lock, flags);
2770 lp->exclusive = i;
2771 } else {
2772 /* Non-exclusive binding or unbind. */
2773 lp->exclusive = -1;
2774 if ((lp->pre_device != -1) && (cfg->exclusive == -1)) {
2775 isdn_unexclusive_channel(lp->pre_device, lp->pre_channel);
2776 isdn_free_channel(lp->pre_device, lp->pre_channel, ISDN_USAGE_NET);
2777 drvidx = -1;
2778 chidx = -1;
2779 }
2780 }
Karsten Keil0f138642007-11-22 12:43:13 +01002781 strlcpy(lp->msn, cfg->eaz, sizeof(lp->msn));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782 lp->pre_device = drvidx;
2783 lp->pre_channel = chidx;
2784 lp->onhtime = cfg->onhtime;
2785 lp->charge = cfg->charge;
2786 lp->l2_proto = cfg->l2_proto;
2787 lp->l3_proto = cfg->l3_proto;
2788 lp->cbdelay = cfg->cbdelay;
2789 lp->dialmax = cfg->dialmax;
2790 lp->triggercps = cfg->triggercps;
2791 lp->slavedelay = cfg->slavedelay * HZ;
2792 lp->pppbind = cfg->pppbind;
2793 lp->dialtimeout = cfg->dialtimeout >= 0 ? cfg->dialtimeout * HZ : -1;
2794 lp->dialwait = cfg->dialwait * HZ;
2795 if (cfg->secure)
2796 lp->flags |= ISDN_NET_SECURE;
2797 else
2798 lp->flags &= ~ISDN_NET_SECURE;
2799 if (cfg->cbhup)
2800 lp->flags |= ISDN_NET_CBHUP;
2801 else
2802 lp->flags &= ~ISDN_NET_CBHUP;
2803 switch (cfg->callback) {
Joe Perches475be4d2012-02-19 19:52:38 -08002804 case 0:
2805 lp->flags &= ~(ISDN_NET_CALLBACK | ISDN_NET_CBOUT);
2806 break;
2807 case 1:
2808 lp->flags |= ISDN_NET_CALLBACK;
2809 lp->flags &= ~ISDN_NET_CBOUT;
2810 break;
2811 case 2:
2812 lp->flags |= ISDN_NET_CBOUT;
2813 lp->flags &= ~ISDN_NET_CALLBACK;
2814 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 }
2816 lp->flags &= ~ISDN_NET_DIALMODE_MASK; /* first all bits off */
2817 if (cfg->dialmode && !(cfg->dialmode & ISDN_NET_DIALMODE_MASK)) {
2818 /* old isdnctrl version, where only 0 or 1 is given */
2819 printk(KERN_WARNING
Joe Perches475be4d2012-02-19 19:52:38 -08002820 "Old isdnctrl version detected! Please update.\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 lp->flags |= ISDN_NET_DM_OFF; /* turn on `off' bit */
2822 }
2823 else {
2824 lp->flags |= cfg->dialmode; /* turn on selected bits */
2825 }
2826 if (cfg->chargehup)
2827 lp->hupflags |= ISDN_CHARGEHUP;
2828 else
2829 lp->hupflags &= ~ISDN_CHARGEHUP;
2830 if (cfg->ihup)
2831 lp->hupflags |= ISDN_INHUP;
2832 else
2833 lp->hupflags &= ~ISDN_INHUP;
2834 if (cfg->chargeint > 10) {
2835 lp->hupflags |= ISDN_CHARGEHUP | ISDN_HAVECHARGE | ISDN_MANCHARGE;
2836 lp->chargeint = cfg->chargeint * HZ;
2837 }
2838 if (cfg->p_encap != lp->p_encap) {
2839 if (cfg->p_encap == ISDN_NET_ENCAP_RAWIP) {
Karsten Keild62a38d2007-10-08 20:37:11 -07002840 p->dev->header_ops = NULL;
Joe Perches475be4d2012-02-19 19:52:38 -08002841 p->dev->flags = IFF_NOARP | IFF_POINTOPOINT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002842 } else {
Karsten Keild62a38d2007-10-08 20:37:11 -07002843 p->dev->header_ops = &isdn_header_ops;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002844 if (cfg->p_encap == ISDN_NET_ENCAP_ETHER)
Karsten Keild62a38d2007-10-08 20:37:11 -07002845 p->dev->flags = IFF_BROADCAST | IFF_MULTICAST;
Stephen Hemminger3b04ddd2007-10-09 01:40:57 -07002846 else
Joe Perches475be4d2012-02-19 19:52:38 -08002847 p->dev->flags = IFF_NOARP | IFF_POINTOPOINT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002848 }
2849 }
2850 lp->p_encap = cfg->p_encap;
2851 return 0;
2852 }
2853 return -ENODEV;
2854}
2855
2856/*
2857 * Perform get-interface-parameters.ioctl
2858 */
2859int
Joe Perches475be4d2012-02-19 19:52:38 -08002860isdn_net_getcfg(isdn_net_ioctl_cfg *cfg)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002861{
2862 isdn_net_dev *p = isdn_net_findif(cfg->name);
2863
2864 if (p) {
2865 isdn_net_local *lp = p->local;
2866
2867 strcpy(cfg->eaz, lp->msn);
2868 cfg->exclusive = lp->exclusive;
2869 if (lp->pre_device >= 0) {
2870 sprintf(cfg->drvid, "%s,%d", dev->drvid[lp->pre_device],
2871 lp->pre_channel);
2872 } else
2873 cfg->drvid[0] = '\0';
2874 cfg->onhtime = lp->onhtime;
2875 cfg->charge = lp->charge;
2876 cfg->l2_proto = lp->l2_proto;
2877 cfg->l3_proto = lp->l3_proto;
2878 cfg->p_encap = lp->p_encap;
2879 cfg->secure = (lp->flags & ISDN_NET_SECURE) ? 1 : 0;
2880 cfg->callback = 0;
2881 if (lp->flags & ISDN_NET_CALLBACK)
2882 cfg->callback = 1;
2883 if (lp->flags & ISDN_NET_CBOUT)
2884 cfg->callback = 2;
2885 cfg->cbhup = (lp->flags & ISDN_NET_CBHUP) ? 1 : 0;
2886 cfg->dialmode = lp->flags & ISDN_NET_DIALMODE_MASK;
Himangi Saraogi7b18ef02014-07-24 02:46:38 +05302887 cfg->chargehup = (lp->hupflags & ISDN_CHARGEHUP) ? 1 : 0;
2888 cfg->ihup = (lp->hupflags & ISDN_INHUP) ? 1 : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002889 cfg->cbdelay = lp->cbdelay;
2890 cfg->dialmax = lp->dialmax;
2891 cfg->triggercps = lp->triggercps;
2892 cfg->slavedelay = lp->slavedelay / HZ;
2893 cfg->chargeint = (lp->hupflags & ISDN_CHARGEHUP) ?
Joe Perches475be4d2012-02-19 19:52:38 -08002894 (lp->chargeint / HZ) : 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002895 cfg->pppbind = lp->pppbind;
2896 cfg->dialtimeout = lp->dialtimeout >= 0 ? lp->dialtimeout / HZ : -1;
2897 cfg->dialwait = lp->dialwait / HZ;
Karsten Keilfaca94f2007-10-15 02:11:44 -07002898 if (lp->slave) {
Dan Carpenter84ce9812010-07-10 04:31:11 +00002899 if (strlen(lp->slave->name) >= 10)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002900 strcpy(cfg->slave, "too-long");
2901 else
2902 strcpy(cfg->slave, lp->slave->name);
2903 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002904 cfg->slave[0] = '\0';
Karsten Keilfaca94f2007-10-15 02:11:44 -07002905 if (lp->master) {
Dan Carpenter84ce9812010-07-10 04:31:11 +00002906 if (strlen(lp->master->name) >= 10)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002907 strcpy(cfg->master, "too-long");
Dan Carpenter84ce9812010-07-10 04:31:11 +00002908 else
2909 strcpy(cfg->master, lp->master->name);
Karsten Keilfaca94f2007-10-15 02:11:44 -07002910 } else
Linus Torvalds1da177e2005-04-16 15:20:36 -07002911 cfg->master[0] = '\0';
2912 return 0;
2913 }
2914 return -ENODEV;
2915}
2916
2917/*
2918 * Add a phone-number to an interface.
2919 */
2920int
Joe Perches475be4d2012-02-19 19:52:38 -08002921isdn_net_addphone(isdn_net_ioctl_phone *phone)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002922{
2923 isdn_net_dev *p = isdn_net_findif(phone->name);
2924 isdn_net_phone *n;
2925
2926 if (p) {
Robert P. J. Day5cbded52006-12-13 00:35:56 -08002927 if (!(n = kmalloc(sizeof(isdn_net_phone), GFP_KERNEL)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 return -ENOMEM;
Karsten Keil0f138642007-11-22 12:43:13 +01002929 strlcpy(n->num, phone->phone, sizeof(n->num));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002930 n->next = p->local->phone[phone->outgoing & 1];
2931 p->local->phone[phone->outgoing & 1] = n;
2932 return 0;
2933 }
2934 return -ENODEV;
2935}
2936
2937/*
2938 * Copy a string of all phone-numbers of an interface to user space.
2939 * This might sleep and must be called with the isdn semaphore down.
2940 */
2941int
Joe Perches475be4d2012-02-19 19:52:38 -08002942isdn_net_getphones(isdn_net_ioctl_phone *phone, char __user *phones)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002943{
2944 isdn_net_dev *p = isdn_net_findif(phone->name);
2945 int inout = phone->outgoing & 1;
2946 int more = 0;
2947 int count = 0;
2948 isdn_net_phone *n;
2949
2950 if (!p)
2951 return -ENODEV;
2952 inout &= 1;
2953 for (n = p->local->phone[inout]; n; n = n->next) {
2954 if (more) {
2955 put_user(' ', phones++);
2956 count++;
2957 }
2958 if (copy_to_user(phones, n->num, strlen(n->num) + 1)) {
2959 return -EFAULT;
2960 }
2961 phones += strlen(n->num);
2962 count += strlen(n->num);
2963 more = 1;
2964 }
2965 put_user(0, phones);
2966 count++;
2967 return count;
2968}
2969
2970/*
2971 * Copy a string containing the peer's phone number of a connected interface
2972 * to user space.
2973 */
2974int
2975isdn_net_getpeer(isdn_net_ioctl_phone *phone, isdn_net_ioctl_phone __user *peer)
2976{
2977 isdn_net_dev *p = isdn_net_findif(phone->name);
2978 int ch, dv, idx;
2979
Karsten Keilfaca94f2007-10-15 02:11:44 -07002980 if (!p)
2981 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982 /*
2983 * Theoretical race: while this executes, the remote number might
2984 * become invalid (hang up) or change (new connection), resulting
Joe Perches475be4d2012-02-19 19:52:38 -08002985 * in (partially) wrong number copied to user. This race
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986 * currently ignored.
2987 */
2988 ch = p->local->isdn_channel;
2989 dv = p->local->isdn_device;
Joe Perches475be4d2012-02-19 19:52:38 -08002990 if (ch < 0 && dv < 0)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002991 return -ENOTCONN;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 idx = isdn_dc2minor(dv, ch);
Joe Perches475be4d2012-02-19 19:52:38 -08002993 if (idx < 0)
Karsten Keilfaca94f2007-10-15 02:11:44 -07002994 return -ENODEV;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995 /* for pre-bound channels, we need this extra check */
Karsten Keilfaca94f2007-10-15 02:11:44 -07002996 if (strncmp(dev->num[idx], "???", 3) == 0)
2997 return -ENOTCONN;
2998 strncpy(phone->phone, dev->num[idx], ISDN_MSNLEN);
2999 phone->outgoing = USG_OUTGOING(dev->usage[idx]);
3000 if (copy_to_user(peer, phone, sizeof(*peer)))
3001 return -EFAULT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 return 0;
3003}
3004/*
3005 * Delete a phone-number from an interface.
3006 */
3007int
Joe Perches475be4d2012-02-19 19:52:38 -08003008isdn_net_delphone(isdn_net_ioctl_phone *phone)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003009{
3010 isdn_net_dev *p = isdn_net_findif(phone->name);
3011 int inout = phone->outgoing & 1;
3012 isdn_net_phone *n;
3013 isdn_net_phone *m;
3014
3015 if (p) {
3016 n = p->local->phone[inout];
3017 m = NULL;
3018 while (n) {
3019 if (!strcmp(n->num, phone->phone)) {
3020 if (p->local->dial == n)
3021 p->local->dial = n->next;
3022 if (m)
3023 m->next = n->next;
3024 else
3025 p->local->phone[inout] = n->next;
3026 kfree(n);
3027 return 0;
3028 }
3029 m = n;
3030 n = (isdn_net_phone *) n->next;
3031 }
3032 return -EINVAL;
3033 }
3034 return -ENODEV;
3035}
3036
3037/*
3038 * Delete all phone-numbers of an interface.
3039 */
3040static int
Joe Perches475be4d2012-02-19 19:52:38 -08003041isdn_net_rmallphone(isdn_net_dev *p)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042{
3043 isdn_net_phone *n;
3044 isdn_net_phone *m;
3045 int i;
3046
3047 for (i = 0; i < 2; i++) {
3048 n = p->local->phone[i];
3049 while (n) {
3050 m = n->next;
3051 kfree(n);
3052 n = m;
3053 }
3054 p->local->phone[i] = NULL;
3055 }
3056 p->local->dial = NULL;
3057 return 0;
3058}
3059
3060/*
3061 * Force a hangup of a network-interface.
3062 */
3063int
3064isdn_net_force_hangup(char *name)
3065{
3066 isdn_net_dev *p = isdn_net_findif(name);
3067 struct net_device *q;
3068
3069 if (p) {
3070 if (p->local->isdn_device < 0)
3071 return 1;
3072 q = p->local->slave;
3073 /* If this interface has slaves, do a hangup for them also. */
3074 while (q) {
3075 isdn_net_hangup(q);
Wang Chen838361f2008-12-03 15:49:46 -08003076 q = MASTER_TO_SLAVE(q);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003077 }
Karsten Keild62a38d2007-10-08 20:37:11 -07003078 isdn_net_hangup(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003079 return 0;
3080 }
3081 return -ENODEV;
3082}
3083
3084/*
3085 * Helper-function for isdn_net_rm: Do the real work.
3086 */
3087static int
Joe Perches475be4d2012-02-19 19:52:38 -08003088isdn_net_realrm(isdn_net_dev *p, isdn_net_dev *q)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003089{
3090 u_long flags;
3091
3092 if (isdn_net_device_started(p)) {
3093 return -EBUSY;
3094 }
3095#ifdef CONFIG_ISDN_X25
Joe Perches475be4d2012-02-19 19:52:38 -08003096 if (p->cprot && p->cprot->pops)
3097 p->cprot->pops->proto_del(p->cprot);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098#endif
3099 /* Free all phone-entries */
3100 isdn_net_rmallphone(p);
3101 /* If interface is bound exclusive, free channel-usage */
3102 if (p->local->exclusive != -1)
3103 isdn_unexclusive_channel(p->local->pre_device, p->local->pre_channel);
3104 if (p->local->master) {
3105 /* It's a slave-device, so update master's slave-pointer if necessary */
Wang Chen838361f2008-12-03 15:49:46 -08003106 if (((isdn_net_local *) ISDN_MASTER_PRIV(p->local))->slave ==
3107 p->dev)
3108 ((isdn_net_local *)ISDN_MASTER_PRIV(p->local))->slave =
3109 p->local->slave;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003110 } else {
3111 /* Unregister only if it's a master-device */
Karsten Keild62a38d2007-10-08 20:37:11 -07003112 unregister_netdev(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003113 }
3114 /* Unlink device from chain */
3115 spin_lock_irqsave(&dev->lock, flags);
3116 if (q)
3117 q->next = p->next;
3118 else
3119 dev->netdev = p->next;
3120 if (p->local->slave) {
3121 /* If this interface has a slave, remove it also */
Karsten Keilfaca94f2007-10-15 02:11:44 -07003122 char *slavename = p->local->slave->name;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003123 isdn_net_dev *n = dev->netdev;
3124 q = NULL;
3125 while (n) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07003126 if (!strcmp(n->dev->name, slavename)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003127 spin_unlock_irqrestore(&dev->lock, flags);
3128 isdn_net_realrm(n, q);
3129 spin_lock_irqsave(&dev->lock, flags);
3130 break;
3131 }
3132 q = n;
Karsten Keilfaca94f2007-10-15 02:11:44 -07003133 n = (isdn_net_dev *)n->next;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 }
3135 }
3136 spin_unlock_irqrestore(&dev->lock, flags);
3137 /* If no more net-devices remain, disable auto-hangup timer */
3138 if (dev->netdev == NULL)
3139 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
Karsten Keild62a38d2007-10-08 20:37:11 -07003140 free_netdev(p->dev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003141 kfree(p);
3142
3143 return 0;
3144}
3145
3146/*
3147 * Remove a single network-interface.
3148 */
3149int
3150isdn_net_rm(char *name)
3151{
3152 u_long flags;
3153 isdn_net_dev *p;
3154 isdn_net_dev *q;
3155
3156 /* Search name in netdev-chain */
3157 spin_lock_irqsave(&dev->lock, flags);
3158 p = dev->netdev;
3159 q = NULL;
3160 while (p) {
Karsten Keilfaca94f2007-10-15 02:11:44 -07003161 if (!strcmp(p->dev->name, name)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003162 spin_unlock_irqrestore(&dev->lock, flags);
3163 return (isdn_net_realrm(p, q));
3164 }
3165 q = p;
3166 p = (isdn_net_dev *) p->next;
3167 }
3168 spin_unlock_irqrestore(&dev->lock, flags);
3169 /* If no more net-devices remain, disable auto-hangup timer */
3170 if (dev->netdev == NULL)
3171 isdn_timer_ctrl(ISDN_TIMER_NETHANGUP, 0);
3172 return -ENODEV;
3173}
3174
3175/*
3176 * Remove all network-interfaces
3177 */
3178int
3179isdn_net_rmall(void)
3180{
3181 u_long flags;
3182 int ret;
3183
3184 /* Walk through netdev-chain */
3185 spin_lock_irqsave(&dev->lock, flags);
3186 while (dev->netdev) {
3187 if (!dev->netdev->local->master) {
3188 /* Remove master-devices only, slaves get removed with their master */
3189 spin_unlock_irqrestore(&dev->lock, flags);
3190 if ((ret = isdn_net_realrm(dev->netdev, NULL))) {
3191 return ret;
3192 }
3193 spin_lock_irqsave(&dev->lock, flags);
3194 }
3195 }
3196 dev->netdev = NULL;
3197 spin_unlock_irqrestore(&dev->lock, flags);
3198 return 0;
3199}