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