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