]> git.kernelconcepts.de Git - karo-tx-uboot.git/blob - drivers/net/sk98lin/skproc.c
Merge branch 'master' of git://git.denx.de/u-boot-arm
[karo-tx-uboot.git] / drivers / net / sk98lin / skproc.c
1 /******************************************************************************
2  *
3  * Name:    skproc.c
4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
5  * Version:     $Revision: 1.4 $
6  * Date:    $Date: 2003/02/25 14:16:37 $
7  * Purpose:     Funktions to display statictic data
8  *
9  ******************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2003 SysKonnect GmbH.
14  *
15  *      This program is free software; you can redistribute it and/or modify
16  *      it under the terms of the GNU General Public License as published by
17  *      the Free Software Foundation; either version 2 of the License, or
18  *      (at your option) any later version.
19  *
20  *      Created 22-Nov-2000
21  *      Author: Mirko Lindner (mlindner@syskonnect.de)
22  *
23  *      The information in this file is provided "AS IS" without warranty.
24  *
25  ******************************************************************************/
26 /******************************************************************************
27  *
28  * History:
29  *
30  *      $Log: skproc.c,v $
31  *      Revision 1.4  2003/02/25 14:16:37  mlindner
32  *      Fix: Copyright statement
33  *
34  *      Revision 1.3  2002/10/02 12:59:51  mlindner
35  *      Add: Support for Yukon
36  *      Add: Speed check and setup
37  *      Add: Merge source for kernel 2.2.x and 2.4.x
38  *      Add: Read sensor names directly from VPD
39  *      Fix: Volt values
40  *
41  *      Revision 1.2.2.7  2002/01/14 12:45:15  mlindner
42  *      Fix: Editorial changes
43  *
44  *      Revision 1.2.2.6  2001/12/06 15:26:07  mlindner
45  *      Fix: Return value of proc_read
46  *
47  *      Revision 1.2.2.5  2001/12/06 09:57:39  mlindner
48  *      New ProcFs entries
49  *
50  *      Revision 1.2.2.4  2001/09/05 12:16:02  mlindner
51  *      Add: New ProcFs entries
52  *      Fix: Counter Errors (Jumbo == to long errors)
53  *      Fix: Kernel error compilation
54  *      Fix: too short counters
55  *
56  *      Revision 1.2.2.3  2001/06/25 07:26:26  mlindner
57  *      Add: More error messages
58  *
59  *      Revision 1.2.2.2  2001/03/15 12:50:13  mlindner
60  *      fix: ProcFS owner protection
61  *
62  *      Revision 1.2.2.1  2001/03/12 16:43:48  mlindner
63  *      chg: 2.4 requirements for procfs
64  *
65  *      Revision 1.1  2001/01/22 14:15:31  mlindner
66  *      added ProcFs functionality
67  *      Dual Net functionality integrated
68  *      Rlmt networks added
69  *
70  *
71  ******************************************************************************/
72
73 #include <config.h>
74
75 #include <linux/proc_fs.h>
76
77 #include "h/skdrv1st.h"
78 #include "h/skdrv2nd.h"
79 #define ZEROPAD         1               /* pad with zero */
80 #define SIGN            2               /* unsigned/signed long */
81 #define PLUS            4               /* show plus */
82 #define SPACE           8               /* space if plus */
83 #define LEFT            16              /* left justified */
84 #define SPECIALX        32              /* 0x */
85 #define LARGE           64
86
87 extern SK_AC *pACList;
88 extern struct net_device *SkGeRootDev;
89
90 extern char *SkNumber (char *str,
91                        long long num,
92                        int base,
93                        int size,
94                        int precision,
95                        int type);
96
97
98 /*****************************************************************************
99  *
100  *      proc_read - print "summaries" entry
101  *
102  * Description:
103  *  This function fills the proc entry with statistic data about
104  *  the ethernet device.
105  *
106  *
107  * Returns: buffer with statistic data
108  *
109  */
110 int proc_read(char *buffer,
111 char **buffer_location,
112 off_t offset,
113 int buffer_length,
114 int *eof,
115 void *data)
116 {
117         int len = 0;
118         int t;
119         int i;
120         DEV_NET                 *pNet;
121         SK_AC                   *pAC;
122         char                    test_buf[100];
123         char                    sens_msg[50];
124         unsigned long           Flags;
125         unsigned int            Size;
126         struct SK_NET_DEVICE    *next;
127         struct SK_NET_DEVICE    *SkgeProcDev = SkGeRootDev;
128
129         SK_PNMI_STRUCT_DATA     *pPnmiStruct;
130         SK_PNMI_STAT            *pPnmiStat;
131         struct proc_dir_entry *file = (struct proc_dir_entry*) data;
132
133         while (SkgeProcDev) {
134                 pNet = (DEV_NET*) SkgeProcDev->priv;
135                 pAC = pNet->pAC;
136                 next = pAC->Next;
137                 pPnmiStruct = &pAC->PnmiStruct;
138                 /* NetIndex in GetStruct is now required, zero is only dummy */
139
140                 for (t=pAC->GIni.GIMacsFound; t > 0; t--) {
141                         if ((pAC->GIni.GIMacsFound == 2) && pAC->RlmtNets == 1)
142                                 t--;
143
144                         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
145                         Size = SK_PNMI_STRUCT_SIZE;
146                         SkPnmiGetStruct(pAC, pAC->IoBase,
147                                 pPnmiStruct, &Size, t-1);
148                         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
149
150                         if (strcmp(pAC->dev[t-1]->name, file->name) == 0) {
151                                 pPnmiStat = &pPnmiStruct->Stat[0];
152                                 len = sprintf(buffer,
153                                         "\nDetailed statistic for device %s\n",
154                                         pAC->dev[t-1]->name);
155                                 len += sprintf(buffer + len,
156                                         "=======================================\n");
157
158                                 /* Board statistics */
159                                 len += sprintf(buffer + len,
160                                         "\nBoard statistics\n\n");
161                                 len += sprintf(buffer + len,
162                                         "Active Port                    %c\n",
163                                         'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
164                                         Net[t-1].PrefPort]->PortNumber);
165                                 len += sprintf(buffer + len,
166                                         "Preferred Port                 %c\n",
167                                         'A' + pAC->Rlmt.Net[t-1].Port[pAC->Rlmt.
168                                         Net[t-1].PrefPort]->PortNumber);
169
170                                 len += sprintf(buffer + len,
171                                         "Bus speed (MHz)                %d\n",
172                                         pPnmiStruct->BusSpeed);
173
174                                 len += sprintf(buffer + len,
175                                         "Bus width (Bit)                %d\n",
176                                         pPnmiStruct->BusWidth);
177                                 len += sprintf(buffer + len,
178                                         "Hardware revision              v%d.%d\n",
179                                         (pAC->GIni.GIPciHwRev >> 4) & 0x0F,
180                                         pAC->GIni.GIPciHwRev & 0x0F);
181
182                                 /* Print sensor informations */
183                                 for (i=0; i < pAC->I2c.MaxSens; i ++) {
184                                         /* Check type */
185                                         switch (pAC->I2c.SenTable[i].SenType) {
186                                         case 1:
187                                                 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
188                                                 strcat(sens_msg, " (C)");
189                                                 len += sprintf(buffer + len,
190                                                         "%-25s      %d.%02d\n",
191                                                         sens_msg,
192                                                         pAC->I2c.SenTable[i].SenValue / 10,
193                                                         pAC->I2c.SenTable[i].SenValue % 10);
194
195                                                 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
196                                                 strcat(sens_msg, " (F)");
197                                                 len += sprintf(buffer + len,
198                                                         "%-25s      %d.%02d\n",
199                                                         sens_msg,
200                                                         ((((pAC->I2c.SenTable[i].SenValue)
201                                                         *10)*9)/5 + 3200)/100,
202                                                         ((((pAC->I2c.SenTable[i].SenValue)
203                                                         *10)*9)/5 + 3200) % 10);
204                                                 break;
205                                         case 2:
206                                                 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
207                                                 strcat(sens_msg, " (V)");
208                                                 len += sprintf(buffer + len,
209                                                         "%-25s      %d.%03d\n",
210                                                         sens_msg,
211                                                         pAC->I2c.SenTable[i].SenValue / 1000,
212                                                         pAC->I2c.SenTable[i].SenValue % 1000);
213                                                 break;
214                                         case 3:
215                                                 strcpy(sens_msg, pAC->I2c.SenTable[i].SenDesc);
216                                                 strcat(sens_msg, " (rpm)");
217                                                 len += sprintf(buffer + len,
218                                                         "%-25s      %d\n",
219                                                         sens_msg,
220                                                         pAC->I2c.SenTable[i].SenValue);
221                                                 break;
222                                         default:
223                                                 break;
224                                         }
225                                 }
226
227                                 /*Receive statistics */
228                                 len += sprintf(buffer + len,
229                                 "\nReceive statistics\n\n");
230
231                                 len += sprintf(buffer + len,
232                                         "Received bytes                 %s\n",
233                                         SkNumber(test_buf, pPnmiStat->StatRxOctetsOkCts,
234                                         10,0,-1,0));
235                                 len += sprintf(buffer + len,
236                                         "Received packets               %s\n",
237                                         SkNumber(test_buf, pPnmiStat->StatRxOkCts,
238                                         10,0,-1,0));
239 #if 0
240                                 if (pAC->GIni.GP[0].PhyType == SK_PHY_XMAC &&
241                                         pAC->HWRevision < 12) {
242                                         pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
243                                                 pPnmiStat->StatRxShortsCts;
244                                         pPnmiStat->StatRxShortsCts = 0;
245                                 }
246 #endif
247                                 if (pNet->Mtu > 1500)
248                                         pPnmiStruct->InErrorsCts = pPnmiStruct->InErrorsCts -
249                                                 pPnmiStat->StatRxTooLongCts;
250
251                                 len += sprintf(buffer + len,
252                                         "Receive errors                 %s\n",
253                                         SkNumber(test_buf, pPnmiStruct->InErrorsCts,
254                                         10,0,-1,0));
255                                 len += sprintf(buffer + len,
256                                         "Receive drops                  %s\n",
257                                         SkNumber(test_buf, pPnmiStruct->RxNoBufCts,
258                                         10,0,-1,0));
259                                 len += sprintf(buffer + len,
260                                         "Received multicast             %s\n",
261                                         SkNumber(test_buf, pPnmiStat->StatRxMulticastOkCts,
262                                         10,0,-1,0));
263                                 len += sprintf(buffer + len,
264                                         "Receive error types\n");
265                                 len += sprintf(buffer + len,
266                                         "   length                      %s\n",
267                                         SkNumber(test_buf, pPnmiStat->StatRxRuntCts,
268                                         10, 0, -1, 0));
269                                 len += sprintf(buffer + len,
270                                         "   buffer overflow             %s\n",
271                                         SkNumber(test_buf, pPnmiStat->StatRxFifoOverflowCts,
272                                         10, 0, -1, 0));
273                                 len += sprintf(buffer + len,
274                                         "   bad crc                     %s\n",
275                                         SkNumber(test_buf, pPnmiStat->StatRxFcsCts,
276                                         10, 0, -1, 0));
277                                 len += sprintf(buffer + len,
278                                         "   framing                     %s\n",
279                                         SkNumber(test_buf, pPnmiStat->StatRxFramingCts,
280                                         10, 0, -1, 0));
281                                 len += sprintf(buffer + len,
282                                         "   missed frames               %s\n",
283                                         SkNumber(test_buf, pPnmiStat->StatRxMissedCts,
284                                         10, 0, -1, 0));
285
286                                 if (pNet->Mtu > 1500)
287                                         pPnmiStat->StatRxTooLongCts = 0;
288
289                                 len += sprintf(buffer + len,
290                                         "   too long                    %s\n",
291                                         SkNumber(test_buf, pPnmiStat->StatRxTooLongCts,
292                                         10, 0, -1, 0));
293                                 len += sprintf(buffer + len,
294                                         "   carrier extension           %s\n",
295                                         SkNumber(test_buf, pPnmiStat->StatRxCextCts,
296                                         10, 0, -1, 0));
297                                 len += sprintf(buffer + len,
298                                         "   too short                   %s\n",
299                                         SkNumber(test_buf, pPnmiStat->StatRxShortsCts,
300                                         10, 0, -1, 0));
301                                 len += sprintf(buffer + len,
302                                         "   symbol                      %s\n",
303                                         SkNumber(test_buf, pPnmiStat->StatRxSymbolCts,
304                                         10, 0, -1, 0));
305                                 len += sprintf(buffer + len,
306                                         "   LLC MAC size                %s\n",
307                                         SkNumber(test_buf, pPnmiStat->StatRxIRLengthCts,
308                                         10, 0, -1, 0));
309                                 len += sprintf(buffer + len,
310                                         "   carrier event               %s\n",
311                                         SkNumber(test_buf, pPnmiStat->StatRxCarrierCts,
312                                         10, 0, -1, 0));
313                                 len += sprintf(buffer + len,
314                                         "   jabber                      %s\n",
315                                         SkNumber(test_buf, pPnmiStat->StatRxJabberCts,
316                                         10, 0, -1, 0));
317
318
319                                 /*Transmit statistics */
320                                 len += sprintf(buffer + len,
321                                 "\nTransmit statistics\n\n");
322
323                                 len += sprintf(buffer + len,
324                                         "Transmited bytes               %s\n",
325                                         SkNumber(test_buf, pPnmiStat->StatTxOctetsOkCts,
326                                         10,0,-1,0));
327                                 len += sprintf(buffer + len,
328                                         "Transmited packets             %s\n",
329                                         SkNumber(test_buf, pPnmiStat->StatTxOkCts,
330                                         10,0,-1,0));
331                                 len += sprintf(buffer + len,
332                                         "Transmit errors                %s\n",
333                                         SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
334                                         10,0,-1,0));
335                                 len += sprintf(buffer + len,
336                                         "Transmit dropped               %s\n",
337                                         SkNumber(test_buf, pPnmiStruct->TxNoBufCts,
338                                         10,0,-1,0));
339                                 len += sprintf(buffer + len,
340                                         "Transmit collisions            %s\n",
341                                         SkNumber(test_buf, pPnmiStat->StatTxSingleCollisionCts,
342                                         10,0,-1,0));
343                                 len += sprintf(buffer + len,
344                                         "Transmit errors types\n");
345                                 len += sprintf(buffer + len,
346                                         "   excessive collision         %ld\n",
347                                         pAC->stats.tx_aborted_errors);
348                                 len += sprintf(buffer + len,
349                                         "   carrier                     %s\n",
350                                         SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
351                                         10, 0, -1, 0));
352                                 len += sprintf(buffer + len,
353                                         "   fifo underrun               %s\n",
354                                         SkNumber(test_buf, pPnmiStat->StatTxFifoUnderrunCts,
355                                         10, 0, -1, 0));
356                                 len += sprintf(buffer + len,
357                                         "   heartbeat                   %s\n",
358                                         SkNumber(test_buf, pPnmiStat->StatTxCarrierCts,
359                                         10, 0, -1, 0));
360                                 len += sprintf(buffer + len,
361                                         "   window                      %ld\n",
362                                         pAC->stats.tx_window_errors);
363
364                         }
365                 }
366                 SkgeProcDev = next;
367         }
368         if (offset >= len) {
369                 *eof = 1;
370                 return 0;
371         }
372
373         *buffer_location = buffer + offset;
374         if (buffer_length >= len - offset) {
375                 *eof = 1;
376         }
377         return (min_t(int, buffer_length, len - offset));
378 }
379
380
381 /*****************************************************************************
382  *
383  * SkDoDiv - convert 64bit number
384  *
385  * Description:
386  *      This function "converts" a long long number.
387  *
388  * Returns:
389  *      remainder of division
390  */
391 static long SkDoDiv (long long Dividend, int Divisor, long long *pErg)
392 {
393         long Rest;
394         long long Ergebnis;
395         long Akku;
396
397
398         Akku = Dividend >> 32;
399
400         Ergebnis = ((long long) (Akku / Divisor)) << 32;
401         Rest = Akku % Divisor;
402
403         Akku = Rest << 16;
404         Akku |= ((Dividend & 0xFFFF0000) >> 16);
405
406
407         Ergebnis += ((long long) (Akku / Divisor)) << 16;
408         Rest = Akku % Divisor;
409
410         Akku = Rest << 16;
411         Akku |= (Dividend & 0xFFFF);
412
413         Ergebnis += (Akku / Divisor);
414         Rest = Akku % Divisor;
415
416         *pErg = Ergebnis;
417         return (Rest);
418 }
419
420
421 #if 0
422 #define do_div(n,base) ({ \
423 long long __res; \
424 __res = ((unsigned long long) n) % (unsigned) base; \
425 n = ((unsigned long long) n) / (unsigned) base; \
426 __res; })
427
428 #endif
429
430
431 /*****************************************************************************
432  *
433  * SkNumber - Print results
434  *
435  * Description:
436  *      This function converts a long long number into a string.
437  *
438  * Returns:
439  *      number as string
440  */
441 char * SkNumber(char * str, long long num, int base, int size, int precision
442         ,int type)
443 {
444         char c,sign,tmp[66], *strorg = str;
445         const char *digits="0123456789abcdefghijklmnopqrstuvwxyz";
446         int i;
447
448         if (type & LARGE)
449                 digits = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
450         if (type & LEFT)
451                 type &= ~ZEROPAD;
452         if (base < 2 || base > 36)
453                 return 0;
454         c = (type & ZEROPAD) ? '0' : ' ';
455         sign = 0;
456         if (type & SIGN) {
457                 if (num < 0) {
458                         sign = '-';
459                         num = -num;
460                         size--;
461                 } else if (type & PLUS) {
462                         sign = '+';
463                         size--;
464                 } else if (type & SPACE) {
465                         sign = ' ';
466                         size--;
467                 }
468         }
469         if (type & SPECIALX) {
470                 if (base == 16)
471                         size -= 2;
472                 else if (base == 8)
473                         size--;
474         }
475         i = 0;
476         if (num == 0)
477                 tmp[i++]='0';
478         else while (num != 0)
479                 tmp[i++] = digits[SkDoDiv(num,base, &num)];
480
481         if (i > precision)
482                 precision = i;
483         size -= precision;
484         if (!(type&(ZEROPAD+LEFT)))
485                 while(size-->0)
486                         *str++ = ' ';
487         if (sign)
488                 *str++ = sign;
489         if (type & SPECIALX) {
490                 if (base==8)
491                         *str++ = '0';
492                 else if (base==16) {
493                         *str++ = '0';
494                         *str++ = digits[33];
495                 }
496         }
497         if (!(type & LEFT))
498                 while (size-- > 0)
499                         *str++ = c;
500         while (i < precision--)
501                 *str++ = '0';
502         while (i-- > 0)
503                 *str++ = tmp[i];
504         while (size-- > 0)
505                 *str++ = ' ';
506
507         str[0] = '\0';
508
509         return strorg;
510 }