OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [rc203soc/] [sw/] [uClinux/] [drivers/] [net/] [slip.c] - Blame information for rev 1777

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1626 jcastillo
/*
2
 * slip.c       This module implements the SLIP protocol for kernel-based
3
 *              devices like TTY.  It interfaces between a raw TTY, and the
4
 *              kernel's INET protocol layers.
5
 *
6
 * Version:     @(#)slip.c      0.8.3   12/24/94
7
 *
8
 * Authors:     Laurence Culhane, <loz@holmes.demon.co.uk>
9
 *              Fred N. van Kempen, <waltje@uwalt.nl.mugnet.org>
10
 *
11
 * Fixes:
12
 *              Alan Cox        :       Sanity checks and avoid tx overruns.
13
 *                                      Has a new sl->mtu field.
14
 *              Alan Cox        :       Found cause of overrun. ifconfig sl0 mtu upwards.
15
 *                                      Driver now spots this and grows/shrinks its buffers(hack!).
16
 *                                      Memory leak if you run out of memory setting up a slip driver fixed.
17
 *              Matt Dillon     :       Printable slip (borrowed from NET2E)
18
 *      Pauline Middelink       :       Slip driver fixes.
19
 *              Alan Cox        :       Honours the old SL_COMPRESSED flag
20
 *              Alan Cox        :       KISS AX.25 and AXUI IP support
21
 *              Michael Riepe   :       Automatic CSLIP recognition added
22
 *              Charles Hedrick :       CSLIP header length problem fix.
23
 *              Alan Cox        :       Corrected non-IP cases of the above.
24
 *              Alan Cox        :       Now uses hardware type as per FvK.
25
 *              Alan Cox        :       Default to 192.168.0.0 (RFC 1597)
26
 *              A.N.Kuznetsov   :       dev_tint() recursion fix.
27
 *      Dmitry Gorodchanin      :       SLIP memory leaks
28
 *      Dmitry Gorodchanin      :       Code cleanup. Reduce tty driver
29
 *                                      buffering from 4096 to 256 bytes.
30
 *                                      Improving SLIP response time.
31
 *                                      CONFIG_SLIP_MODE_SLIP6.
32
 *                                      ifconfig sl? up & down now works correctly.
33
 *                                      Modularization.
34
 *              Alan Cox        :       Oops - fix AX.25 buffer lengths
35
 *      Dmitry Gorodchanin      :       Even more cleanups. Preserve CSLIP
36
 *                                      statistics. Include CSLIP code only
37
 *                                      if it really needed.
38
 *              Alan Cox        :       Free slhc buffers in the right place.
39
 *              Alan Cox        :       Allow for digipeated IP over AX.25
40
 *              Matti Aarnio    :       Dynamic SLIP devices, with ideas taken
41
 *                                      from Jim Freeman's <jfree@caldera.com>
42
 *                                      dynamic PPP devices.  We do NOT kfree()
43
 *                                      device entries, just reg./unreg. them
44
 *                                      as they are needed.  We kfree() them
45
 *                                      at module cleanup.
46
 *                                      With MODULE-loading ``insmod'', user can
47
 *                                      issue parameter:   slip_maxdev=1024
48
 *                                      (Or how much he/she wants.. Default is 256)
49
 * *    Stanislav Voronyi       :       Slip line checking, with ideas taken
50
 *                                      from multislip BSDI driver which was written
51
 *                                      by Igor Chechik, RELCOM Corp. Only algorithms
52
 *                                      have been ported to Linux SLIP driver.
53
 */
54
 
55
#define SL_CHECK_TRANSMIT
56
#include <linux/config.h>
57
#include <linux/module.h>
58
 
59
#include <asm/system.h>
60
#include <asm/segment.h>
61
#include <asm/bitops.h>
62
#include <linux/string.h>
63
#include <linux/mm.h>
64
#include <linux/interrupt.h>
65
#include <linux/in.h>
66
#include <linux/tty.h>
67
#include <linux/errno.h>
68
#include <linux/netdevice.h>
69
#include <linux/etherdevice.h>
70
#include <linux/skbuff.h>
71
#include <linux/if_arp.h>
72
#include <linux/if_slip.h>
73
#include "slip.h"
74
#ifdef CONFIG_INET
75
#include <linux/ip.h>
76
#include <linux/tcp.h>
77
#include <net/slhc_vj.h>
78
#endif
79
 
80
#ifdef MODULE
81
#define SLIP_VERSION    "0.8.4-NET3.019-NEWTTY-MODULAR"
82
#else
83
#define SLIP_VERSION    "0.8.4-NET3.019-NEWTTY"
84
#endif
85
 
86
 
87
typedef struct slip_ctrl {
88
        char            if_name[8];     /* "sl0\0" .. "sl99999\0"       */
89
        struct slip     ctrl;           /* SLIP things                  */
90
        struct device   dev;            /* the device                   */
91
} slip_ctrl_t;
92
static slip_ctrl_t      **slip_ctrls = NULL;
93
int slip_maxdev = SL_NRUNIT;            /* Can be overridden with insmod! */
94
 
95
static struct tty_ldisc sl_ldisc;
96
 
97
static int slip_esc(unsigned char *p, unsigned char *d, int len);
98
static void slip_unesc(struct slip *sl, unsigned char c);
99
#ifdef CONFIG_SLIP_MODE_SLIP6
100
static int slip_esc6(unsigned char *p, unsigned char *d, int len);
101
static void slip_unesc6(struct slip *sl, unsigned char c);
102
#endif
103
#ifdef CONFIG_SLIP_SMART
104
static void sl_keepalive(unsigned long sls);
105
static void sl_outfill(unsigned long sls);
106
#endif
107
 
108
/* Find a free SLIP channel, and link in this `tty' line. */
109
static inline struct slip *
110
sl_alloc(void)
111
{
112
        slip_ctrl_t *slp;
113
        int i;
114
 
115
        if (slip_ctrls == NULL) return NULL;    /* Master array missing ! */
116
 
117
        for (i = 0; i < slip_maxdev; i++) {
118
          slp = slip_ctrls[i];
119
          /* Not allocated ? */
120
          if (slp == NULL)
121
            break;
122
          /* Not in use ? */
123
          if (!set_bit(SLF_INUSE, &slp->ctrl.flags))
124
            break;
125
        }
126
        /* SLP is set.. */
127
 
128
        /* Sorry, too many, all slots in use */
129
        if (i >= slip_maxdev) return NULL;
130
 
131
        /* If no channels are available, allocate one */
132
        if (!slp &&
133
            (slip_ctrls[i] = (slip_ctrl_t *)kmalloc(sizeof(slip_ctrl_t),
134
                                                    GFP_KERNEL)) != NULL) {
135
          slp = slip_ctrls[i];
136
          memset(slp, 0, sizeof(slip_ctrl_t));
137
 
138
          /* Initialize channel control data */
139
          set_bit(SLF_INUSE, &slp->ctrl.flags);
140
          slp->ctrl.tty         = NULL;
141
          sprintf(slp->if_name, "sl%d", i);
142
          slp->dev.name         = slp->if_name;
143
          slp->dev.base_addr    = i;
144
          slp->dev.priv         = (void*)&(slp->ctrl);
145
          slp->dev.next         = NULL;
146
          slp->dev.init         = slip_init;
147
/* printk(KERN_INFO "slip: kmalloc()ed SLIP control node for line %s\n",
148
   slp->if_name); */
149
        }
150
        if (slp != NULL) {
151
 
152
          /* register device so that it can be ifconfig'ed       */
153
          /* slip_init() will be called as a side-effect         */
154
          /* SIDE-EFFECT WARNING: slip_init() CLEARS slp->ctrl ! */
155
 
156
          if (register_netdev(&(slp->dev)) == 0) {
157
            /* (Re-)Set the INUSE bit.   Very Important! */
158
            set_bit(SLF_INUSE, &slp->ctrl.flags);
159
            slp->ctrl.dev = &(slp->dev);
160
            slp->dev.priv = (void*)&(slp->ctrl);
161
 
162
/* printk(KERN_INFO "slip: linked in netdev %s for active use\n",
163
   slp->if_name); */
164
 
165
            return (&(slp->ctrl));
166
 
167
          } else {
168
            clear_bit(SLF_INUSE,&(slp->ctrl.flags));
169
            printk("sl_alloc() - register_netdev() failure.\n");
170
          }
171
        }
172
 
173
        return NULL;
174
}
175
 
176
 
177
/* Free a SLIP channel. */
178
static inline void
179
sl_free(struct slip *sl)
180
{
181
        /* Free all SLIP frame buffers. */
182
        if (sl->rbuff)  {
183
                kfree(sl->rbuff);
184
        }
185
        sl->rbuff = NULL;
186
        if (sl->xbuff)  {
187
                kfree(sl->xbuff);
188
        }
189
        sl->xbuff = NULL;
190
#ifdef SL_INCLUDE_CSLIP
191
        /* Save CSLIP statistics */
192
        if (sl->slcomp)  {
193
                sl->rx_compressed += sl->slcomp->sls_i_compressed;
194
                sl->rx_dropped    += sl->slcomp->sls_i_tossed;
195
                sl->tx_compressed += sl->slcomp->sls_o_compressed;
196
                sl->tx_misses     += sl->slcomp->sls_o_misses;
197
        }
198
        if (sl->cbuff)  {
199
                kfree(sl->cbuff);
200
        }
201
        sl->cbuff = NULL;
202
        if(sl->slcomp)
203
                slhc_free(sl->slcomp);
204
        sl->slcomp = NULL;
205
#endif
206
 
207
        if (!clear_bit(SLF_INUSE, &sl->flags)) {
208
                printk("%s: sl_free for already free unit.\n", sl->dev->name);
209
        }
210
}
211
 
212
/* MTU has been changed by the IP layer. Unfortunately we are not told
213
   about this, but we spot it ourselves and fix things up. We could be
214
   in an upcall from the tty driver, or in an ip packet queue. */
215
 
216
static void sl_changedmtu(struct slip *sl)
217
{
218
        struct device *dev = sl->dev;
219
        unsigned char *xbuff, *rbuff, *oxbuff, *orbuff;
220
#ifdef SL_INCLUDE_CSLIP
221
        unsigned char *cbuff, *ocbuff;
222
#endif
223
        int len;
224
        unsigned long flags;
225
 
226
        len = dev->mtu * 2;
227
/*
228
 * allow for arrival of larger UDP packets, even if we say not to
229
 * also fixes a bug in which SunOS sends 512-byte packets even with
230
 * an MSS of 128
231
 */
232
        if (len < 576 * 2)  {
233
                len = 576 * 2;
234
        }
235
 
236
        xbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
237
        rbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
238
#ifdef SL_INCLUDE_CSLIP
239
        cbuff = (unsigned char *) kmalloc (len + 4, GFP_ATOMIC);
240
#endif
241
 
242
#ifdef SL_INCLUDE_CSLIP
243
        if (xbuff == NULL || rbuff == NULL || cbuff == NULL)  {
244
#else
245
        if (xbuff == NULL || rbuff == NULL)  {
246
#endif
247
                printk("%s: unable to grow slip buffers, MTU change cancelled.\n",
248
                       sl->dev->name);
249
                dev->mtu = sl->mtu;
250
                if (xbuff != NULL)  {
251
                        kfree(xbuff);
252
                }
253
                if (rbuff != NULL)  {
254
                        kfree(rbuff);
255
                }
256
#ifdef SL_INCLUDE_CSLIP
257
                if (cbuff != NULL)  {
258
                        kfree(cbuff);
259
                }
260
#endif
261
                return;
262
        }
263
 
264
        save_flags(flags); cli();
265
 
266
        oxbuff    = sl->xbuff;
267
        sl->xbuff = xbuff;
268
        orbuff    = sl->rbuff;
269
        sl->rbuff = rbuff;
270
#ifdef SL_INCLUDE_CSLIP
271
        ocbuff    = sl->cbuff;
272
        sl->cbuff = cbuff;
273
#endif
274
        if (sl->xleft)  {
275
                if (sl->xleft <= len)  {
276
                        memcpy(sl->xbuff, sl->xhead, sl->xleft);
277
                } else  {
278
                        sl->xleft = 0;
279
                        sl->tx_dropped++;
280
                }
281
        }
282
        sl->xhead = sl->xbuff;
283
 
284
        if (sl->rcount)  {
285
                if (sl->rcount <= len) {
286
                        memcpy(sl->rbuff, orbuff, sl->rcount);
287
                } else  {
288
                        sl->rcount = 0;
289
                        sl->rx_over_errors++;
290
                        set_bit(SLF_ERROR, &sl->flags);
291
                }
292
        }
293
        sl->mtu      = dev->mtu;
294
 
295
        sl->buffsize = len;
296
 
297
        restore_flags(flags);
298
 
299
        if (oxbuff != NULL)   {
300
                kfree(oxbuff);
301
        }
302
        if (orbuff != NULL)    {
303
                kfree(orbuff);
304
        }
305
#ifdef SL_INCLUDE_CSLIP
306
        if (ocbuff != NULL)  {
307
                kfree(ocbuff);
308
        }
309
#endif
310
}
311
 
312
 
313
/* Set the "sending" flag.  This must be atomic, hence the ASM. */
314
static inline void
315
sl_lock(struct slip *sl)
316
{
317
        if (set_bit(0, (void *) &sl->dev->tbusy))  {
318
                printk("%s: trying to lock already locked device!\n", sl->dev->name);
319
        }
320
}
321
 
322
 
323
/* Clear the "sending" flag.  This must be atomic, hence the ASM. */
324
static inline void
325
sl_unlock(struct slip *sl)
326
{
327
        if (!clear_bit(0, (void *)&sl->dev->tbusy))  {
328
                printk("%s: trying to unlock already unlocked device!\n", sl->dev->name);
329
        }
330
}
331
 
332
/* Send one completely decapsulated IP datagram to the IP layer. */
333
static void
334
sl_bump(struct slip *sl)
335
{
336
        struct sk_buff *skb;
337
        int count;
338
 
339
        count = sl->rcount;
340
#ifdef SL_INCLUDE_CSLIP
341
        if (sl->mode & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) {
342
                unsigned char c;
343
                if ((c = sl->rbuff[0]) & SL_TYPE_COMPRESSED_TCP) {
344
                        /* ignore compressed packets when CSLIP is off */
345
                        if (!(sl->mode & SL_MODE_CSLIP)) {
346
                                printk("%s: compressed packet ignored\n", sl->dev->name);
347
                                return;
348
                        }
349
                        /* make sure we've reserved enough space for uncompress to use */
350
                        if (count + 80 > sl->buffsize) {
351
                                sl->rx_over_errors++;
352
                                return;
353
                        }
354
                        count = slhc_uncompress(sl->slcomp, sl->rbuff, count);
355
                        if (count <= 0) {
356
                                return;
357
                        }
358
                } else if (c >= SL_TYPE_UNCOMPRESSED_TCP) {
359
                        if (!(sl->mode & SL_MODE_CSLIP)) {
360
                                /* turn on header compression */
361
                                sl->mode |= SL_MODE_CSLIP;
362
                                sl->mode &= ~SL_MODE_ADAPTIVE;
363
                                printk("%s: header compression turned on\n", sl->dev->name);
364
                        }
365
                        sl->rbuff[0] &= 0x4f;
366
                        if (slhc_remember(sl->slcomp, sl->rbuff, count) <= 0) {
367
                                return;
368
                        }
369
                }
370
        }
371
#endif  /* SL_INCLUDE_CSLIP */
372
 
373
        skb = dev_alloc_skb(count);
374
        if (skb == NULL)  {
375
                printk("%s: memory squeeze, dropping packet.\n", sl->dev->name);
376
                sl->rx_dropped++;
377
                return;
378
        }
379
        skb->dev = sl->dev;
380
        memcpy(skb_put(skb,count), sl->rbuff, count);
381
        skb->mac.raw=skb->data;
382
        skb->protocol=htons(ETH_P_IP);
383
        netif_rx(skb);
384
        sl->rx_packets++;
385
}
386
 
387
/* Encapsulate one IP datagram and stuff into a TTY queue. */
388
static void
389
sl_encaps(struct slip *sl, unsigned char *icp, int len)
390
{
391
        unsigned char *p;
392
        int actual, count;
393
 
394
 
395
        if (sl->mtu != sl->dev->mtu) {  /* Someone has been ifconfigging */
396
 
397
                sl_changedmtu(sl);
398
        }
399
 
400
        if (len > sl->mtu) {            /* Sigh, shouldn't occur BUT ... */
401
                len = sl->mtu;
402
                printk ("%s: truncating oversized transmit packet!\n", sl->dev->name);
403
                sl->tx_dropped++;
404
                sl_unlock(sl);
405
                return;
406
        }
407
 
408
        p = icp;
409
#ifdef SL_INCLUDE_CSLIP
410
        if (sl->mode & SL_MODE_CSLIP)  {
411
                len = slhc_compress(sl->slcomp, p, len, sl->cbuff, &p, 1);
412
        }
413
#endif
414
#ifdef CONFIG_SLIP_MODE_SLIP6
415
        if(sl->mode & SL_MODE_SLIP6)
416
                count = slip_esc6(p, (unsigned char *) sl->xbuff, len);
417
        else
418
#endif
419
                count = slip_esc(p, (unsigned char *) sl->xbuff, len);
420
 
421
        /* Order of next two lines is *very* important.
422
         * When we are sending a little amount of data,
423
         * the transfer may be completed inside driver.write()
424
         * routine, because it's running with interrupts enabled.
425
         * In this case we *never* got WRITE_WAKEUP event,
426
         * if we did not request it before write operation.
427
         *       14 Oct 1994  Dmitry Gorodchanin.
428
         */
429
        sl->tty->flags |= (1 << TTY_DO_WRITE_WAKEUP);
430
        actual = sl->tty->driver.write(sl->tty, 0, sl->xbuff, count);
431
#ifdef SL_CHECK_TRANSMIT
432
        sl->dev->trans_start = jiffies;
433
#endif
434
        sl->xleft = count - actual;
435
        sl->xhead = sl->xbuff + actual;
436
        /* VSV */
437
        clear_bit(SLF_OUTWAIT, &sl->flags);     /* reset outfill flag */
438
}
439
 
440
/*
441
 * Called by the driver when there's room for more data.  If we have
442
 * more packets to send, we send them here.
443
 */
444
static void slip_write_wakeup(struct tty_struct *tty)
445
{
446
        int actual;
447
        struct slip *sl = (struct slip *) tty->disc_data;
448
 
449
        /* First make sure we're connected. */
450
        if (!sl || sl->magic != SLIP_MAGIC || !sl->dev->start) {
451
                return;
452
        }
453
        if (sl->xleft <= 0)  {
454
                /* Now serial buffer is almost free & we can start
455
                 * transmission of another packet */
456
                sl->tx_packets++;
457
                tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
458
                sl_unlock(sl);
459
                mark_bh(NET_BH);
460
                return;
461
        }
462
 
463
        actual = tty->driver.write(tty, 0, sl->xhead, sl->xleft);
464
        sl->xleft -= actual;
465
        sl->xhead += actual;
466
}
467
 
468
/* Encapsulate an IP datagram and kick it into a TTY queue. */
469
static int
470
sl_xmit(struct sk_buff *skb, struct device *dev)
471
{
472
        struct slip *sl = (struct slip*)(dev->priv);
473
 
474
        if (!dev->start)  {
475
                printk("%s: xmit call when iface is down\n", dev->name);
476
                return 1;
477
        }
478
        /*
479
         * If we are busy already- too bad.  We ought to be able
480
         * to queue things at this point, to allow for a little
481
         * frame buffer.  Oh well...
482
         * -----------------------------------------------------
483
         * I hate queues in SLIP driver. May be it's efficient,
484
         * but for me latency is more important. ;)
485
         * So, no queues !
486
         *        14 Oct 1994  Dmitry Gorodchanin.
487
         */
488
        if (dev->tbusy) {
489
                /* May be we must check transmitter timeout here ?
490
                 *      14 Oct 1994 Dmitry Gorodchanin.
491
                 */
492
#ifdef SL_CHECK_TRANSMIT
493
                if (jiffies - dev->trans_start  < 20 * HZ)  {
494
                        /* 20 sec timeout not reached */
495
                        return 1;
496
                }
497
                printk("%s: transmit timed out, %s?\n", dev->name,
498
                       (sl->tty->driver.chars_in_buffer(sl->tty) || sl->xleft) ?
499
                       "bad line quality" : "driver error");
500
                sl->xleft = 0;
501
                sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
502
                sl_unlock(sl);
503
#else
504
                return 1;
505
#endif
506
        }
507
 
508
        /* We were not busy, so we are now... :-) */
509
        if (skb != NULL) {
510
                sl_lock(sl);
511
                sl_encaps(sl, skb->data, skb->len);
512
                dev_kfree_skb(skb, FREE_WRITE);
513
        }
514
        return 0;
515
}
516
 
517
 
518
/* Return the frame type ID.  This is normally IP but maybe be AX.25. */
519
 
520
/* Fill in the MAC-level header. Not used by SLIP. */
521
static int
522
sl_header(struct sk_buff *skb, struct device *dev, unsigned short type,
523
          void *daddr, void *saddr, unsigned len)
524
{
525
        return 0;
526
}
527
 
528
 
529
/* Rebuild the MAC-level header.  Not used by SLIP. */
530
static int
531
sl_rebuild_header(void *buff, struct device *dev, unsigned long raddr,
532
                  struct sk_buff *skb)
533
{
534
        return 0;
535
}
536
 
537
 
538
/* Open the low-level part of the SLIP channel. Easy! */
539
static int
540
sl_open(struct device *dev)
541
{
542
        struct slip *sl = (struct slip*)(dev->priv);
543
        unsigned long len;
544
 
545
        if (sl->tty == NULL) {
546
                return -ENODEV;
547
        }
548
 
549
        /*
550
         * Allocate the SLIP frame buffers:
551
         *
552
         * rbuff        Receive buffer.
553
         * xbuff        Transmit buffer.
554
         * cbuff        Temporary compression buffer.
555
         */
556
        len = dev->mtu * 2;
557
        /*
558
         * allow for arrival of larger UDP packets, even if we say not to
559
         * also fixes a bug in which SunOS sends 512-byte packets even with
560
         * an MSS of 128
561
         */
562
        if (len < 576 * 2)  {
563
                len = 576 * 2;
564
        }
565
        sl->rbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
566
        if (sl->rbuff == NULL)   {
567
                goto norbuff;
568
        }
569
        sl->xbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
570
        if (sl->xbuff == NULL)   {
571
                goto noxbuff;
572
        }
573
#ifdef SL_INCLUDE_CSLIP
574
        sl->cbuff = (unsigned char *) kmalloc(len + 4, GFP_KERNEL);
575
        if (sl->cbuff == NULL)   {
576
                goto nocbuff;
577
        }
578
        sl->slcomp = slhc_init(16, 16);
579
        if (sl->slcomp == NULL)  {
580
                goto noslcomp;
581
        }
582
#endif
583
        sl->mtu      = dev->mtu;
584
        sl->buffsize = len;
585
        sl->rcount   = 0;
586
        sl->xleft    = 0;
587
#ifdef CONFIG_SLIP_MODE_SLIP6
588
        sl->xdata    = 0;
589
        sl->xbits    = 0;
590
#endif
591
        sl->flags   &= (1 << SLF_INUSE);      /* Clear ESCAPE & ERROR flags */
592
#ifdef CONFIG_SLIP_SMART        
593
        sl->keepalive=0;         /* no keepalive by default = VSV */
594
        init_timer(&sl->keepalive_timer);       /* initialize timer_list struct */
595
        sl->keepalive_timer.data=(unsigned long)sl;
596
        sl->keepalive_timer.function=sl_keepalive;
597
        sl->outfill=0;                   /* & outfill too */
598
        init_timer(&sl->outfill_timer);
599
        sl->outfill_timer.data=(unsigned long)sl;
600
        sl->outfill_timer.function=sl_outfill;
601
#endif
602
        /* Needed because address '0' is special */
603
        if (dev->pa_addr == 0)  {
604
                dev->pa_addr=ntohl(0xC0A80001);
605
        }
606
        dev->tbusy  = 0;
607
/*      dev->flags |= IFF_UP; */
608
        dev->start  = 1;
609
 
610
        return 0;
611
 
612
        /* Cleanup */
613
#ifdef SL_INCLUDE_CSLIP
614
noslcomp:
615
        kfree(sl->cbuff);
616
nocbuff:
617
#endif
618
        kfree(sl->xbuff);
619
noxbuff:
620
        kfree(sl->rbuff);
621
norbuff:
622
        return -ENOMEM;
623
}
624
 
625
 
626
/* Close the low-level part of the SLIP channel. Easy! */
627
static int
628
sl_close(struct device *dev)
629
{
630
        struct slip *sl = (struct slip*)(dev->priv);
631
 
632
        if (sl->tty == NULL) {
633
                return -EBUSY;
634
        }
635
        sl->tty->flags &= ~(1 << TTY_DO_WRITE_WAKEUP);
636
        dev->tbusy = 1;
637
        dev->start = 0;
638
 
639
/*      dev->flags &= ~IFF_UP; */
640
 
641
        return 0;
642
}
643
 
644
static int
645
slip_receive_room(struct tty_struct *tty)
646
{
647
        return 65536;  /* We can handle an infinite amount of data. :-) */
648
}
649
 
650
/*
651
 * Handle the 'receiver data ready' interrupt.
652
 * This function is called by the 'tty_io' module in the kernel when
653
 * a block of SLIP data has been received, which can now be decapsulated
654
 * and sent on to some IP layer for further processing.
655
 */
656
static void
657
slip_receive_buf(struct tty_struct *tty, const unsigned char *cp, char *fp, int count)
658
{
659
        struct slip *sl = (struct slip *) tty->disc_data;
660
 
661
        if (!sl || sl->magic != SLIP_MAGIC || !sl->dev->start)
662
                return;
663
 
664
        /*
665
         * Argh! mtu change time! - costs us the packet part received
666
         * at the change
667
         */
668
        if (sl->mtu != sl->dev->mtu)  {
669
 
670
                sl_changedmtu(sl);
671
        }
672
 
673
        /* Read the characters out of the buffer */
674
        while (count--) {
675
                if (fp && *fp++) {
676
                        if (!set_bit(SLF_ERROR, &sl->flags))  {
677
                                sl->rx_errors++;
678
                        }
679
                        cp++;
680
                        continue;
681
                }
682
#ifdef CONFIG_SLIP_MODE_SLIP6
683
                if (sl->mode & SL_MODE_SLIP6)
684
                        slip_unesc6(sl, *cp++);
685
                else
686
#endif
687
                        slip_unesc(sl, *cp++);
688
        }
689
}
690
 
691
/*
692
 * Open the high-level part of the SLIP channel.
693
 * This function is called by the TTY module when the
694
 * SLIP line discipline is called for.  Because we are
695
 * sure the tty line exists, we only have to link it to
696
 * a free SLIP channel...
697
 */
698
static int
699
slip_open(struct tty_struct *tty)
700
{
701
        struct slip *sl = (struct slip *) tty->disc_data;
702
        int err;
703
 
704
        /* First make sure we're not already connected. */
705
        if (sl && sl->magic == SLIP_MAGIC) {
706
                return -EEXIST;
707
        }
708
 
709
        /* OK.  Find a free SLIP channel to use. */
710
        if ((sl = sl_alloc()) == NULL) {
711
                return -ENFILE;
712
        }
713
 
714
        sl->tty = tty;
715
        tty->disc_data = sl;
716
        if (tty->driver.flush_buffer)  {
717
                tty->driver.flush_buffer(tty);
718
        }
719
        if (tty->ldisc.flush_buffer)  {
720
                tty->ldisc.flush_buffer(tty);
721
        }
722
 
723
        /* Restore default settings */
724
        sl->mode      = SL_MODE_DEFAULT;
725
        sl->dev->type = ARPHRD_SLIP + sl->mode;
726
        /* Perform the low-level SLIP initialization. */
727
        if ((err = sl_open(sl->dev)))  {
728
                return err;
729
        }
730
 
731
        MOD_INC_USE_COUNT;
732
 
733
        /* Done.  We have linked the TTY line to a channel. */
734
        return sl->dev->base_addr;
735
}
736
 
737
 
738
/*
739
 * Close down a SLIP channel.
740
 * This means flushing out any pending queues, and then restoring the
741
 * TTY line discipline to what it was before it got hooked to SLIP
742
 * (which usually is TTY again).
743
 */
744
static void
745
slip_close(struct tty_struct *tty)
746
{
747
        struct slip *sl = (struct slip *) tty->disc_data;
748
 
749
        /* First make sure we're connected. */
750
        if (!sl || sl->magic != SLIP_MAGIC) {
751
                return;
752
        }
753
 
754
        (void) dev_close(sl->dev);
755
 
756
        tty->disc_data = 0;
757
        sl->tty = NULL;
758
        /* VSV = very important to remove timers */
759
#ifdef CONFIG_SLIP_SMART
760
        if (sl->keepalive)
761
                (void)del_timer (&sl->keepalive_timer);
762
        if (sl->outfill)
763
                (void)del_timer (&sl->outfill_timer);
764
#endif
765
        sl_free(sl);
766
        unregister_netdev(sl->dev);
767
        MOD_DEC_USE_COUNT;
768
}
769
 
770
 
771
static struct enet_statistics *
772
sl_get_stats(struct device *dev)
773
{
774
        static struct enet_statistics stats;
775
        struct slip *sl = (struct slip*)(dev->priv);
776
#ifdef SL_INCLUDE_CSLIP
777
        struct slcompress *comp;
778
#endif
779
 
780
        memset(&stats, 0, sizeof(struct enet_statistics));
781
 
782
        stats.rx_packets     = sl->rx_packets;
783
        stats.tx_packets     = sl->tx_packets;
784
        stats.rx_dropped     = sl->rx_dropped;
785
        stats.tx_dropped     = sl->tx_dropped;
786
        stats.tx_errors      = sl->tx_errors;
787
        stats.rx_errors      = sl->rx_errors;
788
        stats.rx_over_errors = sl->rx_over_errors;
789
#ifdef SL_INCLUDE_CSLIP
790
        stats.rx_fifo_errors = sl->rx_compressed;
791
        stats.tx_fifo_errors = sl->tx_compressed;
792
        stats.collisions     = sl->tx_misses;
793
        comp = sl->slcomp;
794
        if (comp) {
795
                stats.rx_fifo_errors += comp->sls_i_compressed;
796
                stats.rx_dropped     += comp->sls_i_tossed;
797
                stats.tx_fifo_errors += comp->sls_o_compressed;
798
                stats.collisions     += comp->sls_o_misses;
799
        }
800
#endif /* CONFIG_INET */
801
        return (&stats);
802
}
803
 
804
 
805
 /************************************************************************
806
  *                     STANDARD SLIP ENCAPSULATION                      *
807
  ************************************************************************/
808
 
809
int
810
slip_esc(unsigned char *s, unsigned char *d, int len)
811
{
812
        unsigned char *ptr = d;
813
        unsigned char c;
814
 
815
        /*
816
         * Send an initial END character to flush out any
817
         * data that may have accumulated in the receiver
818
         * due to line noise.
819
         */
820
 
821
        *ptr++ = END;
822
 
823
        /*
824
         * For each byte in the packet, send the appropriate
825
         * character sequence, according to the SLIP protocol.
826
         */
827
 
828
        while (len-- > 0) {
829
                switch(c = *s++) {
830
                 case END:
831
                        *ptr++ = ESC;
832
                        *ptr++ = ESC_END;
833
                        break;
834
                 case ESC:
835
                        *ptr++ = ESC;
836
                        *ptr++ = ESC_ESC;
837
                        break;
838
                 default:
839
                        *ptr++ = c;
840
                        break;
841
                }
842
        }
843
        *ptr++ = END;
844
        return (ptr - d);
845
}
846
 
847
static void
848
slip_unesc(struct slip *sl, unsigned char s)
849
{
850
 
851
        switch(s) {
852
         case END:
853
                /* drop keeptest bit = VSV */
854
                if (test_bit(SLF_KEEPTEST, &sl->flags))
855
                        clear_bit(SLF_KEEPTEST, &sl->flags);
856
 
857
                if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))  {
858
                        sl_bump(sl);
859
                }
860
                clear_bit(SLF_ESCAPE, &sl->flags);
861
                sl->rcount = 0;
862
                return;
863
 
864
         case ESC:
865
                set_bit(SLF_ESCAPE, &sl->flags);
866
                return;
867
         case ESC_ESC:
868
                if (clear_bit(SLF_ESCAPE, &sl->flags))  {
869
                        s = ESC;
870
                }
871
                break;
872
         case ESC_END:
873
                if (clear_bit(SLF_ESCAPE, &sl->flags))  {
874
                        s = END;
875
                }
876
                break;
877
        }
878
        if (!test_bit(SLF_ERROR, &sl->flags))  {
879
                if (sl->rcount < sl->buffsize)  {
880
                        sl->rbuff[sl->rcount++] = s;
881
                        return;
882
                }
883
                sl->rx_over_errors++;
884
                set_bit(SLF_ERROR, &sl->flags);
885
        }
886
}
887
 
888
 
889
#ifdef CONFIG_SLIP_MODE_SLIP6
890
/************************************************************************
891
 *                       6 BIT SLIP ENCAPSULATION                       *
892
 ************************************************************************/
893
 
894
int
895
slip_esc6(unsigned char *s, unsigned char *d, int len)
896
{
897
        unsigned char *ptr = d;
898
        unsigned char c;
899
        int i;
900
        unsigned short v = 0;
901
        short bits = 0;
902
 
903
        /*
904
         * Send an initial END character to flush out any
905
         * data that may have accumulated in the receiver
906
         * due to line noise.
907
         */
908
 
909
        *ptr++ = 0x70;
910
 
911
        /*
912
         * Encode the packet into printable ascii characters
913
         */
914
 
915
        for (i = 0; i < len; ++i) {
916
                v = (v << 8) | s[i];
917
                bits += 8;
918
                while (bits >= 6) {
919
                        bits -= 6;
920
                        c = 0x30 + ((v >> bits) & 0x3F);
921
                        *ptr++ = c;
922
                }
923
        }
924
        if (bits) {
925
                c = 0x30 + ((v << (6 - bits)) & 0x3F);
926
                *ptr++ = c;
927
        }
928
        *ptr++ = 0x70;
929
        return ptr - d;
930
}
931
 
932
void
933
slip_unesc6(struct slip *sl, unsigned char s)
934
{
935
        unsigned char c;
936
 
937
        if (s == 0x70) {
938
                /* drop keeptest bit = VSV */
939
                if (test_bit(SLF_KEEPTEST, &sl->flags))
940
                        clear_bit(SLF_KEEPTEST, &sl->flags);
941
 
942
                if (!clear_bit(SLF_ERROR, &sl->flags) && (sl->rcount > 2))  {
943
                        sl_bump(sl);
944
                }
945
                sl->rcount = 0;
946
                sl->xbits = 0;
947
                sl->xdata = 0;
948
        } else if (s >= 0x30 && s < 0x70) {
949
                sl->xdata = (sl->xdata << 6) | ((s - 0x30) & 0x3F);
950
                sl->xbits += 6;
951
                if (sl->xbits >= 8) {
952
                        sl->xbits -= 8;
953
                        c = (unsigned char)(sl->xdata >> sl->xbits);
954
                        if (!test_bit(SLF_ERROR, &sl->flags))  {
955
                                if (sl->rcount < sl->buffsize)  {
956
                                        sl->rbuff[sl->rcount++] = c;
957
                                        return;
958
                                }
959
                                sl->rx_over_errors++;
960
                                set_bit(SLF_ERROR, &sl->flags);
961
                        }
962
                }
963
        }
964
}
965
#endif /* CONFIG_SLIP_MODE_SLIP6 */
966
 
967
 
968
/* Perform I/O control on an active SLIP channel. */
969
static int
970
slip_ioctl(struct tty_struct *tty, void *file, int cmd, void *arg)
971
{
972
        struct slip *sl = (struct slip *) tty->disc_data;
973
        int err;
974
        unsigned int tmp;
975
 
976
        /* First make sure we're connected. */
977
        if (!sl || sl->magic != SLIP_MAGIC) {
978
                return -EINVAL;
979
        }
980
 
981
        switch(cmd) {
982
         case SIOCGIFNAME:
983
                err = verify_area(VERIFY_WRITE, arg, strlen(sl->dev->name) + 1);
984
                if (err)  {
985
                        return err;
986
                }
987
                memcpy_tofs(arg, sl->dev->name, strlen(sl->dev->name) + 1);
988
                return 0;
989
 
990
        case SIOCGIFENCAP:
991
                err = verify_area(VERIFY_WRITE, arg, sizeof(int));
992
                if (err)  {
993
                        return err;
994
                }
995
                put_user(sl->mode, (int *)arg);
996
                return 0;
997
 
998
        case SIOCSIFENCAP:
999
                err = verify_area(VERIFY_READ, arg, sizeof(int));
1000
                if (err)  {
1001
                        return err;
1002
                }
1003
                tmp = get_user((int *)arg);
1004
#ifndef SL_INCLUDE_CSLIP
1005
                if (tmp & (SL_MODE_CSLIP|SL_MODE_ADAPTIVE))  {
1006
                        return -EINVAL;
1007
                }
1008
#else
1009
                if ((tmp & (SL_MODE_ADAPTIVE | SL_MODE_CSLIP)) ==
1010
                    (SL_MODE_ADAPTIVE | SL_MODE_CSLIP))  {
1011
                        /* return -EINVAL; */
1012
                        tmp &= ~SL_MODE_ADAPTIVE;
1013
                }
1014
#endif
1015
#ifndef CONFIG_SLIP_MODE_SLIP6
1016
                if (tmp & SL_MODE_SLIP6)  {
1017
                        return -EINVAL;
1018
                }
1019
#endif
1020
                sl->mode = tmp;
1021
                sl->dev->type = ARPHRD_SLIP+sl->mode;
1022
                return 0;
1023
 
1024
         case SIOCSIFHWADDR:
1025
                return -EINVAL;
1026
 
1027
#ifdef CONFIG_SLIP_SMART
1028
        /* VSV changes start here */
1029
        case SIOCSKEEPALIVE:
1030
                if (sl->keepalive)
1031
                        (void)del_timer (&sl->keepalive_timer);
1032
                err = verify_area(VERIFY_READ, arg, sizeof(int));
1033
                if (err)  {
1034
                        return -err;
1035
                }
1036
                tmp = get_user((int *)arg);
1037
                if (tmp > 255) /* max for unchar */
1038
                        return -EINVAL;
1039
                if ((sl->keepalive = (unchar) tmp) != 0) {
1040
                        sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
1041
                        add_timer(&sl->keepalive_timer);
1042
                        set_bit(SLF_KEEPTEST, &sl->flags);
1043
                }
1044
                return 0;
1045
 
1046
        case SIOCGKEEPALIVE:
1047
                err = verify_area(VERIFY_WRITE, arg, sizeof(int));
1048
                if (err)  {
1049
                        return -err;
1050
                }
1051
                put_user(sl->keepalive, (int *)arg);
1052
                return 0;
1053
 
1054
        case SIOCSOUTFILL:
1055
                if (sl->outfill)
1056
                         (void)del_timer (&sl->outfill_timer);
1057
                err = verify_area(VERIFY_READ, arg, sizeof(int));
1058
                if (err)  {
1059
                        return -err;
1060
                }
1061
                tmp = get_user((int *)arg);
1062
                if (tmp > 255) /* max for unchar */
1063
                        return -EINVAL;
1064
                if ((sl->outfill = (unchar) tmp) != 0){
1065
                        sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
1066
                        add_timer(&sl->outfill_timer);
1067
                        set_bit(SLF_OUTWAIT, &sl->flags);
1068
                }
1069
                return 0;
1070
 
1071
        case SIOCGOUTFILL:
1072
                err = verify_area(VERIFY_WRITE, arg, sizeof(int));
1073
                if (err)  {
1074
                        return -err;
1075
                }
1076
                put_user(sl->outfill, (int *)arg);
1077
                return 0;
1078
        /* VSV changes end */
1079
#endif  
1080
 
1081
        /* Allow stty to read, but not set, the serial port */
1082
        case TCGETS:
1083
        case TCGETA:
1084
                return n_tty_ioctl(tty, (struct file *) file, cmd, (unsigned long) arg);
1085
 
1086
        default:
1087
                return -ENOIOCTLCMD;
1088
        }
1089
}
1090
 
1091
static int sl_open_dev(struct device *dev)
1092
{
1093
        struct slip *sl = (struct slip*)(dev->priv);
1094
        if(sl->tty==NULL)
1095
                return -ENODEV;
1096
        return 0;
1097
}
1098
 
1099
/* Initialize SLIP control device -- register SLIP line discipline */
1100
#ifdef MODULE
1101
static int slip_init_ctrl_dev(void)
1102
#else   /* !MODULE */
1103
int slip_init_ctrl_dev(struct device *dummy)
1104
#endif  /* !MODULE */
1105
{
1106
        int status;
1107
 
1108
        if (slip_maxdev < 4) slip_maxdev = 4; /* Sanity */
1109
 
1110
        printk(KERN_INFO "SLIP: version %s (dynamic channels, max=%d)"
1111
#ifdef CONFIG_SLIP_MODE_SLIP6
1112
               " (6 bit encapsulation enabled)"
1113
#endif
1114
               ".\n",
1115
               SLIP_VERSION, slip_maxdev );
1116
#if defined(SL_INCLUDE_CSLIP) && !defined(MODULE)
1117
        printk("CSLIP: code copyright 1989 Regents of the University of California.\n");
1118
#endif
1119
#ifdef CONFIG_SLIP_SMART
1120
        printk(KERN_INFO "SLIP linefill/keepalive option.\n");
1121
#endif  
1122
 
1123
        slip_ctrls = (slip_ctrl_t **) kmalloc(sizeof(void*)*slip_maxdev, GFP_KERNEL);
1124
        if (slip_ctrls == NULL)
1125
        {
1126
                printk("SLIP: Can't allocate slip_ctrls[] array!  Uaargh! (-> No SLIP available)\n");
1127
                return -ENOMEM;
1128
        }
1129
 
1130
        /* Clear the pointer array, we allocate devices when we need them */
1131
        memset(slip_ctrls, 0, sizeof(void*)*slip_maxdev); /* Pointers */
1132
 
1133
        /* Fill in our line protocol discipline, and register it */
1134
        memset(&sl_ldisc, 0, sizeof(sl_ldisc));
1135
        sl_ldisc.magic  = TTY_LDISC_MAGIC;
1136
        sl_ldisc.flags  = 0;
1137
        sl_ldisc.open   = slip_open;
1138
        sl_ldisc.close  = slip_close;
1139
        sl_ldisc.read   = NULL;
1140
        sl_ldisc.write  = NULL;
1141
        sl_ldisc.ioctl  = (int (*)(struct tty_struct *, struct file *,
1142
                                   unsigned int, unsigned long)) slip_ioctl;
1143
        sl_ldisc.select = NULL;
1144
        sl_ldisc.receive_buf = slip_receive_buf;
1145
        sl_ldisc.receive_room = slip_receive_room;
1146
        sl_ldisc.write_wakeup = slip_write_wakeup;
1147
        if ((status = tty_register_ldisc(N_SLIP, &sl_ldisc)) != 0)  {
1148
                printk("SLIP: can't register line discipline (err = %d)\n", status);
1149
        }
1150
 
1151
 
1152
#ifdef MODULE
1153
        return status;
1154
#else
1155
        /* Return "not found", so that dev_init() will unlink
1156
         * the placeholder device entry for us.
1157
         */
1158
        return ENODEV;
1159
#endif
1160
      }
1161
 
1162
 
1163
/* Initialize the SLIP driver.  Called by DDI. */
1164
int
1165
slip_init(struct device *dev)
1166
{
1167
        struct slip *sl = (struct slip*)(dev->priv);
1168
        int i;
1169
 
1170
        if (sl == NULL)         /* Allocation failed ?? */
1171
          return -ENODEV;
1172
 
1173
        /* Set up the "SLIP Control Block". (And clear statistics) */
1174
 
1175
        memset(sl, 0, sizeof (struct slip));
1176
        sl->magic  = SLIP_MAGIC;
1177
        sl->dev    = dev;
1178
 
1179
        /* Finish setting up the DEVICE info. */
1180
        dev->mtu                = SL_MTU;
1181
        dev->hard_start_xmit    = sl_xmit;
1182
        dev->open               = sl_open_dev;
1183
        dev->stop               = sl_close;
1184
        dev->hard_header        = sl_header;
1185
        dev->get_stats          = sl_get_stats;
1186
        dev->hard_header_len    = 0;
1187
        dev->addr_len           = 0;
1188
        dev->type               = ARPHRD_SLIP + SL_MODE_DEFAULT;
1189
        dev->tx_queue_len       = 10;
1190
        dev->rebuild_header     = sl_rebuild_header;
1191
 
1192
        for (i = 0; i < DEV_NUMBUFFS; i++)  {
1193
                skb_queue_head_init(&dev->buffs[i]);
1194
        }
1195
 
1196
        /* New-style flags. */
1197
        dev->flags              = 0;
1198
        dev->family             = AF_INET;
1199
        dev->pa_addr            = 0;
1200
        dev->pa_brdaddr         = 0;
1201
        dev->pa_mask            = 0;
1202
        dev->pa_alen            = 4;
1203
 
1204
        return 0;
1205
}
1206
#ifdef MODULE
1207
 
1208
int
1209
init_module(void)
1210
{
1211
        return slip_init_ctrl_dev();
1212
}
1213
 
1214
void
1215
cleanup_module(void)
1216
{
1217
        int i;
1218
 
1219
        if (slip_ctrls != NULL)
1220
        {
1221
                for (i = 0; i < slip_maxdev; i++)
1222
                {
1223
                        if (slip_ctrls[i])
1224
                        {
1225
                                /*
1226
                                 * VSV = if dev->start==0, then device
1227
                                 * unregistered while close proc.
1228
                                 */
1229
                                if (slip_ctrls[i]->dev.start)
1230
                                        unregister_netdev(&(slip_ctrls[i]->dev));
1231
 
1232
                                kfree(slip_ctrls[i]);
1233
                                slip_ctrls[i] = NULL;
1234
                        }
1235
                }
1236
                kfree(slip_ctrls);
1237
                slip_ctrls = NULL;
1238
        }
1239
        if ((i = tty_register_ldisc(N_SLIP, NULL)))
1240
        {
1241
                printk("SLIP: can't unregister line discipline (err = %d)\n", i);
1242
        }
1243
}
1244
#endif /* MODULE */
1245
 
1246
#ifdef CONFIG_SLIP_SMART
1247
/*
1248
 * This is start of the code for multislip style line checking
1249
 * added by Stanislav Voronyi. All changes before marked VSV
1250
 */
1251
 
1252
static void sl_outfill(unsigned long sls)
1253
{
1254
        struct slip *sl=(struct slip *)sls;
1255
 
1256
        if(sls==0L)
1257
                return;
1258
 
1259
        if(sl->outfill)
1260
        {
1261
                if( test_bit(SLF_OUTWAIT, &sl->flags) )
1262
                {
1263
                        /* no packets were transmitted, do outfill */
1264
#ifdef CONFIG_SLIP_MODE_SLIP6
1265
                        unsigned char s = (sl->mode & SL_MODE_SLIP6)?0x70:END;
1266
#else
1267
                        unsigned char s = END;
1268
#endif
1269
                        /* put END into tty queue. Is it right ??? */
1270
                        if (!test_bit(0, (void *) &sl->dev->tbusy))
1271
                        {
1272
                                /* if device busy no outfill */
1273
                                sl->tty->driver.write(sl->tty, 0, &s, 1);
1274
                        }
1275
                }
1276
                else
1277
                        set_bit(SLF_OUTWAIT, &sl->flags);
1278
                (void)del_timer(&sl->outfill_timer);
1279
                sl->outfill_timer.expires=jiffies+sl->outfill*HZ;
1280
                add_timer(&sl->outfill_timer);
1281
        }
1282
        else
1283
                del_timer(&sl->outfill_timer);
1284
}
1285
 
1286
static void sl_keepalive(unsigned long sls)
1287
{
1288
        struct slip *sl=(struct slip *)sls;
1289
 
1290
        if(sl == NULL)
1291
                return;
1292
 
1293
        if( sl->keepalive)
1294
        {
1295
                if(test_bit(SLF_KEEPTEST, &sl->flags))
1296
                {
1297
                        /* keepalive still high :(, we must hangup */
1298
                        (void)del_timer(&sl->keepalive_timer);
1299
                        if( sl->outfill ) /* outfill timer must be deleted too */
1300
                                (void)del_timer(&sl->outfill_timer);
1301
                        printk("%s: no packets received during keepalive timeout, hangup.\n", sl->dev->name);
1302
                        tty_hangup(sl->tty); /* this must hangup tty & close slip */
1303
                        /* I think we need not something else */
1304
                        return;
1305
                }
1306
                else
1307
                        set_bit(SLF_KEEPTEST, &sl->flags);
1308
                (void)del_timer(&sl->keepalive_timer);
1309
                 sl->keepalive_timer.expires=jiffies+sl->keepalive*HZ;
1310
                add_timer(&sl->keepalive_timer);
1311
        }
1312
        else
1313
                (void)del_timer(&sl->keepalive_timer);
1314
}
1315
 
1316
#endif

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.