blob: 1c2e52e8b5fe401b88505fb5acb43c48d05a3010 [file] [log] [blame]
Bob Beers50ee11f2010-03-04 08:40:46 -05001/* 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
Joe Perchese6e4d052010-05-03 11:02:44 -070014#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15
Bob Beers50ee11f2010-03-04 08:40:46 -050016#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>
David Howells766d1002013-04-08 22:47:46 +010022#include <linux/seq_file.h>
Bob Beers50ee11f2010-03-04 08:40:46 -050023#include <linux/sched.h>
24#include <asm/uaccess.h>
25#include "pmcc4_sysdep.h"
26#include "sbecom_inline_linux.h"
27#include "pmcc4_private.h"
28#include "sbeproc.h"
29
David Howells766d1002013-04-08 22:47:46 +010030extern void sbecom_get_brdinfo(ci_t *, struct sbe_brd_info *, u_int8_t *);
Bob Beers50ee11f2010-03-04 08:40:46 -050031extern struct s_hdw_info hdw_info[MAX_BOARDS];
32
David Howells766d1002013-04-08 22:47:46 +010033void sbecom_proc_brd_cleanup(ci_t *ci)
Bob Beers50ee11f2010-03-04 08:40:46 -050034{
David Howells766d1002013-04-08 22:47:46 +010035 if (ci->dir_dev) {
36 char dir[7 + SBE_IFACETMPL_SIZE + 1];
37 snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
38 remove_proc_entry("info", ci->dir_dev);
39 remove_proc_entry(dir, NULL);
40 ci->dir_dev = NULL;
41 }
Bob Beers50ee11f2010-03-04 08:40:46 -050042}
43
David Howells766d1002013-04-08 22:47:46 +010044static void sbecom_proc_get_brdinfo(ci_t *ci, struct sbe_brd_info *bip)
Bob Beers50ee11f2010-03-04 08:40:46 -050045{
David Howells766d1002013-04-08 22:47:46 +010046 hdw_info_t *hi = &hdw_info[ci->brdno];
Sachin Kamat95f56322013-09-27 09:36:32 +053047 u_int8_t *bsn = NULL;
Bob Beers50ee11f2010-03-04 08:40:46 -050048
David Howells766d1002013-04-08 22:47:46 +010049 switch (hi->promfmt)
50 {
51 case PROM_FORMAT_TYPE1:
52 bsn = (u_int8_t *) hi->mfg_info.pft1.Serial;
53 break;
54 case PROM_FORMAT_TYPE2:
55 bsn = (u_int8_t *) hi->mfg_info.pft2.Serial;
56 break;
57 }
Bob Beers50ee11f2010-03-04 08:40:46 -050058
David Howells766d1002013-04-08 22:47:46 +010059 sbecom_get_brdinfo (ci, bip, bsn);
Bob Beers50ee11f2010-03-04 08:40:46 -050060
David Howells766d1002013-04-08 22:47:46 +010061 pr_devel(">> sbecom_get_brdinfo: returned, first_if %p <%s> last_if %p <%s>\n",
62 bip->first_iname, bip->first_iname,
63 bip->last_iname, bip->last_iname);
64}
Bob Beers50ee11f2010-03-04 08:40:46 -050065
David Howells766d1002013-04-08 22:47:46 +010066/*
67 * Describe the driver state through /proc
68 */
69static int sbecom_proc_get_sbe_info(struct seq_file *m, void *v)
70{
71 ci_t *ci = m->private;
72 char *spd;
73 struct sbe_brd_info *bip;
Bob Beers50ee11f2010-03-04 08:40:46 -050074
Daeseok Youn693d9632014-04-18 09:31:35 +090075 bip = kzalloc(sizeof(struct sbe_brd_info), GFP_KERNEL | GFP_DMA);
Chi Pham24e7d792014-03-12 16:36:19 +010076 if (!bip)
David Howells766d1002013-04-08 22:47:46 +010077 return -ENOMEM;
Bob Beers50ee11f2010-03-04 08:40:46 -050078
David Howells766d1002013-04-08 22:47:46 +010079 pr_devel(">> sbecom_proc_get_sbe_info: entered\n");
Bob Beers50ee11f2010-03-04 08:40:46 -050080
David Howells766d1002013-04-08 22:47:46 +010081 sbecom_proc_get_brdinfo(ci, bip);
Bob Beers50ee11f2010-03-04 08:40:46 -050082
David Howells766d1002013-04-08 22:47:46 +010083 seq_puts(m, "Board Type: ");
84 switch (bip->brd_id) {
85 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T3):
86 seq_puts(m, "wanPMC-C1T3");
87 break;
88 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_E1):
89 seq_puts(m, "wanPTMC-256T3 <E1>");
90 break;
91 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_256T3_T1):
92 seq_puts(m, "wanPTMC-256T3 <T1>");
93 break;
94 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPTMC_C24TE1):
95 seq_puts(m, "wanPTMC-C24TE1");
96 break;
Bob Beers50ee11f2010-03-04 08:40:46 -050097
David Howells766d1002013-04-08 22:47:46 +010098 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1):
99 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C4T1E1_L):
100 seq_puts(m, "wanPMC-C4T1E1");
101 break;
102 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1):
103 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C2T1E1_L):
104 seq_puts(m, "wanPMC-C2T1E1");
105 break;
106 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1):
107 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPMC_C1T1E1_L):
108 seq_puts(m, "wanPMC-C1T1E1");
109 break;
Bob Beers50ee11f2010-03-04 08:40:46 -0500110
David Howells766d1002013-04-08 22:47:46 +0100111 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C4T1E1):
112 seq_puts(m, "wanPCI-C4T1E1");
113 break;
114 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C2T1E1):
115 seq_puts(m, "wanPCI-C2T1E1");
116 break;
117 case SBE_BOARD_ID(PCI_VENDOR_ID_SBE, PCI_DEVICE_ID_WANPCI_C1T1E1):
118 seq_puts(m, "wanPCI-C1T1E1");
119 break;
120
121 default:
122 seq_puts(m, "unknown");
123 break;
124 }
125
126 seq_printf(m, " [%08X]\n", bip->brd_id);
127
128 seq_printf(m, "Board Number: %d\n", bip->brdno);
129 seq_printf(m, "Hardware ID: 0x%02X\n", ci->hdw_bid);
130 seq_printf(m, "Board SN: %06X\n", bip->brd_sn);
131 seq_printf(m, "Board MAC: %pMF\n", bip->brd_mac_addr);
132 seq_printf(m, "Ports: %d\n", ci->max_port);
133 seq_printf(m, "Channels: %d\n", bip->brd_chan_cnt);
Bob Beers50ee11f2010-03-04 08:40:46 -0500134#if 1
David Howells766d1002013-04-08 22:47:46 +0100135 seq_printf(m, "Interface: %s -> %s\n",
136 bip->first_iname, bip->last_iname);
Bob Beers50ee11f2010-03-04 08:40:46 -0500137#else
David Howells766d1002013-04-08 22:47:46 +0100138 seq_printf(m, "Interface: <not available> 1st %p lst %p\n",
139 bip->first_iname, bip->last_iname);
Bob Beers50ee11f2010-03-04 08:40:46 -0500140#endif
141
David Howells766d1002013-04-08 22:47:46 +0100142 switch (bip->brd_pci_speed) {
143 case BINFO_PCI_SPEED_33:
144 spd = "33Mhz";
145 break;
146 case BINFO_PCI_SPEED_66:
147 spd = "66Mhz";
148 break;
149 default:
150 spd = "<not available>";
151 break;
152 }
153 seq_printf(m, "PCI Bus Speed: %s\n", spd);
Bob Beers50ee11f2010-03-04 08:40:46 -0500154
155#ifdef SBE_PMCC4_ENABLE
David Howells766d1002013-04-08 22:47:46 +0100156 {
157 extern int cxt1e1_max_mru;
Bob Beers50ee11f2010-03-04 08:40:46 -0500158#if 0
David Howells766d1002013-04-08 22:47:46 +0100159 extern int max_chans_used;
160 extern int cxt1e1_max_mtu;
Bob Beers50ee11f2010-03-04 08:40:46 -0500161#endif
David Howells766d1002013-04-08 22:47:46 +0100162 extern int max_rxdesc_used, max_txdesc_used;
Bob Beers50ee11f2010-03-04 08:40:46 -0500163
David Howells766d1002013-04-08 22:47:46 +0100164 seq_printf(m, "\ncxt1e1_max_mru: %d\n", cxt1e1_max_mru);
Bob Beers50ee11f2010-03-04 08:40:46 -0500165#if 0
David Howells766d1002013-04-08 22:47:46 +0100166 seq_printf(m, "\nmax_chans_used: %d\n", max_chans_used);
167 seq_printf(m, "cxt1e1_max_mtu: %d\n", cxt1e1_max_mtu);
Bob Beers50ee11f2010-03-04 08:40:46 -0500168#endif
David Howells766d1002013-04-08 22:47:46 +0100169 seq_printf(m, "max_rxdesc_used: %d\n", max_rxdesc_used);
170 seq_printf(m, "max_txdesc_used: %d\n", max_txdesc_used);
171 }
Bob Beers50ee11f2010-03-04 08:40:46 -0500172#endif
173
David Howells766d1002013-04-08 22:47:46 +0100174 kfree(bip);
Bob Beers50ee11f2010-03-04 08:40:46 -0500175
David Howells766d1002013-04-08 22:47:46 +0100176 pr_devel(">> proc_fs: finished\n");
177 return 0;
Bob Beers50ee11f2010-03-04 08:40:46 -0500178}
179
David Howells766d1002013-04-08 22:47:46 +0100180/*
181 * seq_file wrappers for procfile show routines.
182 */
183static int sbecom_proc_open(struct inode *inode, struct file *file)
Bob Beers50ee11f2010-03-04 08:40:46 -0500184{
David Howells766d1002013-04-08 22:47:46 +0100185 return single_open(file, sbecom_proc_get_sbe_info, PDE_DATA(inode));
186}
Bob Beers50ee11f2010-03-04 08:40:46 -0500187
David Howells766d1002013-04-08 22:47:46 +0100188static const struct file_operations sbecom_proc_fops = {
189 .open = sbecom_proc_open,
190 .read = seq_read,
191 .llseek = seq_lseek,
Al Virobae301d2013-05-05 00:15:43 -0400192 .release = single_release,
David Howells766d1002013-04-08 22:47:46 +0100193};
194
195/*
196 * Initialize the /proc subsystem for the specific SBE driver
197 */
198int __init sbecom_proc_brd_init(ci_t *ci)
199{
200 char dir[7 + SBE_IFACETMPL_SIZE + 1];
201
202 snprintf(dir, sizeof(dir), "driver/%s", ci->devname);
203 ci->dir_dev = proc_mkdir(dir, NULL);
204 if (!ci->dir_dev) {
205 pr_err("Unable to create directory /proc/driver/%s\n", ci->devname);
206 goto fail;
207 }
208
209 if (!proc_create_data("info", S_IFREG | S_IRUGO, ci->dir_dev,
210 &sbecom_proc_fops, ci)) {
211 pr_err("Unable to create entry /proc/driver/%s/info\n", ci->devname);
212 goto fail;
213 }
214 return 0;
Bob Beers50ee11f2010-03-04 08:40:46 -0500215
216fail:
David Howells766d1002013-04-08 22:47:46 +0100217 sbecom_proc_brd_cleanup(ci);
218 return 1;
Bob Beers50ee11f2010-03-04 08:40:46 -0500219}