1 /******************************************************************************
2 *
3 * Name: skproc.c
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Purpose: Funktions to display statictic data
6 *
7 ******************************************************************************/
8
9 /******************************************************************************
10 *
11 * (C)Copyright 1998-2002 SysKonnect GmbH.
12 * (C)Copyright 2002-2003 Marvell.
13 *
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.
18 *
19 * Created 22-Nov-2000
20 * Author: Mirko Lindner (mlindner@syskonnect.de)
21 *
22 * The information in this file is provided "AS IS" without warranty.
23 *
24 ******************************************************************************/
25
26 #include <linux/proc_fs.h>
27
28 #include "h/skdrv1st.h"
29 #include "h/skdrv2nd.h"
30 #include "h/skversion.h"
31
32 extern struct SK_NET_DEVICE *SkGeRootDev;
33 static int sk_proc_print(void *writePtr, char *format, ...);
34 static void sk_gen_browse(void *buffer);
35 int len;
36
37 struct proc_dir_entry *file = NULL;
38
39 /*****************************************************************************
40 *
41 * sk_proc_read - show proc information of a particular adapter
42 *
43 * Description:
44 * This function fills the proc entry with statistic data about
45 * the ethernet device. It invokes the generic sk_gen_browse() to
46 * print out all items one per one.
47 *
48 * Returns: number of bytes written
49 *
50 */
sk_proc_read(char * buffer,char ** buffer_location,off_t offset,int buffer_length,int * eof,void * data)51 int sk_proc_read(char *buffer,
52 char **buffer_location,
53 off_t offset,
54 int buffer_length,
55 int *eof,
56 void *data)
57 {
58 void *castedBuffer = (void *) buffer;
59 file = (struct proc_dir_entry*) data;
60 len = 0; /* initial value */
61 sk_gen_browse(castedBuffer);
62
63 if (offset >= len) {
64 *eof = 1;
65 return 0;
66 }
67
68 *buffer_location = buffer + offset;
69 if (buffer_length >= len - offset) {
70 *eof = 1;
71 }
72 return (min_t(int, buffer_length, len - offset));
73 }
74
75 /*****************************************************************************
76 *
77 * sk_gen_browse -generic print "summaries" entry
78 *
79 * Description:
80 * This function fills the proc entry with statistic data about
81 * the ethernet device.
82 *
83 * Returns: -
84 *
85 */
sk_gen_browse(void * buffer)86 static void sk_gen_browse(void *buffer)
87 {
88 struct SK_NET_DEVICE *SkgeProcDev = SkGeRootDev;
89 struct SK_NET_DEVICE *next;
90 SK_PNMI_STRUCT_DATA *pPnmiStruct;
91 SK_PNMI_STAT *pPnmiStat;
92 unsigned long Flags;
93 unsigned int Size;
94 DEV_NET *pNet;
95 SK_AC *pAC;
96 char sens_msg[50];
97 int MaxSecurityCount = 0;
98 int t;
99 int i;
100
101 while (SkgeProcDev) {
102 MaxSecurityCount++;
103 if (MaxSecurityCount > 100) {
104 printk("Max limit for sk_proc_read security counter!\n");
105 return;
106 }
107 pNet = (DEV_NET*) SkgeProcDev->priv;
108 pAC = pNet->pAC;
109 next = pAC->Next;
110 pPnmiStruct = &pAC->PnmiStruct;
111 /* NetIndex in GetStruct is now required, zero is only dummy */
112
113 for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
114 if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
115 t--;
116
117 spin_lock_irqsave(&pAC->SlowPathLock, Flags);
118 Size = SK_PNMI_STRUCT_SIZE;
119 #ifdef SK_DIAG_SUPPORT
120 if (pAC->BoardLevel == SK_INIT_DATA) {
121 SK_MEMCPY(&(pAC->PnmiStruct), &(pAC->PnmiBackup), sizeof(SK_PNMI_STRUCT_DATA));
122 if (pAC->DiagModeActive == DIAG_NOTACTIVE) {
123 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
124 }
125 } else {
126 SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t-1);
127 }
128 #else
129 SkPnmiGetStruct(pAC, pAC->IoBase,
130 pPnmiStruct, &Size, t-1);
131 #endif
132 spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
133
134 if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
135 pPnmiStat = &pPnmiStruct->Stat[0];
136 len = sk_proc_print(buffer,
137 "\nDetailed statistic for device %s\n",
138 pAC->dev[t-1]->name);
139 len += sk_proc_print(buffer,
140 "=======================================\n");
141
142 /* Board statistics */
143 len += sk_proc_print(buffer,
144 "\nBoard statistics\n\n");
145 len += sk_proc_print(buffer,
146 "Active Port %c\n",
147 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
148 Net[t-1].PrefPort]->PortNumber);
149 len += sk_proc_print(buffer,
150 "Preferred Port %c\n",
151 'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
152 Net[t-1].PrefPort]->PortNumber);
153
154 len += sk_proc_print(buffer,
155 "Bus speed (MHz) %d\n",
156 pPnmiStruct->BusSpeed);
157
158 len += sk_proc_print(buffer,
159 "Bus width (Bit) %d\n",
160 pPnmiStruct->BusWidth);
161 len += sk_proc_print(buffer,
162 "Driver version %s\n",
163 VER_STRING);
164 len += sk_proc_print(buffer,
165 "Hardware revision v%d.%d\n",
166 (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
167 pAC->GIni.GIPciHwRev & 0x0F);
168
169 /* Print sensor informations */
170 for (i=0; i < pAC->I2c.MaxSens; i ++) {
171 /* Check type */
172 switch (pAC->I2c.SenTable[i].SenType) {
173 case 1:
174 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
175 strcat(sens_msg, " (C)");
176 len += sk_proc_print(buffer,
177 "%-25s %d.%02d\n",
178 sens_msg,
179 pAC->I2c.SenTable[i].SenValue / 10,
180 pAC->I2c.SenTable[i].SenValue % 10);
181
182 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
183 strcat(sens_msg, " (F)");
184 len += sk_proc_print(buffer,
185 "%-25s %d.%02d\n",
186 sens_msg,
187 ((((pAC->I2c.SenTable[i].SenValue)
188 *10)*9)/5 + 3200)/100,
189 ((((pAC->I2c.SenTable[i].SenValue)
190 *10)*9)/5 + 3200) % 10);
191 break;
192 case 2:
193 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
194 strcat(sens_msg, " (V)");
195 len += sk_proc_print(buffer,
196 "%-25s %d.%03d\n",
197 sens_msg,
198 pAC->I2c.SenTable[i].SenValue / 1000,
199 pAC->I2c.SenTable[i].SenValue % 1000);
200 break;
201 case 3:
202 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
203 strcat(sens_msg, " (rpm)");
204 len += sk_proc_print(buffer,
205 "%-25s %d\n",
206 sens_msg,
207 pAC->I2c.SenTable[i].SenValue);
208 break;
209 default:
210 break;
211 }
212 }
213
214 /*Receive statistics */
215 len += sk_proc_print(buffer,
216 "\nReceive statistics\n\n");
217
218 len += sk_proc_print(buffer,
219 "Received bytes %Lu\n",
220 (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
221 len += sk_proc_print(buffer,
222 "Received packets %Lu\n",
223 (unsigned long long) pPnmiStat->StatRxOkCts);
224 #if 0
225 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
226 pAC->HWRevision < 12) {
227 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
228 pPnmiStat->StatRxShortsCts;
229 pPnmiStat->StatRxShortsCts = 0;
230 }
231 #endif
232 if (pNet->Mtu > 1500)
233 pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
234 pPnmiStat->StatRxTooLongCts;
235
236 len += sk_proc_print(buffer,
237 "Receive errors %Lu\n",
238 (unsigned long long) pPnmiStruct->InErrorsCts);
239 len += sk_proc_print(buffer,
240 "Receive dropped %Lu\n",
241 (unsigned long long) pPnmiStruct->RxNoBufCts);
242 len += sk_proc_print(buffer,
243 "Received multicast %Lu\n",
244 (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
245 len += sk_proc_print(buffer,
246 "Receive error types\n");
247 len += sk_proc_print(buffer,
248 " length %Lu\n",
249 (unsigned long long) pPnmiStat->StatRxRuntCts);
250 len += sk_proc_print(buffer,
251 " buffer overflow %Lu\n",
252 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
253 len += sk_proc_print(buffer,
254 " bad crc %Lu\n",
255 (unsigned long long) pPnmiStat->StatRxFcsCts);
256 len += sk_proc_print(buffer,
257 " framing %Lu\n",
258 (unsigned long long) pPnmiStat->StatRxFramingCts);
259 len += sk_proc_print(buffer,
260 " missed frames %Lu\n",
261 (unsigned long long) pPnmiStat->StatRxMissedCts);
262
263 if (pNet->Mtu > 1500)
264 pPnmiStat->StatRxTooLongCts = 0;
265
266 len += sk_proc_print(buffer,
267 " too long %Lu\n",
268 (unsigned long long) pPnmiStat->StatRxTooLongCts);
269 len += sk_proc_print(buffer,
270 " carrier extension %Lu\n",
271 (unsigned long long) pPnmiStat->StatRxCextCts);
272 len += sk_proc_print(buffer,
273 " too short %Lu\n",
274 (unsigned long long) pPnmiStat->StatRxShortsCts);
275 len += sk_proc_print(buffer,
276 " symbol %Lu\n",
277 (unsigned long long) pPnmiStat->StatRxSymbolCts);
278 len += sk_proc_print(buffer,
279 " LLC MAC size %Lu\n",
280 (unsigned long long) pPnmiStat->StatRxIRLengthCts);
281 len += sk_proc_print(buffer,
282 " carrier event %Lu\n",
283 (unsigned long long) pPnmiStat->StatRxCarrierCts);
284 len += sk_proc_print(buffer,
285 " jabber %Lu\n",
286 (unsigned long long) pPnmiStat->StatRxJabberCts);
287
288
289 /*Transmit statistics */
290 len += sk_proc_print(buffer,
291 "\nTransmit statistics\n\n");
292
293 len += sk_proc_print(buffer,
294 "Transmited bytes %Lu\n",
295 (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
296 len += sk_proc_print(buffer,
297 "Transmited packets %Lu\n",
298 (unsigned long long) pPnmiStat->StatTxOkCts);
299 len += sk_proc_print(buffer,
300 "Transmit errors %Lu\n",
301 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
302 len += sk_proc_print(buffer,
303 "Transmit dropped %Lu\n",
304 (unsigned long long) pPnmiStruct->TxNoBufCts);
305 len += sk_proc_print(buffer,
306 "Transmit collisions %Lu\n",
307 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
308 len += sk_proc_print(buffer,
309 "Transmit error types\n");
310 len += sk_proc_print(buffer,
311 " excessive collision %ld\n",
312 pAC->stats.tx_aborted_errors);
313 len += sk_proc_print(buffer,
314 " carrier %Lu\n",
315 (unsigned long long) pPnmiStat->StatTxCarrierCts);
316 len += sk_proc_print(buffer,
317 " fifo underrun %Lu\n",
318 (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
319 len += sk_proc_print(buffer,
320 " heartbeat %Lu\n",
321 (unsigned long long) pPnmiStat->StatTxCarrierCts);
322 len += sk_proc_print(buffer,
323 " window %ld\n",
324 pAC->stats.tx_window_errors);
325
326 } /* if (strcmp(pACname, currDeviceName) == 0) */
327 }
328 SkgeProcDev = next;
329 }
330 }
331
332 /*****************************************************************************
333 *
334 * sk_proc_print -generic line print
335 *
336 * Description:
337 * This function fills the proc entry with statistic data about
338 * the ethernet device.
339 *
340 * Returns: number of bytes written
341 *
342 */
sk_proc_print(void * writePtr,char * format,...)343 static int sk_proc_print(void *writePtr, char *format, ...)
344 {
345 #define MAX_LEN_SINGLE_LINE 256
346 char str[MAX_LEN_SINGLE_LINE];
347 va_list a_start;
348 int lenght = 0;
349
350 char *buffer = (char *) writePtr;
351 buffer = buffer + len; /* plus global variable len for current location */
352
353 SK_MEMSET(str, 0, MAX_LEN_SINGLE_LINE);
354
355 va_start(a_start, format);
356 vsprintf(str, format, a_start);
357 va_end(a_start);
358
359 lenght = strlen(str);
360
361 sprintf(buffer, str);
362 return lenght;
363 }
364
365
366 /*******************************************************************************
367 *
368 * End of file
369 *
370 ******************************************************************************/
371