Merge branch 'next' into for-linus
[deliverable/linux.git] / net / wanrouter / wanproc.c
1 /*****************************************************************************
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/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/smp_lock.h>
31
32 #include <net/net_namespace.h>
33 #include <asm/io.h>
34
35 #define PROC_STATS_FORMAT "%30s: %12lu\n"
36
37 /****** Defines and Macros **************************************************/
38
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" : \
44 " Unknown" )
45
46 /****** Function Prototypes *************************************************/
47
48 #ifdef CONFIG_PROC_FS
49
50 /* Miscellaneous */
51
52 /*
53 * Structures for interfacing with the /proc filesystem.
54 * Router creates its own directory /proc/net/router with the folowing
55 * entries:
56 * config device configuration
57 * status global device statistics
58 * <device> entry for each WAN device
59 */
60
61 /*
62 * Generic /proc/net/router/<file> file and inode operations
63 */
64
65 /*
66 * /proc/net/router
67 */
68
69 static struct proc_dir_entry *proc_router;
70
71 /* Strings */
72
73 /*
74 * Interface functions
75 */
76
77 /****** Proc filesystem entry points ****************************************/
78
79 /*
80 * Iterator
81 */
82 static void *r_start(struct seq_file *m, loff_t *pos)
83 __acquires(kernel_lock)
84 {
85 struct wan_device *wandev;
86 loff_t l = *pos;
87
88 lock_kernel();
89 if (!l--)
90 return SEQ_START_TOKEN;
91 for (wandev = wanrouter_router_devlist; l-- && wandev;
92 wandev = wandev->next)
93 ;
94 return wandev;
95 }
96
97 static void *r_next(struct seq_file *m, void *v, loff_t *pos)
98 {
99 struct wan_device *wandev = v;
100 (*pos)++;
101 return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next;
102 }
103
104 static void r_stop(struct seq_file *m, void *v)
105 __releases(kernel_lock)
106 {
107 unlock_kernel();
108 }
109
110 static int config_show(struct seq_file *m, void *v)
111 {
112 struct wan_device *p = v;
113 if (v == SEQ_START_TOKEN) {
114 seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |"
115 "mem.size|option1|option2|option3|option4\n");
116 return 0;
117 }
118 if (!p->state)
119 return 0;
120 seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n",
121 p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize,
122 p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]);
123 return 0;
124 }
125
126 static int status_show(struct seq_file *m, void *v)
127 {
128 struct wan_device *p = v;
129 if (v == SEQ_START_TOKEN) {
130 seq_puts(m, "Device name |protocol|station|interface|"
131 "clocking|baud rate| MTU |ndev|link state\n");
132 return 0;
133 }
134 if (!p->state)
135 return 0;
136 seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |",
137 p->name,
138 PROT_DECODE(p->config_id),
139 p->config_id == WANCONFIG_FR ?
140 (p->station ? "Node" : "CPE") :
141 (p->config_id == WANCONFIG_X25 ?
142 (p->station ? "DCE" : "DTE") :
143 ("N/A")),
144 p->interface ? "V.35" : "RS-232",
145 p->clocking ? "internal" : "external",
146 p->bps,
147 p->mtu,
148 p->ndev);
149
150 switch (p->state) {
151 case WAN_UNCONFIGURED:
152 seq_printf(m, "%-12s\n", "unconfigured");
153 break;
154 case WAN_DISCONNECTED:
155 seq_printf(m, "%-12s\n", "disconnected");
156 break;
157 case WAN_CONNECTING:
158 seq_printf(m, "%-12s\n", "connecting");
159 break;
160 case WAN_CONNECTED:
161 seq_printf(m, "%-12s\n", "connected");
162 break;
163 default:
164 seq_printf(m, "%-12s\n", "invalid");
165 break;
166 }
167 return 0;
168 }
169
170 static const struct seq_operations config_op = {
171 .start = r_start,
172 .next = r_next,
173 .stop = r_stop,
174 .show = config_show,
175 };
176
177 static const struct seq_operations status_op = {
178 .start = r_start,
179 .next = r_next,
180 .stop = r_stop,
181 .show = status_show,
182 };
183
184 static int config_open(struct inode *inode, struct file *file)
185 {
186 return seq_open(file, &config_op);
187 }
188
189 static int status_open(struct inode *inode, struct file *file)
190 {
191 return seq_open(file, &status_op);
192 }
193
194 static const struct file_operations config_fops = {
195 .owner = THIS_MODULE,
196 .open = config_open,
197 .read = seq_read,
198 .llseek = seq_lseek,
199 .release = seq_release,
200 };
201
202 static const struct file_operations status_fops = {
203 .owner = THIS_MODULE,
204 .open = status_open,
205 .read = seq_read,
206 .llseek = seq_lseek,
207 .release = seq_release,
208 };
209
210 static int wandev_show(struct seq_file *m, void *v)
211 {
212 struct wan_device *wandev = m->private;
213
214 if (wandev->magic != ROUTER_MAGIC)
215 return 0;
216
217 if (!wandev->state) {
218 seq_puts(m, "device is not configured!\n");
219 return 0;
220 }
221
222 /* Update device statistics */
223 if (wandev->update) {
224 int err = wandev->update(wandev);
225 if (err == -EAGAIN) {
226 seq_puts(m, "Device is busy!\n");
227 return 0;
228 }
229 if (err) {
230 seq_puts(m, "Device is not configured!\n");
231 return 0;
232 }
233 }
234
235 seq_printf(m, PROC_STATS_FORMAT,
236 "total packets received", wandev->stats.rx_packets);
237 seq_printf(m, PROC_STATS_FORMAT,
238 "total packets transmitted", wandev->stats.tx_packets);
239 seq_printf(m, PROC_STATS_FORMAT,
240 "total bytes received", wandev->stats.rx_bytes);
241 seq_printf(m, PROC_STATS_FORMAT,
242 "total bytes transmitted", wandev->stats.tx_bytes);
243 seq_printf(m, PROC_STATS_FORMAT,
244 "bad packets received", wandev->stats.rx_errors);
245 seq_printf(m, PROC_STATS_FORMAT,
246 "packet transmit problems", wandev->stats.tx_errors);
247 seq_printf(m, PROC_STATS_FORMAT,
248 "received frames dropped", wandev->stats.rx_dropped);
249 seq_printf(m, PROC_STATS_FORMAT,
250 "transmit frames dropped", wandev->stats.tx_dropped);
251 seq_printf(m, PROC_STATS_FORMAT,
252 "multicast packets received", wandev->stats.multicast);
253 seq_printf(m, PROC_STATS_FORMAT,
254 "transmit collisions", wandev->stats.collisions);
255 seq_printf(m, PROC_STATS_FORMAT,
256 "receive length errors", wandev->stats.rx_length_errors);
257 seq_printf(m, PROC_STATS_FORMAT,
258 "receiver overrun errors", wandev->stats.rx_over_errors);
259 seq_printf(m, PROC_STATS_FORMAT,
260 "CRC errors", wandev->stats.rx_crc_errors);
261 seq_printf(m, PROC_STATS_FORMAT,
262 "frame format errors (aborts)", wandev->stats.rx_frame_errors);
263 seq_printf(m, PROC_STATS_FORMAT,
264 "receiver fifo overrun", wandev->stats.rx_fifo_errors);
265 seq_printf(m, PROC_STATS_FORMAT,
266 "receiver missed packet", wandev->stats.rx_missed_errors);
267 seq_printf(m, PROC_STATS_FORMAT,
268 "aborted frames transmitted", wandev->stats.tx_aborted_errors);
269 return 0;
270 }
271
272 static int wandev_open(struct inode *inode, struct file *file)
273 {
274 return single_open(file, wandev_show, PDE(inode)->data);
275 }
276
277 static const struct file_operations wandev_fops = {
278 .owner = THIS_MODULE,
279 .open = wandev_open,
280 .read = seq_read,
281 .llseek = seq_lseek,
282 .release = single_release,
283 .unlocked_ioctl = wanrouter_ioctl,
284 };
285
286 /*
287 * Initialize router proc interface.
288 */
289
290 int __init wanrouter_proc_init(void)
291 {
292 struct proc_dir_entry *p;
293 proc_router = proc_mkdir(ROUTER_NAME, init_net.proc_net);
294 if (!proc_router)
295 goto fail;
296
297 p = proc_create("config", S_IRUGO, proc_router, &config_fops);
298 if (!p)
299 goto fail_config;
300 p = proc_create("status", S_IRUGO, proc_router, &status_fops);
301 if (!p)
302 goto fail_stat;
303 return 0;
304 fail_stat:
305 remove_proc_entry("config", proc_router);
306 fail_config:
307 remove_proc_entry(ROUTER_NAME, init_net.proc_net);
308 fail:
309 return -ENOMEM;
310 }
311
312 /*
313 * Clean up router proc interface.
314 */
315
316 void wanrouter_proc_cleanup(void)
317 {
318 remove_proc_entry("config", proc_router);
319 remove_proc_entry("status", proc_router);
320 remove_proc_entry(ROUTER_NAME, init_net.proc_net);
321 }
322
323 /*
324 * Add directory entry for WAN device.
325 */
326
327 int wanrouter_proc_add(struct wan_device* wandev)
328 {
329 if (wandev->magic != ROUTER_MAGIC)
330 return -EINVAL;
331
332 wandev->dent = proc_create(wandev->name, S_IRUGO,
333 proc_router, &wandev_fops);
334 if (!wandev->dent)
335 return -ENOMEM;
336 wandev->dent->data = wandev;
337 return 0;
338 }
339
340 /*
341 * Delete directory entry for WAN device.
342 */
343 int wanrouter_proc_delete(struct wan_device* wandev)
344 {
345 if (wandev->magic != ROUTER_MAGIC)
346 return -EINVAL;
347 remove_proc_entry(wandev->name, proc_router);
348 return 0;
349 }
350
351 #else
352
353 /*
354 * No /proc - output stubs
355 */
356
357 int __init wanrouter_proc_init(void)
358 {
359 return 0;
360 }
361
362 void wanrouter_proc_cleanup(void)
363 {
364 }
365
366 int wanrouter_proc_add(struct wan_device *wandev)
367 {
368 return 0;
369 }
370
371 int wanrouter_proc_delete(struct wan_device *wandev)
372 {
373 return 0;
374 }
375
376 #endif
377
378 /*
379 * End
380 */
381
This page took 0.061734 seconds and 5 git commands to generate.