• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /netgear-R7000-V1.0.7.12_1.2.5/components/opensource/linux/linux-2.6.36/net/wanrouter/
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/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/****** 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
69static DEFINE_MUTEX(config_mutex);
70static struct proc_dir_entry *proc_router;
71
72/* Strings */
73
74/*
75 *	Interface functions
76 */
77
78/****** Proc filesystem entry points ****************************************/
79
80/*
81 *	Iterator
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	/* Update device statistics */
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 *	Initialize router proc interface.
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 *	Clean up router proc interface.
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 *	Add directory entry for WAN device.
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 *	Delete directory entry for WAN device.
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 *	No /proc - output stubs
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 *	End
381 */
382