aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skgepnmi.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-04-16 18:20:36 -0400
commit1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch)
tree0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/net/sk98lin/skgepnmi.c
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
Diffstat (limited to 'drivers/net/sk98lin/skgepnmi.c')
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8359
1 files changed, 8359 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
new file mode 100644
index 000000000000..58e1a5be913f
--- /dev/null
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -0,0 +1,8359 @@
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
27static 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 */
58int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
62 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
63int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
64 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
65int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
68 unsigned int *pLen, SK_U32 NetIndex);
69int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
70 unsigned int *pLen, SK_U32 NetIndex);
71int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
72int 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
80PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
81 PhysPortIndex);
82PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
83 PhysPortIndex);
84PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
85PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
86PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
87 unsigned int PhysPortIndex, unsigned int StatIndex);
88PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
89 unsigned int StatIndex, SK_U32 NetIndex);
90PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
91PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
92 unsigned int *pEntries);
93PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
94 unsigned int KeyArrLen, unsigned int *pKeyNo);
95PNMI_STATIC int LookupId(SK_U32 Id);
96PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
97 unsigned int LastMac);
98PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
99 unsigned int *pLen, SK_U32 NetIndex);
100PNMI_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);
102PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
103PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
104 unsigned int PortIndex);
105PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
106 unsigned int SensorIndex);
107PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
108PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
109PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
110PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
111PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
112PNMI_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);
114PNMI_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 */
129PNMI_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 */
199PNMI_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 */
355int SkPnmiInit(
356SK_AC *pAC, /* Pointer to adapter context */
357SK_IOC IoC, /* IO context handle */
358int 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 */
590int SkPnmiGetVar(
591SK_AC *pAC, /* Pointer to adapter context */
592SK_IOC IoC, /* IO context handle */
593SK_U32 Id, /* Object ID that is to be processed */
594void *pBuf, /* Buffer to which the management data will be copied */
595unsigned int *pLen, /* On call: buffer length. On return: used buffer */
596SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
597SK_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 */
632int SkPnmiPreSetVar(
633SK_AC *pAC, /* Pointer to adapter context */
634SK_IOC IoC, /* IO context handle */
635SK_U32 Id, /* Object ID that is to be processed */
636void *pBuf, /* Buffer to which the management data will be copied */
637unsigned int *pLen, /* Total length of management data */
638SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
639SK_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 */
675int SkPnmiSetVar(
676SK_AC *pAC, /* Pointer to adapter context */
677SK_IOC IoC, /* IO context handle */
678SK_U32 Id, /* Object ID that is to be processed */
679void *pBuf, /* Buffer to which the management data will be copied */
680unsigned int *pLen, /* Total length of management data */
681SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
682SK_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 */
711int SkPnmiGetStruct(
712SK_AC *pAC, /* Pointer to adapter context */
713SK_IOC IoC, /* IO context handle */
714void *pBuf, /* Buffer to which the management data will be copied. */
715unsigned int *pLen, /* Length of buffer */
716SK_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 */
889int SkPnmiPreSetStruct(
890SK_AC *pAC, /* Pointer to adapter context */
891SK_IOC IoC, /* IO context handle */
892void *pBuf, /* Buffer which contains the data to be set */
893unsigned int *pLen, /* Length of buffer */
894SK_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 */
927int SkPnmiSetStruct(
928SK_AC *pAC, /* Pointer to adapter context */
929SK_IOC IoC, /* IO context handle */
930void *pBuf, /* Buffer which contains the data to be set */
931unsigned int *pLen, /* Length of buffer */
932SK_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 */
992int SkPnmiEvent(
993SK_AC *pAC, /* Pointer to adapter context */
994SK_IOC IoC, /* IO context handle */
995SK_U32 Event, /* Event-Id */
996SK_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 */
1700PNMI_STATIC int PnmiVar(
1701SK_AC *pAC, /* Pointer to adapter context */
1702SK_IOC IoC, /* IO context handle */
1703int Action, /* GET/PRESET/SET action */
1704SK_U32 Id, /* Object ID that is to be processed */
1705char *pBuf, /* Buffer used for the management data transfer */
1706unsigned int *pLen, /* Total length of pBuf management data */
1707SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1708SK_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 */
1753PNMI_STATIC int PnmiStruct(
1754SK_AC *pAC, /* Pointer to adapter context */
1755SK_IOC IoC, /* IO context handle */
1756int Action, /* PRESET/SET action to be performed */
1757char *pBuf, /* Buffer used for the management data transfer */
1758unsigned int *pLen, /* Length of pBuf management data buffer */
1759SK_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 */
1918PNMI_STATIC int LookupId(
1919SK_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 */
1955PNMI_STATIC int OidStruct(
1956SK_AC *pAC, /* Pointer to adapter context */
1957SK_IOC IoC, /* IO context handle */
1958int Action, /* GET/PRESET/SET action */
1959SK_U32 Id, /* Object ID that is to be processed */
1960char *pBuf, /* Buffer used for the management data transfer */
1961unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1962SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1963unsigned int TableIndex, /* Index to the Id table */
1964SK_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 */
2022PNMI_STATIC int Perform(
2023SK_AC *pAC, /* Pointer to adapter context */
2024SK_IOC IoC, /* IO context handle */
2025int Action, /* GET/PRESET/SET action */
2026SK_U32 Id, /* Object ID that is to be processed */
2027char *pBuf, /* Buffer used for the management data transfer */
2028unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2029SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2030unsigned int TableIndex, /* Index to the Id table */
2031SK_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 */
2153PNMI_STATIC int Mac8023Stat(
2154SK_AC *pAC, /* Pointer to adapter context */
2155SK_IOC IoC, /* IO context handle */
2156int Action, /* GET/PRESET/SET action */
2157SK_U32 Id, /* Object ID that is to be processed */
2158char *pBuf, /* Buffer used for the management data transfer */
2159unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2160SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2161unsigned int TableIndex, /* Index to the Id table */
2162SK_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 */
2289PNMI_STATIC int MacPrivateStat(
2290SK_AC *pAC, /* Pointer to adapter context */
2291SK_IOC IoC, /* IO context handle */
2292int Action, /* GET/PRESET/SET action */
2293SK_U32 Id, /* Object ID that is to be processed */
2294char *pBuf, /* Buffer used for the management data transfer */
2295unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2296SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2297unsigned int TableIndex, /* Index to the Id table */
2298SK_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 */
2451PNMI_STATIC int Addr(
2452SK_AC *pAC, /* Pointer to adapter context */
2453SK_IOC IoC, /* IO context handle */
2454int Action, /* GET/PRESET/SET action */
2455SK_U32 Id, /* Object ID that is to be processed */
2456char *pBuf, /* Buffer used for the management data transfer */
2457unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2458SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2459unsigned int TableIndex, /* Index to the Id table */
2460SK_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 */
2652PNMI_STATIC int CsumStat(
2653SK_AC *pAC, /* Pointer to adapter context */
2654SK_IOC IoC, /* IO context handle */
2655int Action, /* GET/PRESET/SET action */
2656SK_U32 Id, /* Object ID that is to be processed */
2657char *pBuf, /* Buffer used for the management data transfer */
2658unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2659SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2660unsigned int TableIndex, /* Index to the Id table */
2661SK_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 */
2768PNMI_STATIC int SensorStat(
2769SK_AC *pAC, /* Pointer to adapter context */
2770SK_IOC IoC, /* IO context handle */
2771int Action, /* GET/PRESET/SET action */
2772SK_U32 Id, /* Object ID that is to be processed */
2773char *pBuf, /* Buffer used for the management data transfer */
2774unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2775SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2776unsigned int TableIndex, /* Index to the Id table */
2777SK_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 */
3013PNMI_STATIC int Vpd(
3014SK_AC *pAC, /* Pointer to adapter context */
3015SK_IOC IoC, /* IO context handle */
3016int Action, /* GET/PRESET/SET action */
3017SK_U32 Id, /* Object ID that is to be processed */
3018char *pBuf, /* Buffer used for the management data transfer */
3019unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3020SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3021unsigned int TableIndex, /* Index to the Id table */
3022SK_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 */
3487PNMI_STATIC int General(
3488SK_AC *pAC, /* Pointer to adapter context */
3489SK_IOC IoC, /* IO context handle */
3490int Action, /* GET/PRESET/SET action */
3491SK_U32 Id, /* Object ID that is to be processed */
3492char *pBuf, /* Buffer used for the management data transfer */
3493unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3494SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3495unsigned int TableIndex, /* Index to the Id table */
3496SK_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 */
4485PNMI_STATIC int Rlmt(
4486SK_AC *pAC, /* Pointer to adapter context */
4487SK_IOC IoC, /* IO context handle */
4488int Action, /* GET/PRESET/SET action */
4489SK_U32 Id, /* Object ID that is to be processed */
4490char *pBuf, /* Buffer used for the management data transfer */
4491unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4492SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4493unsigned int TableIndex, /* Index to the Id table */
4494SK_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 */
4790PNMI_STATIC int RlmtStat(
4791SK_AC *pAC, /* Pointer to adapter context */
4792SK_IOC IoC, /* IO context handle */
4793int Action, /* GET/PRESET/SET action */
4794SK_U32 Id, /* Object ID that is to be processed */
4795char *pBuf, /* Buffer used for the management data transfer */
4796unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4797SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4798unsigned int TableIndex, /* Index to the Id table */
4799SK_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 */
4992PNMI_STATIC int MacPrivateConf(
4993SK_AC *pAC, /* Pointer to adapter context */
4994SK_IOC IoC, /* IO context handle */
4995int Action, /* GET/PRESET/SET action */
4996SK_U32 Id, /* Object ID that is to be processed */
4997char *pBuf, /* Buffer used for the management data transfer */
4998unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4999SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5000unsigned int TableIndex, /* Index to the Id table */
5001SK_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 /* Get value for physical ports */
5194 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5195 pAC, LogPortIndex);
5196
5197 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5198 }
5199 }
5200 else { /* DualNetMode */
5201
5202 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5203 }
5204 Offset += sizeof(char);
5205 break;
5206
5207 case OID_SKGE_LINK_MODE_STATUS:
5208 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5209 if (LogPortIndex == 0) {
5210 /* Get value for virtual port */
5211 VirtualConf(pAC, IoC, Id, pBufPtr);
5212 }
5213 else {
5214 /* Get value for physical port */
5215 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5216 pAC, LogPortIndex);
5217
5218 *pBufPtr =
5219 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5220 }
5221 }
5222 else { /* DualNetMode */
5223
5224 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5225 }
5226 Offset += sizeof(char);
5227 break;
5228
5229 case OID_SKGE_LINK_STATUS:
5230 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5231 if (LogPortIndex == 0) {
5232 /* Get value for virtual port */
5233 VirtualConf(pAC, IoC, Id, pBufPtr);
5234 }
5235 else {
5236 /* Get value for physical ports */
5237 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5238 pAC, LogPortIndex);
5239
5240 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5241 }
5242 }
5243 else { /* DualNetMode */
5244
5245 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5246 }
5247 Offset += sizeof(char);
5248 break;
5249
5250 case OID_SKGE_FLOWCTRL_CAP:
5251 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5252 if (LogPortIndex == 0) {
5253 /* Get value for virtual port */
5254 VirtualConf(pAC, IoC, Id, pBufPtr);
5255 }
5256 else {
5257 /* Get value for physical ports */
5258 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5259 pAC, LogPortIndex);
5260
5261 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5262 }
5263 }
5264 else { /* DualNetMode */
5265
5266 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5267 }
5268 Offset += sizeof(char);
5269 break;
5270
5271 case OID_SKGE_FLOWCTRL_MODE:
5272 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5273 if (LogPortIndex == 0) {
5274 /* Get value for virtual port */
5275 VirtualConf(pAC, IoC, Id, pBufPtr);
5276 }
5277 else {
5278 /* Get value for physical port */
5279 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5280 pAC, LogPortIndex);
5281
5282 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5283 }
5284 }
5285 else { /* DualNetMode */
5286
5287 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5288 }
5289 Offset += sizeof(char);
5290 break;
5291
5292 case OID_SKGE_FLOWCTRL_STATUS:
5293 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5294 if (LogPortIndex == 0) {
5295 /* Get value for virtual port */
5296 VirtualConf(pAC, IoC, Id, pBufPtr);
5297 }
5298 else {
5299 /* Get value for physical port */
5300 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5301 pAC, LogPortIndex);
5302
5303 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5304 }
5305 }
5306 else { /* DualNetMode */
5307
5308 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5309 }
5310 Offset += sizeof(char);
5311 break;
5312
5313 case OID_SKGE_PHY_OPERATION_CAP:
5314 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5315 if (LogPortIndex == 0) {
5316 /* Get value for virtual port */
5317 VirtualConf(pAC, IoC, Id, pBufPtr);
5318 }
5319 else {
5320 /* Get value for physical ports */
5321 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5322 pAC, LogPortIndex);
5323
5324 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5325 }
5326 }
5327 else { /* DualNetMode */
5328
5329 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5330 }
5331 Offset += sizeof(char);
5332 break;
5333
5334 case OID_SKGE_PHY_OPERATION_MODE:
5335 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5336 if (LogPortIndex == 0) {
5337 /* Get value for virtual port */
5338 VirtualConf(pAC, IoC, Id, pBufPtr);
5339 }
5340 else {
5341 /* Get value for physical port */
5342 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5343 pAC, LogPortIndex);
5344
5345 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5346 }
5347 }
5348 else { /* DualNetMode */
5349
5350 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5351 }
5352 Offset += sizeof(char);
5353 break;
5354
5355 case OID_SKGE_PHY_OPERATION_STATUS:
5356 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5357 if (LogPortIndex == 0) {
5358 /* Get value for virtual port */
5359 VirtualConf(pAC, IoC, Id, pBufPtr);
5360 }
5361 else {
5362 /* Get value for physical port */
5363 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5364 pAC, LogPortIndex);
5365
5366 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5367 }
5368 }
5369 else {
5370
5371 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5372 }
5373 Offset += sizeof(char);
5374 break;
5375
5376 case OID_SKGE_SPEED_CAP:
5377 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5378 if (LogPortIndex == 0) {
5379 /* Get value for virtual port */
5380 VirtualConf(pAC, IoC, Id, pBufPtr);
5381 }
5382 else {
5383 /* Get value for physical ports */
5384 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5385 pAC, LogPortIndex);
5386
5387 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5388 }
5389 }
5390 else { /* DualNetMode */
5391
5392 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5393 }
5394 Offset += sizeof(char);
5395 break;
5396
5397 case OID_SKGE_SPEED_MODE:
5398 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5399 if (LogPortIndex == 0) {
5400 /* Get value for virtual port */
5401 VirtualConf(pAC, IoC, Id, pBufPtr);
5402 }
5403 else {
5404 /* Get value for physical port */
5405 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5406 pAC, LogPortIndex);
5407
5408 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5409 }
5410 }
5411 else { /* DualNetMode */
5412
5413 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5414 }
5415 Offset += sizeof(char);
5416 break;
5417
5418 case OID_SKGE_SPEED_STATUS:
5419 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5420 if (LogPortIndex == 0) {
5421 /* Get value for virtual port */
5422 VirtualConf(pAC, IoC, Id, pBufPtr);
5423 }
5424 else {
5425 /* Get value for physical port */
5426 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5427 pAC, LogPortIndex);
5428
5429 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5430 }
5431 }
5432 else { /* DualNetMode */
5433
5434 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5435 }
5436 Offset += sizeof(char);
5437 break;
5438
5439 case OID_SKGE_MTU:
5440 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5441 SK_PNMI_STORE_U32(pBufPtr, Val32);
5442 Offset += sizeof(SK_U32);
5443 break;
5444
5445 default:
5446 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5447 ("MacPrivateConf: Unknown OID should be handled before"));
5448
5449 pAC->Pnmi.SirqUpdatedFlag --;
5450 return (SK_PNMI_ERR_GENERAL);
5451 }
5452 }
5453 *pLen = Offset;
5454 pAC->Pnmi.SirqUpdatedFlag --;
5455
5456 return (SK_PNMI_ERR_OK);
5457 }
5458
5459 /*
5460 * From here SET or PRESET action. Check if the passed
5461 * buffer length is plausible.
5462 */
5463 switch (Id) {
5464
5465 case OID_SKGE_LINK_MODE:
5466 case OID_SKGE_FLOWCTRL_MODE:
5467 case OID_SKGE_PHY_OPERATION_MODE:
5468 case OID_SKGE_SPEED_MODE:
5469 if (*pLen < Limit - LogPortIndex) {
5470
5471 *pLen = Limit - LogPortIndex;
5472 return (SK_PNMI_ERR_TOO_SHORT);
5473 }
5474 if (*pLen != Limit - LogPortIndex) {
5475
5476 *pLen = 0;
5477 return (SK_PNMI_ERR_BAD_VALUE);
5478 }
5479 break;
5480
5481#ifdef SK_PHY_LP_MODE
5482 case OID_SKGE_PHY_LP_MODE:
5483 if (*pLen < Limit - LogPortIndex) {
5484
5485 *pLen = Limit - LogPortIndex;
5486 return (SK_PNMI_ERR_TOO_SHORT);
5487 }
5488 break;
5489#endif
5490
5491 case OID_SKGE_MTU:
5492 if (*pLen < sizeof(SK_U32)) {
5493
5494 *pLen = sizeof(SK_U32);
5495 return (SK_PNMI_ERR_TOO_SHORT);
5496 }
5497 if (*pLen != sizeof(SK_U32)) {
5498
5499 *pLen = 0;
5500 return (SK_PNMI_ERR_BAD_VALUE);
5501 }
5502 break;
5503
5504 default:
5505 *pLen = 0;
5506 return (SK_PNMI_ERR_READ_ONLY);
5507 }
5508
5509 /*
5510 * Perform preset or set
5511 */
5512 Offset = 0;
5513 for (; LogPortIndex < Limit; LogPortIndex ++) {
5514
5515 switch (Id) {
5516
5517 case OID_SKGE_LINK_MODE:
5518 /* Check the value range */
5519 Val8 = *(pBuf + Offset);
5520 if (Val8 == 0) {
5521
5522 Offset += sizeof(char);
5523 break;
5524 }
5525 if (Val8 < SK_LMODE_HALF ||
5526 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5527 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5528
5529 *pLen = 0;
5530 return (SK_PNMI_ERR_BAD_VALUE);
5531 }
5532
5533 /* The preset ends here */
5534 if (Action == SK_PNMI_PRESET) {
5535
5536 return (SK_PNMI_ERR_OK);
5537 }
5538
5539 if (LogPortIndex == 0) {
5540
5541 /*
5542 * The virtual port consists of all currently
5543 * active ports. Find them and send an event
5544 * with the new link mode to SIRQ.
5545 */
5546 for (PhysPortIndex = 0;
5547 PhysPortIndex < PhysPortMax;
5548 PhysPortIndex ++) {
5549
5550 if (!pAC->Pnmi.Port[PhysPortIndex].
5551 ActiveFlag) {
5552
5553 continue;
5554 }
5555
5556 EventParam.Para32[0] = PhysPortIndex;
5557 EventParam.Para32[1] = (SK_U32)Val8;
5558 if (SkGeSirqEvent(pAC, IoC,
5559 SK_HWEV_SET_LMODE,
5560 EventParam) > 0) {
5561
5562 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5563 SK_PNMI_ERR043,
5564 SK_PNMI_ERR043MSG);
5565
5566 *pLen = 0;
5567 return (SK_PNMI_ERR_GENERAL);
5568 }
5569 }
5570 }
5571 else {
5572 /*
5573 * Send an event with the new link mode to
5574 * the SIRQ module.
5575 */
5576 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5577 pAC, LogPortIndex);
5578 EventParam.Para32[1] = (SK_U32)Val8;
5579 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5580 EventParam) > 0) {
5581
5582 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5583 SK_PNMI_ERR043,
5584 SK_PNMI_ERR043MSG);
5585
5586 *pLen = 0;
5587 return (SK_PNMI_ERR_GENERAL);
5588 }
5589 }
5590 Offset += sizeof(char);
5591 break;
5592
5593 case OID_SKGE_FLOWCTRL_MODE:
5594 /* Check the value range */
5595 Val8 = *(pBuf + Offset);
5596 if (Val8 == 0) {
5597
5598 Offset += sizeof(char);
5599 break;
5600 }
5601 if (Val8 < SK_FLOW_MODE_NONE ||
5602 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5603 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5604
5605 *pLen = 0;
5606 return (SK_PNMI_ERR_BAD_VALUE);
5607 }
5608
5609 /* The preset ends here */
5610 if (Action == SK_PNMI_PRESET) {
5611
5612 return (SK_PNMI_ERR_OK);
5613 }
5614
5615 if (LogPortIndex == 0) {
5616
5617 /*
5618 * The virtual port consists of all currently
5619 * active ports. Find them and send an event
5620 * with the new flow control mode to SIRQ.
5621 */
5622 for (PhysPortIndex = 0;
5623 PhysPortIndex < PhysPortMax;
5624 PhysPortIndex ++) {
5625
5626 if (!pAC->Pnmi.Port[PhysPortIndex].
5627 ActiveFlag) {
5628
5629 continue;
5630 }
5631
5632 EventParam.Para32[0] = PhysPortIndex;
5633 EventParam.Para32[1] = (SK_U32)Val8;
5634 if (SkGeSirqEvent(pAC, IoC,
5635 SK_HWEV_SET_FLOWMODE,
5636 EventParam) > 0) {
5637
5638 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5639 SK_PNMI_ERR044,
5640 SK_PNMI_ERR044MSG);
5641
5642 *pLen = 0;
5643 return (SK_PNMI_ERR_GENERAL);
5644 }
5645 }
5646 }
5647 else {
5648 /*
5649 * Send an event with the new flow control
5650 * mode to the SIRQ module.
5651 */
5652 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5653 pAC, LogPortIndex);
5654 EventParam.Para32[1] = (SK_U32)Val8;
5655 if (SkGeSirqEvent(pAC, IoC,
5656 SK_HWEV_SET_FLOWMODE, EventParam)
5657 > 0) {
5658
5659 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5660 SK_PNMI_ERR044,
5661 SK_PNMI_ERR044MSG);
5662
5663 *pLen = 0;
5664 return (SK_PNMI_ERR_GENERAL);
5665 }
5666 }
5667 Offset += sizeof(char);
5668 break;
5669
5670 case OID_SKGE_PHY_OPERATION_MODE :
5671 /* Check the value range */
5672 Val8 = *(pBuf + Offset);
5673 if (Val8 == 0) {
5674 /* mode of this port remains unchanged */
5675 Offset += sizeof(char);
5676 break;
5677 }
5678 if (Val8 < SK_MS_MODE_AUTO ||
5679 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5680 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5681
5682 *pLen = 0;
5683 return (SK_PNMI_ERR_BAD_VALUE);
5684 }
5685
5686 /* The preset ends here */
5687 if (Action == SK_PNMI_PRESET) {
5688
5689 return (SK_PNMI_ERR_OK);
5690 }
5691
5692 if (LogPortIndex == 0) {
5693
5694 /*
5695 * The virtual port consists of all currently
5696 * active ports. Find them and send an event
5697 * with new master/slave (role) mode to SIRQ.
5698 */
5699 for (PhysPortIndex = 0;
5700 PhysPortIndex < PhysPortMax;
5701 PhysPortIndex ++) {
5702
5703 if (!pAC->Pnmi.Port[PhysPortIndex].
5704 ActiveFlag) {
5705
5706 continue;
5707 }
5708
5709 EventParam.Para32[0] = PhysPortIndex;
5710 EventParam.Para32[1] = (SK_U32)Val8;
5711 if (SkGeSirqEvent(pAC, IoC,
5712 SK_HWEV_SET_ROLE,
5713 EventParam) > 0) {
5714
5715 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5716 SK_PNMI_ERR042,
5717 SK_PNMI_ERR042MSG);
5718
5719 *pLen = 0;
5720 return (SK_PNMI_ERR_GENERAL);
5721 }
5722 }
5723 }
5724 else {
5725 /*
5726 * Send an event with the new master/slave
5727 * (role) mode to the SIRQ module.
5728 */
5729 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5730 pAC, LogPortIndex);
5731 EventParam.Para32[1] = (SK_U32)Val8;
5732 if (SkGeSirqEvent(pAC, IoC,
5733 SK_HWEV_SET_ROLE, EventParam) > 0) {
5734
5735 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5736 SK_PNMI_ERR042,
5737 SK_PNMI_ERR042MSG);
5738
5739 *pLen = 0;
5740 return (SK_PNMI_ERR_GENERAL);
5741 }
5742 }
5743
5744 Offset += sizeof(char);
5745 break;
5746
5747 case OID_SKGE_SPEED_MODE:
5748 /* Check the value range */
5749 Val8 = *(pBuf + Offset);
5750 if (Val8 == 0) {
5751
5752 Offset += sizeof(char);
5753 break;
5754 }
5755 if (Val8 < (SK_LSPEED_AUTO) ||
5756 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5757 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5758
5759 *pLen = 0;
5760 return (SK_PNMI_ERR_BAD_VALUE);
5761 }
5762
5763 /* The preset ends here */
5764 if (Action == SK_PNMI_PRESET) {
5765
5766 return (SK_PNMI_ERR_OK);
5767 }
5768
5769 if (LogPortIndex == 0) {
5770
5771 /*
5772 * The virtual port consists of all currently
5773 * active ports. Find them and send an event
5774 * with the new flow control mode to SIRQ.
5775 */
5776 for (PhysPortIndex = 0;
5777 PhysPortIndex < PhysPortMax;
5778 PhysPortIndex ++) {
5779
5780 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5781
5782 continue;
5783 }
5784
5785 EventParam.Para32[0] = PhysPortIndex;
5786 EventParam.Para32[1] = (SK_U32)Val8;
5787 if (SkGeSirqEvent(pAC, IoC,
5788 SK_HWEV_SET_SPEED,
5789 EventParam) > 0) {
5790
5791 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5792 SK_PNMI_ERR045,
5793 SK_PNMI_ERR045MSG);
5794
5795 *pLen = 0;
5796 return (SK_PNMI_ERR_GENERAL);
5797 }
5798 }
5799 }
5800 else {
5801 /*
5802 * Send an event with the new flow control
5803 * mode to the SIRQ module.
5804 */
5805 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5806 pAC, LogPortIndex);
5807 EventParam.Para32[1] = (SK_U32)Val8;
5808 if (SkGeSirqEvent(pAC, IoC,
5809 SK_HWEV_SET_SPEED,
5810 EventParam) > 0) {
5811
5812 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5813 SK_PNMI_ERR045,
5814 SK_PNMI_ERR045MSG);
5815
5816 *pLen = 0;
5817 return (SK_PNMI_ERR_GENERAL);
5818 }
5819 }
5820 Offset += sizeof(char);
5821 break;
5822
5823 case OID_SKGE_MTU :
5824 /* Check the value range */
5825 Val32 = *(SK_U32*)(pBuf + Offset);
5826 if (Val32 == 0) {
5827 /* mtu of this port remains unchanged */
5828 Offset += sizeof(SK_U32);
5829 break;
5830 }
5831 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5832 *pLen = 0;
5833 return (SK_PNMI_ERR_BAD_VALUE);
5834 }
5835
5836 /* The preset ends here */
5837 if (Action == SK_PNMI_PRESET) {
5838 return (SK_PNMI_ERR_OK);
5839 }
5840
5841 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5842 return (SK_PNMI_ERR_GENERAL);
5843 }
5844
5845 Offset += sizeof(SK_U32);
5846 break;
5847
5848#ifdef SK_PHY_LP_MODE
5849 case OID_SKGE_PHY_LP_MODE:
5850 /* The preset ends here */
5851 if (Action == SK_PNMI_PRESET) {
5852
5853 return (SK_PNMI_ERR_OK);
5854 }
5855
5856 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5857 if (LogPortIndex == 0) {
5858 Offset = 0;
5859 continue;
5860 }
5861 else {
5862 /* Set value for physical ports */
5863 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5864
5865 switch (*(pBuf + Offset)) {
5866 case 0:
5867 /* If LowPowerMode is active, we can leave it. */
5868 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5869
5870 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5871
5872 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5873
5874 SkDrvInitAdapter(pAC);
5875 }
5876 break;
5877 }
5878 else {
5879 *pLen = 0;
5880 return (SK_PNMI_ERR_GENERAL);
5881 }
5882 case 1:
5883 case 2:
5884 case 3:
5885 case 4:
5886 /* If no LowPowerMode is active, we can enter it. */
5887 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5888
5889 if ((*(pBuf + Offset)) < 3) {
5890
5891 SkDrvDeInitAdapter(pAC);
5892 }
5893
5894 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5895 break;
5896 }
5897 else {
5898 *pLen = 0;
5899 return (SK_PNMI_ERR_GENERAL);
5900 }
5901 default:
5902 *pLen = 0;
5903 return (SK_PNMI_ERR_BAD_VALUE);
5904 }
5905 }
5906 }
5907 else { /* DualNetMode */
5908
5909 switch (*(pBuf + Offset)) {
5910 case 0:
5911 /* If we are in a LowPowerMode, we can leave it. */
5912 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5913
5914 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5915
5916 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5917
5918 SkDrvInitAdapter(pAC);
5919 }
5920 break;
5921 }
5922 else {
5923 *pLen = 0;
5924 return (SK_PNMI_ERR_GENERAL);
5925 }
5926
5927 case 1:
5928 case 2:
5929 case 3:
5930 case 4:
5931 /* If we are not already in LowPowerMode, we can enter it. */
5932 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5933
5934 if ((*(pBuf + Offset)) < 3) {
5935
5936 SkDrvDeInitAdapter(pAC);
5937 }
5938 else {
5939
5940 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5941 }
5942 break;
5943 }
5944 else {
5945 *pLen = 0;
5946 return (SK_PNMI_ERR_GENERAL);
5947 }
5948
5949 default:
5950 *pLen = 0;
5951 return (SK_PNMI_ERR_BAD_VALUE);
5952 }
5953 }
5954 Offset += sizeof(SK_U8);
5955 break;
5956#endif
5957
5958 default:
5959 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5960 ("MacPrivateConf: Unknown OID should be handled before set"));
5961
5962 *pLen = 0;
5963 return (SK_PNMI_ERR_GENERAL);
5964 }
5965 }
5966
5967 return (SK_PNMI_ERR_OK);
5968}
5969
5970/*****************************************************************************
5971 *
5972 * Monitor - OID handler function for RLMT_MONITOR_XXX
5973 *
5974 * Description:
5975 * Because RLMT currently does not support the monitoring of
5976 * remote adapter cards, we return always an empty table.
5977 *
5978 * Returns:
5979 * SK_PNMI_ERR_OK The request was successfully performed.
5980 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5981 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5982 * the correct data (e.g. a 32bit value is
5983 * needed, but a 16 bit value was passed).
5984 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5985 * value range.
5986 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5987 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5988 * exist (e.g. port instance 3 on a two port
5989 * adapter.
5990 */
5991PNMI_STATIC int Monitor(
5992SK_AC *pAC, /* Pointer to adapter context */
5993SK_IOC IoC, /* IO context handle */
5994int Action, /* GET/PRESET/SET action */
5995SK_U32 Id, /* Object ID that is to be processed */
5996char *pBuf, /* Buffer used for the management data transfer */
5997unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5998SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5999unsigned int TableIndex, /* Index to the Id table */
6000SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
6001{
6002 unsigned int Index;
6003 unsigned int Limit;
6004 unsigned int Offset;
6005 unsigned int Entries;
6006
6007
6008 /*
6009 * Calculate instance if wished.
6010 */
6011 /* XXX Not yet implemented. Return always an empty table. */
6012 Entries = 0;
6013
6014 if ((Instance != (SK_U32)(-1))) {
6015
6016 if ((Instance < 1) || (Instance > Entries)) {
6017
6018 *pLen = 0;
6019 return (SK_PNMI_ERR_UNKNOWN_INST);
6020 }
6021
6022 Index = (unsigned int)Instance - 1;
6023 Limit = (unsigned int)Instance;
6024 }
6025 else {
6026 Index = 0;
6027 Limit = Entries;
6028 }
6029
6030 /*
6031 * Get/Set value
6032 */
6033 if (Action == SK_PNMI_GET) {
6034
6035 for (Offset=0; Index < Limit; Index ++) {
6036
6037 switch (Id) {
6038
6039 case OID_SKGE_RLMT_MONITOR_INDEX:
6040 case OID_SKGE_RLMT_MONITOR_ADDR:
6041 case OID_SKGE_RLMT_MONITOR_ERRS:
6042 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6043 case OID_SKGE_RLMT_MONITOR_ADMIN:
6044 break;
6045
6046 default:
6047 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6048 SK_PNMI_ERR046MSG);
6049
6050 *pLen = 0;
6051 return (SK_PNMI_ERR_GENERAL);
6052 }
6053 }
6054 *pLen = Offset;
6055 }
6056 else {
6057 /* Only MONITOR_ADMIN can be set */
6058 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6059
6060 *pLen = 0;
6061 return (SK_PNMI_ERR_READ_ONLY);
6062 }
6063
6064 /* Check if the length is plausible */
6065 if (*pLen < (Limit - Index)) {
6066
6067 return (SK_PNMI_ERR_TOO_SHORT);
6068 }
6069 /* Okay, we have a wide value range */
6070 if (*pLen != (Limit - Index)) {
6071
6072 *pLen = 0;
6073 return (SK_PNMI_ERR_BAD_VALUE);
6074 }
6075/*
6076 for (Offset=0; Index < Limit; Index ++) {
6077 }
6078*/
6079/*
6080 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6081 * is empty.
6082 */
6083 *pLen = 0;
6084 return (SK_PNMI_ERR_BAD_VALUE);
6085 }
6086
6087 return (SK_PNMI_ERR_OK);
6088}
6089
6090/*****************************************************************************
6091 *
6092 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6093 *
6094 * Description:
6095 * We handle here the get of the configuration group OIDs, which are
6096 * a little bit complicated. The virtual port consists of all currently
6097 * active physical ports. If multiple ports are active and configured
6098 * differently we get in some trouble to return a single value. So we
6099 * get the value of the first active port and compare it with that of
6100 * the other active ports. If they are not the same, we return a value
6101 * that indicates that the state is indeterminated.
6102 *
6103 * Returns:
6104 * Nothing
6105 */
6106PNMI_STATIC void VirtualConf(
6107SK_AC *pAC, /* Pointer to adapter context */
6108SK_IOC IoC, /* IO context handle */
6109SK_U32 Id, /* Object ID that is to be processed */
6110char *pBuf) /* Buffer used for the management data transfer */
6111{
6112 unsigned int PhysPortMax;
6113 unsigned int PhysPortIndex;
6114 SK_U8 Val8;
6115 SK_U32 Val32;
6116 SK_BOOL PortActiveFlag;
6117 SK_GEPORT *pPrt;
6118
6119 *pBuf = 0;
6120 PortActiveFlag = SK_FALSE;
6121 PhysPortMax = pAC->GIni.GIMacsFound;
6122
6123 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6124 PhysPortIndex ++) {
6125
6126 pPrt = &pAC->GIni.GP[PhysPortIndex];
6127
6128 /* Check if the physical port is active */
6129 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6130
6131 continue;
6132 }
6133
6134 PortActiveFlag = SK_TRUE;
6135
6136 switch (Id) {
6137
6138 case OID_SKGE_PHY_TYPE:
6139 /* Check if it is the first active port */
6140 if (*pBuf == 0) {
6141 Val32 = pPrt->PhyType;
6142 SK_PNMI_STORE_U32(pBuf, Val32);
6143 continue;
6144 }
6145
6146 case OID_SKGE_LINK_CAP:
6147
6148 /*
6149 * Different capabilities should not happen, but
6150 * in the case of the cases OR them all together.
6151 * From a curious point of view the virtual port
6152 * is capable of all found capabilities.
6153 */
6154 *pBuf |= pPrt->PLinkCap;
6155 break;
6156
6157 case OID_SKGE_LINK_MODE:
6158 /* Check if it is the first active port */
6159 if (*pBuf == 0) {
6160
6161 *pBuf = pPrt->PLinkModeConf;
6162 continue;
6163 }
6164
6165 /*
6166 * If we find an active port with a different link
6167 * mode than the first one we return a value that
6168 * indicates that the link mode is indeterminated.
6169 */
6170 if (*pBuf != pPrt->PLinkModeConf) {
6171
6172 *pBuf = SK_LMODE_INDETERMINATED;
6173 }
6174 break;
6175
6176 case OID_SKGE_LINK_MODE_STATUS:
6177 /* Get the link mode of the physical port */
6178 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6179
6180 /* Check if it is the first active port */
6181 if (*pBuf == 0) {
6182
6183 *pBuf = Val8;
6184 continue;
6185 }
6186
6187 /*
6188 * If we find an active port with a different link
6189 * mode status than the first one we return a value
6190 * that indicates that the link mode status is
6191 * indeterminated.
6192 */
6193 if (*pBuf != Val8) {
6194
6195 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6196 }
6197 break;
6198
6199 case OID_SKGE_LINK_STATUS:
6200 /* Get the link status of the physical port */
6201 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6202
6203 /* Check if it is the first active port */
6204 if (*pBuf == 0) {
6205
6206 *pBuf = Val8;
6207 continue;
6208 }
6209
6210 /*
6211 * If we find an active port with a different link
6212 * status than the first one, we return a value
6213 * that indicates that the link status is
6214 * indeterminated.
6215 */
6216 if (*pBuf != Val8) {
6217
6218 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6219 }
6220 break;
6221
6222 case OID_SKGE_FLOWCTRL_CAP:
6223 /* Check if it is the first active port */
6224 if (*pBuf == 0) {
6225
6226 *pBuf = pPrt->PFlowCtrlCap;
6227 continue;
6228 }
6229
6230 /*
6231 * From a curious point of view the virtual port
6232 * is capable of all found capabilities.
6233 */
6234 *pBuf |= pPrt->PFlowCtrlCap;
6235 break;
6236
6237 case OID_SKGE_FLOWCTRL_MODE:
6238 /* Check if it is the first active port */
6239 if (*pBuf == 0) {
6240
6241 *pBuf = pPrt->PFlowCtrlMode;
6242 continue;
6243 }
6244
6245 /*
6246 * If we find an active port with a different flow
6247 * control mode than the first one, we return a value
6248 * that indicates that the mode is indeterminated.
6249 */
6250 if (*pBuf != pPrt->PFlowCtrlMode) {
6251
6252 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6253 }
6254 break;
6255
6256 case OID_SKGE_FLOWCTRL_STATUS:
6257 /* Check if it is the first active port */
6258 if (*pBuf == 0) {
6259
6260 *pBuf = pPrt->PFlowCtrlStatus;
6261 continue;
6262 }
6263
6264 /*
6265 * If we find an active port with a different flow
6266 * control status than the first one, we return a
6267 * value that indicates that the status is
6268 * indeterminated.
6269 */
6270 if (*pBuf != pPrt->PFlowCtrlStatus) {
6271
6272 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6273 }
6274 break;
6275
6276 case OID_SKGE_PHY_OPERATION_CAP:
6277 /* Check if it is the first active port */
6278 if (*pBuf == 0) {
6279
6280 *pBuf = pPrt->PMSCap;
6281 continue;
6282 }
6283
6284 /*
6285 * From a curious point of view the virtual port
6286 * is capable of all found capabilities.
6287 */
6288 *pBuf |= pPrt->PMSCap;
6289 break;
6290
6291 case OID_SKGE_PHY_OPERATION_MODE:
6292 /* Check if it is the first active port */
6293 if (*pBuf == 0) {
6294
6295 *pBuf = pPrt->PMSMode;
6296 continue;
6297 }
6298
6299 /*
6300 * If we find an active port with a different master/
6301 * slave mode than the first one, we return a value
6302 * that indicates that the mode is indeterminated.
6303 */
6304 if (*pBuf != pPrt->PMSMode) {
6305
6306 *pBuf = SK_MS_MODE_INDETERMINATED;
6307 }
6308 break;
6309
6310 case OID_SKGE_PHY_OPERATION_STATUS:
6311 /* Check if it is the first active port */
6312 if (*pBuf == 0) {
6313
6314 *pBuf = pPrt->PMSStatus;
6315 continue;
6316 }
6317
6318 /*
6319 * If we find an active port with a different master/
6320 * slave status than the first one, we return a
6321 * value that indicates that the status is
6322 * indeterminated.
6323 */
6324 if (*pBuf != pPrt->PMSStatus) {
6325
6326 *pBuf = SK_MS_STAT_INDETERMINATED;
6327 }
6328 break;
6329
6330 case OID_SKGE_SPEED_MODE:
6331 /* Check if it is the first active port */
6332 if (*pBuf == 0) {
6333
6334 *pBuf = pPrt->PLinkSpeed;
6335 continue;
6336 }
6337
6338 /*
6339 * If we find an active port with a different flow
6340 * control mode than the first one, we return a value
6341 * that indicates that the mode is indeterminated.
6342 */
6343 if (*pBuf != pPrt->PLinkSpeed) {
6344
6345 *pBuf = SK_LSPEED_INDETERMINATED;
6346 }
6347 break;
6348
6349 case OID_SKGE_SPEED_STATUS:
6350 /* Check if it is the first active port */
6351 if (*pBuf == 0) {
6352
6353 *pBuf = pPrt->PLinkSpeedUsed;
6354 continue;
6355 }
6356
6357 /*
6358 * If we find an active port with a different flow
6359 * control status than the first one, we return a
6360 * value that indicates that the status is
6361 * indeterminated.
6362 */
6363 if (*pBuf != pPrt->PLinkSpeedUsed) {
6364
6365 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6366 }
6367 break;
6368 }
6369 }
6370
6371 /*
6372 * If no port is active return an indeterminated answer
6373 */
6374 if (!PortActiveFlag) {
6375
6376 switch (Id) {
6377
6378 case OID_SKGE_LINK_CAP:
6379 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6380 break;
6381
6382 case OID_SKGE_LINK_MODE:
6383 *pBuf = SK_LMODE_INDETERMINATED;
6384 break;
6385
6386 case OID_SKGE_LINK_MODE_STATUS:
6387 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6388 break;
6389
6390 case OID_SKGE_LINK_STATUS:
6391 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6392 break;
6393
6394 case OID_SKGE_FLOWCTRL_CAP:
6395 case OID_SKGE_FLOWCTRL_MODE:
6396 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6397 break;
6398
6399 case OID_SKGE_FLOWCTRL_STATUS:
6400 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6401 break;
6402
6403 case OID_SKGE_PHY_OPERATION_CAP:
6404 *pBuf = SK_MS_CAP_INDETERMINATED;
6405 break;
6406
6407 case OID_SKGE_PHY_OPERATION_MODE:
6408 *pBuf = SK_MS_MODE_INDETERMINATED;
6409 break;
6410
6411 case OID_SKGE_PHY_OPERATION_STATUS:
6412 *pBuf = SK_MS_STAT_INDETERMINATED;
6413 break;
6414 case OID_SKGE_SPEED_CAP:
6415 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6416 break;
6417
6418 case OID_SKGE_SPEED_MODE:
6419 *pBuf = SK_LSPEED_INDETERMINATED;
6420 break;
6421
6422 case OID_SKGE_SPEED_STATUS:
6423 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6424 break;
6425 }
6426 }
6427}
6428
6429/*****************************************************************************
6430 *
6431 * CalculateLinkStatus - Determins the link status of a physical port
6432 *
6433 * Description:
6434 * Determins the link status the following way:
6435 * LSTAT_PHY_DOWN: Link is down
6436 * LSTAT_AUTONEG: Auto-negotiation failed
6437 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6438 * logically up.
6439 * LSTAT_LOG_UP: RLMT marked the port as up
6440 *
6441 * Returns:
6442 * Link status of physical port
6443 */
6444PNMI_STATIC SK_U8 CalculateLinkStatus(
6445SK_AC *pAC, /* Pointer to adapter context */
6446SK_IOC IoC, /* IO context handle */
6447unsigned int PhysPortIndex) /* Physical port index */
6448{
6449 SK_U8 Result;
6450
6451 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6452
6453 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6454 }
6455 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6456
6457 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6458 }
6459 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6460
6461 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6462 }
6463 else {
6464 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6465 }
6466
6467 return (Result);
6468}
6469
6470/*****************************************************************************
6471 *
6472 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6473 *
6474 * Description:
6475 * The COMMON module only tells us if the mode is half or full duplex.
6476 * But in the decade of auto sensing it is usefull for the user to
6477 * know if the mode was negotiated or forced. Therefore we have a
6478 * look to the mode, which was last used by the negotiation process.
6479 *
6480 * Returns:
6481 * The link mode status
6482 */
6483PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6484SK_AC *pAC, /* Pointer to adapter context */
6485SK_IOC IoC, /* IO context handle */
6486unsigned int PhysPortIndex) /* Physical port index */
6487{
6488 SK_U8 Result;
6489
6490 /* Get the current mode, which can be full or half duplex */
6491 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6492
6493 /* Check if no valid mode could be found (link is down) */
6494 if (Result < SK_LMODE_STAT_HALF) {
6495
6496 Result = SK_LMODE_STAT_UNKNOWN;
6497 }
6498 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6499
6500 /*
6501 * Auto-negotiation was used to bring up the link. Change
6502 * the already found duplex status that it indicates
6503 * auto-negotiation was involved.
6504 */
6505 if (Result == SK_LMODE_STAT_HALF) {
6506
6507 Result = SK_LMODE_STAT_AUTOHALF;
6508 }
6509 else if (Result == SK_LMODE_STAT_FULL) {
6510
6511 Result = SK_LMODE_STAT_AUTOFULL;
6512 }
6513 }
6514
6515 return (Result);
6516}
6517
6518/*****************************************************************************
6519 *
6520 * GetVpdKeyArr - Obtain an array of VPD keys
6521 *
6522 * Description:
6523 * Read the VPD keys and build an array of VPD keys, which are
6524 * easy to access.
6525 *
6526 * Returns:
6527 * SK_PNMI_ERR_OK Task successfully performed.
6528 * SK_PNMI_ERR_GENERAL Something went wrong.
6529 */
6530PNMI_STATIC int GetVpdKeyArr(
6531SK_AC *pAC, /* Pointer to adapter context */
6532SK_IOC IoC, /* IO context handle */
6533char *pKeyArr, /* Ptr KeyArray */
6534unsigned int KeyArrLen, /* Length of array in bytes */
6535unsigned int *pKeyNo) /* Number of keys */
6536{
6537 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6538 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6539 unsigned int StartOffset;
6540 unsigned int Offset;
6541 int Index;
6542 int Ret;
6543
6544
6545 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6546
6547 /*
6548 * Get VPD key list
6549 */
6550 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6551 (int *)pKeyNo);
6552 if (Ret > 0) {
6553
6554 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6555 SK_PNMI_ERR014MSG);
6556
6557 return (SK_PNMI_ERR_GENERAL);
6558 }
6559 /* If no keys are available return now */
6560 if (*pKeyNo == 0 || BufKeysLen == 0) {
6561
6562 return (SK_PNMI_ERR_OK);
6563 }
6564 /*
6565 * If the key list is too long for us trunc it and give a
6566 * errorlog notification. This case should not happen because
6567 * the maximum number of keys is limited due to RAM limitations
6568 */
6569 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6570
6571 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6572 SK_PNMI_ERR015MSG);
6573
6574 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6575 }
6576
6577 /*
6578 * Now build an array of fixed string length size and copy
6579 * the keys together.
6580 */
6581 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6582 Offset ++) {
6583
6584 if (BufKeys[Offset] != 0) {
6585
6586 continue;
6587 }
6588
6589 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6590
6591 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6592 SK_PNMI_ERR016MSG);
6593 return (SK_PNMI_ERR_GENERAL);
6594 }
6595
6596 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6597 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6598
6599 Index ++;
6600 StartOffset = Offset + 1;
6601 }
6602
6603 /* Last key not zero terminated? Get it anyway */
6604 if (StartOffset < Offset) {
6605
6606 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6607 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6608 }
6609
6610 return (SK_PNMI_ERR_OK);
6611}
6612
6613/*****************************************************************************
6614 *
6615 * SirqUpdate - Let the SIRQ update its internal values
6616 *
6617 * Description:
6618 * Just to be sure that the SIRQ module holds its internal data
6619 * structures up to date, we send an update event before we make
6620 * any access.
6621 *
6622 * Returns:
6623 * SK_PNMI_ERR_OK Task successfully performed.
6624 * SK_PNMI_ERR_GENERAL Something went wrong.
6625 */
6626PNMI_STATIC int SirqUpdate(
6627SK_AC *pAC, /* Pointer to adapter context */
6628SK_IOC IoC) /* IO context handle */
6629{
6630 SK_EVPARA EventParam;
6631
6632
6633 /* Was the module already updated during the current PNMI call? */
6634 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6635
6636 return (SK_PNMI_ERR_OK);
6637 }
6638
6639 /* Send an synchronuous update event to the module */
6640 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6641 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6642
6643 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6644 SK_PNMI_ERR047MSG);
6645
6646 return (SK_PNMI_ERR_GENERAL);
6647 }
6648
6649 return (SK_PNMI_ERR_OK);
6650}
6651
6652/*****************************************************************************
6653 *
6654 * RlmtUpdate - Let the RLMT update its internal values
6655 *
6656 * Description:
6657 * Just to be sure that the RLMT module holds its internal data
6658 * structures up to date, we send an update event before we make
6659 * any access.
6660 *
6661 * Returns:
6662 * SK_PNMI_ERR_OK Task successfully performed.
6663 * SK_PNMI_ERR_GENERAL Something went wrong.
6664 */
6665PNMI_STATIC int RlmtUpdate(
6666SK_AC *pAC, /* Pointer to adapter context */
6667SK_IOC IoC, /* IO context handle */
6668SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6669{
6670 SK_EVPARA EventParam;
6671
6672
6673 /* Was the module already updated during the current PNMI call? */
6674 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6675
6676 return (SK_PNMI_ERR_OK);
6677 }
6678
6679 /* Send an synchronuous update event to the module */
6680 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6681 EventParam.Para32[0] = NetIndex;
6682 EventParam.Para32[1] = (SK_U32)-1;
6683 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6684
6685 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6686 SK_PNMI_ERR048MSG);
6687
6688 return (SK_PNMI_ERR_GENERAL);
6689 }
6690
6691 return (SK_PNMI_ERR_OK);
6692}
6693
6694/*****************************************************************************
6695 *
6696 * MacUpdate - Force the XMAC to output the current statistic
6697 *
6698 * Description:
6699 * The XMAC holds its statistic internally. To obtain the current
6700 * values we must send a command so that the statistic data will
6701 * be written to a predefined memory area on the adapter.
6702 *
6703 * Returns:
6704 * SK_PNMI_ERR_OK Task successfully performed.
6705 * SK_PNMI_ERR_GENERAL Something went wrong.
6706 */
6707PNMI_STATIC int MacUpdate(
6708SK_AC *pAC, /* Pointer to adapter context */
6709SK_IOC IoC, /* IO context handle */
6710unsigned int FirstMac, /* Index of the first Mac to be updated */
6711unsigned int LastMac) /* Index of the last Mac to be updated */
6712{
6713 unsigned int MacIndex;
6714
6715 /*
6716 * Were the statistics already updated during the
6717 * current PNMI call?
6718 */
6719 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6720
6721 return (SK_PNMI_ERR_OK);
6722 }
6723
6724 /* Send an update command to all MACs specified */
6725 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6726
6727 /*
6728 * 2002-09-13 pweber: Freeze the current SW counters.
6729 * (That should be done as close as
6730 * possible to the update of the
6731 * HW counters)
6732 */
6733 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6734 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6735 }
6736
6737 /* 2002-09-13 pweber: Update the HW counter */
6738 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6739
6740 return (SK_PNMI_ERR_GENERAL);
6741 }
6742 }
6743
6744 return (SK_PNMI_ERR_OK);
6745}
6746
6747/*****************************************************************************
6748 *
6749 * GetStatVal - Retrieve an XMAC statistic counter
6750 *
6751 * Description:
6752 * Retrieves the statistic counter of a virtual or physical port. The
6753 * virtual port is identified by the index 0. It consists of all
6754 * currently active ports. To obtain the counter value for this port
6755 * we must add the statistic counter of all active ports. To grant
6756 * continuous counter values for the virtual port even when port
6757 * switches occur we must additionally add a delta value, which was
6758 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6759 *
6760 * Returns:
6761 * Requested statistic value
6762 */
6763PNMI_STATIC SK_U64 GetStatVal(
6764SK_AC *pAC, /* Pointer to adapter context */
6765SK_IOC IoC, /* IO context handle */
6766unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6767unsigned int StatIndex, /* Index to statistic value */
6768SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6769{
6770 unsigned int PhysPortIndex;
6771 unsigned int PhysPortMax;
6772 SK_U64 Val = 0;
6773
6774
6775 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6776
6777 PhysPortIndex = NetIndex;
6778
6779 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6780 }
6781 else { /* Single Net mode */
6782
6783 if (LogPortIndex == 0) {
6784
6785 PhysPortMax = pAC->GIni.GIMacsFound;
6786
6787 /* Add counter of all active ports */
6788 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6789 PhysPortIndex ++) {
6790
6791 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6792
6793 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6794 }
6795 }
6796
6797 /* Correct value because of port switches */
6798 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6799 }
6800 else {
6801 /* Get counter value of physical port */
6802 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6803
6804 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6805 }
6806 }
6807 return (Val);
6808}
6809
6810/*****************************************************************************
6811 *
6812 * GetPhysStatVal - Get counter value for physical port
6813 *
6814 * Description:
6815 * Builds a 64bit counter value. Except for the octet counters
6816 * the lower 32bit are counted in hardware and the upper 32bit
6817 * in software by monitoring counter overflow interrupts in the
6818 * event handler. To grant continous counter values during XMAC
6819 * resets (caused by a workaround) we must add a delta value.
6820 * The delta was calculated in the event handler when a
6821 * SK_PNMI_EVT_XMAC_RESET was received.
6822 *
6823 * Returns:
6824 * Counter value
6825 */
6826PNMI_STATIC SK_U64 GetPhysStatVal(
6827SK_AC *pAC, /* Pointer to adapter context */
6828SK_IOC IoC, /* IO context handle */
6829unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6830unsigned int StatIndex) /* Index to statistic value */
6831{
6832 SK_U64 Val = 0;
6833 SK_U32 LowVal = 0;
6834 SK_U32 HighVal = 0;
6835 SK_U16 Word;
6836 int MacType;
6837 unsigned int HelpIndex;
6838 SK_GEPORT *pPrt;
6839
6840 SK_PNMI_PORT *pPnmiPrt;
6841 SK_GEMACFUNC *pFnMac;
6842
6843 pPrt = &pAC->GIni.GP[PhysPortIndex];
6844
6845 MacType = pAC->GIni.GIMacType;
6846
6847 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6848 if (MacType == SK_MAC_XMAC) {
6849 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6850 }
6851 else {
6852 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6853 }
6854
6855 pFnMac = &pAC->GIni.GIFunc;
6856
6857 switch (StatIndex) {
6858 case SK_PNMI_HTX:
6859 if (MacType == SK_MAC_GMAC) {
6860 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6861 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6862 &LowVal);
6863 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6864 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6865 &HighVal);
6866 LowVal += HighVal;
6867 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6868 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6869 &HighVal);
6870 LowVal += HighVal;
6871 }
6872 else {
6873 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6874 StatAddr[StatIndex][MacType].Reg,
6875 &LowVal);
6876 }
6877 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6878 break;
6879
6880 case SK_PNMI_HRX:
6881 if (MacType == SK_MAC_GMAC) {
6882 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6883 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6884 &LowVal);
6885 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6886 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6887 &HighVal);
6888 LowVal += HighVal;
6889 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6890 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6891 &HighVal);
6892 LowVal += HighVal;
6893 }
6894 else {
6895 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6896 StatAddr[StatIndex][MacType].Reg,
6897 &LowVal);
6898 }
6899 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6900 break;
6901
6902 case SK_PNMI_HTX_OCTET:
6903 case SK_PNMI_HRX_OCTET:
6904 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6905 StatAddr[StatIndex][MacType].Reg,
6906 &HighVal);
6907 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6908 StatAddr[StatIndex + 1][MacType].Reg,
6909 &LowVal);
6910 break;
6911
6912 case SK_PNMI_HTX_BURST:
6913 case SK_PNMI_HTX_EXCESS_DEF:
6914 case SK_PNMI_HTX_CARRIER:
6915 /* Not supported by GMAC */
6916 if (MacType == SK_MAC_GMAC) {
6917 return (Val);
6918 }
6919
6920 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6921 StatAddr[StatIndex][MacType].Reg,
6922 &LowVal);
6923 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6924 break;
6925
6926 case SK_PNMI_HTX_MACC:
6927 /* GMAC only supports PAUSE MAC control frames */
6928 if (MacType == SK_MAC_GMAC) {
6929 HelpIndex = SK_PNMI_HTX_PMACC;
6930 }
6931 else {
6932 HelpIndex = StatIndex;
6933 }
6934
6935 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6936 StatAddr[HelpIndex][MacType].Reg,
6937 &LowVal);
6938
6939 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6940 break;
6941
6942 case SK_PNMI_HTX_COL:
6943 case SK_PNMI_HRX_UNDERSIZE:
6944 /* Not supported by XMAC */
6945 if (MacType == SK_MAC_XMAC) {
6946 return (Val);
6947 }
6948
6949 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6950 StatAddr[StatIndex][MacType].Reg,
6951 &LowVal);
6952 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6953 break;
6954
6955 case SK_PNMI_HTX_DEFFERAL:
6956 /* Not supported by GMAC */
6957 if (MacType == SK_MAC_GMAC) {
6958 return (Val);
6959 }
6960
6961 /*
6962 * XMAC counts frames with deferred transmission
6963 * even in full-duplex mode.
6964 *
6965 * In full-duplex mode the counter remains constant!
6966 */
6967 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6968 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6969
6970 LowVal = 0;
6971 HighVal = 0;
6972 }
6973 else {
6974 /* Otherwise get contents of hardware register */
6975 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6976 StatAddr[StatIndex][MacType].Reg,
6977 &LowVal);
6978 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6979 }
6980 break;
6981
6982 case SK_PNMI_HRX_BADOCTET:
6983 /* Not supported by XMAC */
6984 if (MacType == SK_MAC_XMAC) {
6985 return (Val);
6986 }
6987
6988 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6989 StatAddr[StatIndex][MacType].Reg,
6990 &HighVal);
6991 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6992 StatAddr[StatIndex + 1][MacType].Reg,
6993 &LowVal);
6994 break;
6995
6996 case SK_PNMI_HTX_OCTETLOW:
6997 case SK_PNMI_HRX_OCTETLOW:
6998 case SK_PNMI_HRX_BADOCTETLOW:
6999 return (Val);
7000
7001 case SK_PNMI_HRX_LONGFRAMES:
7002 /* For XMAC the SW counter is managed by PNMI */
7003 if (MacType == SK_MAC_XMAC) {
7004 return (pPnmiPrt->StatRxLongFrameCts);
7005 }
7006
7007 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7008 StatAddr[StatIndex][MacType].Reg,
7009 &LowVal);
7010 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7011 break;
7012
7013 case SK_PNMI_HRX_TOO_LONG:
7014 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7015 StatAddr[StatIndex][MacType].Reg,
7016 &LowVal);
7017 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7018
7019 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7020
7021 if (MacType == SK_MAC_GMAC) {
7022 /* For GMAC the SW counter is additionally managed by PNMI */
7023 Val += pPnmiPrt->StatRxFrameTooLongCts;
7024 }
7025 else {
7026 /*
7027 * Frames longer than IEEE 802.3 frame max size are counted
7028 * by XMAC in frame_too_long counter even reception of long
7029 * frames was enabled and the frame was correct.
7030 * So correct the value by subtracting RxLongFrame counter.
7031 */
7032 Val -= pPnmiPrt->StatRxLongFrameCts;
7033 }
7034
7035 LowVal = (SK_U32)Val;
7036 HighVal = (SK_U32)(Val >> 32);
7037 break;
7038
7039 case SK_PNMI_HRX_SHORTS:
7040 /* Not supported by GMAC */
7041 if (MacType == SK_MAC_GMAC) {
7042 /* GM_RXE_FRAG?? */
7043 return (Val);
7044 }
7045
7046 /*
7047 * XMAC counts short frame errors even if link down (#10620)
7048 *
7049 * If link-down the counter remains constant
7050 */
7051 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7052
7053 /* Otherwise get incremental difference */
7054 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7055 StatAddr[StatIndex][MacType].Reg,
7056 &LowVal);
7057 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7058
7059 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7060 Val -= pPnmiPrt->RxShortZeroMark;
7061
7062 LowVal = (SK_U32)Val;
7063 HighVal = (SK_U32)(Val >> 32);
7064 }
7065 break;
7066
7067 case SK_PNMI_HRX_MACC:
7068 case SK_PNMI_HRX_MACC_UNKWN:
7069 case SK_PNMI_HRX_BURST:
7070 case SK_PNMI_HRX_MISSED:
7071 case SK_PNMI_HRX_FRAMING:
7072 case SK_PNMI_HRX_CARRIER:
7073 case SK_PNMI_HRX_IRLENGTH:
7074 case SK_PNMI_HRX_SYMBOL:
7075 case SK_PNMI_HRX_CEXT:
7076 /* Not supported by GMAC */
7077 if (MacType == SK_MAC_GMAC) {
7078 return (Val);
7079 }
7080
7081 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7082 StatAddr[StatIndex][MacType].Reg,
7083 &LowVal);
7084 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7085 break;
7086
7087 case SK_PNMI_HRX_PMACC_ERR:
7088 /* For GMAC the SW counter is managed by PNMI */
7089 if (MacType == SK_MAC_GMAC) {
7090 return (pPnmiPrt->StatRxPMaccErr);
7091 }
7092
7093 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7094 StatAddr[StatIndex][MacType].Reg,
7095 &LowVal);
7096 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7097 break;
7098
7099 /* SW counter managed by PNMI */
7100 case SK_PNMI_HTX_SYNC:
7101 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7102 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7103 break;
7104
7105 /* SW counter managed by PNMI */
7106 case SK_PNMI_HTX_SYNC_OCTET:
7107 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7108 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7109 break;
7110
7111 case SK_PNMI_HRX_FCS:
7112 /*
7113 * Broadcom filters FCS errors and counts it in
7114 * Receive Error Counter register
7115 */
7116 if (pPrt->PhyType == SK_PHY_BCOM) {
7117 /* do not read while not initialized (PHY_READ hangs!)*/
7118 if (pPrt->PState != SK_PRT_RESET) {
7119 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7120
7121 LowVal = Word;
7122 }
7123 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7124 }
7125 else {
7126 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7127 StatAddr[StatIndex][MacType].Reg,
7128 &LowVal);
7129 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7130 }
7131 break;
7132
7133 default:
7134 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7135 StatAddr[StatIndex][MacType].Reg,
7136 &LowVal);
7137 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7138 break;
7139 }
7140
7141 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7142
7143 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7144 Val += pPnmiPrt->CounterOffset[StatIndex];
7145
7146 return (Val);
7147}
7148
7149/*****************************************************************************
7150 *
7151 * ResetCounter - Set all counters and timestamps to zero
7152 *
7153 * Description:
7154 * Notifies other common modules which store statistic data to
7155 * reset their counters and finally reset our own counters.
7156 *
7157 * Returns:
7158 * Nothing
7159 */
7160PNMI_STATIC void ResetCounter(
7161SK_AC *pAC, /* Pointer to adapter context */
7162SK_IOC IoC, /* IO context handle */
7163SK_U32 NetIndex)
7164{
7165 unsigned int PhysPortIndex;
7166 SK_EVPARA EventParam;
7167
7168
7169 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7170
7171 /* Notify sensor module */
7172 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7173
7174 /* Notify RLMT module */
7175 EventParam.Para32[0] = NetIndex;
7176 EventParam.Para32[1] = (SK_U32)-1;
7177 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7178 EventParam.Para32[1] = 0;
7179
7180 /* Notify SIRQ module */
7181 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7182
7183 /* Notify CSUM module */
7184#ifdef SK_USE_CSUM
7185 EventParam.Para32[0] = NetIndex;
7186 EventParam.Para32[1] = (SK_U32)-1;
7187 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7188 EventParam);
7189#endif /* SK_USE_CSUM */
7190
7191 /* Clear XMAC statistic */
7192 for (PhysPortIndex = 0; PhysPortIndex <
7193 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7194
7195 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7196
7197 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7198 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7199 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7200 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7201 PhysPortIndex].CounterOffset));
7202 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7203 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7204 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7205 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7206 PhysPortIndex].StatSyncOctetsCts));
7207 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7208 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7209 PhysPortIndex].StatRxLongFrameCts));
7210 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7211 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7212 PhysPortIndex].StatRxFrameTooLongCts));
7213 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7214 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7215 PhysPortIndex].StatRxPMaccErr));
7216 }
7217
7218 /*
7219 * Clear local statistics
7220 */
7221 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7222 sizeof(pAC->Pnmi.VirtualCounterOffset));
7223 pAC->Pnmi.RlmtChangeCts = 0;
7224 pAC->Pnmi.RlmtChangeTime = 0;
7225 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7226 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7227 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7228 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7229 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7230 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7231 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7232 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7233 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7234 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7235 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7236 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7237 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7238 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7239}
7240
7241/*****************************************************************************
7242 *
7243 * GetTrapEntry - Get an entry in the trap buffer
7244 *
7245 * Description:
7246 * The trap buffer stores various events. A user application somehow
7247 * gets notified that an event occured and retrieves the trap buffer
7248 * contens (or simply polls the buffer). The buffer is organized as
7249 * a ring which stores the newest traps at the beginning. The oldest
7250 * traps are overwritten by the newest ones. Each trap entry has a
7251 * unique number, so that applications may detect new trap entries.
7252 *
7253 * Returns:
7254 * A pointer to the trap entry
7255 */
7256PNMI_STATIC char* GetTrapEntry(
7257SK_AC *pAC, /* Pointer to adapter context */
7258SK_U32 TrapId, /* SNMP ID of the trap */
7259unsigned int Size) /* Space needed for trap entry */
7260{
7261 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7262 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7263 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7264 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7265 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7266 int Wrap;
7267 unsigned int NeededSpace;
7268 unsigned int EntrySize;
7269 SK_U32 Val32;
7270 SK_U64 Val64;
7271
7272
7273 /* Last byte of entry will get a copy of the entry length */
7274 Size ++;
7275
7276 /*
7277 * Calculate needed buffer space */
7278 if (Beg >= Size) {
7279
7280 NeededSpace = Size;
7281 Wrap = SK_FALSE;
7282 }
7283 else {
7284 NeededSpace = Beg + Size;
7285 Wrap = SK_TRUE;
7286 }
7287
7288 /*
7289 * Check if enough buffer space is provided. Otherwise
7290 * free some entries. Leave one byte space between begin
7291 * and end of buffer to make it possible to detect whether
7292 * the buffer is full or empty
7293 */
7294 while (BufFree < NeededSpace + 1) {
7295
7296 if (End == 0) {
7297
7298 End = SK_PNMI_TRAP_QUEUE_LEN;
7299 }
7300
7301 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7302 BufFree += EntrySize;
7303 End -= EntrySize;
7304#ifdef DEBUG
7305 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7306#endif /* DEBUG */
7307 if (End == BufPad) {
7308#ifdef DEBUG
7309 SK_MEMSET(pBuf, (char)(-1), End);
7310#endif /* DEBUG */
7311 BufFree += End;
7312 End = 0;
7313 BufPad = 0;
7314 }
7315 }
7316
7317 /*
7318 * Insert new entry as first entry. Newest entries are
7319 * stored at the beginning of the queue.
7320 */
7321 if (Wrap) {
7322
7323 BufPad = Beg;
7324 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7325 }
7326 else {
7327 Beg = Beg - Size;
7328 }
7329 BufFree -= NeededSpace;
7330
7331 /* Save the current offsets */
7332 pAC->Pnmi.TrapQueueBeg = Beg;
7333 pAC->Pnmi.TrapQueueEnd = End;
7334 pAC->Pnmi.TrapBufPad = BufPad;
7335 pAC->Pnmi.TrapBufFree = BufFree;
7336
7337 /* Initialize the trap entry */
7338 *(pBuf + Beg + Size - 1) = (char)Size;
7339 *(pBuf + Beg) = (char)Size;
7340 Val32 = (pAC->Pnmi.TrapUnique) ++;
7341 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7342 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7343 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7344 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7345
7346 return (pBuf + Beg);
7347}
7348
7349/*****************************************************************************
7350 *
7351 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7352 *
7353 * Description:
7354 * On a query of the TRAP OID the trap buffer contents will be
7355 * copied continuously to the request buffer, which must be large
7356 * enough. No length check is performed.
7357 *
7358 * Returns:
7359 * Nothing
7360 */
7361PNMI_STATIC void CopyTrapQueue(
7362SK_AC *pAC, /* Pointer to adapter context */
7363char *pDstBuf) /* Buffer to which the queued traps will be copied */
7364{
7365 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7366 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7367 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7368 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7369 unsigned int Len;
7370 unsigned int DstOff = 0;
7371
7372
7373 while (Trap != End) {
7374
7375 Len = (unsigned int)*(pBuf + Trap);
7376
7377 /*
7378 * Last byte containing a copy of the length will
7379 * not be copied.
7380 */
7381 *(pDstBuf + DstOff) = (char)(Len - 1);
7382 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7383 DstOff += Len - 1;
7384
7385 Trap += Len;
7386 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7387
7388 Trap = BufPad;
7389 }
7390 }
7391}
7392
7393/*****************************************************************************
7394 *
7395 * GetTrapQueueLen - Get the length of the trap buffer
7396 *
7397 * Description:
7398 * Evaluates the number of currently stored traps and the needed
7399 * buffer size to retrieve them.
7400 *
7401 * Returns:
7402 * Nothing
7403 */
7404PNMI_STATIC void GetTrapQueueLen(
7405SK_AC *pAC, /* Pointer to adapter context */
7406unsigned int *pLen, /* Length in Bytes of all queued traps */
7407unsigned int *pEntries) /* Returns number of trapes stored in queue */
7408{
7409 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7410 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7411 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7412 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7413 unsigned int Len;
7414 unsigned int Entries = 0;
7415 unsigned int TotalLen = 0;
7416
7417
7418 while (Trap != End) {
7419
7420 Len = (unsigned int)*(pBuf + Trap);
7421 TotalLen += Len - 1;
7422 Entries ++;
7423
7424 Trap += Len;
7425 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7426
7427 Trap = BufPad;
7428 }
7429 }
7430
7431 *pEntries = Entries;
7432 *pLen = TotalLen;
7433}
7434
7435/*****************************************************************************
7436 *
7437 * QueueSimpleTrap - Store a simple trap to the trap buffer
7438 *
7439 * Description:
7440 * A simple trap is a trap with now additional data. It consists
7441 * simply of a trap code.
7442 *
7443 * Returns:
7444 * Nothing
7445 */
7446PNMI_STATIC void QueueSimpleTrap(
7447SK_AC *pAC, /* Pointer to adapter context */
7448SK_U32 TrapId) /* Type of sensor trap */
7449{
7450 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7451}
7452
7453/*****************************************************************************
7454 *
7455 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7456 *
7457 * Description:
7458 * Gets an entry in the trap buffer and fills it with sensor related
7459 * data.
7460 *
7461 * Returns:
7462 * Nothing
7463 */
7464PNMI_STATIC void QueueSensorTrap(
7465SK_AC *pAC, /* Pointer to adapter context */
7466SK_U32 TrapId, /* Type of sensor trap */
7467unsigned int SensorIndex) /* Index of sensor which caused the trap */
7468{
7469 char *pBuf;
7470 unsigned int Offset;
7471 unsigned int DescrLen;
7472 SK_U32 Val32;
7473
7474
7475 /* Get trap buffer entry */
7476 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7477 pBuf = GetTrapEntry(pAC, TrapId,
7478 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7479 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7480
7481 /* Store additionally sensor trap related data */
7482 Val32 = OID_SKGE_SENSOR_INDEX;
7483 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7484 *(pBuf + Offset + 4) = 4;
7485 Val32 = (SK_U32)SensorIndex;
7486 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7487 Offset += 9;
7488
7489 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7490 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7491 *(pBuf + Offset + 4) = (char)DescrLen;
7492 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7493 DescrLen);
7494 Offset += DescrLen + 5;
7495
7496 Val32 = OID_SKGE_SENSOR_TYPE;
7497 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7498 *(pBuf + Offset + 4) = 1;
7499 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7500 Offset += 6;
7501
7502 Val32 = OID_SKGE_SENSOR_VALUE;
7503 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7504 *(pBuf + Offset + 4) = 4;
7505 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7506 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7507}
7508
7509/*****************************************************************************
7510 *
7511 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7512 *
7513 * Description:
7514 * Nothing further to explain.
7515 *
7516 * Returns:
7517 * Nothing
7518 */
7519PNMI_STATIC void QueueRlmtNewMacTrap(
7520SK_AC *pAC, /* Pointer to adapter context */
7521unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7522{
7523 char *pBuf;
7524 SK_U32 Val32;
7525
7526
7527 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7528 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7529
7530 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7531 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7532 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7533 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7534}
7535
7536/*****************************************************************************
7537 *
7538 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7539 *
7540 * Description:
7541 * Nothing further to explain.
7542 *
7543 * Returns:
7544 * Nothing
7545 */
7546PNMI_STATIC void QueueRlmtPortTrap(
7547SK_AC *pAC, /* Pointer to adapter context */
7548SK_U32 TrapId, /* Type of RLMT port trap */
7549unsigned int PortIndex) /* Index of the port, which changed its state */
7550{
7551 char *pBuf;
7552 SK_U32 Val32;
7553
7554
7555 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7556
7557 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7558 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7559 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7560 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7561}
7562
7563/*****************************************************************************
7564 *
7565 * CopyMac - Copies a MAC address
7566 *
7567 * Description:
7568 * Nothing further to explain.
7569 *
7570 * Returns:
7571 * Nothing
7572 */
7573PNMI_STATIC void CopyMac(
7574char *pDst, /* Pointer to destination buffer */
7575SK_MAC_ADDR *pMac) /* Pointer of Source */
7576{
7577 int i;
7578
7579
7580 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7581
7582 *(pDst + i) = pMac->a[i];
7583 }
7584}
7585
7586#ifdef SK_POWER_MGMT
7587/*****************************************************************************
7588 *
7589 * PowerManagement - OID handler function of PowerManagement OIDs
7590 *
7591 * Description:
7592 * The code is simple. No description necessary.
7593 *
7594 * Returns:
7595 * SK_PNMI_ERR_OK The request was successfully performed.
7596 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7597 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7598 * the correct data (e.g. a 32bit value is
7599 * needed, but a 16 bit value was passed).
7600 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7601 * exist (e.g. port instance 3 on a two port
7602 * adapter.
7603 */
7604
7605PNMI_STATIC int PowerManagement(
7606SK_AC *pAC, /* Pointer to adapter context */
7607SK_IOC IoC, /* IO context handle */
7608int Action, /* Get/PreSet/Set action */
7609SK_U32 Id, /* Object ID that is to be processed */
7610char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7611unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7612SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7613unsigned int TableIndex, /* Index to the Id table */
7614SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7615{
7616
7617 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7618
7619 /*
7620 * Check instance. We only handle single instance variables
7621 */
7622 if (Instance != (SK_U32)(-1) && Instance != 1) {
7623
7624 *pLen = 0;
7625 return (SK_PNMI_ERR_UNKNOWN_INST);
7626 }
7627
7628
7629 /* Check length */
7630 switch (Id) {
7631
7632 case OID_PNP_CAPABILITIES:
7633 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7634
7635 *pLen = sizeof(SK_PNP_CAPABILITIES);
7636 return (SK_PNMI_ERR_TOO_SHORT);
7637 }
7638 break;
7639
7640 case OID_PNP_SET_POWER:
7641 case OID_PNP_QUERY_POWER:
7642 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7643 {
7644 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7645 return (SK_PNMI_ERR_TOO_SHORT);
7646 }
7647 break;
7648
7649 case OID_PNP_ADD_WAKE_UP_PATTERN:
7650 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7651 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7652
7653 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7654 return (SK_PNMI_ERR_TOO_SHORT);
7655 }
7656 break;
7657
7658 case OID_PNP_ENABLE_WAKE_UP:
7659 if (*pLen < sizeof(SK_U32)) {
7660
7661 *pLen = sizeof(SK_U32);
7662 return (SK_PNMI_ERR_TOO_SHORT);
7663 }
7664 break;
7665 }
7666
7667 /*
7668 * Perform action
7669 */
7670 if (Action == SK_PNMI_GET) {
7671
7672 /*
7673 * Get value
7674 */
7675 switch (Id) {
7676
7677 case OID_PNP_CAPABILITIES:
7678 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7679 break;
7680
7681 case OID_PNP_QUERY_POWER:
7682 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7683 the miniport to indicate whether it can transition its NIC
7684 to the low-power state.
7685 A miniport driver must always return NDIS_STATUS_SUCCESS
7686 to a query of OID_PNP_QUERY_POWER. */
7687 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7688 RetCode = SK_PNMI_ERR_OK;
7689 break;
7690
7691 /* NDIS handles these OIDs as write-only.
7692 * So in case of get action the buffer with written length = 0
7693 * is returned
7694 */
7695 case OID_PNP_SET_POWER:
7696 case OID_PNP_ADD_WAKE_UP_PATTERN:
7697 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7698 *pLen = 0;
7699 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7700 break;
7701
7702 case OID_PNP_ENABLE_WAKE_UP:
7703 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7704 break;
7705
7706 default:
7707 RetCode = SK_PNMI_ERR_GENERAL;
7708 break;
7709 }
7710
7711 return (RetCode);
7712 }
7713
7714
7715 /*
7716 * Perform preset or set
7717 */
7718
7719 /* POWER module does not support PRESET action */
7720 if (Action == SK_PNMI_PRESET) {
7721 return (SK_PNMI_ERR_OK);
7722 }
7723
7724 switch (Id) {
7725 case OID_PNP_SET_POWER:
7726 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7727 break;
7728
7729 case OID_PNP_ADD_WAKE_UP_PATTERN:
7730 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7731 break;
7732
7733 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7734 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7735 break;
7736
7737 case OID_PNP_ENABLE_WAKE_UP:
7738 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7739 break;
7740
7741 default:
7742 RetCode = SK_PNMI_ERR_READ_ONLY;
7743 }
7744
7745 return (RetCode);
7746}
7747#endif /* SK_POWER_MGMT */
7748
7749#ifdef SK_DIAG_SUPPORT
7750/*****************************************************************************
7751 *
7752 * DiagActions - OID handler function of Diagnostic driver
7753 *
7754 * Description:
7755 * The code is simple. No description necessary.
7756 *
7757 * Returns:
7758 * SK_PNMI_ERR_OK The request was successfully performed.
7759 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7760 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7761 * the correct data (e.g. a 32bit value is
7762 * needed, but a 16 bit value was passed).
7763 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7764 * exist (e.g. port instance 3 on a two port
7765 * adapter.
7766 */
7767
7768PNMI_STATIC int DiagActions(
7769SK_AC *pAC, /* Pointer to adapter context */
7770SK_IOC IoC, /* IO context handle */
7771int Action, /* GET/PRESET/SET action */
7772SK_U32 Id, /* Object ID that is to be processed */
7773char *pBuf, /* Buffer used for the management data transfer */
7774unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7775SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7776unsigned int TableIndex, /* Index to the Id table */
7777SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7778{
7779
7780 SK_U32 DiagStatus;
7781 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7782
7783 /*
7784 * Check instance. We only handle single instance variables.
7785 */
7786 if (Instance != (SK_U32)(-1) && Instance != 1) {
7787
7788 *pLen = 0;
7789 return (SK_PNMI_ERR_UNKNOWN_INST);
7790 }
7791
7792 /*
7793 * Check length.
7794 */
7795 switch (Id) {
7796
7797 case OID_SKGE_DIAG_MODE:
7798 if (*pLen < sizeof(SK_U32)) {
7799
7800 *pLen = sizeof(SK_U32);
7801 return (SK_PNMI_ERR_TOO_SHORT);
7802 }
7803 break;
7804
7805 default:
7806 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7807 *pLen = 0;
7808 return (SK_PNMI_ERR_GENERAL);
7809 }
7810
7811 /* Perform action. */
7812
7813 /* GET value. */
7814 if (Action == SK_PNMI_GET) {
7815
7816 switch (Id) {
7817
7818 case OID_SKGE_DIAG_MODE:
7819 DiagStatus = pAC->Pnmi.DiagAttached;
7820 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7821 *pLen = sizeof(SK_U32);
7822 RetCode = SK_PNMI_ERR_OK;
7823 break;
7824
7825 default:
7826 *pLen = 0;
7827 RetCode = SK_PNMI_ERR_GENERAL;
7828 break;
7829 }
7830 return (RetCode);
7831 }
7832
7833 /* From here SET or PRESET value. */
7834
7835 /* PRESET value is not supported. */
7836 if (Action == SK_PNMI_PRESET) {
7837 return (SK_PNMI_ERR_OK);
7838 }
7839
7840 /* SET value. */
7841 switch (Id) {
7842 case OID_SKGE_DIAG_MODE:
7843
7844 /* Handle the SET. */
7845 switch (*pBuf) {
7846
7847 /* Attach the DIAG to this adapter. */
7848 case SK_DIAG_ATTACHED:
7849 /* Check if we come from running */
7850 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7851
7852 RetCode = SkDrvLeaveDiagMode(pAC);
7853
7854 }
7855 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7856
7857 RetCode = SK_PNMI_ERR_OK;
7858 }
7859
7860 else {
7861
7862 RetCode = SK_PNMI_ERR_GENERAL;
7863
7864 }
7865
7866 if (RetCode == SK_PNMI_ERR_OK) {
7867
7868 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7869 }
7870 break;
7871
7872 /* Enter the DIAG mode in the driver. */
7873 case SK_DIAG_RUNNING:
7874 RetCode = SK_PNMI_ERR_OK;
7875
7876 /*
7877 * If DiagAttached is set, we can tell the driver
7878 * to enter the DIAG mode.
7879 */
7880 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7881 /* If DiagMode is not active, we can enter it. */
7882 if (!pAC->DiagModeActive) {
7883
7884 RetCode = SkDrvEnterDiagMode(pAC);
7885 }
7886 else {
7887
7888 RetCode = SK_PNMI_ERR_GENERAL;
7889 }
7890 }
7891 else {
7892
7893 RetCode = SK_PNMI_ERR_GENERAL;
7894 }
7895
7896 if (RetCode == SK_PNMI_ERR_OK) {
7897
7898 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7899 }
7900 break;
7901
7902 case SK_DIAG_IDLE:
7903 /* Check if we come from running */
7904 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7905
7906 RetCode = SkDrvLeaveDiagMode(pAC);
7907
7908 }
7909 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7910
7911 RetCode = SK_PNMI_ERR_OK;
7912 }
7913
7914 else {
7915
7916 RetCode = SK_PNMI_ERR_GENERAL;
7917
7918 }
7919
7920 if (RetCode == SK_PNMI_ERR_OK) {
7921
7922 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7923 }
7924 break;
7925
7926 default:
7927 RetCode = SK_PNMI_ERR_BAD_VALUE;
7928 break;
7929 }
7930 break;
7931
7932 default:
7933 RetCode = SK_PNMI_ERR_GENERAL;
7934 }
7935
7936 if (RetCode == SK_PNMI_ERR_OK) {
7937 *pLen = sizeof(SK_U32);
7938 }
7939 else {
7940
7941 *pLen = 0;
7942 }
7943 return (RetCode);
7944}
7945#endif /* SK_DIAG_SUPPORT */
7946
7947/*****************************************************************************
7948 *
7949 * Vct - OID handler function of OIDs
7950 *
7951 * Description:
7952 * The code is simple. No description necessary.
7953 *
7954 * Returns:
7955 * SK_PNMI_ERR_OK The request was performed successfully.
7956 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7957 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7958 * the correct data (e.g. a 32bit value is
7959 * needed, but a 16 bit value was passed).
7960 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7961 * exist (e.g. port instance 3 on a two port
7962 * adapter).
7963 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7964 *
7965 */
7966
7967PNMI_STATIC int Vct(
7968SK_AC *pAC, /* Pointer to adapter context */
7969SK_IOC IoC, /* IO context handle */
7970int Action, /* GET/PRESET/SET action */
7971SK_U32 Id, /* Object ID that is to be processed */
7972char *pBuf, /* Buffer used for the management data transfer */
7973unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7974SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7975unsigned int TableIndex, /* Index to the Id table */
7976SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7977{
7978 SK_GEPORT *pPrt;
7979 SK_PNMI_VCT *pVctBackupData;
7980 SK_U32 LogPortMax;
7981 SK_U32 PhysPortMax;
7982 SK_U32 PhysPortIndex;
7983 SK_U32 Limit;
7984 SK_U32 Offset;
7985 SK_BOOL Link;
7986 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7987 int i;
7988 SK_EVPARA Para;
7989 SK_U32 CableLength;
7990
7991 /*
7992 * Calculate the port indexes from the instance.
7993 */
7994 PhysPortMax = pAC->GIni.GIMacsFound;
7995 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7996
7997 /* Dual net mode? */
7998 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7999 LogPortMax--;
8000 }
8001
8002 if ((Instance != (SK_U32) (-1))) {
8003 /* Check instance range. */
8004 if ((Instance < 2) || (Instance > LogPortMax)) {
8005 *pLen = 0;
8006 return (SK_PNMI_ERR_UNKNOWN_INST);
8007 }
8008
8009 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8010 PhysPortIndex = NetIndex;
8011 }
8012 else {
8013 PhysPortIndex = Instance - 2;
8014 }
8015 Limit = PhysPortIndex + 1;
8016 }
8017 else {
8018 /*
8019 * Instance == (SK_U32) (-1), get all Instances of that OID.
8020 *
8021 * Not implemented yet. May be used in future releases.
8022 */
8023 PhysPortIndex = 0;
8024 Limit = PhysPortMax;
8025 }
8026
8027 pPrt = &pAC->GIni.GP[PhysPortIndex];
8028 if (pPrt->PHWLinkUp) {
8029 Link = SK_TRUE;
8030 }
8031 else {
8032 Link = SK_FALSE;
8033 }
8034
8035 /* Check MAC type */
8036 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8037 *pLen = 0;
8038 return (SK_PNMI_ERR_GENERAL);
8039 }
8040
8041 /* Initialize backup data pointer. */
8042 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8043
8044 /* Check action type */
8045 if (Action == SK_PNMI_GET) {
8046 /* Check length */
8047 switch (Id) {
8048
8049 case OID_SKGE_VCT_GET:
8050 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8051 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8052 return (SK_PNMI_ERR_TOO_SHORT);
8053 }
8054 break;
8055
8056 case OID_SKGE_VCT_STATUS:
8057 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8058 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8059 return (SK_PNMI_ERR_TOO_SHORT);
8060 }
8061 break;
8062
8063 default:
8064 *pLen = 0;
8065 return (SK_PNMI_ERR_GENERAL);
8066 }
8067
8068 /* Get value */
8069 Offset = 0;
8070 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8071 switch (Id) {
8072
8073 case OID_SKGE_VCT_GET:
8074 if ((Link == SK_FALSE) &&
8075 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8076 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8077 if (RetCode == 0) {
8078 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8079 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8080 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8081
8082 /* Copy results for later use to PNMI struct. */
8083 for (i = 0; i < 4; i++) {
8084 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8085 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8086 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8087 }
8088 }
8089 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8090 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8091 }
8092 else {
8093 CableLength = 0;
8094 }
8095 pVctBackupData->PMdiPairLen[i] = CableLength;
8096 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8097 }
8098
8099 Para.Para32[0] = PhysPortIndex;
8100 Para.Para32[1] = -1;
8101 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8102 SkEventDispatcher(pAC, IoC);
8103 }
8104 else {
8105 ; /* VCT test is running. */
8106 }
8107 }
8108
8109 /* Get all results. */
8110 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8111 Offset += sizeof(SK_U8);
8112 *(pBuf + Offset) = pPrt->PCableLen;
8113 Offset += sizeof(SK_U8);
8114 for (i = 0; i < 4; i++) {
8115 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8116 Offset += sizeof(SK_U32);
8117 }
8118 for (i = 0; i < 4; i++) {
8119 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8120 Offset += sizeof(SK_U8);
8121 }
8122
8123 RetCode = SK_PNMI_ERR_OK;
8124 break;
8125
8126 case OID_SKGE_VCT_STATUS:
8127 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8128 Offset += sizeof(SK_U8);
8129 RetCode = SK_PNMI_ERR_OK;
8130 break;
8131
8132 default:
8133 *pLen = 0;
8134 return (SK_PNMI_ERR_GENERAL);
8135 }
8136 } /* for */
8137 *pLen = Offset;
8138 return (RetCode);
8139
8140 } /* if SK_PNMI_GET */
8141
8142 /*
8143 * From here SET or PRESET action. Check if the passed
8144 * buffer length is plausible.
8145 */
8146
8147 /* Check length */
8148 switch (Id) {
8149 case OID_SKGE_VCT_SET:
8150 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8151 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8152 return (SK_PNMI_ERR_TOO_SHORT);
8153 }
8154 break;
8155
8156 default:
8157 *pLen = 0;
8158 return (SK_PNMI_ERR_GENERAL);
8159 }
8160
8161 /*
8162 * Perform preset or set.
8163 */
8164
8165 /* VCT does not support PRESET action. */
8166 if (Action == SK_PNMI_PRESET) {
8167 return (SK_PNMI_ERR_OK);
8168 }
8169
8170 Offset = 0;
8171 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8172 switch (Id) {
8173 case OID_SKGE_VCT_SET: /* Start VCT test. */
8174 if (Link == SK_FALSE) {
8175 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8176
8177 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8178 if (RetCode == 0) { /* RetCode: 0 => Start! */
8179 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8180 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8181 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8182
8183 /*
8184 * Start VCT timer counter.
8185 */
8186 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8187 Para.Para32[0] = PhysPortIndex;
8188 Para.Para32[1] = -1;
8189 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8190 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8191 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8192 RetCode = SK_PNMI_ERR_OK;
8193 }
8194 else { /* RetCode: 2 => Running! */
8195 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8196 RetCode = SK_PNMI_ERR_OK;
8197 }
8198 }
8199 else { /* RetCode: 4 => Link! */
8200 RetCode = 4;
8201 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8202 RetCode = SK_PNMI_ERR_OK;
8203 }
8204 Offset += sizeof(SK_U32);
8205 break;
8206
8207 default:
8208 *pLen = 0;
8209 return (SK_PNMI_ERR_GENERAL);
8210 }
8211 } /* for */
8212 *pLen = Offset;
8213 return (RetCode);
8214
8215} /* Vct */
8216
8217
8218PNMI_STATIC void CheckVctStatus(
8219SK_AC *pAC,
8220SK_IOC IoC,
8221char *pBuf,
8222SK_U32 Offset,
8223SK_U32 PhysPortIndex)
8224{
8225 SK_GEPORT *pPrt;
8226 SK_PNMI_VCT *pVctData;
8227 SK_U32 RetCode;
8228
8229 pPrt = &pAC->GIni.GP[PhysPortIndex];
8230
8231 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8232 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8233
8234 if (!pPrt->PHWLinkUp) {
8235
8236 /* Was a VCT test ever made before? */
8237 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8238 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8239 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8240 }
8241 else {
8242 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8243 }
8244 }
8245
8246 /* Check VCT test status. */
8247 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8248 if (RetCode == 2) { /* VCT test is running. */
8249 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8250 }
8251 else { /* VCT data was copied to pAC here. Check PENDING state. */
8252 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8253 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8254 }
8255 }
8256
8257 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8258 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8259 }
8260 }
8261 else {
8262
8263 /* Was a VCT test ever made before? */
8264 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8265 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8266 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8267 }
8268
8269 /* DSP only valid in 100/1000 modes. */
8270 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8271 SK_LSPEED_STAT_10MBPS) {
8272 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8273 }
8274 }
8275} /* CheckVctStatus */
8276
8277
8278/*****************************************************************************
8279 *
8280 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8281 * PNMI function depending on the subcommand and
8282 * returns all data belonging to the complete database
8283 * or OID request.
8284 *
8285 * Description:
8286 * Looks up the requested subcommand, calls the corresponding handler
8287 * function and passes all required parameters to it.
8288 * The function is called by the driver. It is needed to handle the new
8289 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8290 * the OID and a subcommand to decide what kind of request has to be done.
8291 *
8292 * Returns:
8293 * SK_PNMI_ERR_OK The request was successfully performed
8294 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8295 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8296 * the data.
8297 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8298 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8299 * exist (e.g. port instance 3 on a two port
8300 * adapter.
8301 */
8302int SkPnmiGenIoctl(
8303SK_AC *pAC, /* Pointer to adapter context struct */
8304SK_IOC IoC, /* I/O context */
8305void *pBuf, /* Buffer used for the management data transfer */
8306unsigned int *pLen, /* Length of buffer */
8307SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8308{
8309SK_I32 Mode; /* Store value of subcommand. */
8310SK_U32 Oid; /* Store value of OID. */
8311int ReturnCode; /* Store return value to show status of PNMI action. */
8312int HeaderLength; /* Length of desired action plus OID. */
8313
8314 ReturnCode = SK_PNMI_ERR_GENERAL;
8315
8316 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8317 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8318 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8319 *pLen = *pLen - HeaderLength;
8320 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8321
8322 switch(Mode) {
8323 case SK_GET_SINGLE_VAR:
8324 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8325 (char *) pBuf + sizeof(SK_I32), pLen,
8326 ((SK_U32) (-1)), NetIndex);
8327 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8328 *pLen = *pLen + sizeof(SK_I32);
8329 break;
8330 case SK_PRESET_SINGLE_VAR:
8331 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8332 (char *) pBuf + sizeof(SK_I32), pLen,
8333 ((SK_U32) (-1)), NetIndex);
8334 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8335 *pLen = *pLen + sizeof(SK_I32);
8336 break;
8337 case SK_SET_SINGLE_VAR:
8338 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8339 (char *) pBuf + sizeof(SK_I32), pLen,
8340 ((SK_U32) (-1)), NetIndex);
8341 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8342 *pLen = *pLen + sizeof(SK_I32);
8343 break;
8344 case SK_GET_FULL_MIB:
8345 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8346 break;
8347 case SK_PRESET_FULL_MIB:
8348 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8349 break;
8350 case SK_SET_FULL_MIB:
8351 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8352 break;
8353 default:
8354 break;
8355 }
8356
8357 return (ReturnCode);
8358
8359} /* SkGeIocGen */