58e1a5be913f2ae7d26d6e72ab4d95cd8a9449d4
[linux-2.6.git] / drivers / net / sk98lin / skgepnmi.c
1 /*****************************************************************************
2  *
3  * Name:        skgepnmi.c
4  * Project:     GEnesis, PCI Gigabit Ethernet Adapter
5  * Version:     $Revision: 1.111 $
6  * Date:        $Date: 2003/09/15 13:35:35 $
7  * Purpose:     Private Network Management Interface
8  *
9  ****************************************************************************/
10
11 /******************************************************************************
12  *
13  *      (C)Copyright 1998-2002 SysKonnect GmbH.
14  *      (C)Copyright 2002-2003 Marvell.
15  *
16  *      This program is free software; you can redistribute it and/or modify
17  *      it under the terms of the GNU General Public License as published by
18  *      the Free Software Foundation; either version 2 of the License, or
19  *      (at your option) any later version.
20  *
21  *      The information in this file is provided "AS IS" without warranty.
22  *
23  ******************************************************************************/
24
25
26 #ifndef _lint
27 static const char SysKonnectFileId[] =
28         "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
29 #endif /* !_lint */
30
31 #include "h/skdrv1st.h"
32 #include "h/sktypes.h"
33 #include "h/xmac_ii.h"
34 #include "h/skdebug.h"
35 #include "h/skqueue.h"
36 #include "h/skgepnmi.h"
37 #include "h/skgesirq.h"
38 #include "h/skcsum.h"
39 #include "h/skvpd.h"
40 #include "h/skgehw.h"
41 #include "h/skgeinit.h"
42 #include "h/skdrv2nd.h"
43 #include "h/skgepnm2.h"
44 #ifdef SK_POWER_MGMT
45 #include "h/skgepmgt.h"
46 #endif
47 /* defines *******************************************************************/
48
49 #ifndef DEBUG
50 #define PNMI_STATIC     static
51 #else   /* DEBUG */
52 #define PNMI_STATIC
53 #endif /* DEBUG */
54
55 /*
56  * Public Function prototypes
57  */
58 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60         unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
62         unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
63 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
64         unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
65 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66         unsigned int *pLen, SK_U32 NetIndex);
67 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
68         unsigned int *pLen, SK_U32 NetIndex);
69 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
70         unsigned int *pLen, SK_U32 NetIndex);
71 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
72 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
73         unsigned int * pLen, SK_U32 NetIndex);
74
75
76 /*
77  * Private Function prototypes
78  */
79
80 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
81         PhysPortIndex);
82 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
83         PhysPortIndex);
84 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
85 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
86 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
87         unsigned int PhysPortIndex, unsigned int StatIndex);
88 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
89         unsigned int StatIndex, SK_U32 NetIndex);
90 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
91 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
92         unsigned int *pEntries);
93 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
94         unsigned int KeyArrLen, unsigned int *pKeyNo);
95 PNMI_STATIC int LookupId(SK_U32 Id);
96 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
97         unsigned int LastMac);
98 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
99         unsigned int *pLen, SK_U32 NetIndex);
100 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
101         char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
102 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
103 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
104         unsigned int PortIndex);
105 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
106         unsigned int SensorIndex);
107 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
108 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
109 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
110 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
111 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
112 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
113         unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
114 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
115
116 /*
117  * Table to correlate OID with handler function and index to
118  * hardware register stored in StatAddress if applicable.
119  */
120 #include "skgemib.c"
121
122 /* global variables **********************************************************/
123
124 /*
125  * Overflow status register bit table and corresponding counter
126  * dependent on MAC type - the number relates to the size of overflow
127  * mask returned by the pFnMacOverflow function
128  */
129 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
130 /* Bit0  */     { SK_PNMI_HTX,                          SK_PNMI_HTX_UNICAST},
131 /* Bit1  */     { SK_PNMI_HTX_OCTETHIGH,        SK_PNMI_HTX_BROADCAST},
132 /* Bit2  */     { SK_PNMI_HTX_OCTETLOW,         SK_PNMI_HTX_PMACC},
133 /* Bit3  */     { SK_PNMI_HTX_BROADCAST,        SK_PNMI_HTX_MULTICAST},
134 /* Bit4  */     { SK_PNMI_HTX_MULTICAST,        SK_PNMI_HTX_OCTETLOW},
135 /* Bit5  */     { SK_PNMI_HTX_UNICAST,          SK_PNMI_HTX_OCTETHIGH},
136 /* Bit6  */     { SK_PNMI_HTX_LONGFRAMES,       SK_PNMI_HTX_64},
137 /* Bit7  */     { SK_PNMI_HTX_BURST,            SK_PNMI_HTX_127},
138 /* Bit8  */     { SK_PNMI_HTX_PMACC,            SK_PNMI_HTX_255},
139 /* Bit9  */     { SK_PNMI_HTX_MACC,             SK_PNMI_HTX_511},
140 /* Bit10 */     { SK_PNMI_HTX_SINGLE_COL,       SK_PNMI_HTX_1023},
141 /* Bit11 */     { SK_PNMI_HTX_MULTI_COL,        SK_PNMI_HTX_MAX},
142 /* Bit12 */     { SK_PNMI_HTX_EXCESS_COL,       SK_PNMI_HTX_LONGFRAMES},
143 /* Bit13 */     { SK_PNMI_HTX_LATE_COL,         SK_PNMI_HTX_RESERVED},
144 /* Bit14 */     { SK_PNMI_HTX_DEFFERAL,         SK_PNMI_HTX_COL},
145 /* Bit15 */     { SK_PNMI_HTX_EXCESS_DEF,       SK_PNMI_HTX_LATE_COL},
146 /* Bit16 */     { SK_PNMI_HTX_UNDERRUN,         SK_PNMI_HTX_EXCESS_COL},
147 /* Bit17 */     { SK_PNMI_HTX_CARRIER,          SK_PNMI_HTX_MULTI_COL},
148 /* Bit18 */     { SK_PNMI_HTX_UTILUNDER,        SK_PNMI_HTX_SINGLE_COL},
149 /* Bit19 */     { SK_PNMI_HTX_UTILOVER,         SK_PNMI_HTX_UNDERRUN},
150 /* Bit20 */     { SK_PNMI_HTX_64,                       SK_PNMI_HTX_RESERVED},
151 /* Bit21 */     { SK_PNMI_HTX_127,                      SK_PNMI_HTX_RESERVED},
152 /* Bit22 */     { SK_PNMI_HTX_255,                      SK_PNMI_HTX_RESERVED},
153 /* Bit23 */     { SK_PNMI_HTX_511,                      SK_PNMI_HTX_RESERVED},
154 /* Bit24 */     { SK_PNMI_HTX_1023,             SK_PNMI_HTX_RESERVED},
155 /* Bit25 */     { SK_PNMI_HTX_MAX,                      SK_PNMI_HTX_RESERVED},
156 /* Bit26 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
157 /* Bit27 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
158 /* Bit28 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
159 /* Bit29 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
160 /* Bit30 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
161 /* Bit31 */     { SK_PNMI_HTX_RESERVED,         SK_PNMI_HTX_RESERVED},
162 /* Bit32 */     { SK_PNMI_HRX,                          SK_PNMI_HRX_UNICAST},
163 /* Bit33 */     { SK_PNMI_HRX_OCTETHIGH,        SK_PNMI_HRX_BROADCAST},
164 /* Bit34 */     { SK_PNMI_HRX_OCTETLOW,         SK_PNMI_HRX_PMACC},
165 /* Bit35 */     { SK_PNMI_HRX_BROADCAST,        SK_PNMI_HRX_MULTICAST},
166 /* Bit36 */     { SK_PNMI_HRX_MULTICAST,        SK_PNMI_HRX_FCS},
167 /* Bit37 */     { SK_PNMI_HRX_UNICAST,          SK_PNMI_HRX_RESERVED},
168 /* Bit38 */     { SK_PNMI_HRX_PMACC,            SK_PNMI_HRX_OCTETLOW},
169 /* Bit39 */     { SK_PNMI_HRX_MACC,             SK_PNMI_HRX_OCTETHIGH},
170 /* Bit40 */     { SK_PNMI_HRX_PMACC_ERR,        SK_PNMI_HRX_BADOCTETLOW},
171 /* Bit41 */     { SK_PNMI_HRX_MACC_UNKWN,       SK_PNMI_HRX_BADOCTETHIGH},
172 /* Bit42 */     { SK_PNMI_HRX_BURST,            SK_PNMI_HRX_UNDERSIZE},
173 /* Bit43 */     { SK_PNMI_HRX_MISSED,           SK_PNMI_HRX_RUNT},
174 /* Bit44 */     { SK_PNMI_HRX_FRAMING,          SK_PNMI_HRX_64},
175 /* Bit45 */     { SK_PNMI_HRX_OVERFLOW,         SK_PNMI_HRX_127},
176 /* Bit46 */     { SK_PNMI_HRX_JABBER,           SK_PNMI_HRX_255},
177 /* Bit47 */     { SK_PNMI_HRX_CARRIER,          SK_PNMI_HRX_511},
178 /* Bit48 */     { SK_PNMI_HRX_IRLENGTH,         SK_PNMI_HRX_1023},
179 /* Bit49 */     { SK_PNMI_HRX_SYMBOL,           SK_PNMI_HRX_MAX},
180 /* Bit50 */     { SK_PNMI_HRX_SHORTS,           SK_PNMI_HRX_LONGFRAMES},
181 /* Bit51 */     { SK_PNMI_HRX_RUNT,             SK_PNMI_HRX_TOO_LONG},
182 /* Bit52 */     { SK_PNMI_HRX_TOO_LONG,         SK_PNMI_HRX_JABBER},
183 /* Bit53 */     { SK_PNMI_HRX_FCS,                      SK_PNMI_HRX_RESERVED},
184 /* Bit54 */     { SK_PNMI_HRX_RESERVED,         SK_PNMI_HRX_OVERFLOW},
185 /* Bit55 */     { SK_PNMI_HRX_CEXT,             SK_PNMI_HRX_RESERVED},
186 /* Bit56 */     { SK_PNMI_HRX_UTILUNDER,        SK_PNMI_HRX_RESERVED},
187 /* Bit57 */     { SK_PNMI_HRX_UTILOVER,         SK_PNMI_HRX_RESERVED},
188 /* Bit58 */     { SK_PNMI_HRX_64,                       SK_PNMI_HRX_RESERVED},
189 /* Bit59 */     { SK_PNMI_HRX_127,                      SK_PNMI_HRX_RESERVED},
190 /* Bit60 */     { SK_PNMI_HRX_255,                      SK_PNMI_HRX_RESERVED},
191 /* Bit61 */     { SK_PNMI_HRX_511,                      SK_PNMI_HRX_RESERVED},
192 /* Bit62 */     { SK_PNMI_HRX_1023,             SK_PNMI_HRX_RESERVED},
193 /* Bit63 */     { SK_PNMI_HRX_MAX,                      SK_PNMI_HRX_RESERVED}
194 };
195
196 /*
197  * Table for hardware register saving on resets and port switches
198  */
199 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
200         /* SK_PNMI_HTX */
201         {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
202         /* SK_PNMI_HTX_OCTETHIGH */
203         {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
204         /* SK_PNMI_HTX_OCTETLOW */
205         {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
206         /* SK_PNMI_HTX_BROADCAST */
207         {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
208         /* SK_PNMI_HTX_MULTICAST */
209         {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
210         /* SK_PNMI_HTX_UNICAST */
211         {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
212         /* SK_PNMI_HTX_BURST */
213         {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
214         /* SK_PNMI_HTX_PMACC */
215         {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
216         /* SK_PNMI_HTX_MACC */
217         {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
218         /* SK_PNMI_HTX_COL */
219         {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
220         /* SK_PNMI_HTX_SINGLE_COL */
221         {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
222         /* SK_PNMI_HTX_MULTI_COL */
223         {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
224         /* SK_PNMI_HTX_EXCESS_COL */
225         {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
226         /* SK_PNMI_HTX_LATE_COL */
227         {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
228         /* SK_PNMI_HTX_DEFFERAL */
229         {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
230         /* SK_PNMI_HTX_EXCESS_DEF */
231         {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
232         /* SK_PNMI_HTX_UNDERRUN */
233         {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
234         /* SK_PNMI_HTX_CARRIER */
235         {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
236         /* SK_PNMI_HTX_UTILUNDER */
237         {{0, SK_FALSE}, {0, SK_FALSE}},
238         /* SK_PNMI_HTX_UTILOVER */
239         {{0, SK_FALSE}, {0, SK_FALSE}},
240         /* SK_PNMI_HTX_64 */
241         {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
242         /* SK_PNMI_HTX_127 */
243         {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
244         /* SK_PNMI_HTX_255 */
245         {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
246         /* SK_PNMI_HTX_511 */
247         {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
248         /* SK_PNMI_HTX_1023 */
249         {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
250         /* SK_PNMI_HTX_MAX */
251         {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
252         /* SK_PNMI_HTX_LONGFRAMES  */
253         {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
254         /* SK_PNMI_HTX_SYNC */
255         {{0, SK_FALSE}, {0, SK_FALSE}},
256         /* SK_PNMI_HTX_SYNC_OCTET */
257         {{0, SK_FALSE}, {0, SK_FALSE}},
258         /* SK_PNMI_HTX_RESERVED */
259         {{0, SK_FALSE}, {0, SK_FALSE}},
260         /* SK_PNMI_HRX */
261         {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
262         /* SK_PNMI_HRX_OCTETHIGH */
263         {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
264         /* SK_PNMI_HRX_OCTETLOW */
265         {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
266         /* SK_PNMI_HRX_BADOCTETHIGH */
267         {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
268         /* SK_PNMI_HRX_BADOCTETLOW */
269         {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
270         /* SK_PNMI_HRX_BROADCAST */
271         {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
272         /* SK_PNMI_HRX_MULTICAST */
273         {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
274         /* SK_PNMI_HRX_UNICAST */
275         {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
276         /* SK_PNMI_HRX_PMACC */
277         {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
278         /* SK_PNMI_HRX_MACC */
279         {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
280         /* SK_PNMI_HRX_PMACC_ERR */
281         {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
282         /* SK_PNMI_HRX_MACC_UNKWN */
283         {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
284         /* SK_PNMI_HRX_BURST */
285         {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
286         /* SK_PNMI_HRX_MISSED */
287         {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
288         /* SK_PNMI_HRX_FRAMING */
289         {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
290         /* SK_PNMI_HRX_UNDERSIZE */
291         {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
292         /* SK_PNMI_HRX_OVERFLOW */
293         {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
294         /* SK_PNMI_HRX_JABBER */
295         {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
296         /* SK_PNMI_HRX_CARRIER */
297         {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
298         /* SK_PNMI_HRX_IRLENGTH */
299         {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
300         /* SK_PNMI_HRX_SYMBOL */
301         {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
302         /* SK_PNMI_HRX_SHORTS */
303         {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
304         /* SK_PNMI_HRX_RUNT */
305         {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
306         /* SK_PNMI_HRX_TOO_LONG */
307         {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
308         /* SK_PNMI_HRX_FCS */
309         {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
310         /* SK_PNMI_HRX_CEXT */
311         {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
312         /* SK_PNMI_HRX_UTILUNDER */
313         {{0, SK_FALSE}, {0, SK_FALSE}},
314         /* SK_PNMI_HRX_UTILOVER */
315         {{0, SK_FALSE}, {0, SK_FALSE}},
316         /* SK_PNMI_HRX_64 */
317         {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
318         /* SK_PNMI_HRX_127 */
319         {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
320         /* SK_PNMI_HRX_255 */
321         {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
322         /* SK_PNMI_HRX_511 */
323         {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
324         /* SK_PNMI_HRX_1023 */
325         {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
326         /* SK_PNMI_HRX_MAX */
327         {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
328         /* SK_PNMI_HRX_LONGFRAMES */
329         {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
330         /* SK_PNMI_HRX_RESERVED */
331         {{0, SK_FALSE}, {0, SK_FALSE}}
332 };
333
334
335 /*****************************************************************************
336  *
337  * Public functions
338  *
339  */
340
341 /*****************************************************************************
342  *
343  * SkPnmiInit - Init function of PNMI
344  *
345  * Description:
346  *      SK_INIT_DATA: Initialises the data structures
347  *      SK_INIT_IO:   Resets the XMAC statistics, determines the device and
348  *                    connector type.
349  *      SK_INIT_RUN:  Starts a timer event for port switch per hour
350  *                    calculation.
351  *
352  * Returns:
353  *      Always 0
354  */
355 int SkPnmiInit(
356 SK_AC *pAC,             /* Pointer to adapter context */
357 SK_IOC IoC,             /* IO context handle */
358 int Level)              /* Initialization level */
359 {
360         unsigned int    PortMax;        /* Number of ports */
361         unsigned int    PortIndex;      /* Current port index in loop */
362         SK_U16          Val16;          /* Multiple purpose 16 bit variable */
363         SK_U8           Val8;           /* Mulitple purpose 8 bit variable */
364         SK_EVPARA       EventParam;     /* Event struct for timer event */
365         SK_PNMI_VCT     *pVctBackupData;
366
367
368         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
369                 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
370
371         switch (Level) {
372
373         case SK_INIT_DATA:
374                 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
375                 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
376                 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
377                 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
378                 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
379
380                         pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
381                         pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
382                 }
383
384 #ifdef SK_PNMI_CHECK
385                 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
386                         
387                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
388
389                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
390                                            ("CounterOffset struct size (%d) differs from"
391                                                 "SK_PNMI_MAX_IDX (%d)\n",
392                                                 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
393                 }
394
395                 if (SK_PNMI_MAX_IDX !=
396                         (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
397                         
398                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
399
400                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
401                                            ("StatAddr table size (%d) differs from "
402                                                 "SK_PNMI_MAX_IDX (%d)\n",
403                                                 (sizeof(StatAddr) /
404                                                  (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
405                                                  SK_PNMI_MAX_IDX));
406                 }
407 #endif /* SK_PNMI_CHECK */
408                 break;
409
410         case SK_INIT_IO:
411                 /*
412                  * Reset MAC counters
413                  */
414                 PortMax = pAC->GIni.GIMacsFound;
415
416                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
417
418                         pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
419                 }
420                 
421                 /* Initialize DSP variables for Vct() to 0xff => Never written! */              
422                 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
423                         pAC->GIni.GP[PortIndex].PCableLen = 0xff;
424                         pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
425                         pVctBackupData->PCableLen = 0xff;
426                 }
427                 
428                 /*
429                  * Get pci bus speed
430                  */
431                 SK_IN16(IoC, B0_CTST, &Val16);
432                 if ((Val16 & CS_BUS_CLOCK) == 0) {
433
434                         pAC->Pnmi.PciBusSpeed = 33;
435                 }
436                 else {
437                         pAC->Pnmi.PciBusSpeed = 66;
438                 }
439
440                 /*
441                  * Get pci bus width
442                  */
443                 SK_IN16(IoC, B0_CTST, &Val16);
444                 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
445
446                         pAC->Pnmi.PciBusWidth = 32;
447                 }
448                 else {
449                         pAC->Pnmi.PciBusWidth = 64;
450                 }
451
452                 /*
453                  * Get chipset
454                  */
455                 switch (pAC->GIni.GIChipId) {
456                 case CHIP_ID_GENESIS:
457                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
458                         break;
459
460                 case CHIP_ID_YUKON:
461                         pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
462                         break;
463
464                 default:
465                         break;
466                 }
467
468                 /*
469                  * Get PMD and DeviceType
470                  */
471                 SK_IN8(IoC, B2_PMD_TYP, &Val8);
472                 switch (Val8) {
473                 case 'S':
474                         pAC->Pnmi.PMD = 3;
475                         if (pAC->GIni.GIMacsFound > 1) {
476
477                                 pAC->Pnmi.DeviceType = 0x00020002;
478                         }
479                         else {
480                                 pAC->Pnmi.DeviceType = 0x00020001;
481                         }
482                         break;
483
484                 case 'L':
485                         pAC->Pnmi.PMD = 2;
486                         if (pAC->GIni.GIMacsFound > 1) {
487
488                                 pAC->Pnmi.DeviceType = 0x00020004;
489                         }
490                         else {
491                                 pAC->Pnmi.DeviceType = 0x00020003;
492                         }
493                         break;
494
495                 case 'C':
496                         pAC->Pnmi.PMD = 4;
497                         if (pAC->GIni.GIMacsFound > 1) {
498
499                                 pAC->Pnmi.DeviceType = 0x00020006;
500                         }
501                         else {
502                                 pAC->Pnmi.DeviceType = 0x00020005;
503                         }
504                         break;
505
506                 case 'T':
507                         pAC->Pnmi.PMD = 5;
508                         if (pAC->GIni.GIMacsFound > 1) {
509
510                                 pAC->Pnmi.DeviceType = 0x00020008;
511                         }
512                         else {
513                                 pAC->Pnmi.DeviceType = 0x00020007;
514                         }
515                         break;
516
517                 default :
518                         pAC->Pnmi.PMD = 1;
519                         pAC->Pnmi.DeviceType = 0;
520                         break;
521                 }
522
523                 /*
524                  * Get connector
525                  */
526                 SK_IN8(IoC, B2_CONN_TYP, &Val8);
527                 switch (Val8) {
528                 case 'C':
529                         pAC->Pnmi.Connector = 2;
530                         break;
531
532                 case 'D':
533                         pAC->Pnmi.Connector = 3;
534                         break;
535
536                 case 'F':
537                         pAC->Pnmi.Connector = 4;
538                         break;
539
540                 case 'J':
541                         pAC->Pnmi.Connector = 5;
542                         break;
543
544                 case 'V':
545                         pAC->Pnmi.Connector = 6;
546                         break;
547
548                 default:
549                         pAC->Pnmi.Connector = 1;
550                         break;
551                 }
552                 break;
553
554         case SK_INIT_RUN:
555                 /*
556                  * Start timer for RLMT change counter
557                  */
558                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
559                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
560                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
561                         EventParam);
562                 break;
563
564         default:
565                 break; /* Nothing todo */
566         }
567
568         return (0);
569 }
570
571 /*****************************************************************************
572  *
573  * SkPnmiGetVar - Retrieves the value of a single OID
574  *
575  * Description:
576  *      Calls a general sub-function for all this stuff. If the instance
577  *      -1 is passed, the values of all instances are returned in an
578  *      array of values.
579  *
580  * Returns:
581  *      SK_PNMI_ERR_OK           The request was successfully performed
582  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
583  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
584  *                               the data.
585  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown
586  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
587  *                           exist (e.g. port instance 3 on a two port
588  *                               adapter.
589  */
590 int SkPnmiGetVar(
591 SK_AC *pAC,             /* Pointer to adapter context */
592 SK_IOC IoC,             /* IO context handle */
593 SK_U32 Id,              /* Object ID that is to be processed */
594 void *pBuf,             /* Buffer to which the management data will be copied */
595 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
596 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
597 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
598 {
599         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
600                 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
601                         Id, *pLen, Instance, NetIndex));
602
603         return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
604                 Instance, NetIndex));
605 }
606
607 /*****************************************************************************
608  *
609  * SkPnmiPreSetVar - Presets the value of a single OID
610  *
611  * Description:
612  *      Calls a general sub-function for all this stuff. The preset does
613  *      the same as a set, but returns just before finally setting the
614  *      new value. This is usefull to check if a set might be successfull.
615  *      If the instance -1 is passed, an array of values is supposed and
616  *      all instances of the OID will be set.
617  *
618  * Returns:
619  *      SK_PNMI_ERR_OK           The request was successfully performed.
620  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
621  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
622  *                               the correct data (e.g. a 32bit value is
623  *                               needed, but a 16 bit value was passed).
624  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
625  *                               value range.
626  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
627  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
628  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
629  *                           exist (e.g. port instance 3 on a two port
630  *                               adapter.
631  */
632 int SkPnmiPreSetVar(
633 SK_AC *pAC,             /* Pointer to adapter context */
634 SK_IOC IoC,             /* IO context handle */
635 SK_U32 Id,              /* Object ID that is to be processed */
636 void *pBuf,             /* Buffer to which the management data will be copied */
637 unsigned int *pLen,     /* Total length of management data */
638 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
639 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
640 {
641         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
642                 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
643                         Id, *pLen, Instance, NetIndex));
644
645
646         return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
647                 Instance, NetIndex));
648 }
649
650 /*****************************************************************************
651  *
652  * SkPnmiSetVar - Sets the value of a single OID
653  *
654  * Description:
655  *      Calls a general sub-function for all this stuff. The preset does
656  *      the same as a set, but returns just before finally setting the
657  *      new value. This is usefull to check if a set might be successfull.
658  *      If the instance -1 is passed, an array of values is supposed and
659  *      all instances of the OID will be set.
660  *
661  * Returns:
662  *      SK_PNMI_ERR_OK           The request was successfully performed.
663  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
664  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
665  *                               the correct data (e.g. a 32bit value is
666  *                               needed, but a 16 bit value was passed).
667  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
668  *                               value range.
669  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
670  *      SK_PNMI_ERR_UNKNOWN_OID  The requested OID is unknown.
671  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
672  *                           exist (e.g. port instance 3 on a two port
673  *                               adapter.
674  */
675 int SkPnmiSetVar(
676 SK_AC *pAC,             /* Pointer to adapter context */
677 SK_IOC IoC,             /* IO context handle */
678 SK_U32 Id,              /* Object ID that is to be processed */
679 void *pBuf,             /* Buffer to which the management data will be copied */
680 unsigned int *pLen,     /* Total length of management data */
681 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
682 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
683 {
684         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
685                 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
686                         Id, *pLen, Instance, NetIndex));
687
688         return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
689                 Instance, NetIndex));
690 }
691
692 /*****************************************************************************
693  *
694  * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
695  *
696  * Description:
697  *      Runs through the IdTable, queries the single OIDs and stores the
698  *      returned data into the management database structure
699  *      SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
700  *      is stored in the IdTable. The return value of the function will also
701  *      be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
702  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE.
703  *
704  * Returns:
705  *      SK_PNMI_ERR_OK           The request was successfully performed
706  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured
707  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to take
708  *                               the data.
709  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
710  */
711 int SkPnmiGetStruct(
712 SK_AC *pAC,             /* Pointer to adapter context */
713 SK_IOC IoC,             /* IO context handle */
714 void *pBuf,             /* Buffer to which the management data will be copied. */
715 unsigned int *pLen,     /* Length of buffer */
716 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
717 {
718         int             Ret;
719         unsigned int    TableIndex;
720         unsigned int    DstOffset;
721         unsigned int    InstanceNo;
722         unsigned int    InstanceCnt;
723         SK_U32          Instance;
724         unsigned int    TmpLen;
725         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
726
727
728         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
729                 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
730                         *pLen, NetIndex));
731
732         if (*pLen < SK_PNMI_STRUCT_SIZE) {
733
734                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
735
736                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
737                                 (SK_U32)(-1));
738                 }
739
740                 *pLen = SK_PNMI_STRUCT_SIZE;
741                 return (SK_PNMI_ERR_TOO_SHORT);
742         }
743
744     /*
745      * Check NetIndex
746      */
747         if (NetIndex >= pAC->Rlmt.NumNets) {
748                 return (SK_PNMI_ERR_UNKNOWN_NET);
749         }
750
751         /* Update statistic */
752         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
753
754         if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
755                 SK_PNMI_ERR_OK) {
756
757                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
758                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
759                 return (Ret);
760         }
761
762         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
763
764                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
765                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
766                 return (Ret);
767         }
768
769         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
770
771                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
772                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
773                 return (Ret);
774         }
775
776         /*
777          * Increment semaphores to indicate that an update was
778          * already done
779          */
780         pAC->Pnmi.MacUpdatedFlag ++;
781         pAC->Pnmi.RlmtUpdatedFlag ++;
782         pAC->Pnmi.SirqUpdatedFlag ++;
783
784         /* Get vpd keys for instance calculation */
785         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
786         if (Ret != SK_PNMI_ERR_OK) {
787
788                 pAC->Pnmi.MacUpdatedFlag --;
789                 pAC->Pnmi.RlmtUpdatedFlag --;
790                 pAC->Pnmi.SirqUpdatedFlag --;
791
792                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
793                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
794                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
795                 return (SK_PNMI_ERR_GENERAL);
796         }
797
798         /* Retrieve values */
799         SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
800         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
801
802                 InstanceNo = IdTable[TableIndex].InstanceNo;
803                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
804                         InstanceCnt ++) {
805
806                         DstOffset = IdTable[TableIndex].Offset +
807                                 (InstanceCnt - 1) *
808                                 IdTable[TableIndex].StructSize;
809
810                         /*
811                          * For the VPD the instance is not an index number
812                          * but the key itself. Determin with the instance
813                          * counter the VPD key to be used.
814                          */
815                         if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
816                                 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
817                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
818                                 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
819
820                                 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
821                         }
822                         else {
823                                 Instance = (SK_U32)InstanceCnt;
824                         }
825
826                         TmpLen = *pLen - DstOffset;
827                         Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
828                                 IdTable[TableIndex].Id, (char *)pBuf +
829                                 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
830
831                         /*
832                          * An unknown instance error means that we reached
833                          * the last instance of that variable. Proceed with
834                          * the next OID in the table and ignore the return
835                          * code.
836                          */
837                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
838
839                 break;
840                         }
841
842                         if (Ret != SK_PNMI_ERR_OK) {
843
844                                 pAC->Pnmi.MacUpdatedFlag --;
845                                 pAC->Pnmi.RlmtUpdatedFlag --;
846                                 pAC->Pnmi.SirqUpdatedFlag --;
847
848                                 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
849                                 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
850                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
851                                 return (Ret);
852                         }
853                 }
854         }
855
856         pAC->Pnmi.MacUpdatedFlag --;
857         pAC->Pnmi.RlmtUpdatedFlag --;
858         pAC->Pnmi.SirqUpdatedFlag --;
859
860         *pLen = SK_PNMI_STRUCT_SIZE;
861         SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
862         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
863         return (SK_PNMI_ERR_OK);
864 }
865
866 /*****************************************************************************
867  *
868  * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
869  *
870  * Description:
871  *      Calls a general sub-function for all this set stuff. The preset does
872  *      the same as a set, but returns just before finally setting the
873  *      new value. This is usefull to check if a set might be successfull.
874  *      The sub-function runs through the IdTable, checks which OIDs are able
875  *      to set, and calls the handler function of the OID to perform the
876  *      preset. The return value of the function will also be stored in
877  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
878  *      SK_PNMI_MIN_STRUCT_SIZE.
879  *
880  * Returns:
881  *      SK_PNMI_ERR_OK           The request was successfully performed.
882  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
883  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
884  *                               the correct data (e.g. a 32bit value is
885  *                               needed, but a 16 bit value was passed).
886  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
887  *                               value range.
888  */
889 int SkPnmiPreSetStruct(
890 SK_AC *pAC,             /* Pointer to adapter context */
891 SK_IOC IoC,             /* IO context handle */
892 void *pBuf,             /* Buffer which contains the data to be set */
893 unsigned int *pLen,     /* Length of buffer */
894 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
895 {
896         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
897                 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
898                         *pLen, NetIndex));
899
900         return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
901                                         pLen, NetIndex));
902 }
903
904 /*****************************************************************************
905  *
906  * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
907  *
908  * Description:
909  *      Calls a general sub-function for all this set stuff. The return value
910  *      of the function will also be stored in SK_PNMI_STRUCT_DATA if the
911  *      passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
912  *      The sub-function runs through the IdTable, checks which OIDs are able
913  *      to set, and calls the handler function of the OID to perform the
914  *      set. The return value of the function will also be stored in
915  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
916  *      SK_PNMI_MIN_STRUCT_SIZE.
917  *
918  * Returns:
919  *      SK_PNMI_ERR_OK           The request was successfully performed.
920  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
921  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
922  *                               the correct data (e.g. a 32bit value is
923  *                               needed, but a 16 bit value was passed).
924  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
925  *                               value range.
926  */
927 int SkPnmiSetStruct(
928 SK_AC *pAC,             /* Pointer to adapter context */
929 SK_IOC IoC,             /* IO context handle */
930 void *pBuf,             /* Buffer which contains the data to be set */
931 unsigned int *pLen,     /* Length of buffer */
932 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
933 {
934         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
935                 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
936                         *pLen, NetIndex));
937
938         return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
939                                         pLen, NetIndex));
940 }
941
942 /*****************************************************************************
943  *
944  * SkPnmiEvent - Event handler
945  *
946  * Description:
947  *      Handles the following events:
948  *      SK_PNMI_EVT_SIRQ_OVERFLOW     When a hardware counter overflows an
949  *                                    interrupt will be generated which is
950  *                                    first handled by SIRQ which generates a
951  *                                    this event. The event increments the
952  *                                    upper 32 bit of the 64 bit counter.
953  *      SK_PNMI_EVT_SEN_XXX           The event is generated by the I2C module
954  *                                    when a sensor reports a warning or
955  *                                    error. The event will store a trap
956  *                                    message in the trap buffer.
957  *      SK_PNMI_EVT_CHG_EST_TIMER     The timer event was initiated by this
958  *                                    module and is used to calculate the
959  *                                    port switches per hour.
960  *      SK_PNMI_EVT_CLEAR_COUNTER     The event clears all counters and
961  *                                    timestamps.
962  *      SK_PNMI_EVT_XMAC_RESET        The event is generated by the driver
963  *                                    before a hard reset of the XMAC is
964  *                                    performed. All counters will be saved
965  *                                    and added to the hardware counter
966  *                                    values after reset to grant continuous
967  *                                    counter values.
968  *      SK_PNMI_EVT_RLMT_PORT_UP      Generated by RLMT to notify that a port
969  *                                    went logically up. A trap message will
970  *                                    be stored to the trap buffer.
971  *      SK_PNMI_EVT_RLMT_PORT_DOWN    Generated by RLMT to notify that a port
972  *                                    went logically down. A trap message will
973  *                                    be stored to the trap buffer.
974  *      SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
975  *                                    spanning tree root bridges were
976  *                                    detected. A trap message will be stored
977  *                                    to the trap buffer.
978  *      SK_PNMI_EVT_RLMT_ACTIVE_DOWN  Notifies PNMI that an active port went
979  *                                    down. PNMI will not further add the
980  *                                    statistic values to the virtual port.
981  *      SK_PNMI_EVT_RLMT_ACTIVE_UP    Notifies PNMI that a port went up and
982  *                                    is now an active port. PNMI will now
983  *                                    add the statistic data of this port to
984  *                                    the virtual port.
985  *      SK_PNMI_EVT_RLMT_SET_NETS     Notifies PNMI about the net mode. The first parameter
986  *                                    contains the number of nets. 1 means single net, 2 means
987  *                                    dual net. The second parameter is -1
988  *
989  * Returns:
990  *      Always 0
991  */
992 int SkPnmiEvent(
993 SK_AC *pAC,             /* Pointer to adapter context */
994 SK_IOC IoC,             /* IO context handle */
995 SK_U32 Event,           /* Event-Id */
996 SK_EVPARA Param)        /* Event dependent parameter */
997 {
998         unsigned int    PhysPortIndex;
999     unsigned int        MaxNetNumber;
1000         int                     CounterIndex;
1001         int                     Ret;
1002         SK_U16          MacStatus;
1003         SK_U64          OverflowStatus;
1004         SK_U64          Mask;
1005         int                     MacType;
1006         SK_U64          Value;
1007         SK_U32          Val32;
1008         SK_U16          Register;
1009         SK_EVPARA       EventParam;
1010         SK_U64          NewestValue;
1011         SK_U64          OldestValue;
1012         SK_U64          Delta;
1013         SK_PNMI_ESTIMATE *pEst;
1014         SK_U32          NetIndex;
1015         SK_GEPORT       *pPrt;
1016         SK_PNMI_VCT     *pVctBackupData;
1017         SK_U32          RetCode;
1018         int             i;
1019         SK_U32          CableLength;
1020
1021
1022 #ifdef DEBUG
1023         if (Event != SK_PNMI_EVT_XMAC_RESET) {
1024
1025                 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1026                         ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1027                         (unsigned int)Event, (unsigned int)Param.Para64));
1028         }
1029 #endif /* DEBUG */
1030         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1031
1032         MacType = pAC->GIni.GIMacType;
1033         
1034         switch (Event) {
1035
1036         case SK_PNMI_EVT_SIRQ_OVERFLOW:
1037                 PhysPortIndex = (int)Param.Para32[0];
1038                 MacStatus = (SK_U16)Param.Para32[1];
1039 #ifdef DEBUG
1040                 if (PhysPortIndex >= SK_MAX_MACS) {
1041
1042                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1043                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1044                                  " wrong, PhysPortIndex=0x%x\n",
1045                                 PhysPortIndex));
1046                         return (0);
1047                 }
1048 #endif /* DEBUG */
1049                 OverflowStatus = 0;
1050
1051                 /*
1052                  * Check which source caused an overflow interrupt.
1053                  */
1054                 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1055                                 MacStatus, &OverflowStatus) != 0) ||
1056                         (OverflowStatus == 0)) {
1057
1058                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1059                         return (0);
1060                 }
1061
1062                 /*
1063                  * Check the overflow status register and increment
1064                  * the upper dword of corresponding counter.
1065                  */
1066                 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1067                         CounterIndex ++) {
1068
1069                         Mask = (SK_U64)1 << CounterIndex;
1070                         if ((OverflowStatus & Mask) == 0) {
1071
1072                                 continue;
1073                         }
1074
1075                         switch (StatOvrflwBit[CounterIndex][MacType]) {
1076
1077                         case SK_PNMI_HTX_UTILUNDER:
1078                         case SK_PNMI_HTX_UTILOVER:
1079                                 if (MacType == SK_MAC_XMAC) {
1080                                         XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1081                                         Register |= XM_TX_SAM_LINE;
1082                                         XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1083                                 }
1084                                 break;
1085
1086                         case SK_PNMI_HRX_UTILUNDER:
1087                         case SK_PNMI_HRX_UTILOVER:
1088                                 if (MacType == SK_MAC_XMAC) {
1089                                         XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1090                                         Register |= XM_RX_SAM_LINE;
1091                                         XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1092                                 }
1093                                 break;
1094
1095                         case SK_PNMI_HTX_OCTETHIGH:
1096                         case SK_PNMI_HTX_OCTETLOW:
1097                         case SK_PNMI_HTX_RESERVED:
1098                         case SK_PNMI_HRX_OCTETHIGH:
1099                         case SK_PNMI_HRX_OCTETLOW:
1100                         case SK_PNMI_HRX_IRLENGTH:
1101                         case SK_PNMI_HRX_RESERVED:
1102                         
1103                         /*
1104                          * the following counters aren't be handled (id > 63)
1105                          */
1106                         case SK_PNMI_HTX_SYNC:
1107                         case SK_PNMI_HTX_SYNC_OCTET:
1108                                 break;
1109
1110                         case SK_PNMI_HRX_LONGFRAMES:
1111                                 if (MacType == SK_MAC_GMAC) {
1112                                         pAC->Pnmi.Port[PhysPortIndex].
1113                                                 CounterHigh[CounterIndex] ++;
1114                                 }
1115                                 break;
1116
1117                         default:
1118                                 pAC->Pnmi.Port[PhysPortIndex].
1119                                         CounterHigh[CounterIndex] ++;
1120                         }
1121                 }
1122                 break;
1123
1124         case SK_PNMI_EVT_SEN_WAR_LOW:
1125 #ifdef DEBUG
1126                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1127
1128                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1129                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1130                                 (unsigned int)Param.Para64));
1131                         return (0);
1132                 }
1133 #endif /* DEBUG */
1134
1135                 /*
1136                  * Store a trap message in the trap buffer and generate
1137                  * an event for user space applications with the
1138                  * SK_DRIVER_SENDEVENT macro.
1139                  */
1140                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1141                         (unsigned int)Param.Para64);
1142                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1143                 break;
1144
1145         case SK_PNMI_EVT_SEN_WAR_UPP:
1146 #ifdef DEBUG
1147                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1148
1149                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1150                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1151                                 (unsigned int)Param.Para64));
1152                         return (0);
1153                 }
1154 #endif /* DEBUG */
1155
1156                 /*
1157                  * Store a trap message in the trap buffer and generate
1158                  * an event for user space applications with the
1159                  * SK_DRIVER_SENDEVENT macro.
1160                  */
1161                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1162                         (unsigned int)Param.Para64);
1163                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1164                 break;
1165
1166         case SK_PNMI_EVT_SEN_ERR_LOW:
1167 #ifdef DEBUG
1168                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1169
1170                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1171                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1172                                 (unsigned int)Param.Para64));
1173                         return (0);
1174                 }
1175 #endif /* DEBUG */
1176
1177                 /*
1178                  * Store a trap message in the trap buffer and generate
1179                  * an event for user space applications with the
1180                  * SK_DRIVER_SENDEVENT macro.
1181                  */
1182                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1183                         (unsigned int)Param.Para64);
1184                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1185                 break;
1186         
1187         case SK_PNMI_EVT_SEN_ERR_UPP:
1188 #ifdef DEBUG
1189                 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1190
1191                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1192                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1193                                 (unsigned int)Param.Para64));
1194                         return (0);
1195                 }
1196 #endif /* DEBUG */
1197
1198                 /*
1199                  * Store a trap message in the trap buffer and generate
1200                  * an event for user space applications with the
1201                  * SK_DRIVER_SENDEVENT macro.
1202                  */
1203                 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1204                         (unsigned int)Param.Para64);
1205                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1206                 break;
1207
1208         case SK_PNMI_EVT_CHG_EST_TIMER:
1209                 /*
1210                  * Calculate port switch average on a per hour basis
1211                  *   Time interval for check       : 28125 ms
1212                  *   Number of values for average  : 8
1213                  *
1214                  * Be careful in changing these values, on change check
1215                  *   - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1216                  *     array one less than value number)
1217                  *   - Timer initialization SkTimerStart() in SkPnmiInit
1218                  *   - Delta value below must be multiplicated with
1219                  *     power of 2
1220                  *
1221                  */
1222                 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1223                 CounterIndex = pEst->EstValueIndex + 1;
1224                 if (CounterIndex == 7) {
1225
1226                         CounterIndex = 0;
1227                 }
1228                 pEst->EstValueIndex = CounterIndex;
1229
1230                 NewestValue = pAC->Pnmi.RlmtChangeCts;
1231                 OldestValue = pEst->EstValue[CounterIndex];
1232                 pEst->EstValue[CounterIndex] = NewestValue;
1233
1234                 /*
1235                  * Calculate average. Delta stores the number of
1236                  * port switches per 28125 * 8 = 225000 ms
1237                  */
1238                 if (NewestValue >= OldestValue) {
1239
1240                         Delta = NewestValue - OldestValue;
1241                 }
1242                 else {
1243                         /* Overflow situation */
1244                         Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1245                 }
1246
1247                 /*
1248                  * Extrapolate delta to port switches per hour.
1249                  *     Estimate = Delta * (3600000 / 225000)
1250                  *              = Delta * 16
1251                  *              = Delta << 4
1252                  */
1253                 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1254
1255                 /*
1256                  * Check if threshold is exceeded. If the threshold is
1257                  * permanently exceeded every 28125 ms an event will be
1258                  * generated to remind the user of this condition.
1259                  */
1260                 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1261                         (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1262                         pAC->Pnmi.RlmtChangeThreshold)) {
1263
1264                         QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1265                         (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1266                 }
1267
1268                 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1269                 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1270                         28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1271                         EventParam);
1272                 break;
1273
1274         case SK_PNMI_EVT_CLEAR_COUNTER:
1275                 /*
1276                  *  Param.Para32[0] contains the NetIndex (0 ..1).
1277                  *  Param.Para32[1] is reserved, contains -1.
1278                  */
1279                 NetIndex = (SK_U32)Param.Para32[0];
1280
1281 #ifdef DEBUG
1282                 if (NetIndex >= pAC->Rlmt.NumNets) {
1283
1284                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1285                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1286                                 NetIndex));
1287
1288                         return (0);
1289                 }
1290 #endif /* DEBUG */
1291
1292                 /*
1293                  * Set all counters and timestamps to zero.
1294                  * The according NetIndex is required as a
1295                  * parameter of the event.
1296                  */
1297                 ResetCounter(pAC, IoC, NetIndex);
1298                 break;
1299
1300         case SK_PNMI_EVT_XMAC_RESET:
1301                 /*
1302                  * To grant continuous counter values store the current
1303                  * XMAC statistic values to the entries 1..n of the
1304                  * CounterOffset array. XMAC Errata #2
1305                  */
1306 #ifdef DEBUG
1307                 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1308
1309                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1310                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1311                                 (unsigned int)Param.Para64));
1312                         return (0);
1313                 }
1314 #endif
1315                 PhysPortIndex = (unsigned int)Param.Para64;
1316
1317                 /*
1318                  * Update XMAC statistic to get fresh values
1319                  */
1320                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1321                 if (Ret != SK_PNMI_ERR_OK) {
1322
1323                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1324                         return (0);
1325                 }
1326                 /*
1327                  * Increment semaphore to indicate that an update was
1328                  * already done
1329                  */
1330                 pAC->Pnmi.MacUpdatedFlag ++;
1331
1332                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1333                         CounterIndex ++) {
1334
1335                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
1336
1337                                 continue;
1338                         }
1339
1340                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1341                                 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1342                         
1343                         pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1344                 }
1345
1346                 pAC->Pnmi.MacUpdatedFlag --;
1347                 break;
1348
1349         case SK_PNMI_EVT_RLMT_PORT_UP:
1350                 PhysPortIndex = (unsigned int)Param.Para32[0];
1351 #ifdef DEBUG
1352                 if (PhysPortIndex >= SK_MAX_MACS) {
1353
1354                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1355                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1356                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1357
1358                         return (0);
1359                 }
1360 #endif /* DEBUG */
1361
1362                 /*
1363                  * Store a trap message in the trap buffer and generate an event for
1364                  * user space applications with the SK_DRIVER_SENDEVENT macro.
1365                  */
1366                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1367                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1368
1369                 /* Bugfix for XMAC errata (#10620)*/
1370                 if (MacType == SK_MAC_XMAC) {
1371                         /* Add incremental difference to offset (#10620)*/
1372                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1373                                 XM_RXE_SHT_ERR, &Val32);
1374                         
1375                         Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1376                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1377                         pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1378                                 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1379                 }
1380                 
1381                 /* Tell VctStatus() that a link was up meanwhile. */
1382                 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;         
1383                 break;
1384
1385     case SK_PNMI_EVT_RLMT_PORT_DOWN:
1386                 PhysPortIndex = (unsigned int)Param.Para32[0];
1387
1388 #ifdef DEBUG
1389                 if (PhysPortIndex >= SK_MAX_MACS) {
1390
1391                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1392                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1393                  " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1394
1395                         return (0);
1396                 }
1397 #endif /* DEBUG */
1398
1399                 /*
1400                  * Store a trap message in the trap buffer and generate an event for
1401                  * user space applications with the SK_DRIVER_SENDEVENT macro.
1402                  */
1403                 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1404                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1405
1406                 /* Bugfix #10620 - get zero level for incremental difference */
1407                 if (MacType == SK_MAC_XMAC) {
1408
1409                         (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1410                                 XM_RXE_SHT_ERR, &Val32);
1411                         
1412                         pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1413                                 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1414                                  CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1415                 }
1416                 break;
1417
1418         case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1419                 PhysPortIndex = (unsigned int)Param.Para32[0];
1420                 NetIndex = (SK_U32)Param.Para32[1];
1421
1422 #ifdef DEBUG
1423                 if (PhysPortIndex >= SK_MAX_MACS) {
1424
1425                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1426                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1427                                 PhysPortIndex));
1428                 }
1429
1430                 if (NetIndex >= pAC->Rlmt.NumNets) {
1431
1432                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1433                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1434                                 NetIndex));
1435                 }
1436 #endif /* DEBUG */
1437
1438                 /*
1439                  * For now, ignore event if NetIndex != 0.
1440                  */
1441                 if (Param.Para32[1] != 0) {
1442
1443                         return (0);
1444                 }
1445
1446                 /*
1447                  * Nothing to do if port is already inactive
1448                  */
1449                 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1450
1451                         return (0);
1452                 }
1453
1454                 /*
1455                  * Update statistic counters to calculate new offset for the virtual
1456                  * port and increment semaphore to indicate that an update was already
1457                  * done.
1458                  */
1459                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1460                         SK_PNMI_ERR_OK) {
1461
1462                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1463                         return (0);
1464                 }
1465                 pAC->Pnmi.MacUpdatedFlag ++;
1466
1467                 /*
1468                  * Calculate new counter offset for virtual port to grant continous
1469                  * counting on port switches. The virtual port consists of all currently
1470                  * active ports. The port down event indicates that a port is removed
1471                  * from the virtual port. Therefore add the counter value of the removed
1472                  * port to the CounterOffset for the virtual port to grant the same
1473                  * counter value.
1474                  */
1475                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1476                         CounterIndex ++) {
1477
1478                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
1479
1480                                 continue;
1481                         }
1482
1483                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1484
1485                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1486                 }
1487
1488                 /*
1489                  * Set port to inactive
1490                  */
1491                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1492
1493                 pAC->Pnmi.MacUpdatedFlag --;
1494                 break;
1495
1496         case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1497                 PhysPortIndex = (unsigned int)Param.Para32[0];
1498                 NetIndex = (SK_U32)Param.Para32[1];
1499
1500 #ifdef DEBUG
1501                 if (PhysPortIndex >= SK_MAX_MACS) {
1502
1503                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1504                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1505                                 PhysPortIndex));
1506                 }
1507
1508                 if (NetIndex >= pAC->Rlmt.NumNets) {
1509
1510                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1511                                 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1512                                 NetIndex));
1513                 }
1514 #endif /* DEBUG */
1515
1516                 /*
1517                  * For now, ignore event if NetIndex != 0.
1518                  */
1519                 if (Param.Para32[1] != 0) {
1520
1521                         return (0);
1522                 }
1523
1524                 /*
1525                  * Nothing to do if port is already active
1526                  */
1527                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1528
1529                         return (0);
1530                 }
1531
1532                 /*
1533                  * Statistic maintenance
1534                  */
1535                 pAC->Pnmi.RlmtChangeCts ++;
1536                 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1537
1538                 /*
1539                  * Store a trap message in the trap buffer and generate an event for
1540                  * user space applications with the SK_DRIVER_SENDEVENT macro.
1541                  */
1542                 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1543                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1544
1545                 /*
1546                  * Update statistic counters to calculate new offset for the virtual
1547                  * port and increment semaphore to indicate that an update was
1548                  * already done.
1549                  */
1550                 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1551                         SK_PNMI_ERR_OK) {
1552
1553                         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1554                         return (0);
1555                 }
1556                 pAC->Pnmi.MacUpdatedFlag ++;
1557
1558                 /*
1559                  * Calculate new counter offset for virtual port to grant continous
1560                  * counting on port switches. A new port is added to the virtual port.
1561                  * Therefore substract the counter value of the new port from the
1562                  * CounterOffset for the virtual port to grant the same value.
1563                  */
1564                 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1565                         CounterIndex ++) {
1566
1567                         if (!StatAddr[CounterIndex][MacType].GetOffset) {
1568
1569                                 continue;
1570                         }
1571
1572                         Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1573
1574                         pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1575                 }
1576
1577                 /* Set port to active */
1578                 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1579
1580                 pAC->Pnmi.MacUpdatedFlag --;
1581                 break;
1582
1583         case SK_PNMI_EVT_RLMT_SEGMENTATION:
1584                 /*
1585                  * Para.Para32[0] contains the NetIndex.
1586                  */
1587
1588                 /*
1589                  * Store a trap message in the trap buffer and generate an event for
1590                  * user space applications with the SK_DRIVER_SENDEVENT macro.
1591                  */
1592                 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1593                 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1594                 break;
1595
1596     case SK_PNMI_EVT_RLMT_SET_NETS:
1597                 /*
1598                  *  Param.Para32[0] contains the number of Nets.
1599                  *  Param.Para32[1] is reserved, contains -1.
1600                  */
1601             /*
1602          * Check number of nets
1603                  */
1604                 MaxNetNumber = pAC->GIni.GIMacsFound;
1605                 if (((unsigned int)Param.Para32[0] < 1)
1606                         || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1607                         return (SK_PNMI_ERR_UNKNOWN_NET);
1608                 }
1609
1610         if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1611                 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1612         }
1613         else { /* dual net mode */
1614                 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1615         }
1616         break;
1617
1618     case SK_PNMI_EVT_VCT_RESET:
1619                 PhysPortIndex = Param.Para32[0];
1620                 pPrt = &pAC->GIni.GP[PhysPortIndex];
1621                 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1622                 
1623                 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1624                         RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1625                         if (RetCode == 2) {
1626                                 /*
1627                                  * VCT test is still running.
1628                                  * Start VCT timer counter again.
1629                                  */
1630                                 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1631                                 Param.Para32[0] = PhysPortIndex;
1632                                 Param.Para32[1] = -1;
1633                                 SkTimerStart(pAC, IoC,
1634                                         &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1635                                 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1636                                 break;
1637                         }
1638                         pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1639                         pAC->Pnmi.VctStatus[PhysPortIndex] |=
1640                                 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1641                         
1642                         /* Copy results for later use to PNMI struct. */
1643                         for (i = 0; i < 4; i++)  {
1644                                 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1645                                         if ((pPrt->PMdiPairLen[i] > 35) &&
1646                                                 (pPrt->PMdiPairLen[i] < 0xff)) {
1647                                                 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1648                                         }
1649                                 }
1650                                 if ((pPrt->PMdiPairLen[i] > 35) &&
1651                                         (pPrt->PMdiPairLen[i] != 0xff)) {
1652                                         CableLength = 1000 *
1653                                                 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1654                                 }
1655                                 else {
1656                                         CableLength = 0;
1657                                 }
1658                                 pVctBackupData->PMdiPairLen[i] = CableLength;
1659                                 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1660                         }
1661                         
1662                         Param.Para32[0] = PhysPortIndex;
1663                         Param.Para32[1] = -1;
1664                         SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1665                         SkEventDispatcher(pAC, IoC);
1666                 }
1667                 
1668                 break;
1669
1670         default:
1671                 break;
1672         }
1673
1674         SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1675         return (0);
1676 }
1677
1678
1679 /******************************************************************************
1680  *
1681  * Private functions
1682  *
1683  */
1684
1685 /*****************************************************************************
1686  *
1687  * PnmiVar - Gets, presets, and sets single OIDs
1688  *
1689  * Description:
1690  *      Looks up the requested OID, calls the corresponding handler
1691  *      function, and passes the parameters with the get, preset, or
1692  *      set command. The function is called by SkGePnmiGetVar,
1693  *      SkGePnmiPreSetVar, or SkGePnmiSetVar.
1694  *
1695  * Returns:
1696  *      SK_PNMI_ERR_XXX. For details have a look at the description of the
1697  *      calling functions.
1698  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
1699  */
1700 PNMI_STATIC int PnmiVar(
1701 SK_AC *pAC,             /* Pointer to adapter context */
1702 SK_IOC IoC,             /* IO context handle */
1703 int Action,             /* GET/PRESET/SET action */
1704 SK_U32 Id,              /* Object ID that is to be processed */
1705 char *pBuf,             /* Buffer used for the management data transfer */
1706 unsigned int *pLen,     /* Total length of pBuf management data  */
1707 SK_U32 Instance,        /* Instance (1..n) that is to be set or -1 */
1708 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
1709 {
1710         unsigned int    TableIndex;
1711         int             Ret;
1712
1713
1714         if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1715
1716                 *pLen = 0;
1717                 return (SK_PNMI_ERR_UNKNOWN_OID);
1718         }
1719         
1720     /* Check NetIndex */
1721         if (NetIndex >= pAC->Rlmt.NumNets) {
1722                 return (SK_PNMI_ERR_UNKNOWN_NET);
1723         }
1724
1725         SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1726
1727         Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1728                 Instance, TableIndex, NetIndex);
1729
1730         SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1731
1732         return (Ret);
1733 }
1734
1735 /*****************************************************************************
1736  *
1737  * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1738  *
1739  * Description:
1740  *      The return value of the function will also be stored in
1741  *      SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1742  *      SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1743  *      checks which OIDs are able to set, and calls the handler function of
1744  *      the OID to perform the set. The return value of the function will
1745  *      also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1746  *      minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1747  *      by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1748  *
1749  * Returns:
1750  *      SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1751  *      SK_PNMI_ERR_UNKNOWN_NET  The requested NetIndex doesn't exist
1752  */
1753 PNMI_STATIC int PnmiStruct(
1754 SK_AC *pAC,             /* Pointer to adapter context */
1755 SK_IOC IoC,             /* IO context handle */
1756 int  Action,    /* PRESET/SET action to be performed */
1757 char *pBuf,             /* Buffer used for the management data transfer */
1758 unsigned int *pLen,     /* Length of pBuf management data buffer */
1759 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
1760 {
1761         int             Ret;
1762         unsigned int    TableIndex;
1763         unsigned int    DstOffset;
1764         unsigned int    Len;
1765         unsigned int    InstanceNo;
1766         unsigned int    InstanceCnt;
1767         SK_U32          Instance;
1768         SK_U32          Id;
1769
1770
1771         /* Check if the passed buffer has the right size */
1772         if (*pLen < SK_PNMI_STRUCT_SIZE) {
1773
1774                 /* Check if we can return the error within the buffer */
1775                 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1776
1777                         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1778                                 (SK_U32)(-1));
1779                 }
1780
1781                 *pLen = SK_PNMI_STRUCT_SIZE;
1782                 return (SK_PNMI_ERR_TOO_SHORT);
1783         }
1784         
1785     /* Check NetIndex */
1786         if (NetIndex >= pAC->Rlmt.NumNets) {
1787                 return (SK_PNMI_ERR_UNKNOWN_NET);
1788         }
1789         
1790         SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1791
1792         /*
1793          * Update the values of RLMT and SIRQ and increment semaphores to
1794          * indicate that an update was already done.
1795          */
1796         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1797
1798                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1799                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1800                 return (Ret);
1801         }
1802
1803         if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1804
1805                 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1806                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1807                 return (Ret);
1808         }
1809
1810         pAC->Pnmi.RlmtUpdatedFlag ++;
1811         pAC->Pnmi.SirqUpdatedFlag ++;
1812
1813         /* Preset/Set values */
1814         for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1815
1816                 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1817                         (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1818
1819                         continue;
1820                 }
1821
1822                 InstanceNo = IdTable[TableIndex].InstanceNo;
1823                 Id = IdTable[TableIndex].Id;
1824
1825                 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1826                         InstanceCnt ++) {
1827
1828                         DstOffset = IdTable[TableIndex].Offset +
1829                                 (InstanceCnt - 1) *
1830                                 IdTable[TableIndex].StructSize;
1831
1832                         /*
1833                          * Because VPD multiple instance variables are
1834                          * not setable we do not need to evaluate VPD
1835                          * instances. Have a look to VPD instance
1836                          * calculation in SkPnmiGetStruct().
1837                          */
1838                         Instance = (SK_U32)InstanceCnt;
1839
1840                         /*
1841                          * Evaluate needed buffer length
1842                          */
1843                         Len = 0;
1844                         Ret = IdTable[TableIndex].Func(pAC, IoC,
1845                                 SK_PNMI_GET, IdTable[TableIndex].Id,
1846                                 NULL, &Len, Instance, TableIndex, NetIndex);
1847
1848                         if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1849
1850                                 break;
1851                         }
1852                         if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1853
1854                                 pAC->Pnmi.RlmtUpdatedFlag --;
1855                                 pAC->Pnmi.SirqUpdatedFlag --;
1856
1857                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1858                                 SK_PNMI_SET_STAT(pBuf,
1859                                         SK_PNMI_ERR_GENERAL, DstOffset);
1860                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1861                                 return (SK_PNMI_ERR_GENERAL);
1862                         }
1863                         if (Id == OID_SKGE_VPD_ACTION) {
1864
1865                                 switch (*(pBuf + DstOffset)) {
1866
1867                                 case SK_PNMI_VPD_CREATE:
1868                                         Len = 3 + *(pBuf + DstOffset + 3);
1869                                         break;
1870
1871                                 case SK_PNMI_VPD_DELETE:
1872                                         Len = 3;
1873                                         break;
1874
1875                                 default:
1876                                         Len = 1;
1877                                         break;
1878                                 }
1879                         }
1880
1881                         /* Call the OID handler function */
1882                         Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1883                                 IdTable[TableIndex].Id, pBuf + DstOffset,
1884                                 &Len, Instance, TableIndex, NetIndex);
1885
1886                         if (Ret != SK_PNMI_ERR_OK) {
1887
1888                                 pAC->Pnmi.RlmtUpdatedFlag --;
1889                                 pAC->Pnmi.SirqUpdatedFlag --;
1890
1891                                 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1892                                 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1893                                         DstOffset);
1894                                 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1895                                 return (SK_PNMI_ERR_BAD_VALUE);
1896                         }
1897                 }
1898         }
1899
1900         pAC->Pnmi.RlmtUpdatedFlag --;
1901         pAC->Pnmi.SirqUpdatedFlag --;
1902
1903         SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1904         SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1905         return (SK_PNMI_ERR_OK);
1906 }
1907
1908 /*****************************************************************************
1909  *
1910  * LookupId - Lookup an OID in the IdTable
1911  *
1912  * Description:
1913  *      Scans the IdTable to find the table entry of an OID.
1914  *
1915  * Returns:
1916  *      The table index or -1 if not found.
1917  */
1918 PNMI_STATIC int LookupId(
1919 SK_U32 Id)              /* Object identifier to be searched */
1920 {
1921         int i;
1922
1923         for (i = 0; i < ID_TABLE_SIZE; i++) {
1924
1925                 if (IdTable[i].Id == Id) {
1926
1927                         return i;
1928                 }
1929         }
1930
1931         return (-1);
1932 }
1933
1934 /*****************************************************************************
1935  *
1936  * OidStruct - Handler of OID_SKGE_ALL_DATA
1937  *
1938  * Description:
1939  *      This OID performs a Get/Preset/SetStruct call and returns all data
1940  *      in a SK_PNMI_STRUCT_DATA structure.
1941  *
1942  * Returns:
1943  *      SK_PNMI_ERR_OK           The request was successfully performed.
1944  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
1945  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
1946  *                               the correct data (e.g. a 32bit value is
1947  *                               needed, but a 16 bit value was passed).
1948  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
1949  *                               value range.
1950  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
1951  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1952  *                           exist (e.g. port instance 3 on a two port
1953  *                               adapter.
1954  */
1955 PNMI_STATIC int OidStruct(
1956 SK_AC *pAC,             /* Pointer to adapter context */
1957 SK_IOC IoC,             /* IO context handle */
1958 int Action,             /* GET/PRESET/SET action */
1959 SK_U32 Id,              /* Object ID that is to be processed */
1960 char *pBuf,             /* Buffer used for the management data transfer */
1961 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
1962 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
1963 unsigned int TableIndex, /* Index to the Id table */
1964 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
1965 {
1966         if (Id != OID_SKGE_ALL_DATA) {
1967
1968                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1969                         SK_PNMI_ERR003MSG);
1970
1971                 *pLen = 0;
1972                 return (SK_PNMI_ERR_GENERAL);
1973         }
1974
1975         /*
1976          * Check instance. We only handle single instance variables
1977          */
1978         if (Instance != (SK_U32)(-1) && Instance != 1) {
1979
1980                 *pLen = 0;
1981                 return (SK_PNMI_ERR_UNKNOWN_INST);
1982         }
1983
1984         switch (Action) {
1985
1986         case SK_PNMI_GET:
1987                 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1988
1989         case SK_PNMI_PRESET:
1990                 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1991
1992         case SK_PNMI_SET:
1993                 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1994         }
1995
1996         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1997
1998         *pLen = 0;
1999         return (SK_PNMI_ERR_GENERAL);
2000 }
2001
2002 /*****************************************************************************
2003  *
2004  * Perform - OID handler of OID_SKGE_ACTION
2005  *
2006  * Description:
2007  *      None.
2008  *
2009  * Returns:
2010  *      SK_PNMI_ERR_OK           The request was successfully performed.
2011  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2012  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2013  *                               the correct data (e.g. a 32bit value is
2014  *                               needed, but a 16 bit value was passed).
2015  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
2016  *                               value range.
2017  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
2018  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2019  *                           exist (e.g. port instance 3 on a two port
2020  *                               adapter.
2021  */
2022 PNMI_STATIC int Perform(
2023 SK_AC *pAC,             /* Pointer to adapter context */
2024 SK_IOC IoC,             /* IO context handle */
2025 int Action,             /* GET/PRESET/SET action */
2026 SK_U32 Id,              /* Object ID that is to be processed */
2027 char *pBuf,             /* Buffer used for the management data transfer */
2028 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2029 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2030 unsigned int TableIndex, /* Index to the Id table */
2031 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2032 {
2033         int     Ret;
2034         SK_U32  ActionOp;
2035
2036
2037         /*
2038          * Check instance. We only handle single instance variables
2039          */
2040         if (Instance != (SK_U32)(-1) && Instance != 1) {
2041
2042                 *pLen = 0;
2043                 return (SK_PNMI_ERR_UNKNOWN_INST);
2044         }
2045
2046         if (*pLen < sizeof(SK_U32)) {
2047
2048                 *pLen = sizeof(SK_U32);
2049                 return (SK_PNMI_ERR_TOO_SHORT);
2050         }
2051
2052         /* Check if a get should be performed */
2053         if (Action == SK_PNMI_GET) {
2054
2055                 /* A get is easy. We always return the same value */
2056                 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2057                 SK_PNMI_STORE_U32(pBuf, ActionOp);
2058                 *pLen = sizeof(SK_U32);
2059
2060                 return (SK_PNMI_ERR_OK);
2061         }
2062
2063         /* Continue with PRESET/SET action */
2064         if (*pLen > sizeof(SK_U32)) {
2065
2066                 return (SK_PNMI_ERR_BAD_VALUE);
2067         }
2068
2069         /* Check if the command is a known one */
2070         SK_PNMI_READ_U32(pBuf, ActionOp);
2071         if (*pLen > sizeof(SK_U32) ||
2072                 (ActionOp != SK_PNMI_ACT_IDLE &&
2073                 ActionOp != SK_PNMI_ACT_RESET &&
2074                 ActionOp != SK_PNMI_ACT_SELFTEST &&
2075                 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2076
2077                 *pLen = 0;
2078                 return (SK_PNMI_ERR_BAD_VALUE);
2079         }
2080
2081         /* A preset ends here */
2082         if (Action == SK_PNMI_PRESET) {
2083
2084                 return (SK_PNMI_ERR_OK);
2085         }
2086
2087         switch (ActionOp) {
2088
2089         case SK_PNMI_ACT_IDLE:
2090                 /* Nothing to do */
2091                 break;
2092
2093         case SK_PNMI_ACT_RESET:
2094                 /*
2095                  * Perform a driver reset or something that comes near
2096                  * to this.
2097                  */
2098                 Ret = SK_DRIVER_RESET(pAC, IoC);
2099                 if (Ret != 0) {
2100
2101                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2102                                 SK_PNMI_ERR005MSG);
2103
2104                         return (SK_PNMI_ERR_GENERAL);
2105                 }
2106                 break;
2107
2108         case SK_PNMI_ACT_SELFTEST:
2109                 /*
2110                  * Perform a driver selftest or something similar to this.
2111                  * Currently this feature is not used and will probably
2112                  * implemented in another way.
2113                  */
2114                 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2115                 pAC->Pnmi.TestResult = Ret;
2116                 break;
2117
2118         case SK_PNMI_ACT_RESETCNT:
2119                 /* Set all counters and timestamps to zero */
2120                 ResetCounter(pAC, IoC, NetIndex);
2121                 break;
2122
2123         default:
2124                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2125                         SK_PNMI_ERR006MSG);
2126
2127                 return (SK_PNMI_ERR_GENERAL);
2128         }
2129
2130         return (SK_PNMI_ERR_OK);
2131 }
2132
2133 /*****************************************************************************
2134  *
2135  * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2136  *
2137  * Description:
2138  *      Retrieves the statistic values of the virtual port (logical
2139  *      index 0). Only special OIDs of NDIS are handled which consist
2140  *      of a 32 bit instead of a 64 bit value. The OIDs are public
2141  *      because perhaps some other platform can use them too.
2142  *
2143  * Returns:
2144  *      SK_PNMI_ERR_OK           The request was successfully performed.
2145  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2146  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2147  *                               the correct data (e.g. a 32bit value is
2148  *                               needed, but a 16 bit value was passed).
2149  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2150  *                           exist (e.g. port instance 3 on a two port
2151  *                               adapter.
2152  */
2153 PNMI_STATIC int Mac8023Stat(
2154 SK_AC *pAC,             /* Pointer to adapter context */
2155 SK_IOC IoC,             /* IO context handle */
2156 int Action,             /* GET/PRESET/SET action */
2157 SK_U32 Id,              /* Object ID that is to be processed */
2158 char *pBuf,             /* Buffer used for the management data transfer */
2159 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2160 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2161 unsigned int TableIndex,        /* Index to the Id table */
2162 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2163 {
2164         int     Ret;
2165         SK_U64  StatVal;
2166         SK_U32  StatVal32;
2167         SK_BOOL Is64BitReq = SK_FALSE;
2168
2169         /*
2170          * Only the active Mac is returned
2171          */
2172         if (Instance != (SK_U32)(-1) && Instance != 1) {
2173
2174                 *pLen = 0;
2175                 return (SK_PNMI_ERR_UNKNOWN_INST);
2176         }
2177
2178         /*
2179          * Check action type
2180          */
2181         if (Action != SK_PNMI_GET) {
2182
2183                 *pLen = 0;
2184                 return (SK_PNMI_ERR_READ_ONLY);
2185         }
2186
2187         /* Check length */
2188         switch (Id) {
2189
2190         case OID_802_3_PERMANENT_ADDRESS:
2191         case OID_802_3_CURRENT_ADDRESS:
2192                 if (*pLen < sizeof(SK_MAC_ADDR)) {
2193
2194                         *pLen = sizeof(SK_MAC_ADDR);
2195                         return (SK_PNMI_ERR_TOO_SHORT);
2196                 }
2197                 break;
2198
2199         default:
2200 #ifndef SK_NDIS_64BIT_CTR
2201                 if (*pLen < sizeof(SK_U32)) {
2202                         *pLen = sizeof(SK_U32);
2203                         return (SK_PNMI_ERR_TOO_SHORT);
2204                 }
2205
2206 #else /* SK_NDIS_64BIT_CTR */
2207
2208                 /* for compatibility, at least 32bit are required for OID */
2209                 if (*pLen < sizeof(SK_U32)) {
2210                         /*
2211                         * but indicate handling for 64bit values,
2212                         * if insufficient space is provided
2213                         */
2214                         *pLen = sizeof(SK_U64);
2215                         return (SK_PNMI_ERR_TOO_SHORT);
2216                 }
2217
2218                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2219 #endif /* SK_NDIS_64BIT_CTR */
2220                 break;
2221         }
2222
2223         /*
2224          * Update all statistics, because we retrieve virtual MAC, which
2225          * consists of multiple physical statistics and increment semaphore
2226          * to indicate that an update was already done.
2227          */
2228         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2229         if ( Ret != SK_PNMI_ERR_OK) {
2230
2231                 *pLen = 0;
2232                 return (Ret);
2233         }
2234         pAC->Pnmi.MacUpdatedFlag ++;
2235
2236         /*
2237          * Get value (MAC Index 0 identifies the virtual MAC)
2238          */
2239         switch (Id) {
2240
2241         case OID_802_3_PERMANENT_ADDRESS:
2242                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2243                 *pLen = sizeof(SK_MAC_ADDR);
2244                 break;
2245
2246         case OID_802_3_CURRENT_ADDRESS:
2247                 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2248                 *pLen = sizeof(SK_MAC_ADDR);
2249                 break;
2250
2251         default:
2252                 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2253
2254                 /* by default 32bit values are evaluated */
2255                 if (!Is64BitReq) {
2256                         StatVal32 = (SK_U32)StatVal;
2257                         SK_PNMI_STORE_U32(pBuf, StatVal32);
2258                         *pLen = sizeof(SK_U32);
2259                 }
2260                 else {
2261                         SK_PNMI_STORE_U64(pBuf, StatVal);
2262                         *pLen = sizeof(SK_U64);
2263                 }
2264                 break;
2265         }
2266
2267         pAC->Pnmi.MacUpdatedFlag --;
2268
2269         return (SK_PNMI_ERR_OK);
2270 }
2271
2272 /*****************************************************************************
2273  *
2274  * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2275  *
2276  * Description:
2277  *      Retrieves the MAC statistic data.
2278  *
2279  * Returns:
2280  *      SK_PNMI_ERR_OK           The request was successfully performed.
2281  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2282  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2283  *                               the correct data (e.g. a 32bit value is
2284  *                               needed, but a 16 bit value was passed).
2285  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2286  *                           exist (e.g. port instance 3 on a two port
2287  *                               adapter.
2288  */
2289 PNMI_STATIC int MacPrivateStat(
2290 SK_AC *pAC,             /* Pointer to adapter context */
2291 SK_IOC IoC,             /* IO context handle */
2292 int Action,             /* GET/PRESET/SET action */
2293 SK_U32 Id,              /* Object ID that is to be processed */
2294 char *pBuf,             /* Buffer used for the management data transfer */
2295 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2296 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2297 unsigned int TableIndex, /* Index to the Id table */
2298 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2299 {
2300         unsigned int    LogPortMax;
2301         unsigned int    LogPortIndex;
2302         unsigned int    PhysPortMax;
2303         unsigned int    Limit;
2304         unsigned int    Offset;
2305         int                             MacType;
2306         int                             Ret;
2307         SK_U64                  StatVal;
2308         
2309         
2310
2311         /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2312         PhysPortMax = pAC->GIni.GIMacsFound;
2313         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2314         
2315         MacType = pAC->GIni.GIMacType;
2316
2317         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2318                 LogPortMax--;
2319         }
2320
2321         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2322                 /* Check instance range */
2323                 if ((Instance < 1) || (Instance > LogPortMax)) {
2324
2325                         *pLen = 0;
2326                         return (SK_PNMI_ERR_UNKNOWN_INST);
2327                 }
2328                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2329                 Limit = LogPortIndex + 1;
2330         }
2331
2332         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2333
2334                 LogPortIndex = 0;
2335                 Limit = LogPortMax;
2336         }
2337
2338         /* Check action */
2339         if (Action != SK_PNMI_GET) {
2340
2341                 *pLen = 0;
2342                 return (SK_PNMI_ERR_READ_ONLY);
2343         }
2344
2345         /* Check length */
2346         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2347
2348                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2349                 return (SK_PNMI_ERR_TOO_SHORT);
2350         }
2351
2352         /*
2353          * Update MAC statistic and increment semaphore to indicate that
2354          * an update was already done.
2355          */
2356         Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2357         if (Ret != SK_PNMI_ERR_OK) {
2358
2359                 *pLen = 0;
2360                 return (Ret);
2361         }
2362         pAC->Pnmi.MacUpdatedFlag ++;
2363
2364         /* Get value */
2365         Offset = 0;
2366         for (; LogPortIndex < Limit; LogPortIndex ++) {
2367
2368                 switch (Id) {
2369
2370 /* XXX not yet implemented due to XMAC problems
2371                 case OID_SKGE_STAT_TX_UTIL:
2372                         return (SK_PNMI_ERR_GENERAL);
2373 */
2374 /* XXX not yet implemented due to XMAC problems
2375                 case OID_SKGE_STAT_RX_UTIL:
2376                         return (SK_PNMI_ERR_GENERAL);
2377 */
2378                 case OID_SKGE_STAT_RX:
2379                         if (MacType == SK_MAC_GMAC) {
2380                                 StatVal =
2381                                         GetStatVal(pAC, IoC, LogPortIndex,
2382                                                            SK_PNMI_HRX_BROADCAST, NetIndex) +
2383                                         GetStatVal(pAC, IoC, LogPortIndex,
2384                                                            SK_PNMI_HRX_MULTICAST, NetIndex) +
2385                                         GetStatVal(pAC, IoC, LogPortIndex,
2386                                                            SK_PNMI_HRX_UNICAST, NetIndex) +
2387                                         GetStatVal(pAC, IoC, LogPortIndex,
2388                                                            SK_PNMI_HRX_UNDERSIZE, NetIndex);
2389                         }
2390                         else {
2391                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2392                                         IdTable[TableIndex].Param, NetIndex);
2393                         }
2394                         break;
2395
2396                 case OID_SKGE_STAT_TX:
2397                         if (MacType == SK_MAC_GMAC) {
2398                                 StatVal =
2399                                         GetStatVal(pAC, IoC, LogPortIndex,
2400                                                            SK_PNMI_HTX_BROADCAST, NetIndex) +
2401                                         GetStatVal(pAC, IoC, LogPortIndex,
2402                                                            SK_PNMI_HTX_MULTICAST, NetIndex) +
2403                                         GetStatVal(pAC, IoC, LogPortIndex,
2404                                                            SK_PNMI_HTX_UNICAST, NetIndex);
2405                         }
2406                         else {
2407                                 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2408                                         IdTable[TableIndex].Param, NetIndex);
2409                         }
2410                         break;
2411
2412                 default:
2413                         StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2414                                 IdTable[TableIndex].Param, NetIndex);
2415                 }
2416                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2417
2418                 Offset += sizeof(SK_U64);
2419         }
2420         *pLen = Offset;
2421
2422         pAC->Pnmi.MacUpdatedFlag --;
2423
2424         return (SK_PNMI_ERR_OK);
2425 }
2426
2427 /*****************************************************************************
2428  *
2429  * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2430  *
2431  * Description:
2432  *      Get/Presets/Sets the current and factory MAC address. The MAC
2433  *      address of the virtual port, which is reported to the OS, may
2434  *      not be changed, but the physical ones. A set to the virtual port
2435  *      will be ignored. No error should be reported because otherwise
2436  *      a multiple instance set (-1) would always fail.
2437  *
2438  * Returns:
2439  *      SK_PNMI_ERR_OK           The request was successfully performed.
2440  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2441  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2442  *                               the correct data (e.g. a 32bit value is
2443  *                               needed, but a 16 bit value was passed).
2444  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
2445  *                               value range.
2446  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
2447  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2448  *                           exist (e.g. port instance 3 on a two port
2449  *                               adapter.
2450  */
2451 PNMI_STATIC int Addr(
2452 SK_AC *pAC,             /* Pointer to adapter context */
2453 SK_IOC IoC,             /* IO context handle */
2454 int Action,             /* GET/PRESET/SET action */
2455 SK_U32 Id,              /* Object ID that is to be processed */
2456 char *pBuf,             /* Buffer used for the management data transfer */
2457 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2458 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2459 unsigned int TableIndex, /* Index to the Id table */
2460 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2461 {
2462         int             Ret;
2463         unsigned int    LogPortMax;
2464         unsigned int    PhysPortMax;
2465         unsigned int    LogPortIndex;
2466         unsigned int    PhysPortIndex;
2467         unsigned int    Limit;
2468         unsigned int    Offset = 0;
2469
2470         /*
2471          * Calculate instance if wished. MAC index 0 is the virtual
2472          * MAC.
2473          */
2474         PhysPortMax = pAC->GIni.GIMacsFound;
2475         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2476
2477         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2478                 LogPortMax--;
2479         }
2480
2481         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2482                 /* Check instance range */
2483                 if ((Instance < 1) || (Instance > LogPortMax)) {
2484
2485                         *pLen = 0;
2486                         return (SK_PNMI_ERR_UNKNOWN_INST);
2487                 }
2488                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2489                 Limit = LogPortIndex + 1;
2490         }
2491         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2492
2493                 LogPortIndex = 0;
2494                 Limit = LogPortMax;
2495         }
2496
2497         /*
2498          * Perform Action
2499          */
2500         if (Action == SK_PNMI_GET) {
2501
2502                 /* Check length */
2503                 if (*pLen < (Limit - LogPortIndex) * 6) {
2504
2505                         *pLen = (Limit - LogPortIndex) * 6;
2506                         return (SK_PNMI_ERR_TOO_SHORT);
2507                 }
2508
2509                 /*
2510                  * Get value
2511                  */
2512                 for (; LogPortIndex < Limit; LogPortIndex ++) {
2513
2514                         switch (Id) {
2515
2516                         case OID_SKGE_PHYS_CUR_ADDR:
2517                                 if (LogPortIndex == 0) {
2518                                         CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2519                                 }
2520                                 else {
2521                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2522
2523                                         CopyMac(pBuf + Offset,
2524                                                 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2525                                 }
2526                                 Offset += 6;
2527                                 break;
2528
2529                         case OID_SKGE_PHYS_FAC_ADDR:
2530                                 if (LogPortIndex == 0) {
2531                                         CopyMac(pBuf + Offset,
2532                                                 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2533                                 }
2534                                 else {
2535                                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2536                                                 pAC, LogPortIndex);
2537
2538                                         CopyMac(pBuf + Offset,
2539                                                 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2540                                 }
2541                                 Offset += 6;
2542                                 break;
2543
2544                         default:
2545                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2546                                         SK_PNMI_ERR008MSG);
2547
2548                                 *pLen = 0;
2549                                 return (SK_PNMI_ERR_GENERAL);
2550                         }
2551                 }
2552
2553                 *pLen = Offset;
2554         }
2555         else {
2556                 /*
2557                  * The logical MAC address may not be changed only
2558                  * the physical ones
2559                  */
2560                 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2561
2562                         *pLen = 0;
2563                         return (SK_PNMI_ERR_READ_ONLY);
2564                 }
2565
2566                 /*
2567                  * Only the current address may be changed
2568                  */
2569                 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2570
2571                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2572                                 SK_PNMI_ERR009MSG);
2573
2574                         *pLen = 0;
2575                         return (SK_PNMI_ERR_GENERAL);
2576                 }
2577
2578                 /* Check length */
2579                 if (*pLen < (Limit - LogPortIndex) * 6) {
2580
2581                         *pLen = (Limit - LogPortIndex) * 6;
2582                         return (SK_PNMI_ERR_TOO_SHORT);
2583                 }
2584                 if (*pLen > (Limit - LogPortIndex) * 6) {
2585
2586                         *pLen = 0;
2587                         return (SK_PNMI_ERR_BAD_VALUE);
2588                 }
2589
2590                 /*
2591                  * Check Action
2592                  */
2593                 if (Action == SK_PNMI_PRESET) {
2594
2595                         *pLen = 0;
2596                         return (SK_PNMI_ERR_OK);
2597                 }
2598
2599                 /*
2600                  * Set OID_SKGE_MAC_CUR_ADDR
2601                  */
2602                 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2603
2604                         /*
2605                          * A set to virtual port and set of broadcast
2606                          * address will be ignored
2607                          */
2608                         if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2609                                 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2610
2611                                 continue;
2612                         }
2613
2614                         PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2615                                 LogPortIndex);
2616
2617                         Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2618                                 (SK_MAC_ADDR *)(pBuf + Offset),
2619                                 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2620                                 SK_ADDR_PHYSICAL_ADDRESS));
2621                         if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2622
2623                                 return (SK_PNMI_ERR_GENERAL);
2624                         }
2625                 }
2626                 *pLen = Offset;
2627         }
2628
2629         return (SK_PNMI_ERR_OK);
2630 }
2631
2632 /*****************************************************************************
2633  *
2634  * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2635  *
2636  * Description:
2637  *      Retrieves the statistic values of the CSUM module. The CSUM data
2638  *      structure must be available in the SK_AC even if the CSUM module
2639  *      is not included, because PNMI reads the statistic data from the
2640  *      CSUM part of SK_AC directly.
2641  *
2642  * Returns:
2643  *      SK_PNMI_ERR_OK           The request was successfully performed.
2644  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2645  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2646  *                               the correct data (e.g. a 32bit value is
2647  *                               needed, but a 16 bit value was passed).
2648  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2649  *                           exist (e.g. port instance 3 on a two port
2650  *                               adapter.
2651  */
2652 PNMI_STATIC int CsumStat(
2653 SK_AC *pAC,             /* Pointer to adapter context */
2654 SK_IOC IoC,             /* IO context handle */
2655 int Action,             /* GET/PRESET/SET action */
2656 SK_U32 Id,              /* Object ID that is to be processed */
2657 char *pBuf,             /* Buffer used for the management data transfer */
2658 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2659 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2660 unsigned int TableIndex, /* Index to the Id table */
2661 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2662 {
2663         unsigned int    Index;
2664         unsigned int    Limit;
2665         unsigned int    Offset = 0;
2666         SK_U64          StatVal;
2667
2668
2669         /*
2670          * Calculate instance if wished
2671          */
2672         if (Instance != (SK_U32)(-1)) {
2673
2674                 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2675
2676                         *pLen = 0;
2677                         return (SK_PNMI_ERR_UNKNOWN_INST);
2678                 }
2679                 Index = (unsigned int)Instance - 1;
2680                 Limit = Index + 1;
2681         }
2682         else {
2683                 Index = 0;
2684                 Limit = SKCS_NUM_PROTOCOLS;
2685         }
2686
2687         /*
2688          * Check action
2689          */
2690         if (Action != SK_PNMI_GET) {
2691
2692                 *pLen = 0;
2693                 return (SK_PNMI_ERR_READ_ONLY);
2694         }
2695
2696         /* Check length */
2697         if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2698
2699                 *pLen = (Limit - Index) * sizeof(SK_U64);
2700                 return (SK_PNMI_ERR_TOO_SHORT);
2701         }
2702
2703         /*
2704          * Get value
2705          */
2706         for (; Index < Limit; Index ++) {
2707
2708                 switch (Id) {
2709
2710                 case OID_SKGE_CHKSM_RX_OK_CTS:
2711                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2712                         break;
2713
2714                 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2715                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2716                         break;
2717
2718                 case OID_SKGE_CHKSM_RX_ERR_CTS:
2719                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2720                         break;
2721
2722                 case OID_SKGE_CHKSM_TX_OK_CTS:
2723                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2724                         break;
2725
2726                 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2727                         StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2728                         break;
2729
2730                 default:
2731                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2732                                 SK_PNMI_ERR010MSG);
2733
2734                         *pLen = 0;
2735                         return (SK_PNMI_ERR_GENERAL);
2736                 }
2737
2738                 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2739                 Offset += sizeof(SK_U64);
2740         }
2741
2742         /*
2743          * Store used buffer space
2744          */
2745         *pLen = Offset;
2746
2747         return (SK_PNMI_ERR_OK);
2748 }
2749
2750 /*****************************************************************************
2751  *
2752  * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2753  *
2754  * Description:
2755  *      Retrieves the statistic values of the I2C module, which handles
2756  *      the temperature and voltage sensors.
2757  *
2758  * Returns:
2759  *      SK_PNMI_ERR_OK           The request was successfully performed.
2760  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
2761  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
2762  *                               the correct data (e.g. a 32bit value is
2763  *                               needed, but a 16 bit value was passed).
2764  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2765  *                           exist (e.g. port instance 3 on a two port
2766  *                               adapter.
2767  */
2768 PNMI_STATIC int SensorStat(
2769 SK_AC *pAC,             /* Pointer to adapter context */
2770 SK_IOC IoC,             /* IO context handle */
2771 int Action,             /* GET/PRESET/SET action */
2772 SK_U32 Id,              /* Object ID that is to be processed */
2773 char *pBuf,             /* Buffer used for the management data transfer */
2774 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
2775 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
2776 unsigned int TableIndex, /* Index to the Id table */
2777 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
2778 {
2779         unsigned int    i;
2780         unsigned int    Index;
2781         unsigned int    Limit;
2782         unsigned int    Offset;
2783         unsigned int    Len;
2784         SK_U32          Val32;
2785         SK_U64          Val64;
2786
2787
2788         /*
2789          * Calculate instance if wished
2790          */
2791         if ((Instance != (SK_U32)(-1))) {
2792
2793                 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2794
2795                         *pLen = 0;
2796                         return (SK_PNMI_ERR_UNKNOWN_INST);
2797                 }
2798
2799                 Index = (unsigned int)Instance -1;
2800                 Limit = (unsigned int)Instance;
2801         }
2802         else {
2803                 Index = 0;
2804                 Limit = (unsigned int) pAC->I2c.MaxSens;
2805         }
2806
2807         /*
2808          * Check action
2809          */
2810         if (Action != SK_PNMI_GET) {
2811
2812                 *pLen = 0;
2813                 return (SK_PNMI_ERR_READ_ONLY);
2814         }
2815
2816         /* Check length */
2817         switch (Id) {
2818
2819         case OID_SKGE_SENSOR_VALUE:
2820         case OID_SKGE_SENSOR_WAR_THRES_LOW:
2821         case OID_SKGE_SENSOR_WAR_THRES_UPP:
2822         case OID_SKGE_SENSOR_ERR_THRES_LOW:
2823         case OID_SKGE_SENSOR_ERR_THRES_UPP:
2824                 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2825
2826                         *pLen = (Limit - Index) * sizeof(SK_U32);
2827                         return (SK_PNMI_ERR_TOO_SHORT);
2828                 }
2829                 break;
2830
2831         case OID_SKGE_SENSOR_DESCR:
2832                 for (Offset = 0, i = Index; i < Limit; i ++) {
2833
2834                         Len = (unsigned int)
2835                                 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2836                         if (Len >= SK_PNMI_STRINGLEN2) {
2837
2838                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2839                                         SK_PNMI_ERR011MSG);
2840
2841                                 *pLen = 0;
2842                                 return (SK_PNMI_ERR_GENERAL);
2843                         }
2844                         Offset += Len;
2845                 }
2846                 if (*pLen < Offset) {
2847
2848                         *pLen = Offset;
2849                         return (SK_PNMI_ERR_TOO_SHORT);
2850                 }
2851                 break;
2852
2853         case OID_SKGE_SENSOR_INDEX:
2854         case OID_SKGE_SENSOR_TYPE:
2855         case OID_SKGE_SENSOR_STATUS:
2856                 if (*pLen < Limit - Index) {
2857
2858                         *pLen = Limit - Index;
2859                         return (SK_PNMI_ERR_TOO_SHORT);
2860                 }
2861                 break;
2862
2863         case OID_SKGE_SENSOR_WAR_CTS:
2864         case OID_SKGE_SENSOR_WAR_TIME:
2865         case OID_SKGE_SENSOR_ERR_CTS:
2866         case OID_SKGE_SENSOR_ERR_TIME:
2867                 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2868
2869                         *pLen = (Limit - Index) * sizeof(SK_U64);
2870                         return (SK_PNMI_ERR_TOO_SHORT);
2871                 }
2872                 break;
2873
2874         default:
2875                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2876                         SK_PNMI_ERR012MSG);
2877
2878                 *pLen = 0;
2879                 return (SK_PNMI_ERR_GENERAL);
2880
2881         }
2882
2883         /*
2884          * Get value
2885          */
2886         for (Offset = 0; Index < Limit; Index ++) {
2887
2888                 switch (Id) {
2889
2890                 case OID_SKGE_SENSOR_INDEX:
2891                         *(pBuf + Offset) = (char)Index;
2892                         Offset += sizeof(char);
2893                         break;
2894
2895                 case OID_SKGE_SENSOR_DESCR:
2896                         Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2897                         SK_MEMCPY(pBuf + Offset + 1,
2898                                 pAC->I2c.SenTable[Index].SenDesc, Len);
2899                         *(pBuf + Offset) = (char)Len;
2900                         Offset += Len + 1;
2901                         break;
2902
2903                 case OID_SKGE_SENSOR_TYPE:
2904                         *(pBuf + Offset) =
2905                                 (char)pAC->I2c.SenTable[Index].SenType;
2906                         Offset += sizeof(char);
2907                         break;
2908
2909                 case OID_SKGE_SENSOR_VALUE:
2910                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2911                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2912                         Offset += sizeof(SK_U32);
2913                         break;
2914
2915                 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2916                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2917                                 SenThreWarnLow;
2918                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2919                         Offset += sizeof(SK_U32);
2920                         break;
2921
2922                 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2923                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2924                                 SenThreWarnHigh;
2925                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2926                         Offset += sizeof(SK_U32);
2927                         break;
2928
2929                 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2930                         Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2931                                 SenThreErrLow;
2932                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2933                         Offset += sizeof(SK_U32);
2934                         break;
2935
2936                 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2937                         Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2938                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2939                         Offset += sizeof(SK_U32);
2940                         break;
2941
2942                 case OID_SKGE_SENSOR_STATUS:
2943                         *(pBuf + Offset) =
2944                                 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2945                         Offset += sizeof(char);
2946                         break;
2947
2948                 case OID_SKGE_SENSOR_WAR_CTS:
2949                         Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2950                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2951                         Offset += sizeof(SK_U64);
2952                         break;
2953
2954                 case OID_SKGE_SENSOR_ERR_CTS:
2955                         Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2956                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2957                         Offset += sizeof(SK_U64);
2958                         break;
2959
2960                 case OID_SKGE_SENSOR_WAR_TIME:
2961                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2962                                 SenBegWarnTS);
2963                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2964                         Offset += sizeof(SK_U64);
2965                         break;
2966
2967                 case OID_SKGE_SENSOR_ERR_TIME:
2968                         Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2969                                 SenBegErrTS);
2970                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2971                         Offset += sizeof(SK_U64);
2972                         break;
2973
2974                 default:
2975                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2976                                 ("SensorStat: Unknown OID should be handled before"));
2977
2978                         return (SK_PNMI_ERR_GENERAL);
2979                 }
2980         }
2981
2982         /*
2983          * Store used buffer space
2984          */
2985         *pLen = Offset;
2986
2987         return (SK_PNMI_ERR_OK);
2988 }
2989
2990 /*****************************************************************************
2991  *
2992  * Vpd - OID handler function of OID_SKGE_VPD_XXX
2993  *
2994  * Description:
2995  *      Get/preset/set of VPD data. As instance the name of a VPD key
2996  *      can be passed. The Instance parameter is a SK_U32 and can be
2997  *      used as a string buffer for the VPD key, because their maximum
2998  *      length is 4 byte.
2999  *
3000  * Returns:
3001  *      SK_PNMI_ERR_OK           The request was successfully performed.
3002  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
3003  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
3004  *                               the correct data (e.g. a 32bit value is
3005  *                               needed, but a 16 bit value was passed).
3006  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
3007  *                               value range.
3008  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
3009  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3010  *                           exist (e.g. port instance 3 on a two port
3011  *                               adapter.
3012  */
3013 PNMI_STATIC int Vpd(
3014 SK_AC *pAC,             /* Pointer to adapter context */
3015 SK_IOC IoC,             /* IO context handle */
3016 int Action,             /* GET/PRESET/SET action */
3017 SK_U32 Id,              /* Object ID that is to be processed */
3018 char *pBuf,             /* Buffer used for the management data transfer */
3019 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
3020 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
3021 unsigned int TableIndex, /* Index to the Id table */
3022 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
3023 {
3024         SK_VPD_STATUS   *pVpdStatus;
3025         unsigned int    BufLen;
3026         char            Buf[256];
3027         char            KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3028         char            KeyStr[SK_PNMI_VPD_KEY_SIZE];
3029         unsigned int    KeyNo;
3030         unsigned int    Offset;
3031         unsigned int    Index;
3032         unsigned int    FirstIndex;
3033         unsigned int    LastIndex;
3034         unsigned int    Len;
3035         int             Ret;
3036         SK_U32          Val32;
3037
3038         /*
3039          * Get array of all currently stored VPD keys
3040          */
3041         Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3042         if (Ret != SK_PNMI_ERR_OK) {
3043                 *pLen = 0;
3044                 return (Ret);
3045         }
3046
3047         /*
3048          * If instance is not -1, try to find the requested VPD key for
3049          * the multiple instance variables. The other OIDs as for example
3050          * OID VPD_ACTION are single instance variables and must be
3051          * handled separatly.
3052          */
3053         FirstIndex = 0;
3054         LastIndex = KeyNo;
3055
3056         if ((Instance != (SK_U32)(-1))) {
3057
3058                 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3059                         Id == OID_SKGE_VPD_ACCESS) {
3060
3061                         SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3062                         KeyStr[4] = 0;
3063
3064                         for (Index = 0; Index < KeyNo; Index ++) {
3065
3066                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3067                                         FirstIndex = Index;
3068                                         LastIndex = Index+1;
3069                                         break;
3070                                 }
3071                         }
3072                         if (Index == KeyNo) {
3073
3074                                 *pLen = 0;
3075                                 return (SK_PNMI_ERR_UNKNOWN_INST);
3076                         }
3077                 }
3078                 else if (Instance != 1) {
3079
3080                         *pLen = 0;
3081                         return (SK_PNMI_ERR_UNKNOWN_INST);
3082                 }
3083         }
3084
3085         /*
3086          * Get value, if a query should be performed
3087          */
3088         if (Action == SK_PNMI_GET) {
3089
3090                 switch (Id) {
3091
3092                 case OID_SKGE_VPD_FREE_BYTES:
3093                         /* Check length of buffer */
3094                         if (*pLen < sizeof(SK_U32)) {
3095
3096                                 *pLen = sizeof(SK_U32);
3097                                 return (SK_PNMI_ERR_TOO_SHORT);
3098                         }
3099                         /* Get number of free bytes */
3100                         pVpdStatus = VpdStat(pAC, IoC);
3101                         if (pVpdStatus == NULL) {
3102
3103                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3104                                         SK_PNMI_ERR017MSG);
3105
3106                                 *pLen = 0;
3107                                 return (SK_PNMI_ERR_GENERAL);
3108                         }
3109                         if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3110
3111                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3112                                         SK_PNMI_ERR018MSG);
3113
3114                                 *pLen = 0;
3115                                 return (SK_PNMI_ERR_GENERAL);
3116                         }
3117                         
3118                         Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3119                         SK_PNMI_STORE_U32(pBuf, Val32);
3120                         *pLen = sizeof(SK_U32);
3121                         break;
3122
3123                 case OID_SKGE_VPD_ENTRIES_LIST:
3124                         /* Check length */
3125                         for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3126
3127                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
3128                         }
3129                         if (*pLen < Len) {
3130
3131                                 *pLen = Len;
3132                                 return (SK_PNMI_ERR_TOO_SHORT);
3133                         }
3134
3135                         /* Get value */
3136                         *(pBuf) = (char)Len - 1;
3137                         for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3138
3139                                 Len = SK_STRLEN(KeyArr[Index]);
3140                                 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3141
3142                                 Offset += Len;
3143
3144                                 if (Index < KeyNo - 1) {
3145
3146                                         *(pBuf + Offset) = ' ';
3147                                         Offset ++;
3148                                 }
3149                         }
3150                         *pLen = Offset;
3151                         break;
3152
3153                 case OID_SKGE_VPD_ENTRIES_NUMBER:
3154                         /* Check length */
3155                         if (*pLen < sizeof(SK_U32)) {
3156
3157                                 *pLen = sizeof(SK_U32);
3158                                 return (SK_PNMI_ERR_TOO_SHORT);
3159                         }
3160
3161                         Val32 = (SK_U32)KeyNo;
3162                         SK_PNMI_STORE_U32(pBuf, Val32);
3163                         *pLen = sizeof(SK_U32);
3164                         break;
3165
3166                 case OID_SKGE_VPD_KEY:
3167                         /* Check buffer length, if it is large enough */
3168                         for (Len = 0, Index = FirstIndex;
3169                                 Index < LastIndex; Index ++) {
3170
3171                                 Len += SK_STRLEN(KeyArr[Index]) + 1;
3172                         }
3173                         if (*pLen < Len) {
3174
3175                                 *pLen = Len;
3176                                 return (SK_PNMI_ERR_TOO_SHORT);
3177                         }
3178
3179                         /*
3180                          * Get the key to an intermediate buffer, because
3181                          * we have to prepend a length byte.
3182                          */
3183                         for (Offset = 0, Index = FirstIndex;
3184                                 Index < LastIndex; Index ++) {
3185
3186                                 Len = SK_STRLEN(KeyArr[Index]);
3187
3188                                 *(pBuf + Offset) = (char)Len;
3189                                 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3190                                         Len);
3191                                 Offset += Len + 1;
3192                         }
3193                         *pLen = Offset;
3194                         break;
3195
3196                 case OID_SKGE_VPD_VALUE:
3197                         /* Check the buffer length if it is large enough */
3198                         for (Offset = 0, Index = FirstIndex;
3199                                 Index < LastIndex; Index ++) {
3200
3201                                 BufLen = 256;
3202                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3203                                         (int *)&BufLen) > 0 ||
3204                                         BufLen >= SK_PNMI_VPD_DATALEN) {
3205
3206                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
3207                                                 SK_PNMI_ERR021,
3208                                                 SK_PNMI_ERR021MSG);
3209
3210                                         return (SK_PNMI_ERR_GENERAL);
3211                                 }
3212                                 Offset += BufLen + 1;
3213                         }
3214                         if (*pLen < Offset) {
3215
3216                                 *pLen = Offset;
3217                                 return (SK_PNMI_ERR_TOO_SHORT);
3218                         }
3219
3220                         /*
3221                          * Get the value to an intermediate buffer, because
3222                          * we have to prepend a length byte.
3223                          */
3224                         for (Offset = 0, Index = FirstIndex;
3225                                 Index < LastIndex; Index ++) {
3226
3227                                 BufLen = 256;
3228                                 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3229                                         (int *)&BufLen) > 0 ||
3230                                         BufLen >= SK_PNMI_VPD_DATALEN) {
3231
3232                                         SK_ERR_LOG(pAC, SK_ERRCL_SW,
3233                                                 SK_PNMI_ERR022,
3234                                                 SK_PNMI_ERR022MSG);
3235
3236                                         *pLen = 0;
3237                                         return (SK_PNMI_ERR_GENERAL);
3238                                 }
3239
3240                                 *(pBuf + Offset) = (char)BufLen;
3241                                 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3242                                 Offset += BufLen + 1;
3243                         }
3244                         *pLen = Offset;
3245                         break;
3246
3247                 case OID_SKGE_VPD_ACCESS:
3248                         if (*pLen < LastIndex - FirstIndex) {
3249
3250                                 *pLen = LastIndex - FirstIndex;
3251                                 return (SK_PNMI_ERR_TOO_SHORT);
3252                         }
3253
3254                         for (Offset = 0, Index = FirstIndex;
3255                                 Index < LastIndex; Index ++) {
3256
3257                                 if (VpdMayWrite(KeyArr[Index])) {
3258
3259                                         *(pBuf + Offset) = SK_PNMI_VPD_RW;
3260                                 }
3261                                 else {
3262                                         *(pBuf + Offset) = SK_PNMI_VPD_RO;
3263                                 }
3264                                 Offset ++;
3265                         }
3266                         *pLen = Offset;
3267                         break;
3268
3269                 case OID_SKGE_VPD_ACTION:
3270                         Offset = LastIndex - FirstIndex;
3271                         if (*pLen < Offset) {
3272
3273                                 *pLen = Offset;
3274                                 return (SK_PNMI_ERR_TOO_SHORT);
3275                         }
3276                         SK_MEMSET(pBuf, 0, Offset);
3277                         *pLen = Offset;
3278                         break;
3279
3280                 default:
3281                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3282                                 SK_PNMI_ERR023MSG);
3283
3284                         *pLen = 0;
3285                         return (SK_PNMI_ERR_GENERAL);
3286                 }
3287         }
3288         else {
3289                 /* The only OID which can be set is VPD_ACTION */
3290                 if (Id != OID_SKGE_VPD_ACTION) {
3291
3292                         if (Id == OID_SKGE_VPD_FREE_BYTES ||
3293                                 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3294                                 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3295                                 Id == OID_SKGE_VPD_KEY ||
3296                                 Id == OID_SKGE_VPD_VALUE ||
3297                                 Id == OID_SKGE_VPD_ACCESS) {
3298
3299                                 *pLen = 0;
3300                                 return (SK_PNMI_ERR_READ_ONLY);
3301                         }
3302
3303                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3304                                 SK_PNMI_ERR024MSG);
3305
3306                         *pLen = 0;
3307                         return (SK_PNMI_ERR_GENERAL);
3308                 }
3309
3310                 /*
3311                  * From this point we handle VPD_ACTION. Check the buffer
3312                  * length. It should at least have the size of one byte.
3313                  */
3314                 if (*pLen < 1) {
3315
3316                         *pLen = 1;
3317                         return (SK_PNMI_ERR_TOO_SHORT);
3318                 }
3319
3320                 /*
3321                  * The first byte contains the VPD action type we should
3322                  * perform.
3323                  */
3324                 switch (*pBuf) {
3325
3326                 case SK_PNMI_VPD_IGNORE:
3327                         /* Nothing to do */
3328                         break;
3329
3330                 case SK_PNMI_VPD_CREATE:
3331                         /*
3332                          * We have to create a new VPD entry or we modify
3333                          * an existing one. Check first the buffer length.
3334                          */
3335                         if (*pLen < 4) {
3336
3337                                 *pLen = 4;
3338                                 return (SK_PNMI_ERR_TOO_SHORT);
3339                         }
3340                         KeyStr[0] = pBuf[1];
3341                         KeyStr[1] = pBuf[2];
3342                         KeyStr[2] = 0;
3343
3344                         /*
3345                          * Is the entry writable or does it belong to the
3346                          * read-only area?
3347                          */
3348                         if (!VpdMayWrite(KeyStr)) {
3349
3350                                 *pLen = 0;
3351                                 return (SK_PNMI_ERR_BAD_VALUE);
3352                         }
3353
3354                         Offset = (int)pBuf[3] & 0xFF;
3355
3356                         SK_MEMCPY(Buf, pBuf + 4, Offset);
3357                         Buf[Offset] = 0;
3358
3359                         /* A preset ends here */
3360                         if (Action == SK_PNMI_PRESET) {
3361
3362                                 return (SK_PNMI_ERR_OK);
3363                         }
3364
3365                         /* Write the new entry or modify an existing one */
3366                         Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3367                         if (Ret == SK_PNMI_VPD_NOWRITE ) {
3368
3369                                 *pLen = 0;
3370                                 return (SK_PNMI_ERR_BAD_VALUE);
3371                         }
3372                         else if (Ret != SK_PNMI_VPD_OK) {
3373
3374                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3375                                         SK_PNMI_ERR025MSG);
3376
3377                                 *pLen = 0;
3378                                 return (SK_PNMI_ERR_GENERAL);
3379                         }
3380
3381                         /*
3382                          * Perform an update of the VPD data. This is
3383                          * not mandantory, but just to be sure.
3384                          */
3385                         Ret = VpdUpdate(pAC, IoC);
3386                         if (Ret != SK_PNMI_VPD_OK) {
3387
3388                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3389                                         SK_PNMI_ERR026MSG);
3390
3391                                 *pLen = 0;
3392                                 return (SK_PNMI_ERR_GENERAL);
3393                         }
3394                         break;
3395
3396                 case SK_PNMI_VPD_DELETE:
3397                         /* Check if the buffer size is plausible */
3398                         if (*pLen < 3) {
3399
3400                                 *pLen = 3;
3401                                 return (SK_PNMI_ERR_TOO_SHORT);
3402                         }
3403                         if (*pLen > 3) {
3404
3405                                 *pLen = 0;
3406                                 return (SK_PNMI_ERR_BAD_VALUE);
3407                         }
3408                         KeyStr[0] = pBuf[1];
3409                         KeyStr[1] = pBuf[2];
3410                         KeyStr[2] = 0;
3411
3412                         /* Find the passed key in the array */
3413                         for (Index = 0; Index < KeyNo; Index ++) {
3414
3415                                 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3416
3417                                         break;
3418                                 }
3419                         }
3420                         /*
3421                          * If we cannot find the key it is wrong, so we
3422                          * return an appropriate error value.
3423                          */
3424                         if (Index == KeyNo) {
3425
3426                                 *pLen = 0;
3427                                 return (SK_PNMI_ERR_BAD_VALUE);
3428                         }
3429
3430                         if (Action == SK_PNMI_PRESET) {
3431
3432                                 return (SK_PNMI_ERR_OK);
3433                         }
3434
3435                         /* Ok, you wanted it and you will get it */
3436                         Ret = VpdDelete(pAC, IoC, KeyStr);
3437                         if (Ret != SK_PNMI_VPD_OK) {
3438
3439                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3440                                         SK_PNMI_ERR027MSG);
3441
3442                                 *pLen = 0;
3443                                 return (SK_PNMI_ERR_GENERAL);
3444                         }
3445
3446                         /*
3447                          * Perform an update of the VPD data. This is
3448                          * not mandantory, but just to be sure.
3449                          */
3450                         Ret = VpdUpdate(pAC, IoC);
3451                         if (Ret != SK_PNMI_VPD_OK) {
3452
3453                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3454                                         SK_PNMI_ERR028MSG);
3455
3456                                 *pLen = 0;
3457                                 return (SK_PNMI_ERR_GENERAL);
3458                         }
3459                         break;
3460
3461                 default:
3462                         *pLen = 0;
3463                         return (SK_PNMI_ERR_BAD_VALUE);
3464                 }
3465         }
3466
3467         return (SK_PNMI_ERR_OK);
3468 }
3469
3470 /*****************************************************************************
3471  *
3472  * General - OID handler function of various single instance OIDs
3473  *
3474  * Description:
3475  *      The code is simple. No description necessary.
3476  *
3477  * Returns:
3478  *      SK_PNMI_ERR_OK           The request was successfully performed.
3479  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
3480  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
3481  *                               the correct data (e.g. a 32bit value is
3482  *                               needed, but a 16 bit value was passed).
3483  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3484  *                           exist (e.g. port instance 3 on a two port
3485  *                               adapter.
3486  */
3487 PNMI_STATIC int General(
3488 SK_AC *pAC,             /* Pointer to adapter context */
3489 SK_IOC IoC,             /* IO context handle */
3490 int Action,             /* GET/PRESET/SET action */
3491 SK_U32 Id,              /* Object ID that is to be processed */
3492 char *pBuf,             /* Buffer used for the management data transfer */
3493 unsigned int *pLen,     /* On call: buffer length. On return: used buffer */
3494 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
3495 unsigned int TableIndex, /* Index to the Id table */
3496 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
3497 {
3498         int             Ret;
3499         unsigned int    Index;
3500         unsigned int    Len;
3501         unsigned int    Offset;
3502         unsigned int    Val;
3503         SK_U8           Val8;
3504         SK_U16          Val16;
3505         SK_U32          Val32;
3506         SK_U64          Val64;
3507         SK_U64          Val64RxHwErrs = 0;
3508         SK_U64          Val64TxHwErrs = 0;
3509         SK_BOOL         Is64BitReq = SK_FALSE;
3510         char            Buf[256];
3511         int                     MacType;
3512
3513         /*
3514          * Check instance. We only handle single instance variables.
3515          */
3516         if (Instance != (SK_U32)(-1) && Instance != 1) {
3517
3518                 *pLen = 0;
3519                 return (SK_PNMI_ERR_UNKNOWN_INST);
3520         }
3521
3522         /*
3523          * Check action. We only allow get requests.
3524          */
3525         if (Action != SK_PNMI_GET) {
3526
3527                 *pLen = 0;
3528                 return (SK_PNMI_ERR_READ_ONLY);
3529         }
3530         
3531         MacType = pAC->GIni.GIMacType;
3532         
3533         /*
3534          * Check length for the various supported OIDs
3535          */
3536         switch (Id) {
3537
3538         case OID_GEN_XMIT_ERROR:
3539         case OID_GEN_RCV_ERROR:
3540         case OID_GEN_RCV_NO_BUFFER:
3541 #ifndef SK_NDIS_64BIT_CTR
3542                 if (*pLen < sizeof(SK_U32)) {
3543                         *pLen = sizeof(SK_U32);
3544                         return (SK_PNMI_ERR_TOO_SHORT);
3545                 }
3546
3547 #else /* SK_NDIS_64BIT_CTR */
3548
3549                 /*
3550                  * for compatibility, at least 32bit are required for oid
3551                  */
3552                 if (*pLen < sizeof(SK_U32)) {
3553                         /*
3554                         * but indicate handling for 64bit values,
3555                         * if insufficient space is provided
3556                         */
3557                         *pLen = sizeof(SK_U64);
3558                         return (SK_PNMI_ERR_TOO_SHORT);
3559                 }
3560
3561                 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3562 #endif /* SK_NDIS_64BIT_CTR */
3563                 break;
3564
3565         case OID_SKGE_PORT_NUMBER:
3566         case OID_SKGE_DEVICE_TYPE:
3567         case OID_SKGE_RESULT:
3568         case OID_SKGE_RLMT_MONITOR_NUMBER:
3569         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3570         case OID_SKGE_TRAP_NUMBER:
3571         case OID_SKGE_MDB_VERSION:
3572         case OID_SKGE_BOARDLEVEL:
3573         case OID_SKGE_CHIPID:
3574         case OID_SKGE_RAMSIZE:
3575                 if (*pLen < sizeof(SK_U32)) {
3576
3577                         *pLen = sizeof(SK_U32);
3578                         return (SK_PNMI_ERR_TOO_SHORT);
3579                 }
3580                 break;
3581
3582         case OID_SKGE_CHIPSET:
3583                 if (*pLen < sizeof(SK_U16)) {
3584
3585                         *pLen = sizeof(SK_U16);
3586                         return (SK_PNMI_ERR_TOO_SHORT);
3587                 }
3588                 break;
3589
3590         case OID_SKGE_BUS_TYPE:
3591         case OID_SKGE_BUS_SPEED:
3592         case OID_SKGE_BUS_WIDTH:
3593         case OID_SKGE_SENSOR_NUMBER:
3594         case OID_SKGE_CHKSM_NUMBER:
3595         case OID_SKGE_VAUXAVAIL:
3596                 if (*pLen < sizeof(SK_U8)) {
3597
3598                         *pLen = sizeof(SK_U8);
3599                         return (SK_PNMI_ERR_TOO_SHORT);
3600                 }
3601                 break;
3602
3603         case OID_SKGE_TX_SW_QUEUE_LEN:
3604         case OID_SKGE_TX_SW_QUEUE_MAX:
3605         case OID_SKGE_TX_RETRY:
3606         case OID_SKGE_RX_INTR_CTS:
3607         case OID_SKGE_TX_INTR_CTS:
3608         case OID_SKGE_RX_NO_BUF_CTS:
3609         case OID_SKGE_TX_NO_BUF_CTS:
3610         case OID_SKGE_TX_USED_DESCR_NO:
3611         case OID_SKGE_RX_DELIVERED_CTS:
3612         case OID_SKGE_RX_OCTETS_DELIV_CTS:
3613         case OID_SKGE_RX_HW_ERROR_CTS:
3614         case OID_SKGE_TX_HW_ERROR_CTS:
3615         case OID_SKGE_IN_ERRORS_CTS:
3616         case OID_SKGE_OUT_ERROR_CTS:
3617         case OID_SKGE_ERR_RECOVERY_CTS:
3618         case OID_SKGE_SYSUPTIME:
3619                 if (*pLen < sizeof(SK_U64)) {
3620
3621                         *pLen = sizeof(SK_U64);
3622                         return (SK_PNMI_ERR_TOO_SHORT);
3623                 }
3624                 break;
3625
3626         default:
3627                 /* Checked later */
3628                 break;
3629         }
3630
3631         /* Update statistic */
3632         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3633                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3634                 Id == OID_SKGE_IN_ERRORS_CTS ||
3635                 Id == OID_SKGE_OUT_ERROR_CTS ||
3636                 Id == OID_GEN_XMIT_ERROR ||
3637                 Id == OID_GEN_RCV_ERROR) {
3638
3639                 /* Force the XMAC to update its statistic counters and
3640                  * Increment semaphore to indicate that an update was
3641                  * already done.
3642                  */
3643                 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3644                 if (Ret != SK_PNMI_ERR_OK) {
3645
3646                         *pLen = 0;
3647                         return (Ret);
3648                 }
3649                 pAC->Pnmi.MacUpdatedFlag ++;
3650
3651                 /*
3652                  * Some OIDs consist of multiple hardware counters. Those
3653                  * values which are contained in all of them will be added
3654                  * now.
3655                  */
3656                 switch (Id) {
3657
3658                 case OID_SKGE_RX_HW_ERROR_CTS:
3659                 case OID_SKGE_IN_ERRORS_CTS:
3660                 case OID_GEN_RCV_ERROR:
3661                         Val64RxHwErrs =
3662                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3663                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3664                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3665                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3666                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3667                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3668                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3669                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3670                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3671                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3672                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3673                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3674                 break;
3675
3676                 case OID_SKGE_TX_HW_ERROR_CTS:
3677                 case OID_SKGE_OUT_ERROR_CTS:
3678                 case OID_GEN_XMIT_ERROR:
3679                         Val64TxHwErrs =
3680                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3681                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3682                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3683                                 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3684                         break;
3685                 }
3686         }
3687
3688         /*
3689          * Retrieve value
3690          */
3691         switch (Id) {
3692
3693         case OID_SKGE_SUPPORTED_LIST:
3694                 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3695                 if (*pLen < Len) {
3696
3697                         *pLen = Len;
3698                         return (SK_PNMI_ERR_TOO_SHORT);
3699                 }
3700                 for (Offset = 0, Index = 0; Offset < Len;
3701                         Offset += sizeof(SK_U32), Index ++) {
3702
3703                         Val32 = (SK_U32)IdTable[Index].Id;
3704                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3705                 }
3706                 *pLen = Len;
3707                 break;
3708
3709         case OID_SKGE_BOARDLEVEL:
3710                 Val32 = (SK_U32)pAC->GIni.GILevel;
3711                 SK_PNMI_STORE_U32(pBuf, Val32);
3712                 *pLen = sizeof(SK_U32);
3713                 break;
3714
3715         case OID_SKGE_PORT_NUMBER:
3716                 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3717                 SK_PNMI_STORE_U32(pBuf, Val32);
3718                 *pLen = sizeof(SK_U32);
3719                 break;
3720
3721         case OID_SKGE_DEVICE_TYPE:
3722                 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3723                 SK_PNMI_STORE_U32(pBuf, Val32);
3724                 *pLen = sizeof(SK_U32);
3725                 break;
3726
3727         case OID_SKGE_DRIVER_DESCR:
3728                 if (pAC->Pnmi.pDriverDescription == NULL) {
3729
3730                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3731                                 SK_PNMI_ERR007MSG);
3732
3733                         *pLen = 0;
3734                         return (SK_PNMI_ERR_GENERAL);
3735                 }
3736
3737                 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3738                 if (Len > SK_PNMI_STRINGLEN1) {
3739
3740                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3741                                 SK_PNMI_ERR029MSG);
3742
3743                         *pLen = 0;
3744                         return (SK_PNMI_ERR_GENERAL);
3745                 }
3746
3747                 if (*pLen < Len) {
3748
3749                         *pLen = Len;
3750                         return (SK_PNMI_ERR_TOO_SHORT);
3751                 }
3752                 *pBuf = (char)(Len - 1);
3753                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3754                 *pLen = Len;
3755                 break;
3756
3757         case OID_SKGE_DRIVER_VERSION:
3758                 if (pAC->Pnmi.pDriverVersion == NULL) {
3759
3760                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3761                                 SK_PNMI_ERR030MSG);
3762
3763                         *pLen = 0;
3764                         return (SK_PNMI_ERR_GENERAL);
3765                 }
3766
3767                 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3768                 if (Len > SK_PNMI_STRINGLEN1) {
3769
3770                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3771                                 SK_PNMI_ERR031MSG);
3772
3773                         *pLen = 0;
3774                         return (SK_PNMI_ERR_GENERAL);
3775                 }
3776
3777                 if (*pLen < Len) {
3778
3779                         *pLen = Len;
3780                         return (SK_PNMI_ERR_TOO_SHORT);
3781                 }
3782                 *pBuf = (char)(Len - 1);
3783                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3784                 *pLen = Len;
3785                 break;
3786
3787         case OID_SKGE_DRIVER_RELDATE:
3788                 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3789
3790                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3791                                 SK_PNMI_ERR053MSG);
3792
3793                         *pLen = 0;
3794                         return (SK_PNMI_ERR_GENERAL);
3795                 }
3796
3797                 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3798                 if (Len > SK_PNMI_STRINGLEN1) {
3799
3800                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3801                                 SK_PNMI_ERR054MSG);
3802
3803                         *pLen = 0;
3804                         return (SK_PNMI_ERR_GENERAL);
3805                 }
3806
3807                 if (*pLen < Len) {
3808
3809                         *pLen = Len;
3810                         return (SK_PNMI_ERR_TOO_SHORT);
3811                 }
3812                 *pBuf = (char)(Len - 1);
3813                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3814                 *pLen = Len;
3815                 break;
3816
3817         case OID_SKGE_DRIVER_FILENAME:
3818                 if (pAC->Pnmi.pDriverFileName == NULL) {
3819
3820                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3821                                 SK_PNMI_ERR055MSG);
3822
3823                         *pLen = 0;
3824                         return (SK_PNMI_ERR_GENERAL);
3825                 }
3826
3827                 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3828                 if (Len > SK_PNMI_STRINGLEN1) {
3829
3830                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3831                                 SK_PNMI_ERR056MSG);
3832
3833                         *pLen = 0;
3834                         return (SK_PNMI_ERR_GENERAL);
3835                 }
3836
3837                 if (*pLen < Len) {
3838
3839                         *pLen = Len;
3840                         return (SK_PNMI_ERR_TOO_SHORT);
3841                 }
3842                 *pBuf = (char)(Len - 1);
3843                 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3844                 *pLen = Len;
3845                 break;
3846
3847         case OID_SKGE_HW_DESCR:
3848                 /*
3849                  * The hardware description is located in the VPD. This
3850                  * query may move to the initialisation routine. But
3851                  * the VPD data is cached and therefore a call here
3852                  * will not make much difference.
3853                  */
3854                 Len = 256;
3855                 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3856
3857                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3858                                 SK_PNMI_ERR032MSG);
3859
3860                         *pLen = 0;
3861                         return (SK_PNMI_ERR_GENERAL);
3862                 }
3863                 Len ++;
3864                 if (Len > SK_PNMI_STRINGLEN1) {
3865
3866                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3867                                 SK_PNMI_ERR033MSG);
3868
3869                         *pLen = 0;
3870                         return (SK_PNMI_ERR_GENERAL);
3871                 }
3872                 if (*pLen < Len) {
3873
3874                         *pLen = Len;
3875                         return (SK_PNMI_ERR_TOO_SHORT);
3876                 }
3877                 *pBuf = (char)(Len - 1);
3878                 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3879                 *pLen = Len;
3880                 break;
3881
3882         case OID_SKGE_HW_VERSION:
3883                 /* Oh, I love to do some string manipulation */
3884                 if (*pLen < 5) {
3885
3886                         *pLen = 5;
3887                         return (SK_PNMI_ERR_TOO_SHORT);
3888                 }
3889                 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3890                 pBuf[0] = 4;
3891                 pBuf[1] = 'v';
3892                 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3893                 pBuf[3] = '.';
3894                 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3895                 *pLen = 5;
3896                 break;
3897
3898         case OID_SKGE_CHIPSET:
3899                 Val16 = pAC->Pnmi.Chipset;
3900                 SK_PNMI_STORE_U16(pBuf, Val16);
3901                 *pLen = sizeof(SK_U16);
3902                 break;
3903
3904         case OID_SKGE_CHIPID:
3905                 Val32 = pAC->GIni.GIChipId;
3906                 SK_PNMI_STORE_U32(pBuf, Val32);
3907                 *pLen = sizeof(SK_U32);
3908                 break;
3909
3910         case OID_SKGE_RAMSIZE:
3911                 Val32 = pAC->GIni.GIRamSize;
3912                 SK_PNMI_STORE_U32(pBuf, Val32);
3913                 *pLen = sizeof(SK_U32);
3914                 break;
3915
3916         case OID_SKGE_VAUXAVAIL:
3917                 *pBuf = (char) pAC->GIni.GIVauxAvail;
3918                 *pLen = sizeof(char);
3919                 break;
3920
3921         case OID_SKGE_BUS_TYPE:
3922                 *pBuf = (char) SK_PNMI_BUS_PCI;
3923                 *pLen = sizeof(char);
3924                 break;
3925
3926         case OID_SKGE_BUS_SPEED:
3927                 *pBuf = pAC->Pnmi.PciBusSpeed;
3928                 *pLen = sizeof(char);
3929                 break;
3930
3931         case OID_SKGE_BUS_WIDTH:
3932                 *pBuf = pAC->Pnmi.PciBusWidth;
3933                 *pLen = sizeof(char);
3934                 break;
3935
3936         case OID_SKGE_RESULT:
3937                 Val32 = pAC->Pnmi.TestResult;
3938                 SK_PNMI_STORE_U32(pBuf, Val32);
3939                 *pLen = sizeof(SK_U32);
3940                 break;
3941
3942         case OID_SKGE_SENSOR_NUMBER:
3943                 *pBuf = (char)pAC->I2c.MaxSens;
3944                 *pLen = sizeof(char);
3945                 break;
3946
3947         case OID_SKGE_CHKSM_NUMBER:
3948                 *pBuf = SKCS_NUM_PROTOCOLS;
3949                 *pLen = sizeof(char);
3950                 break;
3951
3952         case OID_SKGE_TRAP_NUMBER:
3953                 GetTrapQueueLen(pAC, &Len, &Val);
3954                 Val32 = (SK_U32)Val;
3955                 SK_PNMI_STORE_U32(pBuf, Val32);
3956                 *pLen = sizeof(SK_U32);
3957                 break;
3958
3959         case OID_SKGE_TRAP:
3960                 GetTrapQueueLen(pAC, &Len, &Val);
3961                 if (*pLen < Len) {
3962
3963                         *pLen = Len;
3964                         return (SK_PNMI_ERR_TOO_SHORT);
3965                 }
3966                 CopyTrapQueue(pAC, pBuf);
3967                 *pLen = Len;
3968                 break;
3969
3970         case OID_SKGE_RLMT_MONITOR_NUMBER:
3971 /* XXX Not yet implemented by RLMT therefore we return zero elements */
3972                 Val32 = 0;
3973                 SK_PNMI_STORE_U32(pBuf, Val32);
3974                 *pLen = sizeof(SK_U32);
3975                 break;
3976
3977         case OID_SKGE_TX_SW_QUEUE_LEN:
3978                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3979                 if (MacType == SK_MAC_XMAC) {
3980                         /* Dual net mode */
3981                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3982                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3983                         }
3984                         /* Single net mode */
3985                         else {
3986                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3987                                         pAC->Pnmi.BufPort[1].TxSwQueueLen;
3988                         }                       
3989                 }
3990                 else {
3991                         /* Dual net mode */
3992                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3993                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3994                         }
3995                         /* Single net mode */
3996                         else {
3997                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3998                                         pAC->Pnmi.Port[1].TxSwQueueLen;
3999                         }                       
4000                 }
4001                 SK_PNMI_STORE_U64(pBuf, Val64);
4002                 *pLen = sizeof(SK_U64);
4003                 break;
4004
4005
4006         case OID_SKGE_TX_SW_QUEUE_MAX:
4007                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4008                 if (MacType == SK_MAC_XMAC) {
4009                         /* Dual net mode */
4010                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4011                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4012                         }
4013                         /* Single net mode */
4014                         else {
4015                                 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4016                                         pAC->Pnmi.BufPort[1].TxSwQueueMax;
4017                         }
4018                 }
4019                 else {
4020                         /* Dual net mode */
4021                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4022                                 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4023                         }
4024                         /* Single net mode */
4025                         else {
4026                                 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4027                                         pAC->Pnmi.Port[1].TxSwQueueMax;
4028                         }
4029                 }
4030                 SK_PNMI_STORE_U64(pBuf, Val64);
4031                 *pLen = sizeof(SK_U64);
4032                 break;
4033
4034         case OID_SKGE_TX_RETRY:
4035                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4036                 if (MacType == SK_MAC_XMAC) {
4037                         /* Dual net mode */
4038                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4039                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4040                         }
4041                         /* Single net mode */
4042                         else {
4043                                 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4044                                         pAC->Pnmi.BufPort[1].TxRetryCts;
4045                         }
4046                 }
4047                 else {
4048                         /* Dual net mode */
4049                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4050                                 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4051                         }
4052                         /* Single net mode */
4053                         else {
4054                                 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4055                                         pAC->Pnmi.Port[1].TxRetryCts;
4056                         }
4057                 }
4058                 SK_PNMI_STORE_U64(pBuf, Val64);
4059                 *pLen = sizeof(SK_U64);
4060                 break;
4061
4062         case OID_SKGE_RX_INTR_CTS:
4063                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4064                 if (MacType == SK_MAC_XMAC) {
4065                         /* Dual net mode */
4066                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4067                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4068                         }
4069                         /* Single net mode */
4070                         else {
4071                                 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4072                                         pAC->Pnmi.BufPort[1].RxIntrCts;
4073                         }
4074                 }
4075                 else {
4076                         /* Dual net mode */
4077                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4078                                 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4079                         }
4080                         /* Single net mode */
4081                         else {
4082                                 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4083                                         pAC->Pnmi.Port[1].RxIntrCts;
4084                         }
4085                 }
4086                 SK_PNMI_STORE_U64(pBuf, Val64);
4087                 *pLen = sizeof(SK_U64);
4088                 break;
4089
4090         case OID_SKGE_TX_INTR_CTS:
4091                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4092                 if (MacType == SK_MAC_XMAC) {
4093                         /* Dual net mode */
4094                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4095                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4096                         }
4097                         /* Single net mode */
4098                         else {
4099                                 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4100                                         pAC->Pnmi.BufPort[1].TxIntrCts;
4101                         }
4102                 }
4103                 else {
4104                         /* Dual net mode */
4105                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4106                                 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4107                         }
4108                         /* Single net mode */
4109                         else {
4110                                 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4111                                         pAC->Pnmi.Port[1].TxIntrCts;
4112                         }
4113                 }
4114                 SK_PNMI_STORE_U64(pBuf, Val64);
4115                 *pLen = sizeof(SK_U64);
4116                 break;
4117
4118         case OID_SKGE_RX_NO_BUF_CTS:
4119                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4120                 if (MacType == SK_MAC_XMAC) {
4121                         /* Dual net mode */
4122                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4123                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4124                         }
4125                         /* Single net mode */
4126                         else {
4127                                 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4128                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
4129                         }
4130                 }
4131                 else {
4132                         /* Dual net mode */
4133                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4134                                 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4135                         }
4136                         /* Single net mode */
4137                         else {
4138                                 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4139                                         pAC->Pnmi.Port[1].RxNoBufCts;
4140                         }
4141                 }
4142                 SK_PNMI_STORE_U64(pBuf, Val64);
4143                 *pLen = sizeof(SK_U64);
4144                 break;
4145
4146         case OID_SKGE_TX_NO_BUF_CTS:
4147                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4148                 if (MacType == SK_MAC_XMAC) {
4149                         /* Dual net mode */
4150                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4151                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4152                         }
4153                         /* Single net mode */
4154                         else {
4155                                 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4156                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
4157                         }
4158                 }
4159                 else {
4160                         /* Dual net mode */
4161                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4162                                 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4163                         }
4164                         /* Single net mode */
4165                         else {
4166                                 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4167                                         pAC->Pnmi.Port[1].TxNoBufCts;
4168                         }
4169                 }
4170                 SK_PNMI_STORE_U64(pBuf, Val64);
4171                 *pLen = sizeof(SK_U64);
4172                 break;
4173
4174         case OID_SKGE_TX_USED_DESCR_NO:
4175                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4176                 if (MacType == SK_MAC_XMAC) {
4177                         /* Dual net mode */
4178                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4179                                 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4180                         }
4181                         /* Single net mode */
4182                         else {
4183                                 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4184                                         pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4185                         }
4186                 }
4187                 else {
4188                         /* Dual net mode */
4189                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4190                                 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4191                         }
4192                         /* Single net mode */
4193                         else {
4194                                 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4195                                         pAC->Pnmi.Port[1].TxUsedDescrNo;
4196                         }
4197                 }
4198                 SK_PNMI_STORE_U64(pBuf, Val64);
4199                 *pLen = sizeof(SK_U64);
4200                 break;
4201
4202         case OID_SKGE_RX_DELIVERED_CTS:
4203                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4204                 if (MacType == SK_MAC_XMAC) {
4205                         /* Dual net mode */
4206                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4207                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4208                         }
4209                         /* Single net mode */
4210                         else {
4211                                 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4212                                         pAC->Pnmi.BufPort[1].RxDeliveredCts;
4213                         }
4214                 }
4215                 else {
4216                         /* Dual net mode */
4217                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4218                                 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4219                         }
4220                         /* Single net mode */
4221                         else {
4222                                 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4223                                         pAC->Pnmi.Port[1].RxDeliveredCts;
4224                         }
4225                 }
4226                 SK_PNMI_STORE_U64(pBuf, Val64);
4227                 *pLen = sizeof(SK_U64);
4228                 break;
4229
4230         case OID_SKGE_RX_OCTETS_DELIV_CTS:
4231                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4232                 if (MacType == SK_MAC_XMAC) {
4233                         /* Dual net mode */
4234                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4235                                 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4236                         }
4237                         /* Single net mode */
4238                         else {
4239                                 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4240                                         pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4241                         }
4242                 }
4243                 else {
4244                         /* Dual net mode */
4245                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4246                                 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4247                         }
4248                         /* Single net mode */
4249                         else {
4250                                 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4251                                         pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4252                         }
4253                 }
4254                 SK_PNMI_STORE_U64(pBuf, Val64);
4255                 *pLen = sizeof(SK_U64);
4256                 break;
4257
4258         case OID_SKGE_RX_HW_ERROR_CTS:
4259                 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4260                 *pLen = sizeof(SK_U64);
4261                 break;
4262
4263         case OID_SKGE_TX_HW_ERROR_CTS:
4264                 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4265                 *pLen = sizeof(SK_U64);
4266                 break;
4267
4268         case OID_SKGE_IN_ERRORS_CTS:
4269                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4270                 if (MacType == SK_MAC_XMAC) {
4271                         /* Dual net mode */
4272                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4273                                 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4274                         }
4275                         /* Single net mode */
4276                         else {
4277                                 Val64 = Val64RxHwErrs +
4278                                         pAC->Pnmi.BufPort[0].RxNoBufCts +
4279                                         pAC->Pnmi.BufPort[1].RxNoBufCts;
4280                         }
4281                 }
4282                 else {
4283                         /* Dual net mode */
4284                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4285                                 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4286                         }
4287                         /* Single net mode */
4288                         else {
4289                                 Val64 = Val64RxHwErrs +
4290                                         pAC->Pnmi.Port[0].RxNoBufCts +
4291                                         pAC->Pnmi.Port[1].RxNoBufCts;
4292                         }
4293                 }
4294                 SK_PNMI_STORE_U64(pBuf, Val64);
4295                 *pLen = sizeof(SK_U64);
4296                 break;
4297
4298         case OID_SKGE_OUT_ERROR_CTS:
4299                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4300                 if (MacType == SK_MAC_XMAC) {
4301                         /* Dual net mode */
4302                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4303                                 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4304                         }
4305                         /* Single net mode */
4306                         else {
4307                                 Val64 = Val64TxHwErrs +
4308                                         pAC->Pnmi.BufPort[0].TxNoBufCts +
4309                                         pAC->Pnmi.BufPort[1].TxNoBufCts;
4310                         }
4311                 }
4312                 else {
4313                         /* Dual net mode */
4314                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4315                                 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4316                         }
4317                         /* Single net mode */
4318                         else {
4319                                 Val64 = Val64TxHwErrs +
4320                                         pAC->Pnmi.Port[0].TxNoBufCts +
4321                                         pAC->Pnmi.Port[1].TxNoBufCts;
4322                         }
4323                 }
4324                 SK_PNMI_STORE_U64(pBuf, Val64);
4325                 *pLen = sizeof(SK_U64);
4326                 break;
4327
4328         case OID_SKGE_ERR_RECOVERY_CTS:
4329                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4330                 if (MacType == SK_MAC_XMAC) {
4331                         /* Dual net mode */
4332                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4333                                 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4334                         }
4335                         /* Single net mode */
4336                         else {
4337                                 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4338                                         pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4339                         }
4340                 }
4341                 else {
4342                         /* Dual net mode */
4343                         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4344                                 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4345                         }
4346                         /* Single net mode */
4347                         else {
4348                                 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4349                                         pAC->Pnmi.Port[1].ErrRecoveryCts;
4350                         }
4351                 }
4352                 SK_PNMI_STORE_U64(pBuf, Val64);
4353                 *pLen = sizeof(SK_U64);
4354                 break;
4355
4356         case OID_SKGE_SYSUPTIME:
4357                 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4358                 Val64 -= pAC->Pnmi.StartUpTime;
4359                 SK_PNMI_STORE_U64(pBuf, Val64);
4360                 *pLen = sizeof(SK_U64);
4361                 break;
4362
4363         case OID_SKGE_MDB_VERSION:
4364                 Val32 = SK_PNMI_MDB_VERSION;
4365                 SK_PNMI_STORE_U32(pBuf, Val32);
4366                 *pLen = sizeof(SK_U32);
4367                 break;
4368
4369         case OID_GEN_RCV_ERROR:
4370                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4371                 if (MacType == SK_MAC_XMAC) {
4372                         Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4373                 }
4374                 else {
4375                         Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4376                 }
4377
4378                 /*
4379                  * by default 32bit values are evaluated
4380                  */
4381                 if (!Is64BitReq) {
4382                         Val32 = (SK_U32)Val64;
4383                         SK_PNMI_STORE_U32(pBuf, Val32);
4384                         *pLen = sizeof(SK_U32);
4385                 }
4386                 else {
4387                         SK_PNMI_STORE_U64(pBuf, Val64);
4388                         *pLen = sizeof(SK_U64);
4389                 }
4390                 break;
4391
4392         case OID_GEN_XMIT_ERROR:
4393                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4394                 if (MacType == SK_MAC_XMAC) {
4395                         Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4396                 }
4397                 else {
4398                         Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4399                 }
4400
4401                 /*
4402                  * by default 32bit values are evaluated
4403                  */
4404                 if (!Is64BitReq) {
4405                         Val32 = (SK_U32)Val64;
4406                         SK_PNMI_STORE_U32(pBuf, Val32);
4407                         *pLen = sizeof(SK_U32);
4408                 }
4409                 else {
4410                         SK_PNMI_STORE_U64(pBuf, Val64);
4411                         *pLen = sizeof(SK_U64);
4412                 }
4413                 break;
4414
4415         case OID_GEN_RCV_NO_BUFFER:
4416                 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4417                 if (MacType == SK_MAC_XMAC) {
4418                         Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4419                 }
4420                 else {
4421                         Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4422                 }
4423
4424                 /*
4425                  * by default 32bit values are evaluated
4426                  */
4427                 if (!Is64BitReq) {
4428                         Val32 = (SK_U32)Val64;
4429                         SK_PNMI_STORE_U32(pBuf, Val32);
4430                         *pLen = sizeof(SK_U32);
4431                 }
4432                 else {
4433                         SK_PNMI_STORE_U64(pBuf, Val64);
4434                         *pLen = sizeof(SK_U64);
4435                 }
4436                 break;
4437
4438         case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4439                 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4440                 SK_PNMI_STORE_U32(pBuf, Val32);
4441                 *pLen = sizeof(SK_U32);
4442                 break;
4443
4444         default:
4445                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4446                         SK_PNMI_ERR034MSG);
4447
4448                 *pLen = 0;
4449                 return (SK_PNMI_ERR_GENERAL);
4450         }
4451
4452         if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4453                 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4454                 Id == OID_SKGE_IN_ERRORS_CTS ||
4455                 Id == OID_SKGE_OUT_ERROR_CTS ||
4456                 Id == OID_GEN_XMIT_ERROR ||
4457                 Id == OID_GEN_RCV_ERROR) {
4458
4459                 pAC->Pnmi.MacUpdatedFlag --;
4460         }
4461
4462         return (SK_PNMI_ERR_OK);
4463 }
4464
4465 /*****************************************************************************
4466  *
4467  * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4468  *
4469  * Description:
4470  *      Get/Presets/Sets the RLMT OIDs.
4471  *
4472  * Returns:
4473  *      SK_PNMI_ERR_OK           The request was successfully performed.
4474  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
4475  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
4476  *                               the correct data (e.g. a 32bit value is
4477  *                               needed, but a 16 bit value was passed).
4478  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
4479  *                               value range.
4480  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
4481  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4482  *                           exist (e.g. port instance 3 on a two port
4483  *                               adapter.
4484  */
4485 PNMI_STATIC int Rlmt(
4486 SK_AC *pAC,             /* Pointer to adapter context */
4487 SK_IOC IoC,             /* IO context handle */
4488 int Action,             /* GET/PRESET/SET action */
4489 SK_U32 Id,              /* Object ID that is to be processed */
4490 char *pBuf,             /* Buffer used for the management data transfer */
4491 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
4492 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
4493 unsigned int TableIndex, /* Index to the Id table */
4494 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
4495 {
4496         int             Ret;
4497         unsigned int    PhysPortIndex;
4498         unsigned int    PhysPortMax;
4499         SK_EVPARA       EventParam;
4500         SK_U32          Val32;
4501         SK_U64          Val64;
4502
4503
4504         /*
4505          * Check instance. Only single instance OIDs are allowed here.
4506          */
4507         if (Instance != (SK_U32)(-1) && Instance != 1) {
4508
4509                 *pLen = 0;
4510                 return (SK_PNMI_ERR_UNKNOWN_INST);
4511         }
4512
4513         /*
4514          * Perform the requested action.
4515          */
4516         if (Action == SK_PNMI_GET) {
4517
4518                 /*
4519                  * Check if the buffer length is large enough.
4520                  */
4521
4522                 switch (Id) {
4523
4524                 case OID_SKGE_RLMT_MODE:
4525                 case OID_SKGE_RLMT_PORT_ACTIVE:
4526                 case OID_SKGE_RLMT_PORT_PREFERRED:
4527                         if (*pLen < sizeof(SK_U8)) {
4528
4529                                 *pLen = sizeof(SK_U8);
4530                                 return (SK_PNMI_ERR_TOO_SHORT);
4531                         }
4532                         break;
4533
4534                 case OID_SKGE_RLMT_PORT_NUMBER:
4535                         if (*pLen < sizeof(SK_U32)) {
4536
4537                                 *pLen = sizeof(SK_U32);
4538                                 return (SK_PNMI_ERR_TOO_SHORT);
4539                         }
4540                         break;
4541
4542                 case OID_SKGE_RLMT_CHANGE_CTS:
4543                 case OID_SKGE_RLMT_CHANGE_TIME:
4544                 case OID_SKGE_RLMT_CHANGE_ESTIM:
4545                 case OID_SKGE_RLMT_CHANGE_THRES:
4546                         if (*pLen < sizeof(SK_U64)) {
4547
4548                                 *pLen = sizeof(SK_U64);
4549                                 return (SK_PNMI_ERR_TOO_SHORT);
4550                         }
4551                         break;
4552
4553                 default:
4554                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4555                                 SK_PNMI_ERR035MSG);
4556
4557                         *pLen = 0;
4558                         return (SK_PNMI_ERR_GENERAL);
4559                 }
4560
4561                 /*
4562                  * Update RLMT statistic and increment semaphores to indicate
4563                  * that an update was already done. Maybe RLMT will hold its
4564                  * statistic always up to date some time. Then we can
4565                  * remove this type of call.
4566                  */
4567                 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4568
4569                         *pLen = 0;
4570                         return (Ret);
4571                 }
4572                 pAC->Pnmi.RlmtUpdatedFlag ++;
4573
4574                 /*
4575                  * Retrieve Value
4576                 */
4577                 switch (Id) {
4578
4579                 case OID_SKGE_RLMT_MODE:
4580                         *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4581                         *pLen = sizeof(char);
4582                         break;
4583
4584                 case OID_SKGE_RLMT_PORT_NUMBER:
4585                         Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4586                         SK_PNMI_STORE_U32(pBuf, Val32);
4587                         *pLen = sizeof(SK_U32);
4588                         break;
4589
4590                 case OID_SKGE_RLMT_PORT_ACTIVE:
4591                         *pBuf = 0;
4592                         /*
4593                          * If multiple ports may become active this OID
4594                          * doesn't make sense any more. A new variable in
4595                          * the port structure should be created. However,
4596                          * for this variable the first active port is
4597                          * returned.
4598                          */
4599                         PhysPortMax = pAC->GIni.GIMacsFound;
4600
4601                         for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4602                                 PhysPortIndex ++) {
4603
4604                                 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4605
4606                                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4607                                         break;
4608                                 }
4609                         }
4610                         *pLen = sizeof(char);
4611                         break;
4612
4613                 case OID_SKGE_RLMT_PORT_PREFERRED:
4614                         *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4615                         *pLen = sizeof(char);
4616                         break;
4617
4618                 case OID_SKGE_RLMT_CHANGE_CTS:
4619                         Val64 = pAC->Pnmi.RlmtChangeCts;
4620                         SK_PNMI_STORE_U64(pBuf, Val64);
4621                         *pLen = sizeof(SK_U64);
4622                         break;
4623
4624                 case OID_SKGE_RLMT_CHANGE_TIME:
4625                         Val64 = pAC->Pnmi.RlmtChangeTime;
4626                         SK_PNMI_STORE_U64(pBuf, Val64);
4627                         *pLen = sizeof(SK_U64);
4628                         break;
4629
4630                 case OID_SKGE_RLMT_CHANGE_ESTIM:
4631                         Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4632                         SK_PNMI_STORE_U64(pBuf, Val64);
4633                         *pLen = sizeof(SK_U64);
4634                         break;
4635
4636                 case OID_SKGE_RLMT_CHANGE_THRES:
4637                         Val64 = pAC->Pnmi.RlmtChangeThreshold;
4638                         SK_PNMI_STORE_U64(pBuf, Val64);
4639                         *pLen = sizeof(SK_U64);
4640                         break;
4641
4642                 default:
4643                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4644                                 ("Rlmt: Unknown OID should be handled before"));
4645
4646                         pAC->Pnmi.RlmtUpdatedFlag --;
4647                         *pLen = 0;
4648                         return (SK_PNMI_ERR_GENERAL);
4649                 }
4650
4651                 pAC->Pnmi.RlmtUpdatedFlag --;
4652         }
4653         else {
4654                 /* Perform a preset or set */
4655                 switch (Id) {
4656
4657                 case OID_SKGE_RLMT_MODE:
4658                         /* Check if the buffer length is plausible */
4659                         if (*pLen < sizeof(char)) {
4660
4661                                 *pLen = sizeof(char);
4662                                 return (SK_PNMI_ERR_TOO_SHORT);
4663                         }
4664                         /* Check if the value range is correct */
4665                         if (*pLen != sizeof(char) ||
4666                                 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4667                                 *(SK_U8 *)pBuf > 15) {
4668
4669                                 *pLen = 0;
4670                                 return (SK_PNMI_ERR_BAD_VALUE);
4671                         }
4672                         /* The preset ends here */
4673                         if (Action == SK_PNMI_PRESET) {
4674
4675                                 *pLen = 0;
4676                                 return (SK_PNMI_ERR_OK);
4677                         }
4678                         /* Send an event to RLMT to change the mode */
4679                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4680                         EventParam.Para32[0] |= (SK_U32)(*pBuf);
4681                         EventParam.Para32[1] = 0;
4682                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4683                                 EventParam) > 0) {
4684
4685                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4686                                         SK_PNMI_ERR037MSG);
4687
4688                                 *pLen = 0;
4689                                 return (SK_PNMI_ERR_GENERAL);
4690                         }
4691                         break;
4692
4693                 case OID_SKGE_RLMT_PORT_PREFERRED:
4694                         /* Check if the buffer length is plausible */
4695                         if (*pLen < sizeof(char)) {
4696
4697                                 *pLen = sizeof(char);
4698                                 return (SK_PNMI_ERR_TOO_SHORT);
4699                         }
4700                         /* Check if the value range is correct */
4701                         if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4702                                 (SK_U8)pAC->GIni.GIMacsFound) {
4703
4704                                 *pLen = 0;
4705                                 return (SK_PNMI_ERR_BAD_VALUE);
4706                         }
4707                         /* The preset ends here */
4708                         if (Action == SK_PNMI_PRESET) {
4709
4710                                 *pLen = 0;
4711                                 return (SK_PNMI_ERR_OK);
4712                         }
4713
4714                         /*
4715                          * Send an event to RLMT change the preferred port.
4716                          * A param of -1 means automatic mode. RLMT will
4717                          * make the decision which is the preferred port.
4718                          */
4719                         SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4720                         EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4721                         EventParam.Para32[1] = NetIndex;
4722                         if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4723                                 EventParam) > 0) {
4724
4725                                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4726                                         SK_PNMI_ERR038MSG);
4727
4728                                 *pLen = 0;
4729                                 return (SK_PNMI_ERR_GENERAL);
4730                         }
4731                         break;
4732
4733                 case OID_SKGE_RLMT_CHANGE_THRES:
4734                         /* Check if the buffer length is plausible */
4735                         if (*pLen < sizeof(SK_U64)) {
4736
4737                                 *pLen = sizeof(SK_U64);
4738                                 return (SK_PNMI_ERR_TOO_SHORT);
4739                         }
4740                         /*
4741                          * There are not many restrictions to the
4742                          * value range.
4743                          */
4744                         if (*pLen != sizeof(SK_U64)) {
4745
4746                                 *pLen = 0;
4747                                 return (SK_PNMI_ERR_BAD_VALUE);
4748                         }
4749                         /* A preset ends here */
4750                         if (Action == SK_PNMI_PRESET) {
4751
4752                                 *pLen = 0;
4753                                 return (SK_PNMI_ERR_OK);
4754                         }
4755                         /*
4756                          * Store the new threshold, which will be taken
4757                          * on the next timer event.
4758                          */
4759                         SK_PNMI_READ_U64(pBuf, Val64);
4760                         pAC->Pnmi.RlmtChangeThreshold = Val64;
4761                         break;
4762
4763                 default:
4764                         /* The other OIDs are not be able for set */
4765                         *pLen = 0;
4766                         return (SK_PNMI_ERR_READ_ONLY);
4767                 }
4768         }
4769
4770         return (SK_PNMI_ERR_OK);
4771 }
4772
4773 /*****************************************************************************
4774  *
4775  * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4776  *
4777  * Description:
4778  *      Performs get requests on multiple instance variables.
4779  *
4780  * Returns:
4781  *      SK_PNMI_ERR_OK           The request was successfully performed.
4782  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
4783  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
4784  *                               the correct data (e.g. a 32bit value is
4785  *                               needed, but a 16 bit value was passed).
4786  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4787  *                           exist (e.g. port instance 3 on a two port
4788  *                               adapter.
4789  */
4790 PNMI_STATIC int RlmtStat(
4791 SK_AC *pAC,             /* Pointer to adapter context */
4792 SK_IOC IoC,             /* IO context handle */
4793 int Action,             /* GET/PRESET/SET action */
4794 SK_U32 Id,              /* Object ID that is to be processed */
4795 char *pBuf,             /* Buffer used for the management data transfer */
4796 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
4797 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
4798 unsigned int TableIndex, /* Index to the Id table */
4799 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
4800 {
4801         unsigned int    PhysPortMax;
4802         unsigned int    PhysPortIndex;
4803         unsigned int    Limit;
4804         unsigned int    Offset;
4805         int             Ret;
4806         SK_U32          Val32;
4807         SK_U64          Val64;
4808
4809         /*
4810          * Calculate the port indexes from the instance.
4811          */
4812         PhysPortMax = pAC->GIni.GIMacsFound;
4813
4814         if ((Instance != (SK_U32)(-1))) {
4815                 /* Check instance range */
4816                 if ((Instance < 1) || (Instance > PhysPortMax)) {
4817
4818                         *pLen = 0;
4819                         return (SK_PNMI_ERR_UNKNOWN_INST);
4820                 }
4821
4822                 /* Single net mode */
4823                 PhysPortIndex = Instance - 1;
4824
4825                 /* Dual net mode */
4826                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4827                         PhysPortIndex = NetIndex;
4828                 }
4829
4830                 /* Both net modes */
4831                 Limit = PhysPortIndex + 1;
4832         }
4833         else {
4834                 /* Single net mode */
4835                 PhysPortIndex = 0;
4836                 Limit = PhysPortMax;
4837
4838                 /* Dual net mode */
4839                 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4840                         PhysPortIndex = NetIndex;
4841                         Limit = PhysPortIndex + 1;
4842                 }
4843         }
4844
4845         /*
4846          * Currently only get requests are allowed.
4847          */
4848         if (Action != SK_PNMI_GET) {
4849
4850                 *pLen = 0;
4851                 return (SK_PNMI_ERR_READ_ONLY);
4852         }
4853
4854         /*
4855          * Check if the buffer length is large enough.
4856          */
4857         switch (Id) {
4858
4859         case OID_SKGE_RLMT_PORT_INDEX:
4860         case OID_SKGE_RLMT_STATUS:
4861                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4862
4863                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4864                         return (SK_PNMI_ERR_TOO_SHORT);
4865                 }
4866                 break;
4867
4868         case OID_SKGE_RLMT_TX_HELLO_CTS:
4869         case OID_SKGE_RLMT_RX_HELLO_CTS:
4870         case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4871         case OID_SKGE_RLMT_RX_SP_CTS:
4872                 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4873
4874                         *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4875                         return (SK_PNMI_ERR_TOO_SHORT);
4876                 }
4877                 break;
4878
4879         default:
4880                 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4881                         SK_PNMI_ERR039MSG);
4882
4883                 *pLen = 0;
4884                 return (SK_PNMI_ERR_GENERAL);
4885
4886         }
4887
4888         /*
4889          * Update statistic and increment semaphores to indicate that
4890          * an update was already done.
4891          */
4892         if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4893
4894                 *pLen = 0;
4895                 return (Ret);
4896         }
4897         pAC->Pnmi.RlmtUpdatedFlag ++;
4898
4899         /*
4900          * Get value
4901          */
4902         Offset = 0;
4903         for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4904
4905                 switch (Id) {
4906
4907                 case OID_SKGE_RLMT_PORT_INDEX:
4908                         Val32 = PhysPortIndex;
4909                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4910                         Offset += sizeof(SK_U32);
4911                         break;
4912
4913                 case OID_SKGE_RLMT_STATUS:
4914                         if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4915                                 SK_RLMT_PS_INIT ||
4916                                 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4917                                 SK_RLMT_PS_DOWN) {
4918
4919                                 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4920                         }
4921                         else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4922
4923                                 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4924                         }
4925                         else {
4926                                 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4927                         }
4928                         SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4929                         Offset += sizeof(SK_U32);
4930                         break;
4931
4932                 case OID_SKGE_RLMT_TX_HELLO_CTS:
4933                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4934                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4935                         Offset += sizeof(SK_U64);
4936                         break;
4937
4938                 case OID_SKGE_RLMT_RX_HELLO_CTS:
4939                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4940                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4941                         Offset += sizeof(SK_U64);
4942                         break;
4943
4944                 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4945                         Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4946                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4947                         Offset += sizeof(SK_U64);
4948                         break;
4949
4950                 case OID_SKGE_RLMT_RX_SP_CTS:
4951                         Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4952                         SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4953                         Offset += sizeof(SK_U64);
4954                         break;
4955
4956                 default:
4957                         SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4958                                 ("RlmtStat: Unknown OID should be errored before"));
4959
4960                         pAC->Pnmi.RlmtUpdatedFlag --;
4961                         *pLen = 0;
4962                         return (SK_PNMI_ERR_GENERAL);
4963                 }
4964         }
4965         *pLen = Offset;
4966
4967         pAC->Pnmi.RlmtUpdatedFlag --;
4968
4969         return (SK_PNMI_ERR_OK);
4970 }
4971
4972 /*****************************************************************************
4973  *
4974  * MacPrivateConf - OID handler function of OIDs concerning the configuration
4975  *
4976  * Description:
4977  *      Get/Presets/Sets the OIDs concerning the configuration.
4978  *
4979  * Returns:
4980  *      SK_PNMI_ERR_OK           The request was successfully performed.
4981  *      SK_PNMI_ERR_GENERAL      A general severe internal error occured.
4982  *      SK_PNMI_ERR_TOO_SHORT    The passed buffer is too short to contain
4983  *                               the correct data (e.g. a 32bit value is
4984  *                               needed, but a 16 bit value was passed).
4985  *      SK_PNMI_ERR_BAD_VALUE    The passed value is not in the valid
4986  *                               value range.
4987  *      SK_PNMI_ERR_READ_ONLY    The OID is read-only and cannot be set.
4988  *      SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4989  *                           exist (e.g. port instance 3 on a two port
4990  *                               adapter.
4991  */
4992 PNMI_STATIC int MacPrivateConf(
4993 SK_AC *pAC,             /* Pointer to adapter context */
4994 SK_IOC IoC,             /* IO context handle */
4995 int Action,             /* GET/PRESET/SET action */
4996 SK_U32 Id,              /* Object ID that is to be processed */
4997 char *pBuf,             /* Buffer used for the management data transfer */
4998 unsigned int *pLen,     /* On call: pBuf buffer length. On return: used buffer */
4999 SK_U32 Instance,        /* Instance (1..n) that is to be queried or -1 */
5000 unsigned int TableIndex, /* Index to the Id table */
5001 SK_U32 NetIndex)        /* NetIndex (0..n), in single net mode always zero */
5002 {
5003         unsigned int    PhysPortMax;
5004         unsigned int    PhysPortIndex;
5005         unsigned int    LogPortMax;
5006         unsigned int    LogPortIndex;
5007         unsigned int    Limit;
5008         unsigned int    Offset;
5009         char            Val8;
5010         char            *pBufPtr;
5011         int                     Ret;
5012         SK_EVPARA       EventParam;
5013         SK_U32          Val32;
5014
5015         /*
5016          * Calculate instance if wished. MAC index 0 is the virtual MAC.
5017          */
5018         PhysPortMax = pAC->GIni.GIMacsFound;
5019         LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5020
5021         if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5022                 LogPortMax--;
5023         }
5024
5025         if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5026                 /* Check instance range */
5027                 if ((Instance < 1) || (Instance > LogPortMax)) {
5028
5029                         *pLen = 0;
5030                         return (SK_PNMI_ERR_UNKNOWN_INST);
5031                 }
5032                 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5033                 Limit = LogPortIndex + 1;
5034         }
5035
5036         else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5037
5038                 LogPortIndex = 0;
5039                 Limit = LogPortMax;
5040         }
5041
5042         /*
5043          * Perform action
5044          */
5045         if (Action == SK_PNMI_GET) {
5046
5047                 /* Check length */
5048                 switch (Id) {
5049
5050                 case OID_SKGE_PMD:
5051                 case OID_SKGE_CONNECTOR:
5052                 case OID_SKGE_LINK_CAP:
5053                 case OID_SKGE_LINK_MODE:
5054                 case OID_SKGE_LINK_MODE_STATUS:
5055                 case OID_SKGE_LINK_STATUS:
5056                 case OID_SKGE_FLOWCTRL_CAP:
5057                 case OID_SKGE_FLOWCTRL_MODE:
5058                 case OID_SKGE_FLOWCTRL_STATUS:
5059                 case OID_SKGE_PHY_OPERATION_CAP:
5060                 case OID_SKGE_PHY_OPERATION_MODE:
5061                 case OID_SKGE_PHY_OPERATION_STATUS:
5062                 case OID_SKGE_SPEED_CAP:
5063                 case OID_SKGE_SPEED_MODE:
5064                 case OID_SKGE_SPEED_STATUS:
5065 #ifdef SK_PHY_LP_MODE
5066                 case OID_SKGE_PHY_LP_MODE:
5067 #endif
5068                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5069
5070                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5071                                 return (SK_PNMI_ERR_TOO_SHORT);
5072                         }
5073                         break;
5074
5075         case OID_SKGE_MTU:
5076         case OID_SKGE_PHY_TYPE:
5077                         if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5078
5079                                 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5080                                 return (SK_PNMI_ERR_TOO_SHORT);
5081                         }
5082                         break;
5083
5084                 default:
5085                         SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5086                                 SK_PNMI_ERR041MSG);
5087                         *pLen = 0;
5088                         return (SK_PNMI_ERR_GENERAL);
5089                 }
5090
5091                 /*
5092                  * Update statistic and increment semaphore to indicate
5093                  * that an update was already done.
5094                  */
5095                 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5096
5097                         *pLen = 0;
5098                         return (Ret);
5099                 }
5100                 pAC->Pnmi.SirqUpdatedFlag ++;
5101
5102                 /*
5103                  * Get value
5104                  */
5105                 Offset = 0;
5106                 for (; LogPortIndex < Limit; LogPortIndex ++) {
5107
5108                         pBufPtr = pBuf + Offset;
5109                         
5110                         switch (Id) {
5111
5112                         case OID_SKGE_PMD:
5113                                 *pBufPtr = pAC->Pnmi.PMD;
5114                                 Offset += sizeof(char);
5115                                 break;
5116
5117                         case OID_SKGE_CONNECTOR:
5118                                 *pBufPtr = pAC->Pnmi.Connector;
5119                                 Offset += sizeof(char);
5120                                 break;
5121
5122                         case OID_SKGE_PHY_TYPE:
5123                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5124                                         if (LogPortIndex == 0) {
5125                                                 continue;
5126                                         }
5127                                         else {
5128                                                 /* Get value for physical ports */
5129                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5130                                                         pAC, LogPortIndex);
5131                                                 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5132                                                 SK_PNMI_STORE_U32(pBufPtr, Val32);
5133                                         }
5134                                 }
5135                                 else { /* DualNetMode */
5136                                         
5137                                         Val32 = pAC->GIni.GP[NetIndex].PhyType;
5138                                         SK_PNMI_STORE_U32(pBufPtr, Val32);
5139                                 }
5140                                 Offset += sizeof(SK_U32);
5141                                 break;
5142
5143 #ifdef SK_PHY_LP_MODE
5144                         case OID_SKGE_PHY_LP_MODE:
5145                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5146                                         if (LogPortIndex == 0) {
5147                                                 continue;
5148                                         }
5149                                         else {
5150                                                 /* Get value for physical ports */
5151                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5152                                                 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5153                                                 *pBufPtr = Val8;
5154                                         }
5155                                 }
5156                                 else { /* DualNetMode */
5157                                         
5158                                         Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5159                                         *pBufPtr = Val8;
5160                                 }
5161                                 Offset += sizeof(SK_U8);
5162                                 break;
5163 #endif
5164
5165                         case OID_SKGE_LINK_CAP:
5166                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5167                                         if (LogPortIndex == 0) {
5168                                                 /* Get value for virtual port */
5169                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
5170                                         }
5171                                         else {
5172                                                 /* Get value for physical ports */
5173                                                 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5174                                                         pAC, LogPortIndex);
5175
5176                                                 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5177                                         }
5178                                 }
5179                                 else { /* DualNetMode */
5180                                         
5181                                         *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5182                                 }
5183                                 Offset += sizeof(char);
5184                                 break;
5185
5186                         case OID_SKGE_LINK_MODE:
5187                                 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5188                                         if (LogPortIndex == 0) {
5189                                                 /* Get value for virtual port */
5190                                                 VirtualConf(pAC, IoC, Id, pBufPtr);
5191                                         }
5192                                         else {
5193                        &n