• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/linux/linux-2.6.36/drivers/staging/cxt1e1/
1/* Copyright (C) 2004-2005  SBE, Inc.
2 *
3 *   This program is free software; you can redistribute it and/or modify
4 *   it under the terms of the GNU General Public License as published by
5 *   the Free Software Foundation; either version 2 of the License, or
6 *   (at your option) any later version.
7 *
8 *   This program is distributed in the hope that it will be useful,
9 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
10 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 *   GNU General Public License for more details.
12 */
13
14#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
16#include <linux/types.h>
17#include <linux/module.h>
18#include <linux/errno.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/proc_fs.h>
22#include <linux/sched.h>
23#include <asm/uaccess.h>
24#include "pmcc4_sysdep.h"
25#include "sbecom_inline_linux.h"
26#include "pmcc4_private.h"
27#include "sbeproc.h"
28
29/* forwards */
30void        sbecom_get_brdinfo (ci_t *, struct sbe_brd_info *, u_int8_t *);
31extern struct s_hdw_info hdw_info[MAX_BOARDS];
32
33#ifdef CONFIG_PROC_FS
34
35/********************************************************************/
36/* procfs stuff                                                     */
37/********************************************************************/
38
39
40void
41sbecom_proc_brd_cleanup (ci_t * ci)
42{
43    if (ci->dir_dev)
44    {
45	char dir[7 + SBE_IFACETMPL_SIZE + 1];
46	snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
47        remove_proc_entry("info", ci->dir_dev);
48        remove_proc_entry(dir, NULL);
49        ci->dir_dev = NULL;
50    }
51}
52
53
54static int
55sbecom_proc_get_sbe_info (char *buffer, char **start, off_t offset,
56                          int length, int *eof, void *priv)
57{
58    ci_t       *ci = (ci_t *) priv;
59    int         len = 0;
60    char       *spd;
61    struct sbe_brd_info *bip;
62
63    if (!(bip = OS_kmalloc (sizeof (struct sbe_brd_info))))
64    {
65        return -ENOMEM;
66    }
67
68    {
69        hdw_info_t *hi = &hdw_info[ci->brdno];
70
71        u_int8_t *bsn = 0;
72
73        switch (hi->promfmt)
74        {
75        case PROM_FORMAT_TYPE1:
76            bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
77            break;
78        case PROM_FORMAT_TYPE2:
79            bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
80            break;
81        }
82
83        sbecom_get_brdinfo (ci, bip, bsn);
84    }
85
86    len += sprintf (buffer + len, "Board Type:    ");
87    switch (bip->brd_id)
88    {
89    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
90        len += sprintf (buffer + len, "wanPMC-C1T3");
91        break;
92    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
93        len += sprintf (buffer + len, "wanPTMC-256T3 <E1>");
94        break;
95    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
96        len += sprintf (buffer + len, "wanPTMC-256T3 <T1>");
97        break;
98    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
99        len += sprintf (buffer + len, "wanPTMC-C24TE1");
100        break;
101
102    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
103    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
104        len += sprintf (buffer + len, "wanPMC-C4T1E1");
105        break;
106    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
107    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
108        len += sprintf (buffer + len, "wanPMC-C2T1E1");
109        break;
110    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
111    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
112        len += sprintf (buffer + len, "wanPMC-C1T1E1");
113        break;
114
115    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
116        len += sprintf (buffer + len, "wanPCI-C4T1E1");
117        break;
118    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
119        len += sprintf (buffer + len, "wanPCI-C2T1E1");
120        break;
121    case SBE_BOARD_ID (PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
122        len += sprintf (buffer + len, "wanPCI-C1T1E1");
123        break;
124
125    default:
126        len += sprintf (buffer + len, "unknown");
127        break;
128    }
129    len += sprintf (buffer + len, "  [%08X]\n", bip->brd_id);
130
131    len += sprintf (buffer + len, "Board Number:  %d\n", bip->brdno);
132    len += sprintf (buffer + len, "Hardware ID:   0x%02X\n", ci->hdw_bid);
133    len += sprintf (buffer + len, "Board SN:      %06X\n", bip->brd_sn);
134    len += sprintf (buffer + len, "Board MAC:     %02X-%02X-%02X-%02X-%02X-%02X\n",
135           bip->brd_mac_addr[0], bip->brd_mac_addr[1], bip->brd_mac_addr[2],
136          bip->brd_mac_addr[3], bip->brd_mac_addr[4], bip->brd_mac_addr[5]);
137    len += sprintf (buffer + len, "Ports:         %d\n", ci->max_port);
138    len += sprintf (buffer + len, "Channels:      %d\n", bip->brd_chan_cnt);
139    len += sprintf (buffer + len, "Interface:     %s -> %s\n",
140                    (char *) &bip->first_iname, (char *) &bip->last_iname);
141
142    switch (bip->brd_pci_speed)
143    {
144    case BINFO_PCI_SPEED_33:
145        spd = "33Mhz";
146        break;
147    case BINFO_PCI_SPEED_66:
148        spd = "66Mhz";
149        break;
150    default:
151        spd = "<not available>";
152        break;
153    }
154    len += sprintf (buffer + len, "PCI Bus Speed: %s\n", spd);
155    len += sprintf (buffer + len, "Release:       %s\n", ci->release);
156
157#ifdef SBE_PMCC4_ENABLE
158    {
159        extern int max_mru;
160        extern int max_rxdesc_used, max_txdesc_used;
161
162        len += sprintf (buffer + len, "\nmax_mru:         %d\n", max_mru);
163        len += sprintf (buffer + len, "max_rxdesc_used: %d\n", max_rxdesc_used);
164        len += sprintf (buffer + len, "max_txdesc_used: %d\n", max_txdesc_used);
165    }
166#endif
167
168    OS_kfree (bip);                 /* cleanup */
169
170    /***
171     * How to be a proc read function
172     * ------------------------------
173     * Prototype:
174     *    int f(char *buffer, char **start, off_t offset,
175     *          int count, int *peof, void *dat)
176     *
177     * Assume that the buffer is "count" bytes in size.
178     *
179     * If you know you have supplied all the data you
180     * have, set *peof.
181     *
182     * You have three ways to return data:
183     * 0) Leave *start = NULL.  (This is the default.)
184     *    Put the data of the requested offset at that
185     *    offset within the buffer.  Return the number (n)
186     *    of bytes there are from the beginning of the
187     *    buffer up to the last byte of data.  If the
188     *    number of supplied bytes (= n - offset) is
189     *    greater than zero and you didn't signal eof
190     *    and the reader is prepared to take more data
191     *    you will be called again with the requested
192     *    offset advanced by the number of bytes
193     *    absorbed.  This interface is useful for files
194     *    no larger than the buffer.
195     * 1) Set *start = an unsigned long value less than
196     *    the buffer address but greater than zero.
197     *    Put the data of the requested offset at the
198     *    beginning of the buffer.  Return the number of
199     *    bytes of data placed there.  If this number is
200     *    greater than zero and you didn't signal eof
201     *    and the reader is prepared to take more data
202     *    you will be called again with the requested
203     *    offset advanced by *start.  This interface is
204     *    useful when you have a large file consisting
205     *    of a series of blocks which you want to count
206     *    and return as wholes.
207     *    (Hack by Paul.Russell@rustcorp.com.au)
208     * 2) Set *start = an address within the buffer.
209     *    Put the data of the requested offset at *start.
210     *    Return the number of bytes of data placed there.
211     *    If this number is greater than zero and you
212     *    didn't signal eof and the reader is prepared to
213     *    take more data you will be called again with the
214     *    requested offset advanced by the number of bytes
215     *    absorbed.
216     */
217
218    /* #4 - intepretation of above = set EOF, return len */
219    *eof = 1;
220
221
222#if 0                               /* #2 from net/tokenring/olympic.c +
223                                     * lanstreamer.c */
224    {
225        off_t       begin = 0;
226        int         size = 0;
227        off_t       pos = 0;
228
229        size = len;
230        pos = begin + size;
231        if (pos < offset)
232        {
233            len = 0;
234            begin = pos;
235        }
236        *start = buffer + (offset - begin);     /* Start of wanted data */
237        len -= (offset - begin);    /* Start slop */
238        if (len > length)
239            len = length;           /* Ending slop */
240    }
241#endif
242
243#if 0                               /* #3 from
244                                     * char/ftape/lowlevel/ftape-proc.c */
245    len = strlen (buffer);
246    *start = NULL;
247    if (offset + length >= len)
248        *eof = 1;
249    else
250        *eof = 0;
251#endif
252
253
254/***
255   using NONE: returns = 314.314.314.
256   using #1  : returns = 314, 0.
257   using #2  : returns = 314, 0, 0.
258   using #3  : returns = 314, 314.
259   using #4  : returns = 314, 314.
260***/
261
262    return len;
263}
264
265/* initialize the /proc subsystem for the specific SBE driver */
266
267int         __init
268sbecom_proc_brd_init (ci_t * ci)
269{
270    struct proc_dir_entry *e;
271    char dir[7 + SBE_IFACETMPL_SIZE + 1];
272
273    /* create a directory in the root procfs */
274    snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
275    ci->dir_dev = proc_mkdir(dir, NULL);
276    if (!ci->dir_dev)
277    {
278        pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
279        goto fail;
280    }
281    e = create_proc_read_entry ("info", S_IFREG | S_IRUGO,
282                                ci->dir_dev, sbecom_proc_get_sbe_info, ci);
283    if (!e)
284    {
285        pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
286        goto fail;
287    }
288    return 0;
289
290fail:
291    sbecom_proc_brd_cleanup (ci);
292    return 1;
293}
294
295#else                           /*** ! CONFIG_PROC_FS ***/
296
297/* stubbed off dummy routines */
298
299void
300sbecom_proc_brd_cleanup (ci_t * ci)
301{
302}
303
304int         __init
305sbecom_proc_brd_init (ci_t * ci)
306{
307    return 0;
308}
309
310#endif                          /*** CONFIG_PROC_FS ***/
311
312
313/*** End-of-File ***/
314