ftp://ftp.kernel.org/pub/linux/kernel/v2.6/linux-2.6.6.tar.bz2
[linux-2.6.git] / drivers / net / skfp / lnkstat.c
1 /******************************************************************************
2  *
3  *      (C)Copyright 1998,1999 SysKonnect,
4  *      a business unit of Schneider & Koch & Co. Datensysteme GmbH.
5  *
6  *      See the file "skfddi.c" for further information.
7  *
8  *      This program is free software; you can redistribute it and/or modify
9  *      it under the terms of the GNU General Public License as published by
10  *      the Free Software Foundation; either version 2 of the License, or
11  *      (at your option) any later version.
12  *
13  *      The information in this file is provided "AS IS" without warranty.
14  *
15  ******************************************************************************/
16
17 /*
18         IBM FDDI read error log function
19 */
20
21 #include "h/types.h"
22 #include "h/fddi.h"
23 #include "h/smc.h"
24 #include "h/lnkstat.h"
25
26 #ifndef lint
27 static const char ID_sccs[] = "@(#)lnkstat.c    1.8 97/04/11 (C) SK " ;
28 #endif
29
30 #ifdef  sun
31 #define _far
32 #endif
33
34 #define EL_IS_OK(x,l)   ((((int)&(((struct s_error_log *)0)->x)) + \
35                         sizeof(er->x)) <= l)
36
37 /*
38         BEGIN_MANUAL_ENTRY(if,func;others;11)
39
40         u_long smt_get_error_word(smc)
41         struct s_smc *smc ;
42
43 Function        DOWNCALL        (SMT, lnkstat.c)
44                 This functions returns the SMT error work for AIX events.
45
46 Return  smt_error_word  These bits are supported:
47
48                 SMT_ERL_ALC     ==      [PS/PA].fddiPORTLerFlag
49                 SMT_ERL_BLC     ==      [PB].fddiPORTLerFlag
50                 SMT_ERL_NCC     ==      fddiMACNotCopiedFlag
51                 SMT_ERL_FEC     ==      fddiMACFrameErrorFlag
52
53         END_MANUAL_ENTRY()
54  */
55 u_long smt_get_error_word(smc)
56 struct s_smc *smc ;
57 {
58         u_long  st;
59
60         /*
61          * smt error word low
62          */
63         st = 0 ;
64         if (smc->s.sas == SMT_SAS) {
65                 if (smc->mib.p[PS].fddiPORTLerFlag)
66                         st |= SMT_ERL_ALC ;
67         }
68         else {
69                 if (smc->mib.p[PA].fddiPORTLerFlag)
70                         st |= SMT_ERL_ALC ;
71                 if (smc->mib.p[PB].fddiPORTLerFlag)
72                         st |= SMT_ERL_BLC ;
73         }
74         if (smc->mib.m[MAC0].fddiMACNotCopiedFlag)
75                 st |= SMT_ERL_NCC ;             /* not copied condition */
76         if (smc->mib.m[MAC0].fddiMACFrameErrorFlag)
77                 st |= SMT_ERL_FEC ;             /* frame error condition */
78
79         return st;
80 }
81
82 /*
83         BEGIN_MANUAL_ENTRY(if,func;others;11)
84
85         u_long smt_get_event_word(smc)
86         struct s_smc *smc ;
87
88 Function        DOWNCALL        (SMT, lnkstat.c)
89                 This functions returns the SMT event work for AIX events.
90
91 Return  smt_event_word  always 0
92
93         END_MANUAL_ENTRY()
94  */
95 u_long smt_get_event_word(smc)
96 struct s_smc *smc ;
97 {
98         return (u_long) 0;
99 }
100
101 /*
102         BEGIN_MANUAL_ENTRY(if,func;others;11)
103
104         u_long smt_get_port_event_word(smc)
105         struct s_smc *smc ;
106
107 Function        DOWNCALL        (SMT, lnkstat.c)
108                 This functions returns the SMT port event work for AIX events.
109
110 Return  smt_port_event_word     always 0
111
112         END_MANUAL_ENTRY()
113  */
114 u_long smt_get_port_event_word(smc)
115 struct s_smc *smc ;
116 {
117         return (u_long) 0;
118 }
119
120 /*
121         BEGIN_MANUAL_ENTRY(if,func;others;11)
122
123         u_long smt_read_errorlog(smc,p,len)
124         struct s_smc *smc ;
125         char _far *p ;
126         int len ;
127
128 Function        DOWNCALL        (SMT, lnkstat.c)
129                 This functions returns the SMT error log field for AIX events.
130
131 Para    p       pointer to the error log field
132         len     len of the error log field
133
134 Return  len     used len of the error log field
135
136         END_MANUAL_ENTRY()
137  */
138 int smt_read_errorlog(smc,p,len)
139 struct s_smc *smc ;
140 char _far *p ;
141 int len ;
142 {
143         int                     i ;
144         int                     st ;
145         struct s_error_log _far *er ;
146
147         er = (struct s_error_log _far *) p ;
148         if (len > sizeof(struct s_error_log))
149                 len = sizeof(struct s_error_log) ;
150         for (i = 0 ; i < len ; i++)
151                 *p++ = 0 ;
152         /*
153          * set count
154          */
155         if (EL_IS_OK(set_count_high,len)) {
156                 er->set_count_low = (u_short)smc->mib.fddiSMTSetCount.count ;
157                 er->set_count_high =
158                         (u_short)(smc->mib.fddiSMTSetCount.count >> 16L) ;
159         }
160         /*
161          * aci
162          */
163         if (EL_IS_OK(aci_id_code,len)) {
164                 er->aci_id_code = 0 ;
165         }
166         /*
167          * purge counter is missed frames; 16 bits only
168          */
169         if (EL_IS_OK(purge_frame_counter,len)) {
170                 if (smc->mib.m[MAC0].fddiMACCopied_Ct > 0xffff)
171                         er->purge_frame_counter = 0xffff ;
172                 else
173                         er->purge_frame_counter =
174                                 (u_short)smc->mib.m[MAC0].fddiMACCopied_Ct ;
175         }
176         /*
177          * CMT and RMT state machines
178          */
179         if (EL_IS_OK(ecm_state,len))
180                 er->ecm_state = smc->mib.fddiSMTECMState ;
181
182         if (EL_IS_OK(pcm_b_state,len)) {
183                 if (smc->s.sas == SMT_SAS) {
184                         er->pcm_a_state = smc->y[PS].mib->fddiPORTPCMState ;
185                         er->pcm_b_state = 0 ;
186                 }
187                 else {
188                         er->pcm_a_state = smc->y[PA].mib->fddiPORTPCMState ;
189                         er->pcm_b_state = smc->y[PB].mib->fddiPORTPCMState ;
190                 }
191         }
192         if (EL_IS_OK(cfm_state,len))
193                 er->cfm_state = smc->mib.fddiSMTCF_State ;
194         if (EL_IS_OK(rmt_state,len))
195                 er->rmt_state = smc->mib.m[MAC0].fddiMACRMTState ;
196
197         /*
198          * smt error word low (we only need the low order 16 bits.)
199          */
200
201         st = smt_get_error_word(smc) & 0xffff ;
202
203         if (EL_IS_OK(smt_error_low,len))
204                 er->smt_error_low = st ;
205
206         if (EL_IS_OK(ucode_version_level,len))
207                 er->ucode_version_level = 0x0101 ;
208         return(len) ;
209 }