26cbc43cff10ad7fe2b3c35756a2058199c58c1f
[linux-flexiantxendom0-3.2.10.git] / drivers / net / sk98lin / skproc.c
1 /******************************************************************************
2  *
3  * Name:    skproc.c
4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
5  * Version:     $Revision: 1.2.2.2 $
6  * Date:    $Date: 2001/03/15 12:50:13 $
7  * Purpose:     Funktions to display statictic data
8  *
9  ******************************************************************************/
10  
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2001 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.2.2.2  2001/03/15 12:50:13  mlindner
32  *      fix: ProcFS owner protection
33  *      
34  *      Revision 1.2.2.1  2001/03/12 16:43:48  mlindner
35  *      chg: 2.4 requirements for procfs
36  *      
37  *      Revision 1.1  2001/01/22 14:15:31  mlindner
38  *      added ProcFs functionality
39  *      Dual Net functionality integrated
40  *      Rlmt networks added
41  *      
42  *
43  ******************************************************************************/
44
45 #include <linux/proc_fs.h>
46
47 #include "h/skdrv1st.h"
48 #include "h/skdrv2nd.h"
49
50 extern spinlock_t sk_devs_lock;
51
52 static int sk_show_dev(struct net_device *dev, char *buf)
53 {
54         DEV_NET *pNet = (DEV_NET*) dev->priv;
55         SK_AC *pAC = pNet->pAC;
56         int t = pNet->PortNr;
57         SK_RLMT_NET *rlmt = &pAC->Rlmt.Net[t];
58         unsigned long Flags;            
59         unsigned Size;
60         int len = 0;
61         int i;
62
63         SK_PNMI_STRUCT_DATA     *pPnmiStruct = &pAC->PnmiStruct;
64         SK_PNMI_STAT            *pPnmiStat;
65
66         spin_lock_irqsave(&pAC->SlowPathLock, Flags);
67         Size = SK_PNMI_STRUCT_SIZE;
68         SkPnmiGetStruct(pAC, pAC->IoBase, pPnmiStruct, &Size, t);
69         spin_unlock_irqrestore(&pAC->SlowPathLock, Flags);
70
71         pPnmiStat = &pPnmiStruct->Stat[0];
72
73         len = sprintf(buf, "\nDetailed statistic for device %s\n", dev->name);
74         len += sprintf(buf + len, "==================================\n");
75
76         /* Board statistics */
77         len += sprintf(buf + len, "\nBoard statistics\n\n");
78         len += sprintf(buf + len, "Active Port               %c\n",
79                 'A' + rlmt->Port[rlmt->ActivePort]->PortNumber);
80         len += sprintf(buf + len, "Preferred Port            %c\n",
81                 'A' + rlmt->Port[rlmt->PrefPort]->PortNumber);
82
83         len += sprintf(buf + len, "Bus speed (Mhz)           %d\n",
84                 pPnmiStruct->BusSpeed);
85
86         len += sprintf(buf + len, "Bus width (Bit)           %d\n",
87                 pPnmiStruct->BusWidth);
88
89         for (i=0; i < SK_MAX_SENSORS; i ++) {
90                 SK_SENSOR *sens = &pAC->I2c.SenTable[i];
91                 SK_I32 val = sens->SenValue;
92                 if (strcmp(sens->SenDesc, "Temperature") == 0 ) {
93                         len += sprintf(buf + len,
94                                 "Temperature (C)           %d.%d\n",
95                                 val / 10, val % 10);
96                         val = val * 18 + 3200;
97                         len += sprintf(buf + len,
98                                 "Temperature (F)           %d.%d\n",
99                                 val/100, val % 10);
100                 } else if (strcmp(sens->SenDesc, "Speed Fan") == 0 ) {
101                         len += sprintf(buf + len,
102                                 "Speed Fan                 %d\n",
103                                 val);
104                 } else {
105                         len += sprintf(buf + len,
106                                 "%-20s      %d.%d\n",
107                                 sens->SenDesc, val / 1000, val % 1000);
108                 }
109         }
110         
111         /*Receive statistics */
112         
113         len += sprintf(buf + len, "\nReceive statistics\n\n");
114
115         len += sprintf(buf + len, "Received bytes            %Ld\n",
116                 (unsigned long long) pPnmiStat->StatRxOctetsOkCts);
117         len += sprintf(buf + len, "Received packets          %Ld\n",
118                 (unsigned long long) pPnmiStat->StatRxOkCts);
119         len += sprintf(buf + len, "Received errors           %Ld\n",
120                 (unsigned long long) pPnmiStat->StatRxFcsCts);
121         len += sprintf(buf + len, "Received dropped          %Ld\n",
122                 (unsigned long long) pPnmiStruct->RxNoBufCts);
123         len += sprintf(buf + len, "Received multicast        %Ld\n",
124                 (unsigned long long) pPnmiStat->StatRxMulticastOkCts);
125         len += sprintf(buf + len, "Received errors types\n");
126         len += sprintf(buf + len, "   length errors          %Ld\n",
127                 (unsigned long long) pPnmiStat->StatRxRuntCts);
128         len += sprintf(buf + len, "   over errors            %Ld\n",
129                 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
130         len += sprintf(buf + len, "   crc errors             %Ld\n",
131                 (unsigned long long) pPnmiStat->StatRxFcsCts);
132         len += sprintf(buf + len, "   frame errors           %Ld\n",
133                 (unsigned long long) pPnmiStat->StatRxFramingCts);
134         len += sprintf(buf + len, "   fifo errors            %Ld\n",
135                 (unsigned long long) pPnmiStat->StatRxFifoOverflowCts);
136         len += sprintf(buf + len, "   missed errors          %Ld\n",
137                 (unsigned long long) pPnmiStat->StatRxMissedCts);
138         
139         /*Transmit statistics */
140         len += sprintf(buf + len, "\nTransmit statistics\n\n");
141         
142         len += sprintf(buf + len, "Transmit bytes            %Ld\n",
143                 (unsigned long long) pPnmiStat->StatTxOctetsOkCts);
144         len += sprintf(buf + len, "Transmit packets          %Ld\n",
145                 (unsigned long long) pPnmiStat->StatTxOkCts);
146         len += sprintf(buf + len, "Transmit errors           %Ld\n",
147                 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
148         len += sprintf(buf + len, "Transmit dropped          %Ld\n",
149                 (unsigned long long) pPnmiStruct->TxNoBufCts);
150         len += sprintf(buf + len, "Transmit collisions       %Ld\n",
151                 (unsigned long long) pPnmiStat->StatTxSingleCollisionCts);
152         len += sprintf(buf + len, "Transmited errors types\n");
153         len += sprintf(buf + len, "   aborted errors         %ld\n",
154                 pAC->stats.tx_aborted_errors);
155         len += sprintf(buf + len, "   carrier errors         %Ld\n",
156                 (unsigned long long) pPnmiStat->StatTxCarrierCts);
157         len += sprintf(buf + len, "   fifo errors            %Ld\n",
158                 (unsigned long long) pPnmiStat->StatTxFifoUnderrunCts);
159         len += sprintf(buf + len, "   heartbeat errors       %Ld\n",
160                 (unsigned long long) pPnmiStat->StatTxCarrierCts);
161         len += sprintf(buf + len, "   window errors          %ld\n",
162                 pAC->stats.tx_window_errors);
163         return len;
164 }
165
166 static ssize_t sk_read(struct file *file, char *buf, size_t nbytes, loff_t *ppos)
167 {
168         struct inode * inode = file->f_dentry->d_inode;
169         struct proc_dir_entry *entry = PDE(inode);
170         char *page = (char *)__get_free_page(GFP_KERNEL);
171         struct net_device *dev;
172         loff_t pos = *ppos;
173         ssize_t res = 0;
174         int len = 0;
175
176         if (!page)
177                 return -ENOMEM;
178
179         spin_lock(&sk_devs_lock);
180         dev = entry->data;
181         if (dev)
182                 len = sk_show_dev(dev, page);
183         spin_unlock(&sk_devs_lock);
184
185         if (pos >= 0 && pos < len) {
186                 res = nbytes;
187                 if (res > len - pos)
188                         res = len - pos;
189                 if (copy_to_user(page + pos, buf, nbytes))
190                         res = -EFAULT;
191                 else
192                         *ppos = pos + res;
193         }
194         free_page((unsigned long) page);
195         return nbytes;
196 }
197
198 static loff_t sk_lseek(struct file *file, loff_t offset, int orig)
199 {
200         switch (orig) {
201             case 1:
202                 offset += file->f_pos;
203             case 0:
204                 if (offset >= 0)
205                         return file->f_pos = offset;
206         }
207         return -EINVAL;
208 }
209
210 struct file_operations sk_proc_fops = {
211         .read = sk_read,
212         .llseek = sk_lseek,
213 };