diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /net/wanrouter/wanproc.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'net/wanrouter/wanproc.c')
-rw-r--r-- | net/wanrouter/wanproc.c | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/net/wanrouter/wanproc.c b/net/wanrouter/wanproc.c new file mode 100644 index 000000000000..c28ba5a47209 --- /dev/null +++ b/net/wanrouter/wanproc.c | |||
@@ -0,0 +1,381 @@ | |||
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/config.h> | ||
24 | #include <linux/init.h> /* __initfunc et al. */ | ||
25 | #include <linux/stddef.h> /* offsetof(), etc. */ | ||
26 | #include <linux/errno.h> /* return codes */ | ||
27 | #include <linux/kernel.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/wanrouter.h> /* WAN router API definitions */ | ||
30 | #include <linux/seq_file.h> | ||
31 | #include <linux/smp_lock.h> | ||
32 | |||
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 | { | ||
84 | struct wan_device *wandev; | ||
85 | loff_t l = *pos; | ||
86 | |||
87 | lock_kernel(); | ||
88 | if (!l--) | ||
89 | return SEQ_START_TOKEN; | ||
90 | for (wandev = wanrouter_router_devlist; l-- && wandev; | ||
91 | wandev = wandev->next) | ||
92 | ; | ||
93 | return wandev; | ||
94 | } | ||
95 | |||
96 | static void *r_next(struct seq_file *m, void *v, loff_t *pos) | ||
97 | { | ||
98 | struct wan_device *wandev = v; | ||
99 | (*pos)++; | ||
100 | return (v == SEQ_START_TOKEN) ? wanrouter_router_devlist : wandev->next; | ||
101 | } | ||
102 | |||
103 | static void r_stop(struct seq_file *m, void *v) | ||
104 | { | ||
105 | unlock_kernel(); | ||
106 | } | ||
107 | |||
108 | static int config_show(struct seq_file *m, void *v) | ||
109 | { | ||
110 | struct wan_device *p = v; | ||
111 | if (v == SEQ_START_TOKEN) { | ||
112 | seq_puts(m, "Device name | port |IRQ|DMA| mem.addr |" | ||
113 | "mem.size|option1|option2|option3|option4\n"); | ||
114 | return 0; | ||
115 | } | ||
116 | if (!p->state) | ||
117 | return 0; | ||
118 | seq_printf(m, "%-15s|0x%-4X|%3u|%3u| 0x%-8lX |0x%-6X|%7u|%7u|%7u|%7u\n", | ||
119 | p->name, p->ioport, p->irq, p->dma, p->maddr, p->msize, | ||
120 | p->hw_opt[0], p->hw_opt[1], p->hw_opt[2], p->hw_opt[3]); | ||
121 | return 0; | ||
122 | } | ||
123 | |||
124 | static int status_show(struct seq_file *m, void *v) | ||
125 | { | ||
126 | struct wan_device *p = v; | ||
127 | if (v == SEQ_START_TOKEN) { | ||
128 | seq_puts(m, "Device name |protocol|station|interface|" | ||
129 | "clocking|baud rate| MTU |ndev|link state\n"); | ||
130 | return 0; | ||
131 | } | ||
132 | if (!p->state) | ||
133 | return 0; | ||
134 | seq_printf(m, "%-15s|%-8s| %-7s| %-9s|%-8s|%9u|%5u|%3u |", | ||
135 | p->name, | ||
136 | PROT_DECODE(p->config_id), | ||
137 | p->config_id == WANCONFIG_FR ? | ||
138 | (p->station ? "Node" : "CPE") : | ||
139 | (p->config_id == WANCONFIG_X25 ? | ||
140 | (p->station ? "DCE" : "DTE") : | ||
141 | ("N/A")), | ||
142 | p->interface ? "V.35" : "RS-232", | ||
143 | p->clocking ? "internal" : "external", | ||
144 | p->bps, | ||
145 | p->mtu, | ||
146 | p->ndev); | ||
147 | |||
148 | switch (p->state) { | ||
149 | case WAN_UNCONFIGURED: | ||
150 | seq_printf(m, "%-12s\n", "unconfigured"); | ||
151 | break; | ||
152 | case WAN_DISCONNECTED: | ||
153 | seq_printf(m, "%-12s\n", "disconnected"); | ||
154 | break; | ||
155 | case WAN_CONNECTING: | ||
156 | seq_printf(m, "%-12s\n", "connecting"); | ||
157 | break; | ||
158 | case WAN_CONNECTED: | ||
159 | seq_printf(m, "%-12s\n", "connected"); | ||
160 | break; | ||
161 | default: | ||
162 | seq_printf(m, "%-12s\n", "invalid"); | ||
163 | break; | ||
164 | } | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static struct seq_operations config_op = { | ||
169 | .start = r_start, | ||
170 | .next = r_next, | ||
171 | .stop = r_stop, | ||
172 | .show = config_show, | ||
173 | }; | ||
174 | |||
175 | static struct seq_operations status_op = { | ||
176 | .start = r_start, | ||
177 | .next = r_next, | ||
178 | .stop = r_stop, | ||
179 | .show = status_show, | ||
180 | }; | ||
181 | |||
182 | static int config_open(struct inode *inode, struct file *file) | ||
183 | { | ||
184 | return seq_open(file, &config_op); | ||
185 | } | ||
186 | |||
187 | static int status_open(struct inode *inode, struct file *file) | ||
188 | { | ||
189 | return seq_open(file, &status_op); | ||
190 | } | ||
191 | |||
192 | static struct file_operations config_fops = { | ||
193 | .owner = THIS_MODULE, | ||
194 | .open = config_open, | ||
195 | .read = seq_read, | ||
196 | .llseek = seq_lseek, | ||
197 | .release = seq_release, | ||
198 | }; | ||
199 | |||
200 | static struct file_operations status_fops = { | ||
201 | .owner = THIS_MODULE, | ||
202 | .open = status_open, | ||
203 | .read = seq_read, | ||
204 | .llseek = seq_lseek, | ||
205 | .release = seq_release, | ||
206 | }; | ||
207 | |||
208 | static int wandev_show(struct seq_file *m, void *v) | ||
209 | { | ||
210 | struct wan_device *wandev = m->private; | ||
211 | |||
212 | if (wandev->magic != ROUTER_MAGIC) | ||
213 | return 0; | ||
214 | |||
215 | if (!wandev->state) { | ||
216 | seq_puts(m, "device is not configured!\n"); | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | /* Update device statistics */ | ||
221 | if (wandev->update) { | ||
222 | int err = wandev->update(wandev); | ||
223 | if (err == -EAGAIN) { | ||
224 | seq_puts(m, "Device is busy!\n"); | ||
225 | return 0; | ||
226 | } | ||
227 | if (err) { | ||
228 | seq_puts(m, "Device is not configured!\n"); | ||
229 | return 0; | ||
230 | } | ||
231 | } | ||
232 | |||
233 | seq_printf(m, PROC_STATS_FORMAT, | ||
234 | "total packets received", wandev->stats.rx_packets); | ||
235 | seq_printf(m, PROC_STATS_FORMAT, | ||
236 | "total packets transmitted", wandev->stats.tx_packets); | ||
237 | seq_printf(m, PROC_STATS_FORMAT, | ||
238 | "total bytes received", wandev->stats.rx_bytes); | ||
239 | seq_printf(m, PROC_STATS_FORMAT, | ||
240 | "total bytes transmitted", wandev->stats.tx_bytes); | ||
241 | seq_printf(m, PROC_STATS_FORMAT, | ||
242 | "bad packets received", wandev->stats.rx_errors); | ||
243 | seq_printf(m, PROC_STATS_FORMAT, | ||
244 | "packet transmit problems", wandev->stats.tx_errors); | ||
245 | seq_printf(m, PROC_STATS_FORMAT, | ||
246 | "received frames dropped", wandev->stats.rx_dropped); | ||
247 | seq_printf(m, PROC_STATS_FORMAT, | ||
248 | "transmit frames dropped", wandev->stats.tx_dropped); | ||
249 | seq_printf(m, PROC_STATS_FORMAT, | ||
250 | "multicast packets received", wandev->stats.multicast); | ||
251 | seq_printf(m, PROC_STATS_FORMAT, | ||
252 | "transmit collisions", wandev->stats.collisions); | ||
253 | seq_printf(m, PROC_STATS_FORMAT, | ||
254 | "receive length errors", wandev->stats.rx_length_errors); | ||
255 | seq_printf(m, PROC_STATS_FORMAT, | ||
256 | "receiver overrun errors", wandev->stats.rx_over_errors); | ||
257 | seq_printf(m, PROC_STATS_FORMAT, | ||
258 | "CRC errors", wandev->stats.rx_crc_errors); | ||
259 | seq_printf(m, PROC_STATS_FORMAT, | ||
260 | "frame format errors (aborts)", wandev->stats.rx_frame_errors); | ||
261 | seq_printf(m, PROC_STATS_FORMAT, | ||
262 | "receiver fifo overrun", wandev->stats.rx_fifo_errors); | ||
263 | seq_printf(m, PROC_STATS_FORMAT, | ||
264 | "receiver missed packet", wandev->stats.rx_missed_errors); | ||
265 | seq_printf(m, PROC_STATS_FORMAT, | ||
266 | "aborted frames transmitted", wandev->stats.tx_aborted_errors); | ||
267 | return 0; | ||
268 | } | ||
269 | |||
270 | static int wandev_open(struct inode *inode, struct file *file) | ||
271 | { | ||
272 | return single_open(file, wandev_show, PDE(inode)->data); | ||
273 | } | ||
274 | |||
275 | static struct file_operations wandev_fops = { | ||
276 | .owner = THIS_MODULE, | ||
277 | .open = wandev_open, | ||
278 | .read = seq_read, | ||
279 | .llseek = seq_lseek, | ||
280 | .release = single_release, | ||
281 | .ioctl = wanrouter_ioctl, | ||
282 | }; | ||
283 | |||
284 | /* | ||
285 | * Initialize router proc interface. | ||
286 | */ | ||
287 | |||
288 | int __init wanrouter_proc_init(void) | ||
289 | { | ||
290 | struct proc_dir_entry *p; | ||
291 | proc_router = proc_mkdir(ROUTER_NAME, proc_net); | ||
292 | if (!proc_router) | ||
293 | goto fail; | ||
294 | |||
295 | p = create_proc_entry("config", S_IRUGO, proc_router); | ||
296 | if (!p) | ||
297 | goto fail_config; | ||
298 | p->proc_fops = &config_fops; | ||
299 | p = create_proc_entry("status", S_IRUGO, proc_router); | ||
300 | if (!p) | ||
301 | goto fail_stat; | ||
302 | p->proc_fops = &status_fops; | ||
303 | return 0; | ||
304 | fail_stat: | ||
305 | remove_proc_entry("config", proc_router); | ||
306 | fail_config: | ||
307 | remove_proc_entry(ROUTER_NAME, 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, 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 = create_proc_entry(wandev->name, S_IRUGO, proc_router); | ||
333 | if (!wandev->dent) | ||
334 | return -ENOMEM; | ||
335 | wandev->dent->proc_fops = &wandev_fops; | ||
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 | |||