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

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [wanrouter/] [wanproc.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/*****************************************************************************
2
* wanproc.c     WAN Router Module. /proc filesystem interface.
3
*
4
*               This module is completely hardware-independent and provides
5
*               access to the router using Linux /proc filesystem.
6
*
7
* Author:       Gideon Hack
8
*
9
* Copyright:    (c) 1995-1999 Sangoma Technologies Inc.
10
*
11
*               This program is free software; you can redistribute it and/or
12
*               modify it under the terms of the GNU General Public License
13
*               as published by the Free Software Foundation; either version
14
*               2 of the License, or (at your option) any later version.
15
* ============================================================================
16
* Jun 02, 1999  Gideon Hack     Updates for Linux 2.2.X kernels.
17
* Jun 29, 1997  Alan Cox        Merged with 1.0.3 vendor code
18
* Jan 29, 1997  Gene Kozin      v1.0.1. Implemented /proc read routines
19
* Jan 30, 1997  Alan Cox        Hacked around for 2.1
20
* Dec 13, 1996  Gene Kozin      Initial version (based on Sangoma's WANPIPE)
21
*****************************************************************************/
22
 
23
#include <linux/version.h>
24
#include <linux/config.h>
25
#include <linux/stddef.h>       /* offsetof(), etc. */
26
#include <linux/errno.h>        /* return codes */
27
#include <linux/kernel.h>
28
#include <linux/slab.h> /* kmalloc(), kfree() */
29
#include <linux/mm.h>           /* verify_area(), etc. */
30
#include <linux/string.h>       /* inline mem*, str* functions */
31
#include <asm/byteorder.h>      /* htons(), etc. */
32
#include <asm/io.h>
33
#include <linux/wanrouter.h>    /* WAN router API definitions */
34
 
35
 
36
 
37
#if defined(LINUX_2_1) || defined(LINUX_2_4) 
38
 #include <linux/init.h>        /* __initfunc et al. */
39
 #include <asm/uaccess.h>       /* copy_to_user */
40
 #define PROC_STATS_FORMAT "%30s: %12lu\n"
41
#else
42
 #define PROC_STATS_FORMAT "%30s: %12u\n"
43
 #include <asm/segment.h>       /* kernel <-> user copy */
44
#endif
45
 
46
 
47
/****** Defines and Macros **************************************************/
48
 
49
#define PROC_BUFSZ      4000    /* buffer size for printing proc info */
50
 
51
#define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
52
                              (prot == WANCONFIG_X25) ? " X25" : \
53
                                 (prot == WANCONFIG_PPP) ? " PPP" : \
54
                                    (prot == WANCONFIG_CHDLC) ? " CHDLC": \
55
                                       (prot == WANCONFIG_MPPP) ? " MPPP" : \
56
                                           " Unknown" )
57
 
58
/****** Data Types **********************************************************/
59
 
60
typedef struct wan_stat_entry
61
{
62
        struct wan_stat_entry *next;
63
        char *description;              /* description string */
64
        void *data;                     /* -> data */
65
        unsigned data_type;             /* data type */
66
} wan_stat_entry_t;
67
 
68
/****** Function Prototypes *************************************************/
69
 
70
#ifdef CONFIG_PROC_FS
71
 
72
 
73
#ifdef LINUX_2_4  /* Start of LINUX 2.4.X code */
74
 
75
 
76
        /* Proc filesystem interface */
77
        static int router_proc_perms(struct inode *, int);
78
        static ssize_t router_proc_read(struct file* file, char* buf, size_t count,                                     loff_t *ppos);
79
 
80
        /* Methods for preparing data for reading proc entries */
81
 
82
        static int config_get_info(char* buf, char** start, off_t offs, int len);
83
        static int status_get_info(char* buf, char** start, off_t offs, int len);
84
        static int wandev_get_info(char* buf, char** start, off_t offs, int len);
85
 
86
        /* Miscellaneous */
87
 
88
        /*
89
         *      Structures for interfacing with the /proc filesystem.
90
         *      Router creates its own directory /proc/net/router with the folowing
91
         *      entries:
92
         *      config          device configuration
93
         *      status          global device statistics
94
         *      <device>        entry for each WAN device
95
         */
96
 
97
        /*
98
         *      Generic /proc/net/router/<file> file and inode operations
99
         */
100
        static struct file_operations router_fops =
101
        {
102
                read:           router_proc_read,
103
        };
104
 
105
        static struct inode_operations router_inode =
106
        {
107
                permission:     router_proc_perms,
108
        };
109
 
110
        /*
111
         *      /proc/net/router/<device> file operations
112
         */
113
 
114
        static struct file_operations wandev_fops =
115
        {
116
                read:           router_proc_read,
117
                ioctl:          wanrouter_ioctl,
118
        };
119
 
120
        /*
121
         *      /proc/net/router
122
         */
123
 
124
        static struct proc_dir_entry *proc_router;
125
 
126
        /* Strings */
127
        static char conf_hdr[] =
128
                "Device name    | port |IRQ|DMA|  mem.addr  |mem.size|"
129
                "option1|option2|option3|option4\n";
130
 
131
        static char stat_hdr[] =
132
                "Device name    |protocol|station|interface|clocking|baud rate"
133
                "| MTU |ndev|link state\n";
134
 
135
 
136
        /*
137
         *      Interface functions
138
         */
139
 
140
        /*
141
         *      Initialize router proc interface.
142
         */
143
 
144
        int __init wanrouter_proc_init (void)
145
        {
146
                struct proc_dir_entry *p;
147
                proc_router = proc_mkdir(ROUTER_NAME, proc_net);
148
                if (!proc_router)
149
                        goto fail;
150
 
151
                p = create_proc_entry("config",0,proc_router);
152
                if (!p)
153
                        goto fail_config;
154
                p->proc_fops = &router_fops;
155
                p->proc_iops = &router_inode;
156
                p->get_info = config_get_info;
157
                p = create_proc_entry("status",0,proc_router);
158
                if (!p)
159
                        goto fail_stat;
160
                p->proc_fops = &router_fops;
161
                p->proc_iops = &router_inode;
162
                p->get_info = status_get_info;
163
                return 0;
164
        fail_stat:
165
                remove_proc_entry("config", proc_router);
166
        fail_config:
167
                remove_proc_entry(ROUTER_NAME, proc_net);
168
        fail:
169
                return -ENOMEM;
170
        }
171
 
172
        /*
173
         *      Clean up router proc interface.
174
         */
175
 
176
        void wanrouter_proc_cleanup (void)
177
        {
178
                remove_proc_entry("config", proc_router);
179
                remove_proc_entry("status", proc_router);
180
                remove_proc_entry(ROUTER_NAME,proc_net);
181
        }
182
 
183
        /*
184
         *      Add directory entry for WAN device.
185
         */
186
 
187
        int wanrouter_proc_add (wan_device_t* wandev)
188
        {
189
                if (wandev->magic != ROUTER_MAGIC)
190
                        return -EINVAL;
191
 
192
                wandev->dent = create_proc_entry(wandev->name, 0, proc_router);
193
                if (!wandev->dent)
194
                        return -ENOMEM;
195
                wandev->dent->proc_fops = &wandev_fops;
196
                wandev->dent->proc_iops = &router_inode;
197
                wandev->dent->get_info  = wandev_get_info;
198
                wandev->dent->data      = wandev;
199
                return 0;
200
        }
201
 
202
        /*
203
         *      Delete directory entry for WAN device.
204
         */
205
 
206
        int wanrouter_proc_delete(wan_device_t* wandev)
207
        {
208
                if (wandev->magic != ROUTER_MAGIC)
209
                        return -EINVAL;
210
                remove_proc_entry(wandev->name, proc_router);
211
                return 0;
212
        }
213
 
214
        /****** Proc filesystem entry points ****************************************/
215
 
216
        /*
217
         *      Verify access rights.
218
         */
219
 
220
        static int router_proc_perms (struct inode* inode, int op)
221
        {
222
                return 0;
223
        }
224
 
225
        /*
226
         *      Read router proc directory entry.
227
         *      This is universal routine for reading all entries in /proc/net/wanrouter
228
         *      directory.  Each directory entry contains a pointer to the 'method' for
229
         *      preparing data for that entry.
230
         *      o verify arguments
231
         *      o allocate kernel buffer
232
         *      o call get_info() to prepare data
233
         *      o copy data to user space
234
         *      o release kernel buffer
235
         *
236
         *      Return: number of bytes copied to user space (0, if no data)
237
         *              <0       error
238
         */
239
 
240
        static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
241
                                        loff_t *ppos)
242
        {
243
                struct inode *inode = file->f_dentry->d_inode;
244
                struct proc_dir_entry* dent;
245
                char* page;
246
                int pos, offs, len;
247
 
248
                if (count <= 0)
249
                        return 0;
250
 
251
                dent = inode->u.generic_ip;
252
                if ((dent == NULL) || (dent->get_info == NULL))
253
                        return 0;
254
 
255
                page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
256
                if (page == NULL)
257
                        return -ENOBUFS;
258
 
259
                pos = dent->get_info(page, dent->data, 0, 0);
260
                offs = file->f_pos;
261
                if (offs < pos) {
262
                        len = min_t(unsigned int, pos - offs, count);
263
                        if (copy_to_user(buf, (page + offs), len)) {
264
                                kfree(page);
265
                                return -EFAULT;
266
                        }
267
                        file->f_pos += len;
268
                }
269
                else
270
                        len = 0;
271
                kfree(page);
272
                return len;
273
        }
274
 
275
        /*
276
         *      Prepare data for reading 'Config' entry.
277
         *      Return length of data.
278
         */
279
 
280
        static int config_get_info(char* buf, char** start, off_t offs, int len)
281
        {
282
                int cnt = sizeof(conf_hdr) - 1;
283
                wan_device_t* wandev;
284
                strcpy(buf, conf_hdr);
285
                for (wandev = router_devlist;
286
                     wandev && (cnt < (PROC_BUFSZ - 120));
287
                     wandev = wandev->next) {
288
                        if (wandev->state) cnt += sprintf(&buf[cnt],
289
                                "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
290
                                wandev->name,
291
                                wandev->ioport,
292
                                wandev->irq,
293
                                wandev->dma,
294
                                wandev->maddr,
295
                                wandev->msize,
296
                                wandev->hw_opt[0],
297
                                wandev->hw_opt[1],
298
                                wandev->hw_opt[2],
299
                                wandev->hw_opt[3]);
300
                }
301
 
302
                return cnt;
303
        }
304
 
305
        /*
306
         *      Prepare data for reading 'Status' entry.
307
         *      Return length of data.
308
         */
309
 
310
        static int status_get_info(char* buf, char** start, off_t offs, int len)
311
        {
312
                int cnt = 0;
313
                wan_device_t* wandev;
314
 
315
                //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
316
                strcpy(&buf[cnt], stat_hdr);
317
                cnt += sizeof(stat_hdr) - 1;
318
 
319
                for (wandev = router_devlist;
320
                     wandev && (cnt < (PROC_BUFSZ - 80));
321
                     wandev = wandev->next) {
322
                        if (!wandev->state) continue;
323
                        cnt += sprintf(&buf[cnt],
324
                                "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
325
                                wandev->name,
326
                                PROT_DECODE(wandev->config_id),
327
                                wandev->config_id == WANCONFIG_FR ?
328
                                        (wandev->station ? " Node" : " CPE") :
329
                                        (wandev->config_id == WANCONFIG_X25 ?
330
                                        (wandev->station ? " DCE" : " DTE") :
331
                                        (" N/A")),
332
                                wandev->interface ? " V.35" : " RS-232",
333
                                wandev->clocking ? "internal" : "external",
334
                                wandev->bps,
335
                                wandev->mtu,
336
                                wandev->ndev);
337
 
338
                        switch (wandev->state) {
339
 
340
                        case WAN_UNCONFIGURED:
341
                                cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
342
                                break;
343
 
344
                        case WAN_DISCONNECTED:
345
                                cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
346
                                break;
347
 
348
                        case WAN_CONNECTING:
349
                                cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
350
                                break;
351
 
352
                        case WAN_CONNECTED:
353
                                cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
354
                                break;
355
 
356
                        default:
357
                                cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
358
                                break;
359
                        }
360
                }
361
                return cnt;
362
        }
363
 
364
        /*
365
         *      Prepare data for reading <device> entry.
366
         *      Return length of data.
367
         *
368
         *      On entry, the 'start' argument will contain a pointer to WAN device
369
         *      data space.
370
         */
371
 
372
        static int wandev_get_info(char* buf, char** start, off_t offs, int len)
373
        {
374
                wan_device_t* wandev = (void*)start;
375
                int cnt = 0;
376
                int rslt = 0;
377
 
378
                if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
379
                        return 0;
380
                if (!wandev->state)
381
                        return sprintf(&buf[cnt], "device is not configured!\n");
382
 
383
                /* Update device statistics */
384
                if (wandev->update) {
385
 
386
                        rslt = wandev->update(wandev);
387
                        if(rslt) {
388
                                switch (rslt) {
389
                                case -EAGAIN:
390
                                        return sprintf(&buf[cnt], "Device is busy!\n");
391
 
392
                                default:
393
                                        return sprintf(&buf[cnt],
394
                                                "Device is not configured!\n");
395
                                }
396
                        }
397
                }
398
 
399
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
400
                        "total packets received", wandev->stats.rx_packets);
401
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
402
                        "total packets transmitted", wandev->stats.tx_packets);
403
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
404
                        "total bytes received", wandev->stats.rx_bytes);
405
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
406
                        "total bytes transmitted", wandev->stats.tx_bytes);
407
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
408
                        "bad packets received", wandev->stats.rx_errors);
409
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
410
                        "packet transmit problems", wandev->stats.tx_errors);
411
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
412
                        "received frames dropped", wandev->stats.rx_dropped);
413
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
414
                        "transmit frames dropped", wandev->stats.tx_dropped);
415
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
416
                        "multicast packets received", wandev->stats.multicast);
417
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
418
                        "transmit collisions", wandev->stats.collisions);
419
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
420
                        "receive length errors", wandev->stats.rx_length_errors);
421
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
422
                        "receiver overrun errors", wandev->stats.rx_over_errors);
423
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
424
                        "CRC errors", wandev->stats.rx_crc_errors);
425
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
426
                        "frame format errors (aborts)", wandev->stats.rx_frame_errors);
427
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
428
                        "receiver fifo overrun", wandev->stats.rx_fifo_errors);
429
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
430
                        "receiver missed packet", wandev->stats.rx_missed_errors);
431
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
432
                        "aborted frames transmitted", wandev->stats.tx_aborted_errors);
433
                return cnt;
434
        }
435
 
436
 
437
#else /* ------------------- END OF LINUX 2.4.X VERSION -------------*/
438
 
439
 
440
 
441
        /* Proc filesystem interface */
442
        static int router_proc_perms(struct inode *, int);
443
#ifdef LINUX_2_1
444
        static ssize_t router_proc_read(struct file *file, char *buf, size_t count,                                     loff_t *ppos);
445
#else
446
        static int router_proc_read(
447
                struct inode* inode, struct file* file, char* buf, int count);
448
        static int device_write(
449
                struct inode* inode, struct file* file, const char* buf, int count);
450
#endif
451
 
452
        /* Methods for preparing data for reading proc entries */
453
        static int config_get_info(char* buf, char** start, off_t offs, int len,
454
                int dummy);
455
        static int status_get_info(char* buf, char** start, off_t offs, int len,
456
                int dummy);
457
        static int wandev_get_info(char* buf, char** start, off_t offs, int len,
458
                int dummy);
459
 
460
        /* Miscellaneous */
461
 
462
        /*
463
         *      Global Data
464
         */
465
 
466
        /*
467
         *      Names of the proc directory entries
468
         */
469
 
470
        static char name_root[] = ROUTER_NAME;
471
        static char name_conf[] = "config";
472
        static char name_stat[] = "status";
473
 
474
        /*
475
         *      Structures for interfacing with the /proc filesystem.
476
         *      Router creates its own directory /proc/net/router with the folowing
477
         *      entries:
478
         *      config          device configuration
479
         *      status          global device statistics
480
         *      <device>        entry for each WAN device
481
         */
482
 
483
        /*
484
         *      Generic /proc/net/router/<file> file and inode operations
485
         */
486
#ifdef LINUX_2_1
487
        static struct file_operations router_fops =
488
        {
489
                NULL,                   /* lseek   */
490
                router_proc_read,       /* read    */
491
                NULL,                   /* write   */
492
                NULL,                   /* readdir */
493
                NULL,                   /* select  */
494
                NULL,                   /* ioctl   */
495
                NULL,                   /* mmap    */
496
                NULL,                   /* no special open code    */
497
                NULL,                   /* flush */
498
                NULL,                   /* no special release code */
499
                NULL                    /* can't fsync */
500
        };
501
#else
502
        static struct file_operations router_fops =
503
        {
504
                NULL,                   /* lseek   */
505
                router_proc_read,       /* read    */
506
                NULL,                   /* write   */
507
                NULL,                   /* readdir */
508
                NULL,                   /* select  */
509
                NULL,                   /* ioctl   */
510
                NULL,                   /* mmap    */
511
                NULL,                   /* no special open code    */
512
                NULL,                   /* no special release code */
513
                NULL                    /* can't fsync */
514
        };
515
#endif
516
 
517
        static struct inode_operations router_inode =
518
        {
519
                &router_fops,
520
                NULL,                   /* create */
521
                NULL,                   /* lookup */
522
                NULL,                   /* link */
523
                NULL,                   /* unlink */
524
                NULL,                   /* symlink */
525
                NULL,                   /* mkdir */
526
                NULL,                   /* rmdir */
527
                NULL,                   /* mknod */
528
                NULL,                   /* rename */
529
                NULL,                   /* follow link */
530
                NULL,                   /* readlink */
531
                NULL,                   /* readpage */
532
                NULL,                   /* writepage */
533
                NULL,                   /* bmap */
534
                NULL,                   /* truncate */
535
                router_proc_perms
536
        };
537
 
538
        /*
539
         *      /proc/net/router/<device> file and inode operations
540
         */
541
 
542
#ifdef LINUX_2_1
543
        static struct file_operations wandev_fops =
544
        {
545
                NULL,                   /* lseek   */
546
                router_proc_read,       /* read    */
547
                NULL,                   /* write   */
548
                NULL,                   /* readdir */
549
                NULL,                   /* select  */
550
                wanrouter_ioctl,        /* ioctl   */
551
                NULL,                   /* mmap    */
552
                NULL,                   /* no special open code    */
553
                NULL,                   /* flush */
554
                NULL,                   /* no special release code */
555
                NULL                    /* can't fsync */
556
        };
557
#else
558
        static struct file_operations wandev_fops =
559
        {
560
                NULL,                   /* lseek   */
561
                router_proc_read,       /* read    */
562
                device_write,           /* write   */
563
                NULL,                   /* readdir */
564
                NULL,                   /* select  */
565
                wanrouter_ioctl,        /* ioctl   */
566
                NULL,                   /* mmap    */
567
                NULL,                   /* no special open code    */
568
                NULL,                   /* no special release code */
569
                NULL                    /* can't fsync */
570
        };
571
#endif
572
 
573
        static struct inode_operations wandev_inode =
574
        {
575
                &wandev_fops,
576
                NULL,                   /* create */
577
                NULL,                   /* lookup */
578
                NULL,                   /* link */
579
                NULL,                   /* unlink */
580
                NULL,                   /* symlink */
581
                NULL,                   /* mkdir */
582
                NULL,                   /* rmdir */
583
                NULL,                   /* mknod */
584
                NULL,                   /* rename */
585
                NULL,                   /* readlink */
586
                NULL,                   /* follow_link */
587
                NULL,                   /* readpage */
588
                NULL,                   /* writepage */
589
                NULL,                   /* bmap */
590
                NULL,                   /* truncate */
591
                router_proc_perms
592
        };
593
 
594
        /*
595
         * Proc filesystem derectory entries.
596
         */
597
 
598
        /*
599
         *      /proc/net/router
600
         */
601
 
602
        static struct proc_dir_entry proc_router =
603
        {
604
                0,                       /* .low_ino */
605
                sizeof(name_root) - 1,  /* .namelen */
606
                name_root,              /* .name */
607
                0555 | S_IFDIR,         /* .mode */
608
                2,                      /* .nlink */
609
                0,                       /* .uid */
610
                0,                       /* .gid */
611
                0,                       /* .size */
612
                &proc_dir_inode_operations, /* .ops */
613
                NULL,                   /* .get_info */
614
                NULL,                   /* .fill_node */
615
                NULL,                   /* .next */
616
                NULL,                   /* .parent */
617
                NULL,                   /* .subdir */
618
                NULL,                   /* .data */
619
        };
620
 
621
        /*
622
         *      /proc/net/router/config
623
         */
624
 
625
        static struct proc_dir_entry proc_router_conf =
626
        {
627
                0,                       /* .low_ino */
628
                sizeof(name_conf) - 1,  /* .namelen */
629
                name_conf,              /* .name */
630
                0444 | S_IFREG,         /* .mode */
631
                1,                      /* .nlink */
632
                0,                       /* .uid */
633
                0,                       /* .gid */
634
                0,                       /* .size */
635
                &router_inode,          /* .ops */
636
                &config_get_info,       /* .get_info */
637
                NULL,                   /* .fill_node */
638
                NULL,                   /* .next */
639
                NULL,                   /* .parent */
640
                NULL,                   /* .subdir */
641
                NULL,                   /* .data */
642
        };
643
 
644
        /*
645
         *      /proc/net/router/status
646
         */
647
 
648
        static struct proc_dir_entry proc_router_stat =
649
        {
650
                0,                       /* .low_ino */
651
                sizeof(name_stat) - 1,  /* .namelen */
652
                name_stat,              /* .name */
653
                0444 | S_IFREG,         /* .mode */
654
                1,                      /* .nlink */
655
                0,                       /* .uid */
656
                0,                       /* .gid */
657
                0,                       /* .size */
658
                &router_inode,          /* .ops */
659
                status_get_info,        /* .get_info */
660
                NULL,                   /* .fill_node */
661
                NULL,                   /* .next */
662
                NULL,                   /* .parent */
663
                NULL,                   /* .subdir */
664
                NULL,                   /* .data */
665
        };
666
 
667
        /* Strings */
668
        static char conf_hdr[] =
669
                "Device name    | port |IRQ|DMA|  mem.addr  |mem.size|"
670
                "option1|option2|option3|option4\n";
671
 
672
        static char stat_hdr[] =
673
                "Device name    |protocol|station|interface|clocking|baud rate| MTU |ndev"
674
                "|link state\n";
675
 
676
 
677
        /*
678
         *      Interface functions
679
         */
680
 
681
        /*
682
         *      Initialize router proc interface.
683
         */
684
 
685
#ifdef LINUX_2_1
686
        __initfunc(int wanrouter_proc_init (void))
687
        {
688
                int err = proc_register(proc_net, &proc_router);
689
 
690
                if (!err) {
691
                        proc_register(&proc_router, &proc_router_conf);
692
                        proc_register(&proc_router, &proc_router_stat);
693
                }
694
                return err;
695
        }
696
#else
697
        int wanrouter_proc_init (void)
698
        {
699
                int err = proc_register_dynamic(&proc_net, &proc_router);
700
 
701
                if (!err) {
702
                        proc_register_dynamic(&proc_router, &proc_router_conf);
703
                        proc_register_dynamic(&proc_router, &proc_router_stat);
704
                }
705
                return err;
706
        }
707
#endif
708
 
709
        /*
710
         *      Clean up router proc interface.
711
         */
712
 
713
        void wanrouter_proc_cleanup (void)
714
        {
715
                proc_unregister(&proc_router, proc_router_conf.low_ino);
716
                proc_unregister(&proc_router, proc_router_stat.low_ino);
717
#ifdef LINUX_2_1
718
                proc_unregister(proc_net, proc_router.low_ino);
719
#else
720
                proc_unregister(&proc_net, proc_router.low_ino);
721
#endif
722
        }
723
 
724
        /*
725
         *      Add directory entry for WAN device.
726
         */
727
 
728
        int wanrouter_proc_add (wan_device_t* wandev)
729
        {
730
                if (wandev->magic != ROUTER_MAGIC)
731
                        return -EINVAL;
732
 
733
                memset(&wandev->dent, 0, sizeof(wandev->dent));
734
                wandev->dent.namelen    = strlen(wandev->name);
735
                wandev->dent.name       = wandev->name;
736
                wandev->dent.mode       = 0444 | S_IFREG;
737
                wandev->dent.nlink      = 1;
738
                wandev->dent.ops        = &wandev_inode;
739
                wandev->dent.get_info   = &wandev_get_info;
740
                wandev->dent.data       = wandev;
741
#ifdef LINUX_2_1
742
                return proc_register(&proc_router, &wandev->dent);
743
#else
744
                return proc_register_dynamic(&proc_router, &wandev->dent);
745
#endif
746
        }
747
 
748
        /*
749
         *      Delete directory entry for WAN device.
750
         */
751
 
752
        int wanrouter_proc_delete(wan_device_t* wandev)
753
        {
754
                if (wandev->magic != ROUTER_MAGIC)
755
                        return -EINVAL;
756
                proc_unregister(&proc_router, wandev->dent.low_ino);
757
                return 0;
758
        }
759
 
760
        /****** Proc filesystem entry points ****************************************/
761
 
762
        /*
763
         *      Verify access rights.
764
         */
765
 
766
        static int router_proc_perms (struct inode* inode, int op)
767
        {
768
                return 0;
769
        }
770
 
771
        /*
772
         *      Read router proc directory entry.
773
         *      This is universal routine for reading all entries in /proc/net/wanrouter
774
         *      directory.  Each directory entry contains a pointer to the 'method' for
775
         *      preparing data for that entry.
776
         *      o verify arguments
777
         *      o allocate kernel buffer
778
         *      o call get_info() to prepare data
779
         *      o copy data to user space
780
         *      o release kernel buffer
781
         *
782
         *      Return: number of bytes copied to user space (0, if no data)
783
         *              <0       error
784
         */
785
#ifdef LINUX_2_1
786
        static ssize_t router_proc_read(struct file* file, char* buf, size_t count,
787
                                        loff_t *ppos)
788
        {
789
                struct inode *inode = file->f_dentry->d_inode;
790
                struct proc_dir_entry* dent;
791
                char* page;
792
                int pos, offs, len;
793
 
794
                if (count <= 0)
795
                        return 0;
796
 
797
                dent = inode->u.generic_ip;
798
                if ((dent == NULL) || (dent->get_info == NULL))
799
                        return 0;
800
 
801
                page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
802
                if (page == NULL)
803
                        return -ENOBUFS;
804
 
805
                pos = dent->get_info(page, dent->data, 0, 0, 0);
806
                offs = file->f_pos;
807
                if (offs < pos) {
808
                        len = min_t(unsigned int, pos - offs, count);
809
                        if (copy_to_user(buf, (page + offs), len)) {
810
                                kfree(page);
811
                                return -EFAULT;
812
                        }
813
                        file->f_pos += len;
814
                }
815
                else
816
                        len = 0;
817
                kfree(page);
818
                return len;
819
        }
820
 
821
#else
822
        static int router_proc_read(
823
                struct inode* inode, struct file* file, char* buf, int count)
824
        {
825
                struct proc_dir_entry* dent;
826
                char* page;
827
                int err, pos, offs, len;
828
 
829
                if (count <= 0)
830
                        return 0;
831
                dent = inode->u.generic_ip;
832
                if ((dent == NULL) || (dent->get_info == NULL))
833
                        return -ENODATA;
834
                err = verify_area(VERIFY_WRITE, buf, count);
835
                if (err) return err;
836
 
837
                page = kmalloc(PROC_BUFSZ, GFP_KERNEL);
838
                if (page == NULL)
839
                        return -ENOMEM;
840
 
841
                pos = dent->get_info(page, dent->data, 0, 0, 0);
842
                offs = file->f_pos;
843
                if (offs < pos) {
844
                        len = min_t(unsigned int, pos - offs, count);
845
                        memcpy_tofs((void*)buf, (void*)(page + offs), len);
846
                        file->f_pos += len;
847
                }
848
                else len = 0;
849
                kfree(page);
850
                return len;
851
        }
852
#endif
853
 
854
 
855
        /*
856
         *      Prepare data for reading 'Config' entry.
857
         *      Return length of data.
858
         */
859
 
860
        static int config_get_info(char* buf, char** start, off_t offs, int len,
861
                int dummy)
862
        {
863
                int cnt = sizeof(conf_hdr) - 1;
864
                wan_device_t* wandev;
865
                strcpy(buf, conf_hdr);
866
                for (wandev = router_devlist;
867
                     wandev && (cnt < (PROC_BUFSZ - 120));
868
                     wandev = wandev->next) {
869
                        if (wandev->state) cnt += sprintf(&buf[cnt],
870
                                "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
871
                                wandev->name,
872
                                wandev->ioport,
873
                                wandev->irq,
874
                                wandev->dma,
875
                                wandev->maddr,
876
                                wandev->msize,
877
                                wandev->hw_opt[0],
878
                                wandev->hw_opt[1],
879
                                wandev->hw_opt[2],
880
                                wandev->hw_opt[3]);
881
                }
882
 
883
                return cnt;
884
        }
885
 
886
        /*
887
         *      Prepare data for reading 'Status' entry.
888
         *      Return length of data.
889
         */
890
 
891
        static int status_get_info(char* buf, char** start, off_t offs, int len,
892
                                int dummy)
893
        {
894
                int cnt = 0;
895
                wan_device_t* wandev;
896
 
897
                //cnt += sprintf(&buf[cnt], "\nSTATUS:\n\n");
898
                strcpy(&buf[cnt], stat_hdr);
899
                cnt += sizeof(stat_hdr) - 1;
900
 
901
                for (wandev = router_devlist;
902
                     wandev && (cnt < (PROC_BUFSZ - 80));
903
                     wandev = wandev->next) {
904
                        if (!wandev->state) continue;
905
                        cnt += sprintf(&buf[cnt],
906
                                "%-15s|%-8s|%-7s|%-9s|%-8s|%9u|%5u|%3u |",
907
                                wandev->name,
908
                                PROT_DECODE(wandev->config_id),
909
                                wandev->config_id == WANCONFIG_FR ?
910
                                        (wandev->station ? " Node" : " CPE") :
911
                                        (wandev->config_id == WANCONFIG_X25 ?
912
                                        (wandev->station ? " DCE" : " DTE") :
913
                                        (" N/A")),
914
                                wandev->interface ? " V.35" : " RS-232",
915
                                wandev->clocking ? "internal" : "external",
916
                                wandev->bps,
917
                                wandev->mtu,
918
                                wandev->ndev);
919
 
920
                        switch (wandev->state) {
921
 
922
                        case WAN_UNCONFIGURED:
923
                                cnt += sprintf(&buf[cnt], "%-12s\n", "unconfigured");
924
                                break;
925
 
926
                        case WAN_DISCONNECTED:
927
                                cnt += sprintf(&buf[cnt], "%-12s\n", "disconnected");
928
                                break;
929
 
930
                        case WAN_CONNECTING:
931
                                cnt += sprintf(&buf[cnt], "%-12s\n", "connecting");
932
                                break;
933
 
934
                        case WAN_CONNECTED:
935
                                cnt += sprintf(&buf[cnt], "%-12s\n", "connected");
936
                                break;
937
 
938
                        case WAN_FT1_READY:
939
                                cnt += sprintf(&buf[cnt], "%-12s\n", "ft1 ready");
940
                                break;
941
 
942
                        default:
943
                                cnt += sprintf(&buf[cnt], "%-12s\n", "invalid");
944
                                break;
945
                        }
946
                }
947
                return cnt;
948
        }
949
 
950
        /*
951
         *      Prepare data for reading <device> entry.
952
         *      Return length of data.
953
         *
954
         *      On entry, the 'start' argument will contain a pointer to WAN device
955
         *      data space.
956
         */
957
 
958
        static int wandev_get_info(char* buf, char** start, off_t offs, int len,
959
                                int dummy)
960
        {
961
                wan_device_t* wandev = (void*)start;
962
                int cnt = 0;
963
                int rslt = 0;
964
 
965
                if ((wandev == NULL) || (wandev->magic != ROUTER_MAGIC))
966
                        return 0;
967
                if (!wandev->state)
968
                        return sprintf(&buf[cnt], "Device is not configured!\n");
969
 
970
                /* Update device statistics */
971
                if (wandev->update) {
972
 
973
                        rslt = wandev->update(wandev);
974
                        if(rslt) {
975
                                switch (rslt) {
976
                                case -EAGAIN:
977
                                        return sprintf(&buf[cnt], "Device is busy!\n");
978
 
979
                                default:
980
                                        return sprintf(&buf[cnt],
981
                                                "Device is not configured!\n");
982
                                }
983
                        }
984
                }
985
 
986
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
987
                        "total packets received", wandev->stats.rx_packets);
988
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
989
                        "total packets transmitted", wandev->stats.tx_packets);
990
#ifdef LINUX_2_1
991
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
992
                        "total bytes received", wandev->stats.rx_bytes);
993
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
994
                        "total bytes transmitted", wandev->stats.tx_bytes);
995
#endif
996
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
997
                        "bad packets received", wandev->stats.rx_errors);
998
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
999
                        "packet transmit problems", wandev->stats.tx_errors);
1000
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1001
                        "received frames dropped", wandev->stats.rx_dropped);
1002
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1003
                        "transmit frames dropped", wandev->stats.tx_dropped);
1004
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1005
                        "multicast packets received", wandev->stats.multicast);
1006
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1007
                        "transmit collisions", wandev->stats.collisions);
1008
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1009
                        "receive length errors", wandev->stats.rx_length_errors);
1010
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1011
                        "receiver overrun errors", wandev->stats.rx_over_errors);
1012
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1013
                        "CRC errors", wandev->stats.rx_crc_errors);
1014
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1015
                        "frame format errors (aborts)", wandev->stats.rx_frame_errors);
1016
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1017
                        "receiver fifo overrun", wandev->stats.rx_fifo_errors);
1018
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1019
                        "receiver missed packet", wandev->stats.rx_missed_errors);
1020
                cnt += sprintf(&buf[cnt], PROC_STATS_FORMAT,
1021
                        "aborted frames transmitted", wandev->stats.tx_aborted_errors);
1022
 
1023
                return cnt;
1024
        }
1025
 
1026
#endif /* End of ifdef LINUX_2_4 */
1027
 
1028
 
1029
#else
1030
 
1031
/*
1032
 *      No /proc - output stubs
1033
 */
1034
 
1035
int __init wanrouter_proc_init(void)
1036
{
1037
        return 0;
1038
}
1039
 
1040
void wanrouter_proc_cleanup(void)
1041
{
1042
        return;
1043
}
1044
 
1045
int wanrouter_proc_add(wan_device_t *wandev)
1046
{
1047
        return 0;
1048
}
1049
 
1050
int wanrouter_proc_delete(wan_device_t *wandev)
1051
{
1052
        return 0;
1053
}
1054
 
1055
#endif
1056
 
1057
/*============================================================================
1058
 * Write WAN device ???.
1059
 * o Find WAN device associated with this node
1060
 */
1061
#ifdef LINUX_2_0
1062
static int device_write(
1063
        struct inode* inode, struct file* file, const char* buf, int count)
1064
{
1065
        int err = verify_area(VERIFY_READ, buf, count);
1066
        struct proc_dir_entry* dent;
1067
        wan_device_t* wandev;
1068
 
1069
        if (err) return err;
1070
 
1071
        dent = inode->u.generic_ip;
1072
        if ((dent == NULL) || (dent->data == NULL))
1073
                return -ENODATA;
1074
 
1075
        wandev = dent->data;
1076
 
1077
        printk(KERN_ERR "%s: writing %d bytes to %s...\n",
1078
                name_root, count, dent->name);
1079
 
1080
        return 0;
1081
}
1082
#endif
1083
 
1084
/*
1085
 *      End
1086
 */
1087
 

powered by: WebSVN 2.1.0

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