1 /******************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Purpose: Funktions to display statictic data
7 ******************************************************************************/
9 /******************************************************************************
11 * (C)Copyright 1998-2002 SysKonnect GmbH.
12 * (C)Copyright 2002-2003 Marvell.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
20 * Author: Mirko Lindner (mlindner@syskonnect.de)
22 * The information in this file is provided "AS IS" without warranty.
24 ******************************************************************************/
26 #include <linux/proc_fs.h>
27 #include <linux/seq_file.h>
29 #include "h/skdrv1st.h"
30 #include "h/skdrv2nd.h"
31 #include "h/skversion.h"
33 extern struct SK_NET_DEVICE *SkGeRootDev;
34 static int sk_proc_print(void *writePtr, char *format, ...);
35 static void sk_gen_browse(void *buffer);
38 static int sk_seq_show(struct seq_file *seq, void *v);
39 static int sk_proc_open(struct inode *inode, struct file *file);
40 struct file_operations sk_proc_fops = {
45 .release = single_release,
47 struct net_device *currDev = NULL;
49 /*****************************************************************************
51 * sk_gen_browse -generic print "summaries" entry
54 * This function fills the proc entry with statistic data about
55 * the ethernet device.
60 static void sk_gen_browse(void *buffer)
62 struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev;
63 struct SK_NET_DEVICE *next;
64 SK_PNMI_STRUCT_DATA *pPnmiStruct;
65 SK_PNMI_STAT *pPnmiStat;
71 int MaxSecurityCount = 0;
77 if (MaxSecurityCount > 100) {
78 printk("Max limit for sk_proc_read security counter!\n");
81 pNet = (DEV_NET*) SkgeProcDev->priv;
84 pPnmiStruct = &pAC->PnmiStruct;
85 /* NetIndex in GetStruct is now required, zero is only dummy */
87 for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
88 if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
91 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
92 Size = SK_PNMI_STRUCT_SIZE;
93 #ifdef SK_DIAG_SUPPORT
94 if (pAC->BoardLevel == SK_INIT_DATA) {
95 SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
96 if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
97 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
100 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
103 SkPnmiGetStruct(pAC, pAC->IoBase,
104 pPnmiStruct, &Size, t-1);
106 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
108 if (strcmp(pAC->dev[t-1]->name, currDev->name) == 0) {
109 pPnmiStat = &pPnmiStruct->Stat[0];
110 len = sk_proc_print(buffer,
111 "\nDetailed statistic for device %s\n",
112 pAC->dev[t-1]->name);
113 len += sk_proc_print(buffer,
114 "=======================================\n");
116 /* Board statistics */
117 len += sk_proc_print(buffer,
118 "\nBoard statistics\n\n");
119 len += sk_proc_print(buffer,
121 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
122 Net[t-1].PrefPort]->PortNumber);
123 len += sk_proc_print(buffer,
124 "Preferred Port %c\n",
125 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
126 Net[t-1].PrefPort]->PortNumber);
128 len += sk_proc_print(buffer,
129 "Bus speed (MHz) %d\n",
130 pPnmiStruct->BusSpeed);
132 len += sk_proc_print(buffer,
133 "Bus width (Bit) %d\n",
134 pPnmiStruct->BusWidth);
135 len += sk_proc_print(buffer,
136 "Driver version %s\n",
138 len += sk_proc_print(buffer,
139 "Hardware revision v%d.%d\n",
140 (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
141 pAC->GIni.GIPciHwRev & 0x0F);
143 /* Print sensor informations */
144 for (i=0; i < pAC->I2c.MaxSens; i ++) {
146 switch (pAC->I2c.SenTable[i].SenType) {
148 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
149 strcat(sens_msg, " (C)");
150 len += sk_proc_print(buffer,
153 pAC->I2c.SenTable[i].SenValue / 10,
154 pAC->I2c.SenTable[i].SenValue % 10);
156 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
157 strcat(sens_msg, " (F)");
158 len += sk_proc_print(buffer,
161 ((((pAC->I2c.SenTable[i].SenValue)
162 *10)*9)/5 + 3200)/100,
163 ((((pAC->I2c.SenTable[i].SenValue)
164 *10)*9)/5 + 3200) % 10);
167 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
168 strcat(sens_msg, " (V)");
169 len += sk_proc_print(buffer,
172 pAC->I2c.SenTable[i].SenValue / 1000,
173 pAC->I2c.SenTable[i].SenValue % 1000);
176 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
177 strcat(sens_msg, " (rpm)");
178 len += sk_proc_print(buffer,
181 pAC->I2c.SenTable[i].SenValue);
188 /*Receive statistics */
189 len += sk_proc_print(buffer,
190 "\nReceive statistics\n\n");
192 len += sk_proc_print(buffer,
193 "Received bytes %Lu\n",
194 (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
195 len += sk_proc_print(buffer,
196 "Received packets %Lu\n",
197 (unsigned long long) pPnmiStat->StatRxOkCts);
199 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
200 pAC->HWRevision < 12) {
201 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
202 pPnmiStat->StatRxShortsCts;
203 pPnmiStat->StatRxShortsCts = 0;
206 if (pNet->Mtu > 1500)
207 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
208 pPnmiStat->StatRxTooLongCts;
210 len += sk_proc_print(buffer,
211 "Receive errors %Lu\n",
212 (unsigned long long) pPnmiStruct->InErrorsCts);
213 len += sk_proc_print(buffer,
214 "Receive dropped %Lu\n",
215 (unsigned long long) pPnmiStruct->RxNoBufCts);
216 len += sk_proc_print(buffer,
217 "Received multicast %Lu\n",
218 (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
219 len += sk_proc_print(buffer,
220 "Receive error types\n");
221 len += sk_proc_print(buffer,
223 (unsigned long long) pPnmiStat->StatRxRuntCts);
224 len += sk_proc_print(buffer,
225 " buffer overflow %Lu\n",
226 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
227 len += sk_proc_print(buffer,
229 (unsigned long long) pPnmiStat->StatRxFcsCts);
230 len += sk_proc_print(buffer,
232 (unsigned long long) pPnmiStat->StatRxFramingCts);
233 len += sk_proc_print(buffer,
234 " missed frames %Lu\n",
235 (unsigned long long) pPnmiStat->StatRxMissedCts);
237 if (pNet->Mtu > 1500)
238 pPnmiStat->StatRxTooLongCts = 0;
240 len += sk_proc_print(buffer,
242 (unsigned long long) pPnmiStat->StatRxTooLongCts);
243 len += sk_proc_print(buffer,
244 " carrier extension %Lu\n",
245 (unsigned long long) pPnmiStat->StatRxCextCts);
246 len += sk_proc_print(buffer,
248 (unsigned long long) pPnmiStat->StatRxShortsCts);
249 len += sk_proc_print(buffer,
251 (unsigned long long) pPnmiStat->StatRxSymbolCts);
252 len += sk_proc_print(buffer,
253 " LLC MAC size %Lu\n",
254 (unsigned long long) pPnmiStat->StatRxIRLengthCts);
255 len += sk_proc_print(buffer,
256 " carrier event %Lu\n",
257 (unsigned long long) pPnmiStat->StatRxCarrierCts);
258 len += sk_proc_print(buffer,
260 (unsigned long long) pPnmiStat->StatRxJabberCts);
263 /*Transmit statistics */
264 len += sk_proc_print(buffer,
265 "\nTransmit statistics\n\n");
267 len += sk_proc_print(buffer,
268 "Transmited bytes %Lu\n",
269 (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
270 len += sk_proc_print(buffer,
271 "Transmited packets %Lu\n",
272 (unsigned long long) pPnmiStat->StatTxOkCts);
273 len += sk_proc_print(buffer,
274 "Transmit errors %Lu\n",
275 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
276 len += sk_proc_print(buffer,
277 "Transmit dropped %Lu\n",
278 (unsigned long long) pPnmiStruct->TxNoBufCts);
279 len += sk_proc_print(buffer,
280 "Transmit collisions %Lu\n",
281 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
282 len += sk_proc_print(buffer,
283 "Transmit error types\n");
284 len += sk_proc_print(buffer,
285 " excessive collision %ld\n",
286 pAC->stats.tx_aborted_errors);
287 len += sk_proc_print(buffer,
289 (unsigned long long) pPnmiStat->StatTxCarrierCts);
290 len += sk_proc_print(buffer,
291 " fifo underrun %Lu\n",
292 (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
293 len += sk_proc_print(buffer,
295 (unsigned long long) pPnmiStat->StatTxCarrierCts);
296 len += sk_proc_print(buffer,
298 pAC->stats.tx_window_errors);
300 } /* if (strcmp(pACname, currDeviceName) == 0) */
306 /*****************************************************************************
308 * sk_proc_print -generic line print
311 * This function fills the proc entry with statistic data about
312 * the ethernet device.
314 * Returns: number of bytes written
317 static int sk_proc_print(void *writePtr, char *format, ...)
319 #define MAX_LEN_SINGLE_LINE 256
320 char str[MAX_LEN_SINGLE_LINE];
324 struct seq_file *seq = (struct seq_file *) writePtr;
326 SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
328 va_start(a_start, format);
329 vsprintf(str, format, a_start);
332 lenght = strlen(str);
334 seq_printf(seq, str);
338 /*****************************************************************************
340 * sk_seq_show - show proc information of a particular adapter
343 * This function fills the proc entry with statistic data about
344 * the ethernet device. It invokes the generic sk_gen_browse() to
345 * print out all items one per one.
347 * Returns: number of bytes written
350 static int sk_seq_show(struct seq_file *seq, void *v)
352 void *castedBuffer = (void *) seq;
353 currDev = seq->private;
354 sk_gen_browse(castedBuffer);
358 /*****************************************************************************
360 * sk_proc_open - register the show function when proc is open'ed
363 * This function is called whenever a sk98lin proc file is queried.
365 * Returns: the return value of single_open()
368 static int sk_proc_open(struct inode *inode, struct file *file)
370 return single_open(file, sk_seq_show, PDE(inode)->data);
373 /*******************************************************************************
377 ******************************************************************************/