1 /*****************************************************************************
2 * wanproc.c WAN Router Module. /proc filesystem interface.
4 * This module is completely hardware-independent and provides
5 * access to the router using Linux /proc filesystem.
9 * Copyright: (c) 1995-1999 Sangoma Technologies Inc.
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 *****************************************************************************/
23 #include <linux/init.h> /* __initfunc et al. */
24 #include <linux/stddef.h> /* offsetof(), etc. */
25 #include <linux/errno.h> /* return codes */
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/wanrouter.h> /* WAN router API definitions */
29 #include <linux/seq_file.h>
30 #include <linux/mutex.h>
32 #include <net/net_namespace.h>
35 #define PROC_STATS_FORMAT "%30s: %12lu\n"
37 /****** Defines and Macros **************************************************/
39 #define PROT_DECODE(prot) ((prot == WANCONFIG_FR) ? " FR" :\
40 (prot == WANCONFIG_X25) ? " X25" : \
41 (prot == WANCONFIG_PPP) ? " PPP" : \
42 (prot == WANCONFIG_CHDLC) ? " CHDLC": \
43 (prot == WANCONFIG_MPPP) ? " MPPP" : \
46 /****** Function Prototypes *************************************************/
53 * Structures for interfacing with the /proc filesystem.
54 * Router creates its own directory /proc/net/router with the following
56 * config device configuration
57 * status global device statistics
58 * <device> entry for each WAN device
62 * Generic /proc/net/router/<file> file and inode operations
69 static DEFINE_MUTEX(config_mutex
);
70 static struct proc_dir_entry
*proc_router
;
78 /****** Proc filesystem entry points ****************************************/
83 static void *r_start(struct seq_file
*m
, loff_t
*pos
)
85 struct wan_device
*wandev
;
88 mutex_lock(&config_mutex
);
90 return SEQ_START_TOKEN
;
91 for (wandev
= wanrouter_router_devlist
; l
-- && wandev
;
92 wandev
= wandev
->next
)
97 static void *r_next(struct seq_file
*m
, void *v
, loff_t
*pos
)
99 struct wan_device
*wandev
= v
;
101 return (v
== SEQ_START_TOKEN
) ? wanrouter_router_devlist
: wandev
->next
;
104 static void r_stop(struct seq_file
*m
, void *v
)
106 mutex_unlock(&config_mutex
);
109 static int config_show(struct seq_file
*m
, void *v
)
111 struct wan_device
*p
= v
;
112 if (v
== SEQ_START_TOKEN
) {
113 seq_puts(m
, "Device name | port |IRQ|DMA| mem.addr |"
114 "mem.size|option1|option2|option3|option4\n");
119 seq_printf(m
, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
120 p
->name
, p
->ioport
, p
->irq
, p
->dma
, p
->maddr
, p
->msize
,
121 p
->hw_opt
[0], p
->hw_opt
[1], p
->hw_opt
[2], p
->hw_opt
[3]);
125 static int status_show(struct seq_file
*m
, void *v
)
127 struct wan_device
*p
= v
;
128 if (v
== SEQ_START_TOKEN
) {
129 seq_puts(m
, "Device name |protocol|station|interface|"
130 "clocking|baud rate| MTU |ndev|link state\n");
135 seq_printf(m
, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |",
137 PROT_DECODE(p
->config_id
),
138 p
->config_id
== WANCONFIG_FR
?
139 (p
->station
? "Node" : "CPE") :
140 (p
->config_id
== WANCONFIG_X25
?
141 (p
->station
? "DCE" : "DTE") :
143 p
->interface
? "V.35" : "RS-232",
144 p
->clocking
? "internal" : "external",
150 case WAN_UNCONFIGURED
:
151 seq_printf(m
, "%-12s\n", "unconfigured");
153 case WAN_DISCONNECTED
:
154 seq_printf(m
, "%-12s\n", "disconnected");
157 seq_printf(m
, "%-12s\n", "connecting");
160 seq_printf(m
, "%-12s\n", "connected");
163 seq_printf(m
, "%-12s\n", "invalid");
169 static const struct seq_operations config_op
= {
176 static const struct seq_operations status_op
= {
183 static int config_open(struct inode
*inode
, struct file
*file
)
185 return seq_open(file
, &config_op
);
188 static int status_open(struct inode
*inode
, struct file
*file
)
190 return seq_open(file
, &status_op
);
193 static const struct file_operations config_fops
= {
194 .owner
= THIS_MODULE
,
198 .release
= seq_release
,
201 static const struct file_operations status_fops
= {
202 .owner
= THIS_MODULE
,
206 .release
= seq_release
,
209 static int wandev_show(struct seq_file
*m
, void *v
)
211 struct wan_device
*wandev
= m
->private;
213 if (wandev
->magic
!= ROUTER_MAGIC
)
216 if (!wandev
->state
) {
217 seq_puts(m
, "device is not configured!\n");
221 /* Update device statistics */
222 if (wandev
->update
) {
223 int err
= wandev
->update(wandev
);
224 if (err
== -EAGAIN
) {
225 seq_puts(m
, "Device is busy!\n");
229 seq_puts(m
, "Device is not configured!\n");
234 seq_printf(m
, PROC_STATS_FORMAT
,
235 "total packets received", wandev
->stats
.rx_packets
);
236 seq_printf(m
, PROC_STATS_FORMAT
,
237 "total packets transmitted", wandev
->stats
.tx_packets
);
238 seq_printf(m
, PROC_STATS_FORMAT
,
239 "total bytes received", wandev
->stats
.rx_bytes
);
240 seq_printf(m
, PROC_STATS_FORMAT
,
241 "total bytes transmitted", wandev
->stats
.tx_bytes
);
242 seq_printf(m
, PROC_STATS_FORMAT
,
243 "bad packets received", wandev
->stats
.rx_errors
);
244 seq_printf(m
, PROC_STATS_FORMAT
,
245 "packet transmit problems", wandev
->stats
.tx_errors
);
246 seq_printf(m
, PROC_STATS_FORMAT
,
247 "received frames dropped", wandev
->stats
.rx_dropped
);
248 seq_printf(m
, PROC_STATS_FORMAT
,
249 "transmit frames dropped", wandev
->stats
.tx_dropped
);
250 seq_printf(m
, PROC_STATS_FORMAT
,
251 "multicast packets received", wandev
->stats
.multicast
);
252 seq_printf(m
, PROC_STATS_FORMAT
,
253 "transmit collisions", wandev
->stats
.collisions
);
254 seq_printf(m
, PROC_STATS_FORMAT
,
255 "receive length errors", wandev
->stats
.rx_length_errors
);
256 seq_printf(m
, PROC_STATS_FORMAT
,
257 "receiver overrun errors", wandev
->stats
.rx_over_errors
);
258 seq_printf(m
, PROC_STATS_FORMAT
,
259 "CRC errors", wandev
->stats
.rx_crc_errors
);
260 seq_printf(m
, PROC_STATS_FORMAT
,
261 "frame format errors (aborts)", wandev
->stats
.rx_frame_errors
);
262 seq_printf(m
, PROC_STATS_FORMAT
,
263 "receiver fifo overrun", wandev
->stats
.rx_fifo_errors
);
264 seq_printf(m
, PROC_STATS_FORMAT
,
265 "receiver missed packet", wandev
->stats
.rx_missed_errors
);
266 seq_printf(m
, PROC_STATS_FORMAT
,
267 "aborted frames transmitted", wandev
->stats
.tx_aborted_errors
);
271 static int wandev_open(struct inode
*inode
, struct file
*file
)
273 return single_open(file
, wandev_show
, PDE(inode
)->data
);
276 static const struct file_operations wandev_fops
= {
277 .owner
= THIS_MODULE
,
281 .release
= single_release
,
282 .unlocked_ioctl
= wanrouter_ioctl
,
286 * Initialize router proc interface.
289 int __init
wanrouter_proc_init(void)
291 struct proc_dir_entry
*p
;
292 proc_router
= proc_mkdir(ROUTER_NAME
, init_net
.proc_net
);
296 p
= proc_create("config", S_IRUGO
, proc_router
, &config_fops
);
299 p
= proc_create("status", S_IRUGO
, proc_router
, &status_fops
);
304 remove_proc_entry("config", proc_router
);
306 remove_proc_entry(ROUTER_NAME
, init_net
.proc_net
);
312 * Clean up router proc interface.
315 void wanrouter_proc_cleanup(void)
317 remove_proc_entry("config", proc_router
);
318 remove_proc_entry("status", proc_router
);
319 remove_proc_entry(ROUTER_NAME
, init_net
.proc_net
);
323 * Add directory entry for WAN device.
326 int wanrouter_proc_add(struct wan_device
* wandev
)
328 if (wandev
->magic
!= ROUTER_MAGIC
)
331 wandev
->dent
= proc_create(wandev
->name
, S_IRUGO
,
332 proc_router
, &wandev_fops
);
335 wandev
->dent
->data
= wandev
;
340 * Delete directory entry for WAN device.
342 int wanrouter_proc_delete(struct wan_device
* wandev
)
344 if (wandev
->magic
!= ROUTER_MAGIC
)
346 remove_proc_entry(wandev
->name
, proc_router
);
353 * No /proc - output stubs
356 int __init
wanrouter_proc_init(void)
361 void wanrouter_proc_cleanup(void)
365 int wanrouter_proc_add(struct wan_device
*wandev
)
370 int wanrouter_proc_delete(struct wan_device
*wandev
)