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