aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skgepnmi.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/sk98lin/skgepnmi.c')
-rw-r--r--drivers/net/sk98lin/skgepnmi.c8210
1 files changed, 8210 insertions, 0 deletions
diff --git a/drivers/net/sk98lin/skgepnmi.c b/drivers/net/sk98lin/skgepnmi.c
new file mode 100644
index 000000000000..b36dd9ac6b29
--- /dev/null
+++ b/drivers/net/sk98lin/skgepnmi.c
@@ -0,0 +1,8210 @@
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 SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
62 unsigned int *pLen, SK_U32 NetIndex);
63int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
64 unsigned int *pLen, SK_U32 NetIndex);
65int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
68int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
69 unsigned int * pLen, SK_U32 NetIndex);
70
71
72/*
73 * Private Function prototypes
74 */
75
76PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
77 PhysPortIndex);
78PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
79 PhysPortIndex);
80PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
81PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
82PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
83 unsigned int PhysPortIndex, unsigned int StatIndex);
84PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
85 unsigned int StatIndex, SK_U32 NetIndex);
86PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
87PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
88 unsigned int *pEntries);
89PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
90 unsigned int KeyArrLen, unsigned int *pKeyNo);
91PNMI_STATIC int LookupId(SK_U32 Id);
92PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
93 unsigned int LastMac);
94PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
95 unsigned int *pLen, SK_U32 NetIndex);
96PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
97 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
98PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
99PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
100 unsigned int PortIndex);
101PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
102 unsigned int SensorIndex);
103PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
104PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
105PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
107PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
108PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
109 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
110PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
111
112/*
113 * Table to correlate OID with handler function and index to
114 * hardware register stored in StatAddress if applicable.
115 */
116#include "skgemib.c"
117
118/* global variables **********************************************************/
119
120/*
121 * Overflow status register bit table and corresponding counter
122 * dependent on MAC type - the number relates to the size of overflow
123 * mask returned by the pFnMacOverflow function
124 */
125PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
126/* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
127/* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
128/* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
129/* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
130/* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
131/* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
132/* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
133/* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
134/* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
135/* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
136/* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
137/* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
138/* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
139/* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
140/* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
141/* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
142/* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
143/* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
144/* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
145/* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
146/* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
147/* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
148/* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
149/* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
150/* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
151/* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
152/* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
153/* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154/* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155/* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156/* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157/* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158/* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
159/* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
160/* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
161/* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
162/* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
163/* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
164/* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
165/* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
166/* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
167/* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
168/* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
169/* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
170/* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
171/* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
172/* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
173/* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
174/* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
175/* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
176/* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
177/* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
178/* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
179/* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
180/* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
181/* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
182/* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
183/* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
184/* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
185/* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
186/* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
187/* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
188/* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
189/* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
190};
191
192/*
193 * Table for hardware register saving on resets and port switches
194 */
195PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
196 /* SK_PNMI_HTX */
197 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
198 /* SK_PNMI_HTX_OCTETHIGH */
199 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
200 /* SK_PNMI_HTX_OCTETLOW */
201 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
202 /* SK_PNMI_HTX_BROADCAST */
203 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
204 /* SK_PNMI_HTX_MULTICAST */
205 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
206 /* SK_PNMI_HTX_UNICAST */
207 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_BURST */
209 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
210 /* SK_PNMI_HTX_PMACC */
211 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
212 /* SK_PNMI_HTX_MACC */
213 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_COL */
215 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
216 /* SK_PNMI_HTX_SINGLE_COL */
217 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
218 /* SK_PNMI_HTX_MULTI_COL */
219 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_EXCESS_COL */
221 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_LATE_COL */
223 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_DEFFERAL */
225 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
226 /* SK_PNMI_HTX_EXCESS_DEF */
227 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
228 /* SK_PNMI_HTX_UNDERRUN */
229 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
230 /* SK_PNMI_HTX_CARRIER */
231 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UTILUNDER */
233 {{0, SK_FALSE}, {0, SK_FALSE}},
234 /* SK_PNMI_HTX_UTILOVER */
235 {{0, SK_FALSE}, {0, SK_FALSE}},
236 /* SK_PNMI_HTX_64 */
237 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
238 /* SK_PNMI_HTX_127 */
239 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
240 /* SK_PNMI_HTX_255 */
241 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
242 /* SK_PNMI_HTX_511 */
243 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
244 /* SK_PNMI_HTX_1023 */
245 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
246 /* SK_PNMI_HTX_MAX */
247 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
248 /* SK_PNMI_HTX_LONGFRAMES */
249 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
250 /* SK_PNMI_HTX_SYNC */
251 {{0, SK_FALSE}, {0, SK_FALSE}},
252 /* SK_PNMI_HTX_SYNC_OCTET */
253 {{0, SK_FALSE}, {0, SK_FALSE}},
254 /* SK_PNMI_HTX_RESERVED */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
256 /* SK_PNMI_HRX */
257 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
258 /* SK_PNMI_HRX_OCTETHIGH */
259 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
260 /* SK_PNMI_HRX_OCTETLOW */
261 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
262 /* SK_PNMI_HRX_BADOCTETHIGH */
263 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_BADOCTETLOW */
265 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
266 /* SK_PNMI_HRX_BROADCAST */
267 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
268 /* SK_PNMI_HRX_MULTICAST */
269 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
270 /* SK_PNMI_HRX_UNICAST */
271 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_PMACC */
273 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
274 /* SK_PNMI_HRX_MACC */
275 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
276 /* SK_PNMI_HRX_PMACC_ERR */
277 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
278 /* SK_PNMI_HRX_MACC_UNKWN */
279 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_BURST */
281 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MISSED */
283 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_FRAMING */
285 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_UNDERSIZE */
287 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
288 /* SK_PNMI_HRX_OVERFLOW */
289 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
290 /* SK_PNMI_HRX_JABBER */
291 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
292 /* SK_PNMI_HRX_CARRIER */
293 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
294 /* SK_PNMI_HRX_IRLENGTH */
295 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
296 /* SK_PNMI_HRX_SYMBOL */
297 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_SHORTS */
299 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_RUNT */
301 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
302 /* SK_PNMI_HRX_TOO_LONG */
303 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
304 /* SK_PNMI_HRX_FCS */
305 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
306 /* SK_PNMI_HRX_CEXT */
307 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
308 /* SK_PNMI_HRX_UTILUNDER */
309 {{0, SK_FALSE}, {0, SK_FALSE}},
310 /* SK_PNMI_HRX_UTILOVER */
311 {{0, SK_FALSE}, {0, SK_FALSE}},
312 /* SK_PNMI_HRX_64 */
313 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
314 /* SK_PNMI_HRX_127 */
315 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
316 /* SK_PNMI_HRX_255 */
317 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
318 /* SK_PNMI_HRX_511 */
319 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
320 /* SK_PNMI_HRX_1023 */
321 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
322 /* SK_PNMI_HRX_MAX */
323 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
324 /* SK_PNMI_HRX_LONGFRAMES */
325 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
326 /* SK_PNMI_HRX_RESERVED */
327 {{0, SK_FALSE}, {0, SK_FALSE}}
328};
329
330
331/*****************************************************************************
332 *
333 * Public functions
334 *
335 */
336
337/*****************************************************************************
338 *
339 * SkPnmiInit - Init function of PNMI
340 *
341 * Description:
342 * SK_INIT_DATA: Initialises the data structures
343 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
344 * connector type.
345 * SK_INIT_RUN: Starts a timer event for port switch per hour
346 * calculation.
347 *
348 * Returns:
349 * Always 0
350 */
351int SkPnmiInit(
352SK_AC *pAC, /* Pointer to adapter context */
353SK_IOC IoC, /* IO context handle */
354int Level) /* Initialization level */
355{
356 unsigned int PortMax; /* Number of ports */
357 unsigned int PortIndex; /* Current port index in loop */
358 SK_U16 Val16; /* Multiple purpose 16 bit variable */
359 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
360 SK_EVPARA EventParam; /* Event struct for timer event */
361 SK_PNMI_VCT *pVctBackupData;
362
363
364 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
365 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
366
367 switch (Level) {
368
369 case SK_INIT_DATA:
370 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
371 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
372 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
373 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
374 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
375
376 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
377 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
378 }
379
380#ifdef SK_PNMI_CHECK
381 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
382
383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
384
385 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
386 ("CounterOffset struct size (%d) differs from"
387 "SK_PNMI_MAX_IDX (%d)\n",
388 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
389 }
390
391 if (SK_PNMI_MAX_IDX !=
392 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
393
394 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
395
396 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
397 ("StatAddr table size (%d) differs from "
398 "SK_PNMI_MAX_IDX (%d)\n",
399 (sizeof(StatAddr) /
400 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
401 SK_PNMI_MAX_IDX));
402 }
403#endif /* SK_PNMI_CHECK */
404 break;
405
406 case SK_INIT_IO:
407 /*
408 * Reset MAC counters
409 */
410 PortMax = pAC->GIni.GIMacsFound;
411
412 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
413
414 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
415 }
416
417 /* Initialize DSP variables for Vct() to 0xff => Never written! */
418 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
419 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
420 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
421 pVctBackupData->PCableLen = 0xff;
422 }
423
424 /*
425 * Get pci bus speed
426 */
427 SK_IN16(IoC, B0_CTST, &Val16);
428 if ((Val16 & CS_BUS_CLOCK) == 0) {
429
430 pAC->Pnmi.PciBusSpeed = 33;
431 }
432 else {
433 pAC->Pnmi.PciBusSpeed = 66;
434 }
435
436 /*
437 * Get pci bus width
438 */
439 SK_IN16(IoC, B0_CTST, &Val16);
440 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
441
442 pAC->Pnmi.PciBusWidth = 32;
443 }
444 else {
445 pAC->Pnmi.PciBusWidth = 64;
446 }
447
448 /*
449 * Get chipset
450 */
451 switch (pAC->GIni.GIChipId) {
452 case CHIP_ID_GENESIS:
453 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
454 break;
455
456 case CHIP_ID_YUKON:
457 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
458 break;
459
460 default:
461 break;
462 }
463
464 /*
465 * Get PMD and DeviceType
466 */
467 SK_IN8(IoC, B2_PMD_TYP, &Val8);
468 switch (Val8) {
469 case 'S':
470 pAC->Pnmi.PMD = 3;
471 if (pAC->GIni.GIMacsFound > 1) {
472
473 pAC->Pnmi.DeviceType = 0x00020002;
474 }
475 else {
476 pAC->Pnmi.DeviceType = 0x00020001;
477 }
478 break;
479
480 case 'L':
481 pAC->Pnmi.PMD = 2;
482 if (pAC->GIni.GIMacsFound > 1) {
483
484 pAC->Pnmi.DeviceType = 0x00020004;
485 }
486 else {
487 pAC->Pnmi.DeviceType = 0x00020003;
488 }
489 break;
490
491 case 'C':
492 pAC->Pnmi.PMD = 4;
493 if (pAC->GIni.GIMacsFound > 1) {
494
495 pAC->Pnmi.DeviceType = 0x00020006;
496 }
497 else {
498 pAC->Pnmi.DeviceType = 0x00020005;
499 }
500 break;
501
502 case 'T':
503 pAC->Pnmi.PMD = 5;
504 if (pAC->GIni.GIMacsFound > 1) {
505
506 pAC->Pnmi.DeviceType = 0x00020008;
507 }
508 else {
509 pAC->Pnmi.DeviceType = 0x00020007;
510 }
511 break;
512
513 default :
514 pAC->Pnmi.PMD = 1;
515 pAC->Pnmi.DeviceType = 0;
516 break;
517 }
518
519 /*
520 * Get connector
521 */
522 SK_IN8(IoC, B2_CONN_TYP, &Val8);
523 switch (Val8) {
524 case 'C':
525 pAC->Pnmi.Connector = 2;
526 break;
527
528 case 'D':
529 pAC->Pnmi.Connector = 3;
530 break;
531
532 case 'F':
533 pAC->Pnmi.Connector = 4;
534 break;
535
536 case 'J':
537 pAC->Pnmi.Connector = 5;
538 break;
539
540 case 'V':
541 pAC->Pnmi.Connector = 6;
542 break;
543
544 default:
545 pAC->Pnmi.Connector = 1;
546 break;
547 }
548 break;
549
550 case SK_INIT_RUN:
551 /*
552 * Start timer for RLMT change counter
553 */
554 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
555 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
556 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
557 EventParam);
558 break;
559
560 default:
561 break; /* Nothing todo */
562 }
563
564 return (0);
565}
566
567/*****************************************************************************
568 *
569 * SkPnmiGetVar - Retrieves the value of a single OID
570 *
571 * Description:
572 * Calls a general sub-function for all this stuff. If the instance
573 * -1 is passed, the values of all instances are returned in an
574 * array of values.
575 *
576 * Returns:
577 * SK_PNMI_ERR_OK The request was successfully performed
578 * SK_PNMI_ERR_GENERAL A general severe internal error occured
579 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
580 * the data.
581 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
582 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
583 * exist (e.g. port instance 3 on a two port
584 * adapter.
585 */
586static int SkPnmiGetVar(
587SK_AC *pAC, /* Pointer to adapter context */
588SK_IOC IoC, /* IO context handle */
589SK_U32 Id, /* Object ID that is to be processed */
590void *pBuf, /* Buffer to which the management data will be copied */
591unsigned int *pLen, /* On call: buffer length. On return: used buffer */
592SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
593SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
594{
595 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
596 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
597 Id, *pLen, Instance, NetIndex));
598
599 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
600 Instance, NetIndex));
601}
602
603/*****************************************************************************
604 *
605 * SkPnmiPreSetVar - Presets the value of a single OID
606 *
607 * Description:
608 * Calls a general sub-function for all this stuff. The preset does
609 * the same as a set, but returns just before finally setting the
610 * new value. This is useful to check if a set might be successfull.
611 * If the instance -1 is passed, an array of values is supposed and
612 * all instances of the OID will be set.
613 *
614 * Returns:
615 * SK_PNMI_ERR_OK The request was successfully performed.
616 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
617 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
618 * the correct data (e.g. a 32bit value is
619 * needed, but a 16 bit value was passed).
620 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
621 * value range.
622 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
623 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
624 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
625 * exist (e.g. port instance 3 on a two port
626 * adapter.
627 */
628static int SkPnmiPreSetVar(
629SK_AC *pAC, /* Pointer to adapter context */
630SK_IOC IoC, /* IO context handle */
631SK_U32 Id, /* Object ID that is to be processed */
632void *pBuf, /* Buffer to which the management data will be copied */
633unsigned int *pLen, /* Total length of management data */
634SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
635SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
636{
637 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
638 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
639 Id, *pLen, Instance, NetIndex));
640
641
642 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
643 Instance, NetIndex));
644}
645
646/*****************************************************************************
647 *
648 * SkPnmiSetVar - Sets the value of a single OID
649 *
650 * Description:
651 * Calls a general sub-function for all this stuff. The preset does
652 * the same as a set, but returns just before finally setting the
653 * new value. This is useful to check if a set might be successfull.
654 * If the instance -1 is passed, an array of values is supposed and
655 * all instances of the OID will be set.
656 *
657 * Returns:
658 * SK_PNMI_ERR_OK The request was successfully performed.
659 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
660 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
661 * the correct data (e.g. a 32bit value is
662 * needed, but a 16 bit value was passed).
663 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
664 * value range.
665 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
666 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
667 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
668 * exist (e.g. port instance 3 on a two port
669 * adapter.
670 */
671int SkPnmiSetVar(
672SK_AC *pAC, /* Pointer to adapter context */
673SK_IOC IoC, /* IO context handle */
674SK_U32 Id, /* Object ID that is to be processed */
675void *pBuf, /* Buffer to which the management data will be copied */
676unsigned int *pLen, /* Total length of management data */
677SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
678SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
679{
680 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
681 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
682 Id, *pLen, Instance, NetIndex));
683
684 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
685 Instance, NetIndex));
686}
687
688/*****************************************************************************
689 *
690 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
691 *
692 * Description:
693 * Runs through the IdTable, queries the single OIDs and stores the
694 * returned data into the management database structure
695 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
696 * is stored in the IdTable. The return value of the function will also
697 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
698 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
699 *
700 * Returns:
701 * SK_PNMI_ERR_OK The request was successfully performed
702 * SK_PNMI_ERR_GENERAL A general severe internal error occured
703 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
704 * the data.
705 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
706 */
707int SkPnmiGetStruct(
708SK_AC *pAC, /* Pointer to adapter context */
709SK_IOC IoC, /* IO context handle */
710void *pBuf, /* Buffer to which the management data will be copied. */
711unsigned int *pLen, /* Length of buffer */
712SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
713{
714 int Ret;
715 unsigned int TableIndex;
716 unsigned int DstOffset;
717 unsigned int InstanceNo;
718 unsigned int InstanceCnt;
719 SK_U32 Instance;
720 unsigned int TmpLen;
721 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
722
723
724 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
725 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
726 *pLen, NetIndex));
727
728 if (*pLen < SK_PNMI_STRUCT_SIZE) {
729
730 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
731
732 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
733 (SK_U32)(-1));
734 }
735
736 *pLen = SK_PNMI_STRUCT_SIZE;
737 return (SK_PNMI_ERR_TOO_SHORT);
738 }
739
740 /*
741 * Check NetIndex
742 */
743 if (NetIndex >= pAC->Rlmt.NumNets) {
744 return (SK_PNMI_ERR_UNKNOWN_NET);
745 }
746
747 /* Update statistic */
748 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
749
750 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
751 SK_PNMI_ERR_OK) {
752
753 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
754 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
755 return (Ret);
756 }
757
758 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
759
760 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
761 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
762 return (Ret);
763 }
764
765 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
766
767 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
768 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
769 return (Ret);
770 }
771
772 /*
773 * Increment semaphores to indicate that an update was
774 * already done
775 */
776 pAC->Pnmi.MacUpdatedFlag ++;
777 pAC->Pnmi.RlmtUpdatedFlag ++;
778 pAC->Pnmi.SirqUpdatedFlag ++;
779
780 /* Get vpd keys for instance calculation */
781 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
782 if (Ret != SK_PNMI_ERR_OK) {
783
784 pAC->Pnmi.MacUpdatedFlag --;
785 pAC->Pnmi.RlmtUpdatedFlag --;
786 pAC->Pnmi.SirqUpdatedFlag --;
787
788 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
789 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
790 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
791 return (SK_PNMI_ERR_GENERAL);
792 }
793
794 /* Retrieve values */
795 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
796 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
797
798 InstanceNo = IdTable[TableIndex].InstanceNo;
799 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
800 InstanceCnt ++) {
801
802 DstOffset = IdTable[TableIndex].Offset +
803 (InstanceCnt - 1) *
804 IdTable[TableIndex].StructSize;
805
806 /*
807 * For the VPD the instance is not an index number
808 * but the key itself. Determin with the instance
809 * counter the VPD key to be used.
810 */
811 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
812 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
813 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
814 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
815
816 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
817 }
818 else {
819 Instance = (SK_U32)InstanceCnt;
820 }
821
822 TmpLen = *pLen - DstOffset;
823 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
824 IdTable[TableIndex].Id, (char *)pBuf +
825 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
826
827 /*
828 * An unknown instance error means that we reached
829 * the last instance of that variable. Proceed with
830 * the next OID in the table and ignore the return
831 * code.
832 */
833 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
834
835 break;
836 }
837
838 if (Ret != SK_PNMI_ERR_OK) {
839
840 pAC->Pnmi.MacUpdatedFlag --;
841 pAC->Pnmi.RlmtUpdatedFlag --;
842 pAC->Pnmi.SirqUpdatedFlag --;
843
844 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
845 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
846 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
847 return (Ret);
848 }
849 }
850 }
851
852 pAC->Pnmi.MacUpdatedFlag --;
853 pAC->Pnmi.RlmtUpdatedFlag --;
854 pAC->Pnmi.SirqUpdatedFlag --;
855
856 *pLen = SK_PNMI_STRUCT_SIZE;
857 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
858 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
859 return (SK_PNMI_ERR_OK);
860}
861
862/*****************************************************************************
863 *
864 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
865 *
866 * Description:
867 * Calls a general sub-function for all this set stuff. The preset does
868 * the same as a set, but returns just before finally setting the
869 * new value. This is useful to check if a set might be successfull.
870 * The sub-function runs through the IdTable, checks which OIDs are able
871 * to set, and calls the handler function of the OID to perform the
872 * preset. The return value of the function will also be stored in
873 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
874 * SK_PNMI_MIN_STRUCT_SIZE.
875 *
876 * Returns:
877 * SK_PNMI_ERR_OK The request was successfully performed.
878 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
879 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
880 * the correct data (e.g. a 32bit value is
881 * needed, but a 16 bit value was passed).
882 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
883 * value range.
884 */
885int SkPnmiPreSetStruct(
886SK_AC *pAC, /* Pointer to adapter context */
887SK_IOC IoC, /* IO context handle */
888void *pBuf, /* Buffer which contains the data to be set */
889unsigned int *pLen, /* Length of buffer */
890SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
891{
892 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
893 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
894 *pLen, NetIndex));
895
896 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
897 pLen, NetIndex));
898}
899
900/*****************************************************************************
901 *
902 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
903 *
904 * Description:
905 * Calls a general sub-function for all this set stuff. The return value
906 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
907 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
908 * The sub-function runs through the IdTable, checks which OIDs are able
909 * to set, and calls the handler function of the OID to perform the
910 * set. The return value of the function will also be stored in
911 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
912 * SK_PNMI_MIN_STRUCT_SIZE.
913 *
914 * Returns:
915 * SK_PNMI_ERR_OK The request was successfully performed.
916 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
917 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
918 * the correct data (e.g. a 32bit value is
919 * needed, but a 16 bit value was passed).
920 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
921 * value range.
922 */
923int SkPnmiSetStruct(
924SK_AC *pAC, /* Pointer to adapter context */
925SK_IOC IoC, /* IO context handle */
926void *pBuf, /* Buffer which contains the data to be set */
927unsigned int *pLen, /* Length of buffer */
928SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
929{
930 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
931 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
932 *pLen, NetIndex));
933
934 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
935 pLen, NetIndex));
936}
937
938/*****************************************************************************
939 *
940 * SkPnmiEvent - Event handler
941 *
942 * Description:
943 * Handles the following events:
944 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
945 * interrupt will be generated which is
946 * first handled by SIRQ which generates a
947 * this event. The event increments the
948 * upper 32 bit of the 64 bit counter.
949 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
950 * when a sensor reports a warning or
951 * error. The event will store a trap
952 * message in the trap buffer.
953 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
954 * module and is used to calculate the
955 * port switches per hour.
956 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
957 * timestamps.
958 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
959 * before a hard reset of the XMAC is
960 * performed. All counters will be saved
961 * and added to the hardware counter
962 * values after reset to grant continuous
963 * counter values.
964 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
965 * went logically up. A trap message will
966 * be stored to the trap buffer.
967 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
968 * went logically down. A trap message will
969 * be stored to the trap buffer.
970 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
971 * spanning tree root bridges were
972 * detected. A trap message will be stored
973 * to the trap buffer.
974 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
975 * down. PNMI will not further add the
976 * statistic values to the virtual port.
977 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
978 * is now an active port. PNMI will now
979 * add the statistic data of this port to
980 * the virtual port.
981 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
982 * contains the number of nets. 1 means single net, 2 means
983 * dual net. The second parameter is -1
984 *
985 * Returns:
986 * Always 0
987 */
988int SkPnmiEvent(
989SK_AC *pAC, /* Pointer to adapter context */
990SK_IOC IoC, /* IO context handle */
991SK_U32 Event, /* Event-Id */
992SK_EVPARA Param) /* Event dependent parameter */
993{
994 unsigned int PhysPortIndex;
995 unsigned int MaxNetNumber;
996 int CounterIndex;
997 int Ret;
998 SK_U16 MacStatus;
999 SK_U64 OverflowStatus;
1000 SK_U64 Mask;
1001 int MacType;
1002 SK_U64 Value;
1003 SK_U32 Val32;
1004 SK_U16 Register;
1005 SK_EVPARA EventParam;
1006 SK_U64 NewestValue;
1007 SK_U64 OldestValue;
1008 SK_U64 Delta;
1009 SK_PNMI_ESTIMATE *pEst;
1010 SK_U32 NetIndex;
1011 SK_GEPORT *pPrt;
1012 SK_PNMI_VCT *pVctBackupData;
1013 SK_U32 RetCode;
1014 int i;
1015 SK_U32 CableLength;
1016
1017
1018#ifdef DEBUG
1019 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1020
1021 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1022 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1023 (unsigned int)Event, (unsigned int)Param.Para64));
1024 }
1025#endif /* DEBUG */
1026 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1027
1028 MacType = pAC->GIni.GIMacType;
1029
1030 switch (Event) {
1031
1032 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1033 PhysPortIndex = (int)Param.Para32[0];
1034 MacStatus = (SK_U16)Param.Para32[1];
1035#ifdef DEBUG
1036 if (PhysPortIndex >= SK_MAX_MACS) {
1037
1038 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1039 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1040 " wrong, PhysPortIndex=0x%x\n",
1041 PhysPortIndex));
1042 return (0);
1043 }
1044#endif /* DEBUG */
1045 OverflowStatus = 0;
1046
1047 /*
1048 * Check which source caused an overflow interrupt.
1049 */
1050 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1051 MacStatus, &OverflowStatus) != 0) ||
1052 (OverflowStatus == 0)) {
1053
1054 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1055 return (0);
1056 }
1057
1058 /*
1059 * Check the overflow status register and increment
1060 * the upper dword of corresponding counter.
1061 */
1062 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1063 CounterIndex ++) {
1064
1065 Mask = (SK_U64)1 << CounterIndex;
1066 if ((OverflowStatus & Mask) == 0) {
1067
1068 continue;
1069 }
1070
1071 switch (StatOvrflwBit[CounterIndex][MacType]) {
1072
1073 case SK_PNMI_HTX_UTILUNDER:
1074 case SK_PNMI_HTX_UTILOVER:
1075 if (MacType == SK_MAC_XMAC) {
1076 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1077 Register |= XM_TX_SAM_LINE;
1078 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1079 }
1080 break;
1081
1082 case SK_PNMI_HRX_UTILUNDER:
1083 case SK_PNMI_HRX_UTILOVER:
1084 if (MacType == SK_MAC_XMAC) {
1085 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1086 Register |= XM_RX_SAM_LINE;
1087 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1088 }
1089 break;
1090
1091 case SK_PNMI_HTX_OCTETHIGH:
1092 case SK_PNMI_HTX_OCTETLOW:
1093 case SK_PNMI_HTX_RESERVED:
1094 case SK_PNMI_HRX_OCTETHIGH:
1095 case SK_PNMI_HRX_OCTETLOW:
1096 case SK_PNMI_HRX_IRLENGTH:
1097 case SK_PNMI_HRX_RESERVED:
1098
1099 /*
1100 * the following counters aren't be handled (id > 63)
1101 */
1102 case SK_PNMI_HTX_SYNC:
1103 case SK_PNMI_HTX_SYNC_OCTET:
1104 break;
1105
1106 case SK_PNMI_HRX_LONGFRAMES:
1107 if (MacType == SK_MAC_GMAC) {
1108 pAC->Pnmi.Port[PhysPortIndex].
1109 CounterHigh[CounterIndex] ++;
1110 }
1111 break;
1112
1113 default:
1114 pAC->Pnmi.Port[PhysPortIndex].
1115 CounterHigh[CounterIndex] ++;
1116 }
1117 }
1118 break;
1119
1120 case SK_PNMI_EVT_SEN_WAR_LOW:
1121#ifdef DEBUG
1122 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1123
1124 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1125 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1126 (unsigned int)Param.Para64));
1127 return (0);
1128 }
1129#endif /* DEBUG */
1130
1131 /*
1132 * Store a trap message in the trap buffer and generate
1133 * an event for user space applications with the
1134 * SK_DRIVER_SENDEVENT macro.
1135 */
1136 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1137 (unsigned int)Param.Para64);
1138 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1139 break;
1140
1141 case SK_PNMI_EVT_SEN_WAR_UPP:
1142#ifdef DEBUG
1143 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1144
1145 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1146 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1147 (unsigned int)Param.Para64));
1148 return (0);
1149 }
1150#endif /* DEBUG */
1151
1152 /*
1153 * Store a trap message in the trap buffer and generate
1154 * an event for user space applications with the
1155 * SK_DRIVER_SENDEVENT macro.
1156 */
1157 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1158 (unsigned int)Param.Para64);
1159 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1160 break;
1161
1162 case SK_PNMI_EVT_SEN_ERR_LOW:
1163#ifdef DEBUG
1164 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1165
1166 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1167 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1168 (unsigned int)Param.Para64));
1169 return (0);
1170 }
1171#endif /* DEBUG */
1172
1173 /*
1174 * Store a trap message in the trap buffer and generate
1175 * an event for user space applications with the
1176 * SK_DRIVER_SENDEVENT macro.
1177 */
1178 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1179 (unsigned int)Param.Para64);
1180 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1181 break;
1182
1183 case SK_PNMI_EVT_SEN_ERR_UPP:
1184#ifdef DEBUG
1185 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1186
1187 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1188 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1189 (unsigned int)Param.Para64));
1190 return (0);
1191 }
1192#endif /* DEBUG */
1193
1194 /*
1195 * Store a trap message in the trap buffer and generate
1196 * an event for user space applications with the
1197 * SK_DRIVER_SENDEVENT macro.
1198 */
1199 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1200 (unsigned int)Param.Para64);
1201 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1202 break;
1203
1204 case SK_PNMI_EVT_CHG_EST_TIMER:
1205 /*
1206 * Calculate port switch average on a per hour basis
1207 * Time interval for check : 28125 ms
1208 * Number of values for average : 8
1209 *
1210 * Be careful in changing these values, on change check
1211 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1212 * array one less than value number)
1213 * - Timer initialization SkTimerStart() in SkPnmiInit
1214 * - Delta value below must be multiplicated with
1215 * power of 2
1216 *
1217 */
1218 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1219 CounterIndex = pEst->EstValueIndex + 1;
1220 if (CounterIndex == 7) {
1221
1222 CounterIndex = 0;
1223 }
1224 pEst->EstValueIndex = CounterIndex;
1225
1226 NewestValue = pAC->Pnmi.RlmtChangeCts;
1227 OldestValue = pEst->EstValue[CounterIndex];
1228 pEst->EstValue[CounterIndex] = NewestValue;
1229
1230 /*
1231 * Calculate average. Delta stores the number of
1232 * port switches per 28125 * 8 = 225000 ms
1233 */
1234 if (NewestValue >= OldestValue) {
1235
1236 Delta = NewestValue - OldestValue;
1237 }
1238 else {
1239 /* Overflow situation */
1240 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1241 }
1242
1243 /*
1244 * Extrapolate delta to port switches per hour.
1245 * Estimate = Delta * (3600000 / 225000)
1246 * = Delta * 16
1247 * = Delta << 4
1248 */
1249 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1250
1251 /*
1252 * Check if threshold is exceeded. If the threshold is
1253 * permanently exceeded every 28125 ms an event will be
1254 * generated to remind the user of this condition.
1255 */
1256 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1257 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1258 pAC->Pnmi.RlmtChangeThreshold)) {
1259
1260 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1261 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1262 }
1263
1264 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1265 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1266 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1267 EventParam);
1268 break;
1269
1270 case SK_PNMI_EVT_CLEAR_COUNTER:
1271 /*
1272 * Param.Para32[0] contains the NetIndex (0 ..1).
1273 * Param.Para32[1] is reserved, contains -1.
1274 */
1275 NetIndex = (SK_U32)Param.Para32[0];
1276
1277#ifdef DEBUG
1278 if (NetIndex >= pAC->Rlmt.NumNets) {
1279
1280 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1281 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1282 NetIndex));
1283
1284 return (0);
1285 }
1286#endif /* DEBUG */
1287
1288 /*
1289 * Set all counters and timestamps to zero.
1290 * The according NetIndex is required as a
1291 * parameter of the event.
1292 */
1293 ResetCounter(pAC, IoC, NetIndex);
1294 break;
1295
1296 case SK_PNMI_EVT_XMAC_RESET:
1297 /*
1298 * To grant continuous counter values store the current
1299 * XMAC statistic values to the entries 1..n of the
1300 * CounterOffset array. XMAC Errata #2
1301 */
1302#ifdef DEBUG
1303 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1304
1305 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1306 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1307 (unsigned int)Param.Para64));
1308 return (0);
1309 }
1310#endif
1311 PhysPortIndex = (unsigned int)Param.Para64;
1312
1313 /*
1314 * Update XMAC statistic to get fresh values
1315 */
1316 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1317 if (Ret != SK_PNMI_ERR_OK) {
1318
1319 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1320 return (0);
1321 }
1322 /*
1323 * Increment semaphore to indicate that an update was
1324 * already done
1325 */
1326 pAC->Pnmi.MacUpdatedFlag ++;
1327
1328 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1329 CounterIndex ++) {
1330
1331 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1332
1333 continue;
1334 }
1335
1336 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1337 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1338
1339 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1340 }
1341
1342 pAC->Pnmi.MacUpdatedFlag --;
1343 break;
1344
1345 case SK_PNMI_EVT_RLMT_PORT_UP:
1346 PhysPortIndex = (unsigned int)Param.Para32[0];
1347#ifdef DEBUG
1348 if (PhysPortIndex >= SK_MAX_MACS) {
1349
1350 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1351 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1352 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1353
1354 return (0);
1355 }
1356#endif /* DEBUG */
1357
1358 /*
1359 * Store a trap message in the trap buffer and generate an event for
1360 * user space applications with the SK_DRIVER_SENDEVENT macro.
1361 */
1362 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1363 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1364
1365 /* Bugfix for XMAC errata (#10620)*/
1366 if (MacType == SK_MAC_XMAC) {
1367 /* Add incremental difference to offset (#10620)*/
1368 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1369 XM_RXE_SHT_ERR, &Val32);
1370
1371 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1372 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1373 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1374 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1375 }
1376
1377 /* Tell VctStatus() that a link was up meanwhile. */
1378 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1379 break;
1380
1381 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1382 PhysPortIndex = (unsigned int)Param.Para32[0];
1383
1384#ifdef DEBUG
1385 if (PhysPortIndex >= SK_MAX_MACS) {
1386
1387 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1388 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1389 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1390
1391 return (0);
1392 }
1393#endif /* DEBUG */
1394
1395 /*
1396 * Store a trap message in the trap buffer and generate an event for
1397 * user space applications with the SK_DRIVER_SENDEVENT macro.
1398 */
1399 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1400 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1401
1402 /* Bugfix #10620 - get zero level for incremental difference */
1403 if (MacType == SK_MAC_XMAC) {
1404
1405 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1406 XM_RXE_SHT_ERR, &Val32);
1407
1408 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1409 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1410 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1411 }
1412 break;
1413
1414 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1415 PhysPortIndex = (unsigned int)Param.Para32[0];
1416 NetIndex = (SK_U32)Param.Para32[1];
1417
1418#ifdef DEBUG
1419 if (PhysPortIndex >= SK_MAX_MACS) {
1420
1421 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1422 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1423 PhysPortIndex));
1424 }
1425
1426 if (NetIndex >= pAC->Rlmt.NumNets) {
1427
1428 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1429 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1430 NetIndex));
1431 }
1432#endif /* DEBUG */
1433
1434 /*
1435 * For now, ignore event if NetIndex != 0.
1436 */
1437 if (Param.Para32[1] != 0) {
1438
1439 return (0);
1440 }
1441
1442 /*
1443 * Nothing to do if port is already inactive
1444 */
1445 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1446
1447 return (0);
1448 }
1449
1450 /*
1451 * Update statistic counters to calculate new offset for the virtual
1452 * port and increment semaphore to indicate that an update was already
1453 * done.
1454 */
1455 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1456 SK_PNMI_ERR_OK) {
1457
1458 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1459 return (0);
1460 }
1461 pAC->Pnmi.MacUpdatedFlag ++;
1462
1463 /*
1464 * Calculate new counter offset for virtual port to grant continous
1465 * counting on port switches. The virtual port consists of all currently
1466 * active ports. The port down event indicates that a port is removed
1467 * from the virtual port. Therefore add the counter value of the removed
1468 * port to the CounterOffset for the virtual port to grant the same
1469 * counter value.
1470 */
1471 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1472 CounterIndex ++) {
1473
1474 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1475
1476 continue;
1477 }
1478
1479 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1480
1481 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1482 }
1483
1484 /*
1485 * Set port to inactive
1486 */
1487 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1488
1489 pAC->Pnmi.MacUpdatedFlag --;
1490 break;
1491
1492 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1493 PhysPortIndex = (unsigned int)Param.Para32[0];
1494 NetIndex = (SK_U32)Param.Para32[1];
1495
1496#ifdef DEBUG
1497 if (PhysPortIndex >= SK_MAX_MACS) {
1498
1499 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1500 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1501 PhysPortIndex));
1502 }
1503
1504 if (NetIndex >= pAC->Rlmt.NumNets) {
1505
1506 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1507 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1508 NetIndex));
1509 }
1510#endif /* DEBUG */
1511
1512 /*
1513 * For now, ignore event if NetIndex != 0.
1514 */
1515 if (Param.Para32[1] != 0) {
1516
1517 return (0);
1518 }
1519
1520 /*
1521 * Nothing to do if port is already active
1522 */
1523 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1524
1525 return (0);
1526 }
1527
1528 /*
1529 * Statistic maintenance
1530 */
1531 pAC->Pnmi.RlmtChangeCts ++;
1532 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1533
1534 /*
1535 * Store a trap message in the trap buffer and generate an event for
1536 * user space applications with the SK_DRIVER_SENDEVENT macro.
1537 */
1538 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1539 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1540
1541 /*
1542 * Update statistic counters to calculate new offset for the virtual
1543 * port and increment semaphore to indicate that an update was
1544 * already done.
1545 */
1546 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1547 SK_PNMI_ERR_OK) {
1548
1549 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1550 return (0);
1551 }
1552 pAC->Pnmi.MacUpdatedFlag ++;
1553
1554 /*
1555 * Calculate new counter offset for virtual port to grant continous
1556 * counting on port switches. A new port is added to the virtual port.
1557 * Therefore substract the counter value of the new port from the
1558 * CounterOffset for the virtual port to grant the same value.
1559 */
1560 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1561 CounterIndex ++) {
1562
1563 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1564
1565 continue;
1566 }
1567
1568 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1569
1570 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1571 }
1572
1573 /* Set port to active */
1574 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1575
1576 pAC->Pnmi.MacUpdatedFlag --;
1577 break;
1578
1579 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1580 /*
1581 * Para.Para32[0] contains the NetIndex.
1582 */
1583
1584 /*
1585 * Store a trap message in the trap buffer and generate an event for
1586 * user space applications with the SK_DRIVER_SENDEVENT macro.
1587 */
1588 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1589 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1590 break;
1591
1592 case SK_PNMI_EVT_RLMT_SET_NETS:
1593 /*
1594 * Param.Para32[0] contains the number of Nets.
1595 * Param.Para32[1] is reserved, contains -1.
1596 */
1597 /*
1598 * Check number of nets
1599 */
1600 MaxNetNumber = pAC->GIni.GIMacsFound;
1601 if (((unsigned int)Param.Para32[0] < 1)
1602 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1603 return (SK_PNMI_ERR_UNKNOWN_NET);
1604 }
1605
1606 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1607 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1608 }
1609 else { /* dual net mode */
1610 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1611 }
1612 break;
1613
1614 case SK_PNMI_EVT_VCT_RESET:
1615 PhysPortIndex = Param.Para32[0];
1616 pPrt = &pAC->GIni.GP[PhysPortIndex];
1617 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1618
1619 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1620 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1621 if (RetCode == 2) {
1622 /*
1623 * VCT test is still running.
1624 * Start VCT timer counter again.
1625 */
1626 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1627 Param.Para32[0] = PhysPortIndex;
1628 Param.Para32[1] = -1;
1629 SkTimerStart(pAC, IoC,
1630 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1631 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1632 break;
1633 }
1634 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1635 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1636 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1637
1638 /* Copy results for later use to PNMI struct. */
1639 for (i = 0; i < 4; i++) {
1640 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1641 if ((pPrt->PMdiPairLen[i] > 35) &&
1642 (pPrt->PMdiPairLen[i] < 0xff)) {
1643 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1644 }
1645 }
1646 if ((pPrt->PMdiPairLen[i] > 35) &&
1647 (pPrt->PMdiPairLen[i] != 0xff)) {
1648 CableLength = 1000 *
1649 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1650 }
1651 else {
1652 CableLength = 0;
1653 }
1654 pVctBackupData->PMdiPairLen[i] = CableLength;
1655 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1656 }
1657
1658 Param.Para32[0] = PhysPortIndex;
1659 Param.Para32[1] = -1;
1660 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1661 SkEventDispatcher(pAC, IoC);
1662 }
1663
1664 break;
1665
1666 default:
1667 break;
1668 }
1669
1670 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1671 return (0);
1672}
1673
1674
1675/******************************************************************************
1676 *
1677 * Private functions
1678 *
1679 */
1680
1681/*****************************************************************************
1682 *
1683 * PnmiVar - Gets, presets, and sets single OIDs
1684 *
1685 * Description:
1686 * Looks up the requested OID, calls the corresponding handler
1687 * function, and passes the parameters with the get, preset, or
1688 * set command. The function is called by SkGePnmiGetVar,
1689 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1690 *
1691 * Returns:
1692 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1693 * calling functions.
1694 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1695 */
1696PNMI_STATIC int PnmiVar(
1697SK_AC *pAC, /* Pointer to adapter context */
1698SK_IOC IoC, /* IO context handle */
1699int Action, /* GET/PRESET/SET action */
1700SK_U32 Id, /* Object ID that is to be processed */
1701char *pBuf, /* Buffer used for the management data transfer */
1702unsigned int *pLen, /* Total length of pBuf management data */
1703SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1704SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1705{
1706 unsigned int TableIndex;
1707 int Ret;
1708
1709
1710 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1711
1712 *pLen = 0;
1713 return (SK_PNMI_ERR_UNKNOWN_OID);
1714 }
1715
1716 /* Check NetIndex */
1717 if (NetIndex >= pAC->Rlmt.NumNets) {
1718 return (SK_PNMI_ERR_UNKNOWN_NET);
1719 }
1720
1721 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1722
1723 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1724 Instance, TableIndex, NetIndex);
1725
1726 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1727
1728 return (Ret);
1729}
1730
1731/*****************************************************************************
1732 *
1733 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1734 *
1735 * Description:
1736 * The return value of the function will also be stored in
1737 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1738 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1739 * checks which OIDs are able to set, and calls the handler function of
1740 * the OID to perform the set. The return value of the function will
1741 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1742 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1743 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1744 *
1745 * Returns:
1746 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1747 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1748 */
1749PNMI_STATIC int PnmiStruct(
1750SK_AC *pAC, /* Pointer to adapter context */
1751SK_IOC IoC, /* IO context handle */
1752int Action, /* PRESET/SET action to be performed */
1753char *pBuf, /* Buffer used for the management data transfer */
1754unsigned int *pLen, /* Length of pBuf management data buffer */
1755SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1756{
1757 int Ret;
1758 unsigned int TableIndex;
1759 unsigned int DstOffset;
1760 unsigned int Len;
1761 unsigned int InstanceNo;
1762 unsigned int InstanceCnt;
1763 SK_U32 Instance;
1764 SK_U32 Id;
1765
1766
1767 /* Check if the passed buffer has the right size */
1768 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1769
1770 /* Check if we can return the error within the buffer */
1771 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1772
1773 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1774 (SK_U32)(-1));
1775 }
1776
1777 *pLen = SK_PNMI_STRUCT_SIZE;
1778 return (SK_PNMI_ERR_TOO_SHORT);
1779 }
1780
1781 /* Check NetIndex */
1782 if (NetIndex >= pAC->Rlmt.NumNets) {
1783 return (SK_PNMI_ERR_UNKNOWN_NET);
1784 }
1785
1786 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1787
1788 /*
1789 * Update the values of RLMT and SIRQ and increment semaphores to
1790 * indicate that an update was already done.
1791 */
1792 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1793
1794 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1795 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1796 return (Ret);
1797 }
1798
1799 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1800
1801 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1802 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1803 return (Ret);
1804 }
1805
1806 pAC->Pnmi.RlmtUpdatedFlag ++;
1807 pAC->Pnmi.SirqUpdatedFlag ++;
1808
1809 /* Preset/Set values */
1810 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1811
1812 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1813 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1814
1815 continue;
1816 }
1817
1818 InstanceNo = IdTable[TableIndex].InstanceNo;
1819 Id = IdTable[TableIndex].Id;
1820
1821 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1822 InstanceCnt ++) {
1823
1824 DstOffset = IdTable[TableIndex].Offset +
1825 (InstanceCnt - 1) *
1826 IdTable[TableIndex].StructSize;
1827
1828 /*
1829 * Because VPD multiple instance variables are
1830 * not setable we do not need to evaluate VPD
1831 * instances. Have a look to VPD instance
1832 * calculation in SkPnmiGetStruct().
1833 */
1834 Instance = (SK_U32)InstanceCnt;
1835
1836 /*
1837 * Evaluate needed buffer length
1838 */
1839 Len = 0;
1840 Ret = IdTable[TableIndex].Func(pAC, IoC,
1841 SK_PNMI_GET, IdTable[TableIndex].Id,
1842 NULL, &Len, Instance, TableIndex, NetIndex);
1843
1844 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1845
1846 break;
1847 }
1848 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1849
1850 pAC->Pnmi.RlmtUpdatedFlag --;
1851 pAC->Pnmi.SirqUpdatedFlag --;
1852
1853 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1854 SK_PNMI_SET_STAT(pBuf,
1855 SK_PNMI_ERR_GENERAL, DstOffset);
1856 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1857 return (SK_PNMI_ERR_GENERAL);
1858 }
1859 if (Id == OID_SKGE_VPD_ACTION) {
1860
1861 switch (*(pBuf + DstOffset)) {
1862
1863 case SK_PNMI_VPD_CREATE:
1864 Len = 3 + *(pBuf + DstOffset + 3);
1865 break;
1866
1867 case SK_PNMI_VPD_DELETE:
1868 Len = 3;
1869 break;
1870
1871 default:
1872 Len = 1;
1873 break;
1874 }
1875 }
1876
1877 /* Call the OID handler function */
1878 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1879 IdTable[TableIndex].Id, pBuf + DstOffset,
1880 &Len, Instance, TableIndex, NetIndex);
1881
1882 if (Ret != SK_PNMI_ERR_OK) {
1883
1884 pAC->Pnmi.RlmtUpdatedFlag --;
1885 pAC->Pnmi.SirqUpdatedFlag --;
1886
1887 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1888 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1889 DstOffset);
1890 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1891 return (SK_PNMI_ERR_BAD_VALUE);
1892 }
1893 }
1894 }
1895
1896 pAC->Pnmi.RlmtUpdatedFlag --;
1897 pAC->Pnmi.SirqUpdatedFlag --;
1898
1899 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1900 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1901 return (SK_PNMI_ERR_OK);
1902}
1903
1904/*****************************************************************************
1905 *
1906 * LookupId - Lookup an OID in the IdTable
1907 *
1908 * Description:
1909 * Scans the IdTable to find the table entry of an OID.
1910 *
1911 * Returns:
1912 * The table index or -1 if not found.
1913 */
1914PNMI_STATIC int LookupId(
1915SK_U32 Id) /* Object identifier to be searched */
1916{
1917 int i;
1918
1919 for (i = 0; i < ID_TABLE_SIZE; i++) {
1920
1921 if (IdTable[i].Id == Id) {
1922
1923 return i;
1924 }
1925 }
1926
1927 return (-1);
1928}
1929
1930/*****************************************************************************
1931 *
1932 * OidStruct - Handler of OID_SKGE_ALL_DATA
1933 *
1934 * Description:
1935 * This OID performs a Get/Preset/SetStruct call and returns all data
1936 * in a SK_PNMI_STRUCT_DATA structure.
1937 *
1938 * Returns:
1939 * SK_PNMI_ERR_OK The request was successfully performed.
1940 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1941 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1942 * the correct data (e.g. a 32bit value is
1943 * needed, but a 16 bit value was passed).
1944 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1945 * value range.
1946 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1947 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1948 * exist (e.g. port instance 3 on a two port
1949 * adapter.
1950 */
1951PNMI_STATIC int OidStruct(
1952SK_AC *pAC, /* Pointer to adapter context */
1953SK_IOC IoC, /* IO context handle */
1954int Action, /* GET/PRESET/SET action */
1955SK_U32 Id, /* Object ID that is to be processed */
1956char *pBuf, /* Buffer used for the management data transfer */
1957unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1958SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1959unsigned int TableIndex, /* Index to the Id table */
1960SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1961{
1962 if (Id != OID_SKGE_ALL_DATA) {
1963
1964 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1965 SK_PNMI_ERR003MSG);
1966
1967 *pLen = 0;
1968 return (SK_PNMI_ERR_GENERAL);
1969 }
1970
1971 /*
1972 * Check instance. We only handle single instance variables
1973 */
1974 if (Instance != (SK_U32)(-1) && Instance != 1) {
1975
1976 *pLen = 0;
1977 return (SK_PNMI_ERR_UNKNOWN_INST);
1978 }
1979
1980 switch (Action) {
1981
1982 case SK_PNMI_GET:
1983 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1984
1985 case SK_PNMI_PRESET:
1986 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1987
1988 case SK_PNMI_SET:
1989 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1990 }
1991
1992 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1993
1994 *pLen = 0;
1995 return (SK_PNMI_ERR_GENERAL);
1996}
1997
1998/*****************************************************************************
1999 *
2000 * Perform - OID handler of OID_SKGE_ACTION
2001 *
2002 * Description:
2003 * None.
2004 *
2005 * Returns:
2006 * SK_PNMI_ERR_OK The request was successfully performed.
2007 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2008 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2009 * the correct data (e.g. a 32bit value is
2010 * needed, but a 16 bit value was passed).
2011 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2012 * value range.
2013 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2014 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2015 * exist (e.g. port instance 3 on a two port
2016 * adapter.
2017 */
2018PNMI_STATIC int Perform(
2019SK_AC *pAC, /* Pointer to adapter context */
2020SK_IOC IoC, /* IO context handle */
2021int Action, /* GET/PRESET/SET action */
2022SK_U32 Id, /* Object ID that is to be processed */
2023char *pBuf, /* Buffer used for the management data transfer */
2024unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2025SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2026unsigned int TableIndex, /* Index to the Id table */
2027SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2028{
2029 int Ret;
2030 SK_U32 ActionOp;
2031
2032
2033 /*
2034 * Check instance. We only handle single instance variables
2035 */
2036 if (Instance != (SK_U32)(-1) && Instance != 1) {
2037
2038 *pLen = 0;
2039 return (SK_PNMI_ERR_UNKNOWN_INST);
2040 }
2041
2042 if (*pLen < sizeof(SK_U32)) {
2043
2044 *pLen = sizeof(SK_U32);
2045 return (SK_PNMI_ERR_TOO_SHORT);
2046 }
2047
2048 /* Check if a get should be performed */
2049 if (Action == SK_PNMI_GET) {
2050
2051 /* A get is easy. We always return the same value */
2052 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2053 SK_PNMI_STORE_U32(pBuf, ActionOp);
2054 *pLen = sizeof(SK_U32);
2055
2056 return (SK_PNMI_ERR_OK);
2057 }
2058
2059 /* Continue with PRESET/SET action */
2060 if (*pLen > sizeof(SK_U32)) {
2061
2062 return (SK_PNMI_ERR_BAD_VALUE);
2063 }
2064
2065 /* Check if the command is a known one */
2066 SK_PNMI_READ_U32(pBuf, ActionOp);
2067 if (*pLen > sizeof(SK_U32) ||
2068 (ActionOp != SK_PNMI_ACT_IDLE &&
2069 ActionOp != SK_PNMI_ACT_RESET &&
2070 ActionOp != SK_PNMI_ACT_SELFTEST &&
2071 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2072
2073 *pLen = 0;
2074 return (SK_PNMI_ERR_BAD_VALUE);
2075 }
2076
2077 /* A preset ends here */
2078 if (Action == SK_PNMI_PRESET) {
2079
2080 return (SK_PNMI_ERR_OK);
2081 }
2082
2083 switch (ActionOp) {
2084
2085 case SK_PNMI_ACT_IDLE:
2086 /* Nothing to do */
2087 break;
2088
2089 case SK_PNMI_ACT_RESET:
2090 /*
2091 * Perform a driver reset or something that comes near
2092 * to this.
2093 */
2094 Ret = SK_DRIVER_RESET(pAC, IoC);
2095 if (Ret != 0) {
2096
2097 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2098 SK_PNMI_ERR005MSG);
2099
2100 return (SK_PNMI_ERR_GENERAL);
2101 }
2102 break;
2103
2104 case SK_PNMI_ACT_SELFTEST:
2105 /*
2106 * Perform a driver selftest or something similar to this.
2107 * Currently this feature is not used and will probably
2108 * implemented in another way.
2109 */
2110 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2111 pAC->Pnmi.TestResult = Ret;
2112 break;
2113
2114 case SK_PNMI_ACT_RESETCNT:
2115 /* Set all counters and timestamps to zero */
2116 ResetCounter(pAC, IoC, NetIndex);
2117 break;
2118
2119 default:
2120 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2121 SK_PNMI_ERR006MSG);
2122
2123 return (SK_PNMI_ERR_GENERAL);
2124 }
2125
2126 return (SK_PNMI_ERR_OK);
2127}
2128
2129/*****************************************************************************
2130 *
2131 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2132 *
2133 * Description:
2134 * Retrieves the statistic values of the virtual port (logical
2135 * index 0). Only special OIDs of NDIS are handled which consist
2136 * of a 32 bit instead of a 64 bit value. The OIDs are public
2137 * because perhaps some other platform can use them too.
2138 *
2139 * Returns:
2140 * SK_PNMI_ERR_OK The request was successfully performed.
2141 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2142 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2143 * the correct data (e.g. a 32bit value is
2144 * needed, but a 16 bit value was passed).
2145 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2146 * exist (e.g. port instance 3 on a two port
2147 * adapter.
2148 */
2149PNMI_STATIC int Mac8023Stat(
2150SK_AC *pAC, /* Pointer to adapter context */
2151SK_IOC IoC, /* IO context handle */
2152int Action, /* GET/PRESET/SET action */
2153SK_U32 Id, /* Object ID that is to be processed */
2154char *pBuf, /* Buffer used for the management data transfer */
2155unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2156SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2157unsigned int TableIndex, /* Index to the Id table */
2158SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2159{
2160 int Ret;
2161 SK_U64 StatVal;
2162 SK_U32 StatVal32;
2163 SK_BOOL Is64BitReq = SK_FALSE;
2164
2165 /*
2166 * Only the active Mac is returned
2167 */
2168 if (Instance != (SK_U32)(-1) && Instance != 1) {
2169
2170 *pLen = 0;
2171 return (SK_PNMI_ERR_UNKNOWN_INST);
2172 }
2173
2174 /*
2175 * Check action type
2176 */
2177 if (Action != SK_PNMI_GET) {
2178
2179 *pLen = 0;
2180 return (SK_PNMI_ERR_READ_ONLY);
2181 }
2182
2183 /* Check length */
2184 switch (Id) {
2185
2186 case OID_802_3_PERMANENT_ADDRESS:
2187 case OID_802_3_CURRENT_ADDRESS:
2188 if (*pLen < sizeof(SK_MAC_ADDR)) {
2189
2190 *pLen = sizeof(SK_MAC_ADDR);
2191 return (SK_PNMI_ERR_TOO_SHORT);
2192 }
2193 break;
2194
2195 default:
2196#ifndef SK_NDIS_64BIT_CTR
2197 if (*pLen < sizeof(SK_U32)) {
2198 *pLen = sizeof(SK_U32);
2199 return (SK_PNMI_ERR_TOO_SHORT);
2200 }
2201
2202#else /* SK_NDIS_64BIT_CTR */
2203
2204 /* for compatibility, at least 32bit are required for OID */
2205 if (*pLen < sizeof(SK_U32)) {
2206 /*
2207 * but indicate handling for 64bit values,
2208 * if insufficient space is provided
2209 */
2210 *pLen = sizeof(SK_U64);
2211 return (SK_PNMI_ERR_TOO_SHORT);
2212 }
2213
2214 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2215#endif /* SK_NDIS_64BIT_CTR */
2216 break;
2217 }
2218
2219 /*
2220 * Update all statistics, because we retrieve virtual MAC, which
2221 * consists of multiple physical statistics and increment semaphore
2222 * to indicate that an update was already done.
2223 */
2224 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2225 if ( Ret != SK_PNMI_ERR_OK) {
2226
2227 *pLen = 0;
2228 return (Ret);
2229 }
2230 pAC->Pnmi.MacUpdatedFlag ++;
2231
2232 /*
2233 * Get value (MAC Index 0 identifies the virtual MAC)
2234 */
2235 switch (Id) {
2236
2237 case OID_802_3_PERMANENT_ADDRESS:
2238 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2239 *pLen = sizeof(SK_MAC_ADDR);
2240 break;
2241
2242 case OID_802_3_CURRENT_ADDRESS:
2243 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2244 *pLen = sizeof(SK_MAC_ADDR);
2245 break;
2246
2247 default:
2248 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2249
2250 /* by default 32bit values are evaluated */
2251 if (!Is64BitReq) {
2252 StatVal32 = (SK_U32)StatVal;
2253 SK_PNMI_STORE_U32(pBuf, StatVal32);
2254 *pLen = sizeof(SK_U32);
2255 }
2256 else {
2257 SK_PNMI_STORE_U64(pBuf, StatVal);
2258 *pLen = sizeof(SK_U64);
2259 }
2260 break;
2261 }
2262
2263 pAC->Pnmi.MacUpdatedFlag --;
2264
2265 return (SK_PNMI_ERR_OK);
2266}
2267
2268/*****************************************************************************
2269 *
2270 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2271 *
2272 * Description:
2273 * Retrieves the MAC statistic data.
2274 *
2275 * Returns:
2276 * SK_PNMI_ERR_OK The request was successfully performed.
2277 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2278 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2279 * the correct data (e.g. a 32bit value is
2280 * needed, but a 16 bit value was passed).
2281 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2282 * exist (e.g. port instance 3 on a two port
2283 * adapter.
2284 */
2285PNMI_STATIC int MacPrivateStat(
2286SK_AC *pAC, /* Pointer to adapter context */
2287SK_IOC IoC, /* IO context handle */
2288int Action, /* GET/PRESET/SET action */
2289SK_U32 Id, /* Object ID that is to be processed */
2290char *pBuf, /* Buffer used for the management data transfer */
2291unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2292SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2293unsigned int TableIndex, /* Index to the Id table */
2294SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2295{
2296 unsigned int LogPortMax;
2297 unsigned int LogPortIndex;
2298 unsigned int PhysPortMax;
2299 unsigned int Limit;
2300 unsigned int Offset;
2301 int MacType;
2302 int Ret;
2303 SK_U64 StatVal;
2304
2305
2306
2307 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2308 PhysPortMax = pAC->GIni.GIMacsFound;
2309 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2310
2311 MacType = pAC->GIni.GIMacType;
2312
2313 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2314 LogPortMax--;
2315 }
2316
2317 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2318 /* Check instance range */
2319 if ((Instance < 1) || (Instance > LogPortMax)) {
2320
2321 *pLen = 0;
2322 return (SK_PNMI_ERR_UNKNOWN_INST);
2323 }
2324 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2325 Limit = LogPortIndex + 1;
2326 }
2327
2328 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2329
2330 LogPortIndex = 0;
2331 Limit = LogPortMax;
2332 }
2333
2334 /* Check action */
2335 if (Action != SK_PNMI_GET) {
2336
2337 *pLen = 0;
2338 return (SK_PNMI_ERR_READ_ONLY);
2339 }
2340
2341 /* Check length */
2342 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2343
2344 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2345 return (SK_PNMI_ERR_TOO_SHORT);
2346 }
2347
2348 /*
2349 * Update MAC statistic and increment semaphore to indicate that
2350 * an update was already done.
2351 */
2352 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2353 if (Ret != SK_PNMI_ERR_OK) {
2354
2355 *pLen = 0;
2356 return (Ret);
2357 }
2358 pAC->Pnmi.MacUpdatedFlag ++;
2359
2360 /* Get value */
2361 Offset = 0;
2362 for (; LogPortIndex < Limit; LogPortIndex ++) {
2363
2364 switch (Id) {
2365
2366/* XXX not yet implemented due to XMAC problems
2367 case OID_SKGE_STAT_TX_UTIL:
2368 return (SK_PNMI_ERR_GENERAL);
2369*/
2370/* XXX not yet implemented due to XMAC problems
2371 case OID_SKGE_STAT_RX_UTIL:
2372 return (SK_PNMI_ERR_GENERAL);
2373*/
2374 case OID_SKGE_STAT_RX:
2375 if (MacType == SK_MAC_GMAC) {
2376 StatVal =
2377 GetStatVal(pAC, IoC, LogPortIndex,
2378 SK_PNMI_HRX_BROADCAST, NetIndex) +
2379 GetStatVal(pAC, IoC, LogPortIndex,
2380 SK_PNMI_HRX_MULTICAST, NetIndex) +
2381 GetStatVal(pAC, IoC, LogPortIndex,
2382 SK_PNMI_HRX_UNICAST, NetIndex) +
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2385 }
2386 else {
2387 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2388 IdTable[TableIndex].Param, NetIndex);
2389 }
2390 break;
2391
2392 case OID_SKGE_STAT_TX:
2393 if (MacType == SK_MAC_GMAC) {
2394 StatVal =
2395 GetStatVal(pAC, IoC, LogPortIndex,
2396 SK_PNMI_HTX_BROADCAST, NetIndex) +
2397 GetStatVal(pAC, IoC, LogPortIndex,
2398 SK_PNMI_HTX_MULTICAST, NetIndex) +
2399 GetStatVal(pAC, IoC, LogPortIndex,
2400 SK_PNMI_HTX_UNICAST, NetIndex);
2401 }
2402 else {
2403 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2404 IdTable[TableIndex].Param, NetIndex);
2405 }
2406 break;
2407
2408 default:
2409 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2410 IdTable[TableIndex].Param, NetIndex);
2411 }
2412 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2413
2414 Offset += sizeof(SK_U64);
2415 }
2416 *pLen = Offset;
2417
2418 pAC->Pnmi.MacUpdatedFlag --;
2419
2420 return (SK_PNMI_ERR_OK);
2421}
2422
2423/*****************************************************************************
2424 *
2425 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2426 *
2427 * Description:
2428 * Get/Presets/Sets the current and factory MAC address. The MAC
2429 * address of the virtual port, which is reported to the OS, may
2430 * not be changed, but the physical ones. A set to the virtual port
2431 * will be ignored. No error should be reported because otherwise
2432 * a multiple instance set (-1) would always fail.
2433 *
2434 * Returns:
2435 * SK_PNMI_ERR_OK The request was successfully performed.
2436 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2437 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2438 * the correct data (e.g. a 32bit value is
2439 * needed, but a 16 bit value was passed).
2440 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2441 * value range.
2442 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2443 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2444 * exist (e.g. port instance 3 on a two port
2445 * adapter.
2446 */
2447PNMI_STATIC int Addr(
2448SK_AC *pAC, /* Pointer to adapter context */
2449SK_IOC IoC, /* IO context handle */
2450int Action, /* GET/PRESET/SET action */
2451SK_U32 Id, /* Object ID that is to be processed */
2452char *pBuf, /* Buffer used for the management data transfer */
2453unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2454SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2455unsigned int TableIndex, /* Index to the Id table */
2456SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2457{
2458 int Ret;
2459 unsigned int LogPortMax;
2460 unsigned int PhysPortMax;
2461 unsigned int LogPortIndex;
2462 unsigned int PhysPortIndex;
2463 unsigned int Limit;
2464 unsigned int Offset = 0;
2465
2466 /*
2467 * Calculate instance if wished. MAC index 0 is the virtual
2468 * MAC.
2469 */
2470 PhysPortMax = pAC->GIni.GIMacsFound;
2471 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2472
2473 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2474 LogPortMax--;
2475 }
2476
2477 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2478 /* Check instance range */
2479 if ((Instance < 1) || (Instance > LogPortMax)) {
2480
2481 *pLen = 0;
2482 return (SK_PNMI_ERR_UNKNOWN_INST);
2483 }
2484 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2485 Limit = LogPortIndex + 1;
2486 }
2487 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2488
2489 LogPortIndex = 0;
2490 Limit = LogPortMax;
2491 }
2492
2493 /*
2494 * Perform Action
2495 */
2496 if (Action == SK_PNMI_GET) {
2497
2498 /* Check length */
2499 if (*pLen < (Limit - LogPortIndex) * 6) {
2500
2501 *pLen = (Limit - LogPortIndex) * 6;
2502 return (SK_PNMI_ERR_TOO_SHORT);
2503 }
2504
2505 /*
2506 * Get value
2507 */
2508 for (; LogPortIndex < Limit; LogPortIndex ++) {
2509
2510 switch (Id) {
2511
2512 case OID_SKGE_PHYS_CUR_ADDR:
2513 if (LogPortIndex == 0) {
2514 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2515 }
2516 else {
2517 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2518
2519 CopyMac(pBuf + Offset,
2520 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2521 }
2522 Offset += 6;
2523 break;
2524
2525 case OID_SKGE_PHYS_FAC_ADDR:
2526 if (LogPortIndex == 0) {
2527 CopyMac(pBuf + Offset,
2528 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2529 }
2530 else {
2531 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2532 pAC, LogPortIndex);
2533
2534 CopyMac(pBuf + Offset,
2535 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2536 }
2537 Offset += 6;
2538 break;
2539
2540 default:
2541 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2542 SK_PNMI_ERR008MSG);
2543
2544 *pLen = 0;
2545 return (SK_PNMI_ERR_GENERAL);
2546 }
2547 }
2548
2549 *pLen = Offset;
2550 }
2551 else {
2552 /*
2553 * The logical MAC address may not be changed only
2554 * the physical ones
2555 */
2556 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2557
2558 *pLen = 0;
2559 return (SK_PNMI_ERR_READ_ONLY);
2560 }
2561
2562 /*
2563 * Only the current address may be changed
2564 */
2565 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2566
2567 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2568 SK_PNMI_ERR009MSG);
2569
2570 *pLen = 0;
2571 return (SK_PNMI_ERR_GENERAL);
2572 }
2573
2574 /* Check length */
2575 if (*pLen < (Limit - LogPortIndex) * 6) {
2576
2577 *pLen = (Limit - LogPortIndex) * 6;
2578 return (SK_PNMI_ERR_TOO_SHORT);
2579 }
2580 if (*pLen > (Limit - LogPortIndex) * 6) {
2581
2582 *pLen = 0;
2583 return (SK_PNMI_ERR_BAD_VALUE);
2584 }
2585
2586 /*
2587 * Check Action
2588 */
2589 if (Action == SK_PNMI_PRESET) {
2590
2591 *pLen = 0;
2592 return (SK_PNMI_ERR_OK);
2593 }
2594
2595 /*
2596 * Set OID_SKGE_MAC_CUR_ADDR
2597 */
2598 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2599
2600 /*
2601 * A set to virtual port and set of broadcast
2602 * address will be ignored
2603 */
2604 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2605 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2606
2607 continue;
2608 }
2609
2610 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2611 LogPortIndex);
2612
2613 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2614 (SK_MAC_ADDR *)(pBuf + Offset),
2615 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2616 SK_ADDR_PHYSICAL_ADDRESS));
2617 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2618
2619 return (SK_PNMI_ERR_GENERAL);
2620 }
2621 }
2622 *pLen = Offset;
2623 }
2624
2625 return (SK_PNMI_ERR_OK);
2626}
2627
2628/*****************************************************************************
2629 *
2630 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2631 *
2632 * Description:
2633 * Retrieves the statistic values of the CSUM module. The CSUM data
2634 * structure must be available in the SK_AC even if the CSUM module
2635 * is not included, because PNMI reads the statistic data from the
2636 * CSUM part of SK_AC directly.
2637 *
2638 * Returns:
2639 * SK_PNMI_ERR_OK The request was successfully performed.
2640 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2641 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2642 * the correct data (e.g. a 32bit value is
2643 * needed, but a 16 bit value was passed).
2644 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2645 * exist (e.g. port instance 3 on a two port
2646 * adapter.
2647 */
2648PNMI_STATIC int CsumStat(
2649SK_AC *pAC, /* Pointer to adapter context */
2650SK_IOC IoC, /* IO context handle */
2651int Action, /* GET/PRESET/SET action */
2652SK_U32 Id, /* Object ID that is to be processed */
2653char *pBuf, /* Buffer used for the management data transfer */
2654unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2655SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2656unsigned int TableIndex, /* Index to the Id table */
2657SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2658{
2659 unsigned int Index;
2660 unsigned int Limit;
2661 unsigned int Offset = 0;
2662 SK_U64 StatVal;
2663
2664
2665 /*
2666 * Calculate instance if wished
2667 */
2668 if (Instance != (SK_U32)(-1)) {
2669
2670 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2671
2672 *pLen = 0;
2673 return (SK_PNMI_ERR_UNKNOWN_INST);
2674 }
2675 Index = (unsigned int)Instance - 1;
2676 Limit = Index + 1;
2677 }
2678 else {
2679 Index = 0;
2680 Limit = SKCS_NUM_PROTOCOLS;
2681 }
2682
2683 /*
2684 * Check action
2685 */
2686 if (Action != SK_PNMI_GET) {
2687
2688 *pLen = 0;
2689 return (SK_PNMI_ERR_READ_ONLY);
2690 }
2691
2692 /* Check length */
2693 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2694
2695 *pLen = (Limit - Index) * sizeof(SK_U64);
2696 return (SK_PNMI_ERR_TOO_SHORT);
2697 }
2698
2699 /*
2700 * Get value
2701 */
2702 for (; Index < Limit; Index ++) {
2703
2704 switch (Id) {
2705
2706 case OID_SKGE_CHKSM_RX_OK_CTS:
2707 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2708 break;
2709
2710 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2712 break;
2713
2714 case OID_SKGE_CHKSM_RX_ERR_CTS:
2715 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2716 break;
2717
2718 case OID_SKGE_CHKSM_TX_OK_CTS:
2719 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2720 break;
2721
2722 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2723 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2724 break;
2725
2726 default:
2727 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2728 SK_PNMI_ERR010MSG);
2729
2730 *pLen = 0;
2731 return (SK_PNMI_ERR_GENERAL);
2732 }
2733
2734 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2735 Offset += sizeof(SK_U64);
2736 }
2737
2738 /*
2739 * Store used buffer space
2740 */
2741 *pLen = Offset;
2742
2743 return (SK_PNMI_ERR_OK);
2744}
2745
2746/*****************************************************************************
2747 *
2748 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2749 *
2750 * Description:
2751 * Retrieves the statistic values of the I2C module, which handles
2752 * the temperature and voltage sensors.
2753 *
2754 * Returns:
2755 * SK_PNMI_ERR_OK The request was successfully performed.
2756 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2757 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2758 * the correct data (e.g. a 32bit value is
2759 * needed, but a 16 bit value was passed).
2760 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2761 * exist (e.g. port instance 3 on a two port
2762 * adapter.
2763 */
2764PNMI_STATIC int SensorStat(
2765SK_AC *pAC, /* Pointer to adapter context */
2766SK_IOC IoC, /* IO context handle */
2767int Action, /* GET/PRESET/SET action */
2768SK_U32 Id, /* Object ID that is to be processed */
2769char *pBuf, /* Buffer used for the management data transfer */
2770unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2771SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2772unsigned int TableIndex, /* Index to the Id table */
2773SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2774{
2775 unsigned int i;
2776 unsigned int Index;
2777 unsigned int Limit;
2778 unsigned int Offset;
2779 unsigned int Len;
2780 SK_U32 Val32;
2781 SK_U64 Val64;
2782
2783
2784 /*
2785 * Calculate instance if wished
2786 */
2787 if ((Instance != (SK_U32)(-1))) {
2788
2789 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2790
2791 *pLen = 0;
2792 return (SK_PNMI_ERR_UNKNOWN_INST);
2793 }
2794
2795 Index = (unsigned int)Instance -1;
2796 Limit = (unsigned int)Instance;
2797 }
2798 else {
2799 Index = 0;
2800 Limit = (unsigned int) pAC->I2c.MaxSens;
2801 }
2802
2803 /*
2804 * Check action
2805 */
2806 if (Action != SK_PNMI_GET) {
2807
2808 *pLen = 0;
2809 return (SK_PNMI_ERR_READ_ONLY);
2810 }
2811
2812 /* Check length */
2813 switch (Id) {
2814
2815 case OID_SKGE_SENSOR_VALUE:
2816 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2817 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2818 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2819 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2820 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2821
2822 *pLen = (Limit - Index) * sizeof(SK_U32);
2823 return (SK_PNMI_ERR_TOO_SHORT);
2824 }
2825 break;
2826
2827 case OID_SKGE_SENSOR_DESCR:
2828 for (Offset = 0, i = Index; i < Limit; i ++) {
2829
2830 Len = (unsigned int)
2831 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2832 if (Len >= SK_PNMI_STRINGLEN2) {
2833
2834 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2835 SK_PNMI_ERR011MSG);
2836
2837 *pLen = 0;
2838 return (SK_PNMI_ERR_GENERAL);
2839 }
2840 Offset += Len;
2841 }
2842 if (*pLen < Offset) {
2843
2844 *pLen = Offset;
2845 return (SK_PNMI_ERR_TOO_SHORT);
2846 }
2847 break;
2848
2849 case OID_SKGE_SENSOR_INDEX:
2850 case OID_SKGE_SENSOR_TYPE:
2851 case OID_SKGE_SENSOR_STATUS:
2852 if (*pLen < Limit - Index) {
2853
2854 *pLen = Limit - Index;
2855 return (SK_PNMI_ERR_TOO_SHORT);
2856 }
2857 break;
2858
2859 case OID_SKGE_SENSOR_WAR_CTS:
2860 case OID_SKGE_SENSOR_WAR_TIME:
2861 case OID_SKGE_SENSOR_ERR_CTS:
2862 case OID_SKGE_SENSOR_ERR_TIME:
2863 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2864
2865 *pLen = (Limit - Index) * sizeof(SK_U64);
2866 return (SK_PNMI_ERR_TOO_SHORT);
2867 }
2868 break;
2869
2870 default:
2871 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2872 SK_PNMI_ERR012MSG);
2873
2874 *pLen = 0;
2875 return (SK_PNMI_ERR_GENERAL);
2876
2877 }
2878
2879 /*
2880 * Get value
2881 */
2882 for (Offset = 0; Index < Limit; Index ++) {
2883
2884 switch (Id) {
2885
2886 case OID_SKGE_SENSOR_INDEX:
2887 *(pBuf + Offset) = (char)Index;
2888 Offset += sizeof(char);
2889 break;
2890
2891 case OID_SKGE_SENSOR_DESCR:
2892 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2893 SK_MEMCPY(pBuf + Offset + 1,
2894 pAC->I2c.SenTable[Index].SenDesc, Len);
2895 *(pBuf + Offset) = (char)Len;
2896 Offset += Len + 1;
2897 break;
2898
2899 case OID_SKGE_SENSOR_TYPE:
2900 *(pBuf + Offset) =
2901 (char)pAC->I2c.SenTable[Index].SenType;
2902 Offset += sizeof(char);
2903 break;
2904
2905 case OID_SKGE_SENSOR_VALUE:
2906 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2907 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2908 Offset += sizeof(SK_U32);
2909 break;
2910
2911 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2912 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2913 SenThreWarnLow;
2914 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2915 Offset += sizeof(SK_U32);
2916 break;
2917
2918 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2919 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2920 SenThreWarnHigh;
2921 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2922 Offset += sizeof(SK_U32);
2923 break;
2924
2925 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2926 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2927 SenThreErrLow;
2928 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2929 Offset += sizeof(SK_U32);
2930 break;
2931
2932 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2933 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2934 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2935 Offset += sizeof(SK_U32);
2936 break;
2937
2938 case OID_SKGE_SENSOR_STATUS:
2939 *(pBuf + Offset) =
2940 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2941 Offset += sizeof(char);
2942 break;
2943
2944 case OID_SKGE_SENSOR_WAR_CTS:
2945 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2946 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2947 Offset += sizeof(SK_U64);
2948 break;
2949
2950 case OID_SKGE_SENSOR_ERR_CTS:
2951 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2952 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2953 Offset += sizeof(SK_U64);
2954 break;
2955
2956 case OID_SKGE_SENSOR_WAR_TIME:
2957 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2958 SenBegWarnTS);
2959 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2960 Offset += sizeof(SK_U64);
2961 break;
2962
2963 case OID_SKGE_SENSOR_ERR_TIME:
2964 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2965 SenBegErrTS);
2966 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2967 Offset += sizeof(SK_U64);
2968 break;
2969
2970 default:
2971 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2972 ("SensorStat: Unknown OID should be handled before"));
2973
2974 return (SK_PNMI_ERR_GENERAL);
2975 }
2976 }
2977
2978 /*
2979 * Store used buffer space
2980 */
2981 *pLen = Offset;
2982
2983 return (SK_PNMI_ERR_OK);
2984}
2985
2986/*****************************************************************************
2987 *
2988 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2989 *
2990 * Description:
2991 * Get/preset/set of VPD data. As instance the name of a VPD key
2992 * can be passed. The Instance parameter is a SK_U32 and can be
2993 * used as a string buffer for the VPD key, because their maximum
2994 * length is 4 byte.
2995 *
2996 * Returns:
2997 * SK_PNMI_ERR_OK The request was successfully performed.
2998 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2999 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3000 * the correct data (e.g. a 32bit value is
3001 * needed, but a 16 bit value was passed).
3002 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3003 * value range.
3004 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3005 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3006 * exist (e.g. port instance 3 on a two port
3007 * adapter.
3008 */
3009PNMI_STATIC int Vpd(
3010SK_AC *pAC, /* Pointer to adapter context */
3011SK_IOC IoC, /* IO context handle */
3012int Action, /* GET/PRESET/SET action */
3013SK_U32 Id, /* Object ID that is to be processed */
3014char *pBuf, /* Buffer used for the management data transfer */
3015unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3016SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3017unsigned int TableIndex, /* Index to the Id table */
3018SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3019{
3020 SK_VPD_STATUS *pVpdStatus;
3021 unsigned int BufLen;
3022 char Buf[256];
3023 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3024 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3025 unsigned int KeyNo;
3026 unsigned int Offset;
3027 unsigned int Index;
3028 unsigned int FirstIndex;
3029 unsigned int LastIndex;
3030 unsigned int Len;
3031 int Ret;
3032 SK_U32 Val32;
3033
3034 /*
3035 * Get array of all currently stored VPD keys
3036 */
3037 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3038 if (Ret != SK_PNMI_ERR_OK) {
3039 *pLen = 0;
3040 return (Ret);
3041 }
3042
3043 /*
3044 * If instance is not -1, try to find the requested VPD key for
3045 * the multiple instance variables. The other OIDs as for example
3046 * OID VPD_ACTION are single instance variables and must be
3047 * handled separatly.
3048 */
3049 FirstIndex = 0;
3050 LastIndex = KeyNo;
3051
3052 if ((Instance != (SK_U32)(-1))) {
3053
3054 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3055 Id == OID_SKGE_VPD_ACCESS) {
3056
3057 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3058 KeyStr[4] = 0;
3059
3060 for (Index = 0; Index < KeyNo; Index ++) {
3061
3062 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3063 FirstIndex = Index;
3064 LastIndex = Index+1;
3065 break;
3066 }
3067 }
3068 if (Index == KeyNo) {
3069
3070 *pLen = 0;
3071 return (SK_PNMI_ERR_UNKNOWN_INST);
3072 }
3073 }
3074 else if (Instance != 1) {
3075
3076 *pLen = 0;
3077 return (SK_PNMI_ERR_UNKNOWN_INST);
3078 }
3079 }
3080
3081 /*
3082 * Get value, if a query should be performed
3083 */
3084 if (Action == SK_PNMI_GET) {
3085
3086 switch (Id) {
3087
3088 case OID_SKGE_VPD_FREE_BYTES:
3089 /* Check length of buffer */
3090 if (*pLen < sizeof(SK_U32)) {
3091
3092 *pLen = sizeof(SK_U32);
3093 return (SK_PNMI_ERR_TOO_SHORT);
3094 }
3095 /* Get number of free bytes */
3096 pVpdStatus = VpdStat(pAC, IoC);
3097 if (pVpdStatus == NULL) {
3098
3099 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3100 SK_PNMI_ERR017MSG);
3101
3102 *pLen = 0;
3103 return (SK_PNMI_ERR_GENERAL);
3104 }
3105 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3106
3107 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3108 SK_PNMI_ERR018MSG);
3109
3110 *pLen = 0;
3111 return (SK_PNMI_ERR_GENERAL);
3112 }
3113
3114 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3115 SK_PNMI_STORE_U32(pBuf, Val32);
3116 *pLen = sizeof(SK_U32);
3117 break;
3118
3119 case OID_SKGE_VPD_ENTRIES_LIST:
3120 /* Check length */
3121 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3122
3123 Len += SK_STRLEN(KeyArr[Index]) + 1;
3124 }
3125 if (*pLen < Len) {
3126
3127 *pLen = Len;
3128 return (SK_PNMI_ERR_TOO_SHORT);
3129 }
3130
3131 /* Get value */
3132 *(pBuf) = (char)Len - 1;
3133 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3134
3135 Len = SK_STRLEN(KeyArr[Index]);
3136 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3137
3138 Offset += Len;
3139
3140 if (Index < KeyNo - 1) {
3141
3142 *(pBuf + Offset) = ' ';
3143 Offset ++;
3144 }
3145 }
3146 *pLen = Offset;
3147 break;
3148
3149 case OID_SKGE_VPD_ENTRIES_NUMBER:
3150 /* Check length */
3151 if (*pLen < sizeof(SK_U32)) {
3152
3153 *pLen = sizeof(SK_U32);
3154 return (SK_PNMI_ERR_TOO_SHORT);
3155 }
3156
3157 Val32 = (SK_U32)KeyNo;
3158 SK_PNMI_STORE_U32(pBuf, Val32);
3159 *pLen = sizeof(SK_U32);
3160 break;
3161
3162 case OID_SKGE_VPD_KEY:
3163 /* Check buffer length, if it is large enough */
3164 for (Len = 0, Index = FirstIndex;
3165 Index < LastIndex; Index ++) {
3166
3167 Len += SK_STRLEN(KeyArr[Index]) + 1;
3168 }
3169 if (*pLen < Len) {
3170
3171 *pLen = Len;
3172 return (SK_PNMI_ERR_TOO_SHORT);
3173 }
3174
3175 /*
3176 * Get the key to an intermediate buffer, because
3177 * we have to prepend a length byte.
3178 */
3179 for (Offset = 0, Index = FirstIndex;
3180 Index < LastIndex; Index ++) {
3181
3182 Len = SK_STRLEN(KeyArr[Index]);
3183
3184 *(pBuf + Offset) = (char)Len;
3185 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3186 Len);
3187 Offset += Len + 1;
3188 }
3189 *pLen = Offset;
3190 break;
3191
3192 case OID_SKGE_VPD_VALUE:
3193 /* Check the buffer length if it is large enough */
3194 for (Offset = 0, Index = FirstIndex;
3195 Index < LastIndex; Index ++) {
3196
3197 BufLen = 256;
3198 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3199 (int *)&BufLen) > 0 ||
3200 BufLen >= SK_PNMI_VPD_DATALEN) {
3201
3202 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3203 SK_PNMI_ERR021,
3204 SK_PNMI_ERR021MSG);
3205
3206 return (SK_PNMI_ERR_GENERAL);
3207 }
3208 Offset += BufLen + 1;
3209 }
3210 if (*pLen < Offset) {
3211
3212 *pLen = Offset;
3213 return (SK_PNMI_ERR_TOO_SHORT);
3214 }
3215
3216 /*
3217 * Get the value to an intermediate buffer, because
3218 * we have to prepend a length byte.
3219 */
3220 for (Offset = 0, Index = FirstIndex;
3221 Index < LastIndex; Index ++) {
3222
3223 BufLen = 256;
3224 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3225 (int *)&BufLen) > 0 ||
3226 BufLen >= SK_PNMI_VPD_DATALEN) {
3227
3228 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3229 SK_PNMI_ERR022,
3230 SK_PNMI_ERR022MSG);
3231
3232 *pLen = 0;
3233 return (SK_PNMI_ERR_GENERAL);
3234 }
3235
3236 *(pBuf + Offset) = (char)BufLen;
3237 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3238 Offset += BufLen + 1;
3239 }
3240 *pLen = Offset;
3241 break;
3242
3243 case OID_SKGE_VPD_ACCESS:
3244 if (*pLen < LastIndex - FirstIndex) {
3245
3246 *pLen = LastIndex - FirstIndex;
3247 return (SK_PNMI_ERR_TOO_SHORT);
3248 }
3249
3250 for (Offset = 0, Index = FirstIndex;
3251 Index < LastIndex; Index ++) {
3252
3253 if (VpdMayWrite(KeyArr[Index])) {
3254
3255 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3256 }
3257 else {
3258 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3259 }
3260 Offset ++;
3261 }
3262 *pLen = Offset;
3263 break;
3264
3265 case OID_SKGE_VPD_ACTION:
3266 Offset = LastIndex - FirstIndex;
3267 if (*pLen < Offset) {
3268
3269 *pLen = Offset;
3270 return (SK_PNMI_ERR_TOO_SHORT);
3271 }
3272 SK_MEMSET(pBuf, 0, Offset);
3273 *pLen = Offset;
3274 break;
3275
3276 default:
3277 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3278 SK_PNMI_ERR023MSG);
3279
3280 *pLen = 0;
3281 return (SK_PNMI_ERR_GENERAL);
3282 }
3283 }
3284 else {
3285 /* The only OID which can be set is VPD_ACTION */
3286 if (Id != OID_SKGE_VPD_ACTION) {
3287
3288 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3289 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3290 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3291 Id == OID_SKGE_VPD_KEY ||
3292 Id == OID_SKGE_VPD_VALUE ||
3293 Id == OID_SKGE_VPD_ACCESS) {
3294
3295 *pLen = 0;
3296 return (SK_PNMI_ERR_READ_ONLY);
3297 }
3298
3299 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3300 SK_PNMI_ERR024MSG);
3301
3302 *pLen = 0;
3303 return (SK_PNMI_ERR_GENERAL);
3304 }
3305
3306 /*
3307 * From this point we handle VPD_ACTION. Check the buffer
3308 * length. It should at least have the size of one byte.
3309 */
3310 if (*pLen < 1) {
3311
3312 *pLen = 1;
3313 return (SK_PNMI_ERR_TOO_SHORT);
3314 }
3315
3316 /*
3317 * The first byte contains the VPD action type we should
3318 * perform.
3319 */
3320 switch (*pBuf) {
3321
3322 case SK_PNMI_VPD_IGNORE:
3323 /* Nothing to do */
3324 break;
3325
3326 case SK_PNMI_VPD_CREATE:
3327 /*
3328 * We have to create a new VPD entry or we modify
3329 * an existing one. Check first the buffer length.
3330 */
3331 if (*pLen < 4) {
3332
3333 *pLen = 4;
3334 return (SK_PNMI_ERR_TOO_SHORT);
3335 }
3336 KeyStr[0] = pBuf[1];
3337 KeyStr[1] = pBuf[2];
3338 KeyStr[2] = 0;
3339
3340 /*
3341 * Is the entry writable or does it belong to the
3342 * read-only area?
3343 */
3344 if (!VpdMayWrite(KeyStr)) {
3345
3346 *pLen = 0;
3347 return (SK_PNMI_ERR_BAD_VALUE);
3348 }
3349
3350 Offset = (int)pBuf[3] & 0xFF;
3351
3352 SK_MEMCPY(Buf, pBuf + 4, Offset);
3353 Buf[Offset] = 0;
3354
3355 /* A preset ends here */
3356 if (Action == SK_PNMI_PRESET) {
3357
3358 return (SK_PNMI_ERR_OK);
3359 }
3360
3361 /* Write the new entry or modify an existing one */
3362 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3363 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3364
3365 *pLen = 0;
3366 return (SK_PNMI_ERR_BAD_VALUE);
3367 }
3368 else if (Ret != SK_PNMI_VPD_OK) {
3369
3370 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3371 SK_PNMI_ERR025MSG);
3372
3373 *pLen = 0;
3374 return (SK_PNMI_ERR_GENERAL);
3375 }
3376
3377 /*
3378 * Perform an update of the VPD data. This is
3379 * not mandantory, but just to be sure.
3380 */
3381 Ret = VpdUpdate(pAC, IoC);
3382 if (Ret != SK_PNMI_VPD_OK) {
3383
3384 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3385 SK_PNMI_ERR026MSG);
3386
3387 *pLen = 0;
3388 return (SK_PNMI_ERR_GENERAL);
3389 }
3390 break;
3391
3392 case SK_PNMI_VPD_DELETE:
3393 /* Check if the buffer size is plausible */
3394 if (*pLen < 3) {
3395
3396 *pLen = 3;
3397 return (SK_PNMI_ERR_TOO_SHORT);
3398 }
3399 if (*pLen > 3) {
3400
3401 *pLen = 0;
3402 return (SK_PNMI_ERR_BAD_VALUE);
3403 }
3404 KeyStr[0] = pBuf[1];
3405 KeyStr[1] = pBuf[2];
3406 KeyStr[2] = 0;
3407
3408 /* Find the passed key in the array */
3409 for (Index = 0; Index < KeyNo; Index ++) {
3410
3411 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3412
3413 break;
3414 }
3415 }
3416 /*
3417 * If we cannot find the key it is wrong, so we
3418 * return an appropriate error value.
3419 */
3420 if (Index == KeyNo) {
3421
3422 *pLen = 0;
3423 return (SK_PNMI_ERR_BAD_VALUE);
3424 }
3425
3426 if (Action == SK_PNMI_PRESET) {
3427
3428 return (SK_PNMI_ERR_OK);
3429 }
3430
3431 /* Ok, you wanted it and you will get it */
3432 Ret = VpdDelete(pAC, IoC, KeyStr);
3433 if (Ret != SK_PNMI_VPD_OK) {
3434
3435 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3436 SK_PNMI_ERR027MSG);
3437
3438 *pLen = 0;
3439 return (SK_PNMI_ERR_GENERAL);
3440 }
3441
3442 /*
3443 * Perform an update of the VPD data. This is
3444 * not mandantory, but just to be sure.
3445 */
3446 Ret = VpdUpdate(pAC, IoC);
3447 if (Ret != SK_PNMI_VPD_OK) {
3448
3449 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3450 SK_PNMI_ERR028MSG);
3451
3452 *pLen = 0;
3453 return (SK_PNMI_ERR_GENERAL);
3454 }
3455 break;
3456
3457 default:
3458 *pLen = 0;
3459 return (SK_PNMI_ERR_BAD_VALUE);
3460 }
3461 }
3462
3463 return (SK_PNMI_ERR_OK);
3464}
3465
3466/*****************************************************************************
3467 *
3468 * General - OID handler function of various single instance OIDs
3469 *
3470 * Description:
3471 * The code is simple. No description necessary.
3472 *
3473 * Returns:
3474 * SK_PNMI_ERR_OK The request was successfully performed.
3475 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3476 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3477 * the correct data (e.g. a 32bit value is
3478 * needed, but a 16 bit value was passed).
3479 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3480 * exist (e.g. port instance 3 on a two port
3481 * adapter.
3482 */
3483PNMI_STATIC int General(
3484SK_AC *pAC, /* Pointer to adapter context */
3485SK_IOC IoC, /* IO context handle */
3486int Action, /* GET/PRESET/SET action */
3487SK_U32 Id, /* Object ID that is to be processed */
3488char *pBuf, /* Buffer used for the management data transfer */
3489unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3490SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3491unsigned int TableIndex, /* Index to the Id table */
3492SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3493{
3494 int Ret;
3495 unsigned int Index;
3496 unsigned int Len;
3497 unsigned int Offset;
3498 unsigned int Val;
3499 SK_U8 Val8;
3500 SK_U16 Val16;
3501 SK_U32 Val32;
3502 SK_U64 Val64;
3503 SK_U64 Val64RxHwErrs = 0;
3504 SK_U64 Val64TxHwErrs = 0;
3505 SK_BOOL Is64BitReq = SK_FALSE;
3506 char Buf[256];
3507 int MacType;
3508
3509 /*
3510 * Check instance. We only handle single instance variables.
3511 */
3512 if (Instance != (SK_U32)(-1) && Instance != 1) {
3513
3514 *pLen = 0;
3515 return (SK_PNMI_ERR_UNKNOWN_INST);
3516 }
3517
3518 /*
3519 * Check action. We only allow get requests.
3520 */
3521 if (Action != SK_PNMI_GET) {
3522
3523 *pLen = 0;
3524 return (SK_PNMI_ERR_READ_ONLY);
3525 }
3526
3527 MacType = pAC->GIni.GIMacType;
3528
3529 /*
3530 * Check length for the various supported OIDs
3531 */
3532 switch (Id) {
3533
3534 case OID_GEN_XMIT_ERROR:
3535 case OID_GEN_RCV_ERROR:
3536 case OID_GEN_RCV_NO_BUFFER:
3537#ifndef SK_NDIS_64BIT_CTR
3538 if (*pLen < sizeof(SK_U32)) {
3539 *pLen = sizeof(SK_U32);
3540 return (SK_PNMI_ERR_TOO_SHORT);
3541 }
3542
3543#else /* SK_NDIS_64BIT_CTR */
3544
3545 /*
3546 * for compatibility, at least 32bit are required for oid
3547 */
3548 if (*pLen < sizeof(SK_U32)) {
3549 /*
3550 * but indicate handling for 64bit values,
3551 * if insufficient space is provided
3552 */
3553 *pLen = sizeof(SK_U64);
3554 return (SK_PNMI_ERR_TOO_SHORT);
3555 }
3556
3557 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3558#endif /* SK_NDIS_64BIT_CTR */
3559 break;
3560
3561 case OID_SKGE_PORT_NUMBER:
3562 case OID_SKGE_DEVICE_TYPE:
3563 case OID_SKGE_RESULT:
3564 case OID_SKGE_RLMT_MONITOR_NUMBER:
3565 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3566 case OID_SKGE_TRAP_NUMBER:
3567 case OID_SKGE_MDB_VERSION:
3568 case OID_SKGE_BOARDLEVEL:
3569 case OID_SKGE_CHIPID:
3570 case OID_SKGE_RAMSIZE:
3571 if (*pLen < sizeof(SK_U32)) {
3572
3573 *pLen = sizeof(SK_U32);
3574 return (SK_PNMI_ERR_TOO_SHORT);
3575 }
3576 break;
3577
3578 case OID_SKGE_CHIPSET:
3579 if (*pLen < sizeof(SK_U16)) {
3580
3581 *pLen = sizeof(SK_U16);
3582 return (SK_PNMI_ERR_TOO_SHORT);
3583 }
3584 break;
3585
3586 case OID_SKGE_BUS_TYPE:
3587 case OID_SKGE_BUS_SPEED:
3588 case OID_SKGE_BUS_WIDTH:
3589 case OID_SKGE_SENSOR_NUMBER:
3590 case OID_SKGE_CHKSM_NUMBER:
3591 case OID_SKGE_VAUXAVAIL:
3592 if (*pLen < sizeof(SK_U8)) {
3593
3594 *pLen = sizeof(SK_U8);
3595 return (SK_PNMI_ERR_TOO_SHORT);
3596 }
3597 break;
3598
3599 case OID_SKGE_TX_SW_QUEUE_LEN:
3600 case OID_SKGE_TX_SW_QUEUE_MAX:
3601 case OID_SKGE_TX_RETRY:
3602 case OID_SKGE_RX_INTR_CTS:
3603 case OID_SKGE_TX_INTR_CTS:
3604 case OID_SKGE_RX_NO_BUF_CTS:
3605 case OID_SKGE_TX_NO_BUF_CTS:
3606 case OID_SKGE_TX_USED_DESCR_NO:
3607 case OID_SKGE_RX_DELIVERED_CTS:
3608 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3609 case OID_SKGE_RX_HW_ERROR_CTS:
3610 case OID_SKGE_TX_HW_ERROR_CTS:
3611 case OID_SKGE_IN_ERRORS_CTS:
3612 case OID_SKGE_OUT_ERROR_CTS:
3613 case OID_SKGE_ERR_RECOVERY_CTS:
3614 case OID_SKGE_SYSUPTIME:
3615 if (*pLen < sizeof(SK_U64)) {
3616
3617 *pLen = sizeof(SK_U64);
3618 return (SK_PNMI_ERR_TOO_SHORT);
3619 }
3620 break;
3621
3622 default:
3623 /* Checked later */
3624 break;
3625 }
3626
3627 /* Update statistic */
3628 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3629 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3630 Id == OID_SKGE_IN_ERRORS_CTS ||
3631 Id == OID_SKGE_OUT_ERROR_CTS ||
3632 Id == OID_GEN_XMIT_ERROR ||
3633 Id == OID_GEN_RCV_ERROR) {
3634
3635 /* Force the XMAC to update its statistic counters and
3636 * Increment semaphore to indicate that an update was
3637 * already done.
3638 */
3639 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3640 if (Ret != SK_PNMI_ERR_OK) {
3641
3642 *pLen = 0;
3643 return (Ret);
3644 }
3645 pAC->Pnmi.MacUpdatedFlag ++;
3646
3647 /*
3648 * Some OIDs consist of multiple hardware counters. Those
3649 * values which are contained in all of them will be added
3650 * now.
3651 */
3652 switch (Id) {
3653
3654 case OID_SKGE_RX_HW_ERROR_CTS:
3655 case OID_SKGE_IN_ERRORS_CTS:
3656 case OID_GEN_RCV_ERROR:
3657 Val64RxHwErrs =
3658 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3659 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3660 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3661 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3670 break;
3671
3672 case OID_SKGE_TX_HW_ERROR_CTS:
3673 case OID_SKGE_OUT_ERROR_CTS:
3674 case OID_GEN_XMIT_ERROR:
3675 Val64TxHwErrs =
3676 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3677 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3678 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3679 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3680 break;
3681 }
3682 }
3683
3684 /*
3685 * Retrieve value
3686 */
3687 switch (Id) {
3688
3689 case OID_SKGE_SUPPORTED_LIST:
3690 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3691 if (*pLen < Len) {
3692
3693 *pLen = Len;
3694 return (SK_PNMI_ERR_TOO_SHORT);
3695 }
3696 for (Offset = 0, Index = 0; Offset < Len;
3697 Offset += sizeof(SK_U32), Index ++) {
3698
3699 Val32 = (SK_U32)IdTable[Index].Id;
3700 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3701 }
3702 *pLen = Len;
3703 break;
3704
3705 case OID_SKGE_BOARDLEVEL:
3706 Val32 = (SK_U32)pAC->GIni.GILevel;
3707 SK_PNMI_STORE_U32(pBuf, Val32);
3708 *pLen = sizeof(SK_U32);
3709 break;
3710
3711 case OID_SKGE_PORT_NUMBER:
3712 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3713 SK_PNMI_STORE_U32(pBuf, Val32);
3714 *pLen = sizeof(SK_U32);
3715 break;
3716
3717 case OID_SKGE_DEVICE_TYPE:
3718 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3719 SK_PNMI_STORE_U32(pBuf, Val32);
3720 *pLen = sizeof(SK_U32);
3721 break;
3722
3723 case OID_SKGE_DRIVER_DESCR:
3724 if (pAC->Pnmi.pDriverDescription == NULL) {
3725
3726 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3727 SK_PNMI_ERR007MSG);
3728
3729 *pLen = 0;
3730 return (SK_PNMI_ERR_GENERAL);
3731 }
3732
3733 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3734 if (Len > SK_PNMI_STRINGLEN1) {
3735
3736 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3737 SK_PNMI_ERR029MSG);
3738
3739 *pLen = 0;
3740 return (SK_PNMI_ERR_GENERAL);
3741 }
3742
3743 if (*pLen < Len) {
3744
3745 *pLen = Len;
3746 return (SK_PNMI_ERR_TOO_SHORT);
3747 }
3748 *pBuf = (char)(Len - 1);
3749 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3750 *pLen = Len;
3751 break;
3752
3753 case OID_SKGE_DRIVER_VERSION:
3754 if (pAC->Pnmi.pDriverVersion == NULL) {
3755
3756 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3757 SK_PNMI_ERR030MSG);
3758
3759 *pLen = 0;
3760 return (SK_PNMI_ERR_GENERAL);
3761 }
3762
3763 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3764 if (Len > SK_PNMI_STRINGLEN1) {
3765
3766 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3767 SK_PNMI_ERR031MSG);
3768
3769 *pLen = 0;
3770 return (SK_PNMI_ERR_GENERAL);
3771 }
3772
3773 if (*pLen < Len) {
3774
3775 *pLen = Len;
3776 return (SK_PNMI_ERR_TOO_SHORT);
3777 }
3778 *pBuf = (char)(Len - 1);
3779 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3780 *pLen = Len;
3781 break;
3782
3783 case OID_SKGE_DRIVER_RELDATE:
3784 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3785
3786 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3787 SK_PNMI_ERR053MSG);
3788
3789 *pLen = 0;
3790 return (SK_PNMI_ERR_GENERAL);
3791 }
3792
3793 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3794 if (Len > SK_PNMI_STRINGLEN1) {
3795
3796 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3797 SK_PNMI_ERR054MSG);
3798
3799 *pLen = 0;
3800 return (SK_PNMI_ERR_GENERAL);
3801 }
3802
3803 if (*pLen < Len) {
3804
3805 *pLen = Len;
3806 return (SK_PNMI_ERR_TOO_SHORT);
3807 }
3808 *pBuf = (char)(Len - 1);
3809 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3810 *pLen = Len;
3811 break;
3812
3813 case OID_SKGE_DRIVER_FILENAME:
3814 if (pAC->Pnmi.pDriverFileName == NULL) {
3815
3816 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3817 SK_PNMI_ERR055MSG);
3818
3819 *pLen = 0;
3820 return (SK_PNMI_ERR_GENERAL);
3821 }
3822
3823 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3824 if (Len > SK_PNMI_STRINGLEN1) {
3825
3826 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3827 SK_PNMI_ERR056MSG);
3828
3829 *pLen = 0;
3830 return (SK_PNMI_ERR_GENERAL);
3831 }
3832
3833 if (*pLen < Len) {
3834
3835 *pLen = Len;
3836 return (SK_PNMI_ERR_TOO_SHORT);
3837 }
3838 *pBuf = (char)(Len - 1);
3839 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3840 *pLen = Len;
3841 break;
3842
3843 case OID_SKGE_HW_DESCR:
3844 /*
3845 * The hardware description is located in the VPD. This
3846 * query may move to the initialisation routine. But
3847 * the VPD data is cached and therefore a call here
3848 * will not make much difference.
3849 */
3850 Len = 256;
3851 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3852
3853 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3854 SK_PNMI_ERR032MSG);
3855
3856 *pLen = 0;
3857 return (SK_PNMI_ERR_GENERAL);
3858 }
3859 Len ++;
3860 if (Len > SK_PNMI_STRINGLEN1) {
3861
3862 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3863 SK_PNMI_ERR033MSG);
3864
3865 *pLen = 0;
3866 return (SK_PNMI_ERR_GENERAL);
3867 }
3868 if (*pLen < Len) {
3869
3870 *pLen = Len;
3871 return (SK_PNMI_ERR_TOO_SHORT);
3872 }
3873 *pBuf = (char)(Len - 1);
3874 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3875 *pLen = Len;
3876 break;
3877
3878 case OID_SKGE_HW_VERSION:
3879 /* Oh, I love to do some string manipulation */
3880 if (*pLen < 5) {
3881
3882 *pLen = 5;
3883 return (SK_PNMI_ERR_TOO_SHORT);
3884 }
3885 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3886 pBuf[0] = 4;
3887 pBuf[1] = 'v';
3888 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3889 pBuf[3] = '.';
3890 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3891 *pLen = 5;
3892 break;
3893
3894 case OID_SKGE_CHIPSET:
3895 Val16 = pAC->Pnmi.Chipset;
3896 SK_PNMI_STORE_U16(pBuf, Val16);
3897 *pLen = sizeof(SK_U16);
3898 break;
3899
3900 case OID_SKGE_CHIPID:
3901 Val32 = pAC->GIni.GIChipId;
3902 SK_PNMI_STORE_U32(pBuf, Val32);
3903 *pLen = sizeof(SK_U32);
3904 break;
3905
3906 case OID_SKGE_RAMSIZE:
3907 Val32 = pAC->GIni.GIRamSize;
3908 SK_PNMI_STORE_U32(pBuf, Val32);
3909 *pLen = sizeof(SK_U32);
3910 break;
3911
3912 case OID_SKGE_VAUXAVAIL:
3913 *pBuf = (char) pAC->GIni.GIVauxAvail;
3914 *pLen = sizeof(char);
3915 break;
3916
3917 case OID_SKGE_BUS_TYPE:
3918 *pBuf = (char) SK_PNMI_BUS_PCI;
3919 *pLen = sizeof(char);
3920 break;
3921
3922 case OID_SKGE_BUS_SPEED:
3923 *pBuf = pAC->Pnmi.PciBusSpeed;
3924 *pLen = sizeof(char);
3925 break;
3926
3927 case OID_SKGE_BUS_WIDTH:
3928 *pBuf = pAC->Pnmi.PciBusWidth;
3929 *pLen = sizeof(char);
3930 break;
3931
3932 case OID_SKGE_RESULT:
3933 Val32 = pAC->Pnmi.TestResult;
3934 SK_PNMI_STORE_U32(pBuf, Val32);
3935 *pLen = sizeof(SK_U32);
3936 break;
3937
3938 case OID_SKGE_SENSOR_NUMBER:
3939 *pBuf = (char)pAC->I2c.MaxSens;
3940 *pLen = sizeof(char);
3941 break;
3942
3943 case OID_SKGE_CHKSM_NUMBER:
3944 *pBuf = SKCS_NUM_PROTOCOLS;
3945 *pLen = sizeof(char);
3946 break;
3947
3948 case OID_SKGE_TRAP_NUMBER:
3949 GetTrapQueueLen(pAC, &Len, &Val);
3950 Val32 = (SK_U32)Val;
3951 SK_PNMI_STORE_U32(pBuf, Val32);
3952 *pLen = sizeof(SK_U32);
3953 break;
3954
3955 case OID_SKGE_TRAP:
3956 GetTrapQueueLen(pAC, &Len, &Val);
3957 if (*pLen < Len) {
3958
3959 *pLen = Len;
3960 return (SK_PNMI_ERR_TOO_SHORT);
3961 }
3962 CopyTrapQueue(pAC, pBuf);
3963 *pLen = Len;
3964 break;
3965
3966 case OID_SKGE_RLMT_MONITOR_NUMBER:
3967/* XXX Not yet implemented by RLMT therefore we return zero elements */
3968 Val32 = 0;
3969 SK_PNMI_STORE_U32(pBuf, Val32);
3970 *pLen = sizeof(SK_U32);
3971 break;
3972
3973 case OID_SKGE_TX_SW_QUEUE_LEN:
3974 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3975 if (MacType == SK_MAC_XMAC) {
3976 /* Dual net mode */
3977 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3978 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3979 }
3980 /* Single net mode */
3981 else {
3982 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3983 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3984 }
3985 }
3986 else {
3987 /* Dual net mode */
3988 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3989 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3990 }
3991 /* Single net mode */
3992 else {
3993 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3994 pAC->Pnmi.Port[1].TxSwQueueLen;
3995 }
3996 }
3997 SK_PNMI_STORE_U64(pBuf, Val64);
3998 *pLen = sizeof(SK_U64);
3999 break;
4000
4001
4002 case OID_SKGE_TX_SW_QUEUE_MAX:
4003 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4004 if (MacType == SK_MAC_XMAC) {
4005 /* Dual net mode */
4006 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4007 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4008 }
4009 /* Single net mode */
4010 else {
4011 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4012 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4013 }
4014 }
4015 else {
4016 /* Dual net mode */
4017 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4018 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4019 }
4020 /* Single net mode */
4021 else {
4022 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4023 pAC->Pnmi.Port[1].TxSwQueueMax;
4024 }
4025 }
4026 SK_PNMI_STORE_U64(pBuf, Val64);
4027 *pLen = sizeof(SK_U64);
4028 break;
4029
4030 case OID_SKGE_TX_RETRY:
4031 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4032 if (MacType == SK_MAC_XMAC) {
4033 /* Dual net mode */
4034 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4035 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4036 }
4037 /* Single net mode */
4038 else {
4039 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4040 pAC->Pnmi.BufPort[1].TxRetryCts;
4041 }
4042 }
4043 else {
4044 /* Dual net mode */
4045 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4046 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4047 }
4048 /* Single net mode */
4049 else {
4050 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4051 pAC->Pnmi.Port[1].TxRetryCts;
4052 }
4053 }
4054 SK_PNMI_STORE_U64(pBuf, Val64);
4055 *pLen = sizeof(SK_U64);
4056 break;
4057
4058 case OID_SKGE_RX_INTR_CTS:
4059 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4060 if (MacType == SK_MAC_XMAC) {
4061 /* Dual net mode */
4062 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4063 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4064 }
4065 /* Single net mode */
4066 else {
4067 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4068 pAC->Pnmi.BufPort[1].RxIntrCts;
4069 }
4070 }
4071 else {
4072 /* Dual net mode */
4073 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4074 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4075 }
4076 /* Single net mode */
4077 else {
4078 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4079 pAC->Pnmi.Port[1].RxIntrCts;
4080 }
4081 }
4082 SK_PNMI_STORE_U64(pBuf, Val64);
4083 *pLen = sizeof(SK_U64);
4084 break;
4085
4086 case OID_SKGE_TX_INTR_CTS:
4087 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4088 if (MacType == SK_MAC_XMAC) {
4089 /* Dual net mode */
4090 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4091 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4092 }
4093 /* Single net mode */
4094 else {
4095 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4096 pAC->Pnmi.BufPort[1].TxIntrCts;
4097 }
4098 }
4099 else {
4100 /* Dual net mode */
4101 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4102 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4103 }
4104 /* Single net mode */
4105 else {
4106 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4107 pAC->Pnmi.Port[1].TxIntrCts;
4108 }
4109 }
4110 SK_PNMI_STORE_U64(pBuf, Val64);
4111 *pLen = sizeof(SK_U64);
4112 break;
4113
4114 case OID_SKGE_RX_NO_BUF_CTS:
4115 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4116 if (MacType == SK_MAC_XMAC) {
4117 /* Dual net mode */
4118 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4119 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4120 }
4121 /* Single net mode */
4122 else {
4123 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4124 pAC->Pnmi.BufPort[1].RxNoBufCts;
4125 }
4126 }
4127 else {
4128 /* Dual net mode */
4129 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4130 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4131 }
4132 /* Single net mode */
4133 else {
4134 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4135 pAC->Pnmi.Port[1].RxNoBufCts;
4136 }
4137 }
4138 SK_PNMI_STORE_U64(pBuf, Val64);
4139 *pLen = sizeof(SK_U64);
4140 break;
4141
4142 case OID_SKGE_TX_NO_BUF_CTS:
4143 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4144 if (MacType == SK_MAC_XMAC) {
4145 /* Dual net mode */
4146 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4147 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4148 }
4149 /* Single net mode */
4150 else {
4151 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4152 pAC->Pnmi.BufPort[1].TxNoBufCts;
4153 }
4154 }
4155 else {
4156 /* Dual net mode */
4157 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4158 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4159 }
4160 /* Single net mode */
4161 else {
4162 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4163 pAC->Pnmi.Port[1].TxNoBufCts;
4164 }
4165 }
4166 SK_PNMI_STORE_U64(pBuf, Val64);
4167 *pLen = sizeof(SK_U64);
4168 break;
4169
4170 case OID_SKGE_TX_USED_DESCR_NO:
4171 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4172 if (MacType == SK_MAC_XMAC) {
4173 /* Dual net mode */
4174 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4175 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4176 }
4177 /* Single net mode */
4178 else {
4179 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4180 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4181 }
4182 }
4183 else {
4184 /* Dual net mode */
4185 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4186 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4187 }
4188 /* Single net mode */
4189 else {
4190 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4191 pAC->Pnmi.Port[1].TxUsedDescrNo;
4192 }
4193 }
4194 SK_PNMI_STORE_U64(pBuf, Val64);
4195 *pLen = sizeof(SK_U64);
4196 break;
4197
4198 case OID_SKGE_RX_DELIVERED_CTS:
4199 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4200 if (MacType == SK_MAC_XMAC) {
4201 /* Dual net mode */
4202 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4203 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4204 }
4205 /* Single net mode */
4206 else {
4207 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4208 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4209 }
4210 }
4211 else {
4212 /* Dual net mode */
4213 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4214 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4215 }
4216 /* Single net mode */
4217 else {
4218 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4219 pAC->Pnmi.Port[1].RxDeliveredCts;
4220 }
4221 }
4222 SK_PNMI_STORE_U64(pBuf, Val64);
4223 *pLen = sizeof(SK_U64);
4224 break;
4225
4226 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4227 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4228 if (MacType == SK_MAC_XMAC) {
4229 /* Dual net mode */
4230 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4231 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4232 }
4233 /* Single net mode */
4234 else {
4235 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4236 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4237 }
4238 }
4239 else {
4240 /* Dual net mode */
4241 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4242 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4243 }
4244 /* Single net mode */
4245 else {
4246 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4247 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4248 }
4249 }
4250 SK_PNMI_STORE_U64(pBuf, Val64);
4251 *pLen = sizeof(SK_U64);
4252 break;
4253
4254 case OID_SKGE_RX_HW_ERROR_CTS:
4255 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4256 *pLen = sizeof(SK_U64);
4257 break;
4258
4259 case OID_SKGE_TX_HW_ERROR_CTS:
4260 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4261 *pLen = sizeof(SK_U64);
4262 break;
4263
4264 case OID_SKGE_IN_ERRORS_CTS:
4265 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4266 if (MacType == SK_MAC_XMAC) {
4267 /* Dual net mode */
4268 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4269 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4270 }
4271 /* Single net mode */
4272 else {
4273 Val64 = Val64RxHwErrs +
4274 pAC->Pnmi.BufPort[0].RxNoBufCts +
4275 pAC->Pnmi.BufPort[1].RxNoBufCts;
4276 }
4277 }
4278 else {
4279 /* Dual net mode */
4280 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4281 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4282 }
4283 /* Single net mode */
4284 else {
4285 Val64 = Val64RxHwErrs +
4286 pAC->Pnmi.Port[0].RxNoBufCts +
4287 pAC->Pnmi.Port[1].RxNoBufCts;
4288 }
4289 }
4290 SK_PNMI_STORE_U64(pBuf, Val64);
4291 *pLen = sizeof(SK_U64);
4292 break;
4293
4294 case OID_SKGE_OUT_ERROR_CTS:
4295 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4296 if (MacType == SK_MAC_XMAC) {
4297 /* Dual net mode */
4298 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4299 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4300 }
4301 /* Single net mode */
4302 else {
4303 Val64 = Val64TxHwErrs +
4304 pAC->Pnmi.BufPort[0].TxNoBufCts +
4305 pAC->Pnmi.BufPort[1].TxNoBufCts;
4306 }
4307 }
4308 else {
4309 /* Dual net mode */
4310 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4311 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4312 }
4313 /* Single net mode */
4314 else {
4315 Val64 = Val64TxHwErrs +
4316 pAC->Pnmi.Port[0].TxNoBufCts +
4317 pAC->Pnmi.Port[1].TxNoBufCts;
4318 }
4319 }
4320 SK_PNMI_STORE_U64(pBuf, Val64);
4321 *pLen = sizeof(SK_U64);
4322 break;
4323
4324 case OID_SKGE_ERR_RECOVERY_CTS:
4325 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4326 if (MacType == SK_MAC_XMAC) {
4327 /* Dual net mode */
4328 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4329 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4330 }
4331 /* Single net mode */
4332 else {
4333 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4334 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4335 }
4336 }
4337 else {
4338 /* Dual net mode */
4339 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4340 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4341 }
4342 /* Single net mode */
4343 else {
4344 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4345 pAC->Pnmi.Port[1].ErrRecoveryCts;
4346 }
4347 }
4348 SK_PNMI_STORE_U64(pBuf, Val64);
4349 *pLen = sizeof(SK_U64);
4350 break;
4351
4352 case OID_SKGE_SYSUPTIME:
4353 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4354 Val64 -= pAC->Pnmi.StartUpTime;
4355 SK_PNMI_STORE_U64(pBuf, Val64);
4356 *pLen = sizeof(SK_U64);
4357 break;
4358
4359 case OID_SKGE_MDB_VERSION:
4360 Val32 = SK_PNMI_MDB_VERSION;
4361 SK_PNMI_STORE_U32(pBuf, Val32);
4362 *pLen = sizeof(SK_U32);
4363 break;
4364
4365 case OID_GEN_RCV_ERROR:
4366 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4367 if (MacType == SK_MAC_XMAC) {
4368 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4369 }
4370 else {
4371 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4372 }
4373
4374 /*
4375 * by default 32bit values are evaluated
4376 */
4377 if (!Is64BitReq) {
4378 Val32 = (SK_U32)Val64;
4379 SK_PNMI_STORE_U32(pBuf, Val32);
4380 *pLen = sizeof(SK_U32);
4381 }
4382 else {
4383 SK_PNMI_STORE_U64(pBuf, Val64);
4384 *pLen = sizeof(SK_U64);
4385 }
4386 break;
4387
4388 case OID_GEN_XMIT_ERROR:
4389 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4390 if (MacType == SK_MAC_XMAC) {
4391 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4392 }
4393 else {
4394 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4395 }
4396
4397 /*
4398 * by default 32bit values are evaluated
4399 */
4400 if (!Is64BitReq) {
4401 Val32 = (SK_U32)Val64;
4402 SK_PNMI_STORE_U32(pBuf, Val32);
4403 *pLen = sizeof(SK_U32);
4404 }
4405 else {
4406 SK_PNMI_STORE_U64(pBuf, Val64);
4407 *pLen = sizeof(SK_U64);
4408 }
4409 break;
4410
4411 case OID_GEN_RCV_NO_BUFFER:
4412 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4413 if (MacType == SK_MAC_XMAC) {
4414 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4415 }
4416 else {
4417 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4418 }
4419
4420 /*
4421 * by default 32bit values are evaluated
4422 */
4423 if (!Is64BitReq) {
4424 Val32 = (SK_U32)Val64;
4425 SK_PNMI_STORE_U32(pBuf, Val32);
4426 *pLen = sizeof(SK_U32);
4427 }
4428 else {
4429 SK_PNMI_STORE_U64(pBuf, Val64);
4430 *pLen = sizeof(SK_U64);
4431 }
4432 break;
4433
4434 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4435 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4436 SK_PNMI_STORE_U32(pBuf, Val32);
4437 *pLen = sizeof(SK_U32);
4438 break;
4439
4440 default:
4441 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4442 SK_PNMI_ERR034MSG);
4443
4444 *pLen = 0;
4445 return (SK_PNMI_ERR_GENERAL);
4446 }
4447
4448 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4449 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4450 Id == OID_SKGE_IN_ERRORS_CTS ||
4451 Id == OID_SKGE_OUT_ERROR_CTS ||
4452 Id == OID_GEN_XMIT_ERROR ||
4453 Id == OID_GEN_RCV_ERROR) {
4454
4455 pAC->Pnmi.MacUpdatedFlag --;
4456 }
4457
4458 return (SK_PNMI_ERR_OK);
4459}
4460
4461/*****************************************************************************
4462 *
4463 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4464 *
4465 * Description:
4466 * Get/Presets/Sets the RLMT OIDs.
4467 *
4468 * Returns:
4469 * SK_PNMI_ERR_OK The request was successfully performed.
4470 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4471 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4472 * the correct data (e.g. a 32bit value is
4473 * needed, but a 16 bit value was passed).
4474 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4475 * value range.
4476 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4477 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4478 * exist (e.g. port instance 3 on a two port
4479 * adapter.
4480 */
4481PNMI_STATIC int Rlmt(
4482SK_AC *pAC, /* Pointer to adapter context */
4483SK_IOC IoC, /* IO context handle */
4484int Action, /* GET/PRESET/SET action */
4485SK_U32 Id, /* Object ID that is to be processed */
4486char *pBuf, /* Buffer used for the management data transfer */
4487unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4488SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4489unsigned int TableIndex, /* Index to the Id table */
4490SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4491{
4492 int Ret;
4493 unsigned int PhysPortIndex;
4494 unsigned int PhysPortMax;
4495 SK_EVPARA EventParam;
4496 SK_U32 Val32;
4497 SK_U64 Val64;
4498
4499
4500 /*
4501 * Check instance. Only single instance OIDs are allowed here.
4502 */
4503 if (Instance != (SK_U32)(-1) && Instance != 1) {
4504
4505 *pLen = 0;
4506 return (SK_PNMI_ERR_UNKNOWN_INST);
4507 }
4508
4509 /*
4510 * Perform the requested action.
4511 */
4512 if (Action == SK_PNMI_GET) {
4513
4514 /*
4515 * Check if the buffer length is large enough.
4516 */
4517
4518 switch (Id) {
4519
4520 case OID_SKGE_RLMT_MODE:
4521 case OID_SKGE_RLMT_PORT_ACTIVE:
4522 case OID_SKGE_RLMT_PORT_PREFERRED:
4523 if (*pLen < sizeof(SK_U8)) {
4524
4525 *pLen = sizeof(SK_U8);
4526 return (SK_PNMI_ERR_TOO_SHORT);
4527 }
4528 break;
4529
4530 case OID_SKGE_RLMT_PORT_NUMBER:
4531 if (*pLen < sizeof(SK_U32)) {
4532
4533 *pLen = sizeof(SK_U32);
4534 return (SK_PNMI_ERR_TOO_SHORT);
4535 }
4536 break;
4537
4538 case OID_SKGE_RLMT_CHANGE_CTS:
4539 case OID_SKGE_RLMT_CHANGE_TIME:
4540 case OID_SKGE_RLMT_CHANGE_ESTIM:
4541 case OID_SKGE_RLMT_CHANGE_THRES:
4542 if (*pLen < sizeof(SK_U64)) {
4543
4544 *pLen = sizeof(SK_U64);
4545 return (SK_PNMI_ERR_TOO_SHORT);
4546 }
4547 break;
4548
4549 default:
4550 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4551 SK_PNMI_ERR035MSG);
4552
4553 *pLen = 0;
4554 return (SK_PNMI_ERR_GENERAL);
4555 }
4556
4557 /*
4558 * Update RLMT statistic and increment semaphores to indicate
4559 * that an update was already done. Maybe RLMT will hold its
4560 * statistic always up to date some time. Then we can
4561 * remove this type of call.
4562 */
4563 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4564
4565 *pLen = 0;
4566 return (Ret);
4567 }
4568 pAC->Pnmi.RlmtUpdatedFlag ++;
4569
4570 /*
4571 * Retrieve Value
4572 */
4573 switch (Id) {
4574
4575 case OID_SKGE_RLMT_MODE:
4576 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4577 *pLen = sizeof(char);
4578 break;
4579
4580 case OID_SKGE_RLMT_PORT_NUMBER:
4581 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4582 SK_PNMI_STORE_U32(pBuf, Val32);
4583 *pLen = sizeof(SK_U32);
4584 break;
4585
4586 case OID_SKGE_RLMT_PORT_ACTIVE:
4587 *pBuf = 0;
4588 /*
4589 * If multiple ports may become active this OID
4590 * doesn't make sense any more. A new variable in
4591 * the port structure should be created. However,
4592 * for this variable the first active port is
4593 * returned.
4594 */
4595 PhysPortMax = pAC->GIni.GIMacsFound;
4596
4597 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4598 PhysPortIndex ++) {
4599
4600 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4601
4602 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4603 break;
4604 }
4605 }
4606 *pLen = sizeof(char);
4607 break;
4608
4609 case OID_SKGE_RLMT_PORT_PREFERRED:
4610 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4611 *pLen = sizeof(char);
4612 break;
4613
4614 case OID_SKGE_RLMT_CHANGE_CTS:
4615 Val64 = pAC->Pnmi.RlmtChangeCts;
4616 SK_PNMI_STORE_U64(pBuf, Val64);
4617 *pLen = sizeof(SK_U64);
4618 break;
4619
4620 case OID_SKGE_RLMT_CHANGE_TIME:
4621 Val64 = pAC->Pnmi.RlmtChangeTime;
4622 SK_PNMI_STORE_U64(pBuf, Val64);
4623 *pLen = sizeof(SK_U64);
4624 break;
4625
4626 case OID_SKGE_RLMT_CHANGE_ESTIM:
4627 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4628 SK_PNMI_STORE_U64(pBuf, Val64);
4629 *pLen = sizeof(SK_U64);
4630 break;
4631
4632 case OID_SKGE_RLMT_CHANGE_THRES:
4633 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4634 SK_PNMI_STORE_U64(pBuf, Val64);
4635 *pLen = sizeof(SK_U64);
4636 break;
4637
4638 default:
4639 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4640 ("Rlmt: Unknown OID should be handled before"));
4641
4642 pAC->Pnmi.RlmtUpdatedFlag --;
4643 *pLen = 0;
4644 return (SK_PNMI_ERR_GENERAL);
4645 }
4646
4647 pAC->Pnmi.RlmtUpdatedFlag --;
4648 }
4649 else {
4650 /* Perform a preset or set */
4651 switch (Id) {
4652
4653 case OID_SKGE_RLMT_MODE:
4654 /* Check if the buffer length is plausible */
4655 if (*pLen < sizeof(char)) {
4656
4657 *pLen = sizeof(char);
4658 return (SK_PNMI_ERR_TOO_SHORT);
4659 }
4660 /* Check if the value range is correct */
4661 if (*pLen != sizeof(char) ||
4662 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4663 *(SK_U8 *)pBuf > 15) {
4664
4665 *pLen = 0;
4666 return (SK_PNMI_ERR_BAD_VALUE);
4667 }
4668 /* The preset ends here */
4669 if (Action == SK_PNMI_PRESET) {
4670
4671 *pLen = 0;
4672 return (SK_PNMI_ERR_OK);
4673 }
4674 /* Send an event to RLMT to change the mode */
4675 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4676 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4677 EventParam.Para32[1] = 0;
4678 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4679 EventParam) > 0) {
4680
4681 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4682 SK_PNMI_ERR037MSG);
4683
4684 *pLen = 0;
4685 return (SK_PNMI_ERR_GENERAL);
4686 }
4687 break;
4688
4689 case OID_SKGE_RLMT_PORT_PREFERRED:
4690 /* Check if the buffer length is plausible */
4691 if (*pLen < sizeof(char)) {
4692
4693 *pLen = sizeof(char);
4694 return (SK_PNMI_ERR_TOO_SHORT);
4695 }
4696 /* Check if the value range is correct */
4697 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4698 (SK_U8)pAC->GIni.GIMacsFound) {
4699
4700 *pLen = 0;
4701 return (SK_PNMI_ERR_BAD_VALUE);
4702 }
4703 /* The preset ends here */
4704 if (Action == SK_PNMI_PRESET) {
4705
4706 *pLen = 0;
4707 return (SK_PNMI_ERR_OK);
4708 }
4709
4710 /*
4711 * Send an event to RLMT change the preferred port.
4712 * A param of -1 means automatic mode. RLMT will
4713 * make the decision which is the preferred port.
4714 */
4715 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4716 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4717 EventParam.Para32[1] = NetIndex;
4718 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4719 EventParam) > 0) {
4720
4721 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4722 SK_PNMI_ERR038MSG);
4723
4724 *pLen = 0;
4725 return (SK_PNMI_ERR_GENERAL);
4726 }
4727 break;
4728
4729 case OID_SKGE_RLMT_CHANGE_THRES:
4730 /* Check if the buffer length is plausible */
4731 if (*pLen < sizeof(SK_U64)) {
4732
4733 *pLen = sizeof(SK_U64);
4734 return (SK_PNMI_ERR_TOO_SHORT);
4735 }
4736 /*
4737 * There are not many restrictions to the
4738 * value range.
4739 */
4740 if (*pLen != sizeof(SK_U64)) {
4741
4742 *pLen = 0;
4743 return (SK_PNMI_ERR_BAD_VALUE);
4744 }
4745 /* A preset ends here */
4746 if (Action == SK_PNMI_PRESET) {
4747
4748 *pLen = 0;
4749 return (SK_PNMI_ERR_OK);
4750 }
4751 /*
4752 * Store the new threshold, which will be taken
4753 * on the next timer event.
4754 */
4755 SK_PNMI_READ_U64(pBuf, Val64);
4756 pAC->Pnmi.RlmtChangeThreshold = Val64;
4757 break;
4758
4759 default:
4760 /* The other OIDs are not be able for set */
4761 *pLen = 0;
4762 return (SK_PNMI_ERR_READ_ONLY);
4763 }
4764 }
4765
4766 return (SK_PNMI_ERR_OK);
4767}
4768
4769/*****************************************************************************
4770 *
4771 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4772 *
4773 * Description:
4774 * Performs get requests on multiple instance variables.
4775 *
4776 * Returns:
4777 * SK_PNMI_ERR_OK The request was successfully performed.
4778 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4779 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4780 * the correct data (e.g. a 32bit value is
4781 * needed, but a 16 bit value was passed).
4782 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4783 * exist (e.g. port instance 3 on a two port
4784 * adapter.
4785 */
4786PNMI_STATIC int RlmtStat(
4787SK_AC *pAC, /* Pointer to adapter context */
4788SK_IOC IoC, /* IO context handle */
4789int Action, /* GET/PRESET/SET action */
4790SK_U32 Id, /* Object ID that is to be processed */
4791char *pBuf, /* Buffer used for the management data transfer */
4792unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4793SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4794unsigned int TableIndex, /* Index to the Id table */
4795SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4796{
4797 unsigned int PhysPortMax;
4798 unsigned int PhysPortIndex;
4799 unsigned int Limit;
4800 unsigned int Offset;
4801 int Ret;
4802 SK_U32 Val32;
4803 SK_U64 Val64;
4804
4805 /*
4806 * Calculate the port indexes from the instance.
4807 */
4808 PhysPortMax = pAC->GIni.GIMacsFound;
4809
4810 if ((Instance != (SK_U32)(-1))) {
4811 /* Check instance range */
4812 if ((Instance < 1) || (Instance > PhysPortMax)) {
4813
4814 *pLen = 0;
4815 return (SK_PNMI_ERR_UNKNOWN_INST);
4816 }
4817
4818 /* Single net mode */
4819 PhysPortIndex = Instance - 1;
4820
4821 /* Dual net mode */
4822 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4823 PhysPortIndex = NetIndex;
4824 }
4825
4826 /* Both net modes */
4827 Limit = PhysPortIndex + 1;
4828 }
4829 else {
4830 /* Single net mode */
4831 PhysPortIndex = 0;
4832 Limit = PhysPortMax;
4833
4834 /* Dual net mode */
4835 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4836 PhysPortIndex = NetIndex;
4837 Limit = PhysPortIndex + 1;
4838 }
4839 }
4840
4841 /*
4842 * Currently only get requests are allowed.
4843 */
4844 if (Action != SK_PNMI_GET) {
4845
4846 *pLen = 0;
4847 return (SK_PNMI_ERR_READ_ONLY);
4848 }
4849
4850 /*
4851 * Check if the buffer length is large enough.
4852 */
4853 switch (Id) {
4854
4855 case OID_SKGE_RLMT_PORT_INDEX:
4856 case OID_SKGE_RLMT_STATUS:
4857 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4858
4859 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4860 return (SK_PNMI_ERR_TOO_SHORT);
4861 }
4862 break;
4863
4864 case OID_SKGE_RLMT_TX_HELLO_CTS:
4865 case OID_SKGE_RLMT_RX_HELLO_CTS:
4866 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4867 case OID_SKGE_RLMT_RX_SP_CTS:
4868 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4869
4870 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4871 return (SK_PNMI_ERR_TOO_SHORT);
4872 }
4873 break;
4874
4875 default:
4876 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4877 SK_PNMI_ERR039MSG);
4878
4879 *pLen = 0;
4880 return (SK_PNMI_ERR_GENERAL);
4881
4882 }
4883
4884 /*
4885 * Update statistic and increment semaphores to indicate that
4886 * an update was already done.
4887 */
4888 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4889
4890 *pLen = 0;
4891 return (Ret);
4892 }
4893 pAC->Pnmi.RlmtUpdatedFlag ++;
4894
4895 /*
4896 * Get value
4897 */
4898 Offset = 0;
4899 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4900
4901 switch (Id) {
4902
4903 case OID_SKGE_RLMT_PORT_INDEX:
4904 Val32 = PhysPortIndex;
4905 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4906 Offset += sizeof(SK_U32);
4907 break;
4908
4909 case OID_SKGE_RLMT_STATUS:
4910 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4911 SK_RLMT_PS_INIT ||
4912 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4913 SK_RLMT_PS_DOWN) {
4914
4915 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4916 }
4917 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4918
4919 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4920 }
4921 else {
4922 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4923 }
4924 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4925 Offset += sizeof(SK_U32);
4926 break;
4927
4928 case OID_SKGE_RLMT_TX_HELLO_CTS:
4929 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4930 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4931 Offset += sizeof(SK_U64);
4932 break;
4933
4934 case OID_SKGE_RLMT_RX_HELLO_CTS:
4935 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4936 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4937 Offset += sizeof(SK_U64);
4938 break;
4939
4940 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4941 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4942 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4943 Offset += sizeof(SK_U64);
4944 break;
4945
4946 case OID_SKGE_RLMT_RX_SP_CTS:
4947 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4948 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4949 Offset += sizeof(SK_U64);
4950 break;
4951
4952 default:
4953 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4954 ("RlmtStat: Unknown OID should be errored before"));
4955
4956 pAC->Pnmi.RlmtUpdatedFlag --;
4957 *pLen = 0;
4958 return (SK_PNMI_ERR_GENERAL);
4959 }
4960 }
4961 *pLen = Offset;
4962
4963 pAC->Pnmi.RlmtUpdatedFlag --;
4964
4965 return (SK_PNMI_ERR_OK);
4966}
4967
4968/*****************************************************************************
4969 *
4970 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4971 *
4972 * Description:
4973 * Get/Presets/Sets the OIDs concerning the configuration.
4974 *
4975 * Returns:
4976 * SK_PNMI_ERR_OK The request was successfully performed.
4977 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4978 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4979 * the correct data (e.g. a 32bit value is
4980 * needed, but a 16 bit value was passed).
4981 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4982 * value range.
4983 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4984 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4985 * exist (e.g. port instance 3 on a two port
4986 * adapter.
4987 */
4988PNMI_STATIC int MacPrivateConf(
4989SK_AC *pAC, /* Pointer to adapter context */
4990SK_IOC IoC, /* IO context handle */
4991int Action, /* GET/PRESET/SET action */
4992SK_U32 Id, /* Object ID that is to be processed */
4993char *pBuf, /* Buffer used for the management data transfer */
4994unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4995SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4996unsigned int TableIndex, /* Index to the Id table */
4997SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4998{
4999 unsigned int PhysPortMax;
5000 unsigned int PhysPortIndex;
5001 unsigned int LogPortMax;
5002 unsigned int LogPortIndex;
5003 unsigned int Limit;
5004 unsigned int Offset;
5005 char Val8;
5006 char *pBufPtr;
5007 int Ret;
5008 SK_EVPARA EventParam;
5009 SK_U32 Val32;
5010
5011 /*
5012 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5013 */
5014 PhysPortMax = pAC->GIni.GIMacsFound;
5015 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5016
5017 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5018 LogPortMax--;
5019 }
5020
5021 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5022 /* Check instance range */
5023 if ((Instance < 1) || (Instance > LogPortMax)) {
5024
5025 *pLen = 0;
5026 return (SK_PNMI_ERR_UNKNOWN_INST);
5027 }
5028 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5029 Limit = LogPortIndex + 1;
5030 }
5031
5032 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5033
5034 LogPortIndex = 0;
5035 Limit = LogPortMax;
5036 }
5037
5038 /*
5039 * Perform action
5040 */
5041 if (Action == SK_PNMI_GET) {
5042
5043 /* Check length */
5044 switch (Id) {
5045
5046 case OID_SKGE_PMD:
5047 case OID_SKGE_CONNECTOR:
5048 case OID_SKGE_LINK_CAP:
5049 case OID_SKGE_LINK_MODE:
5050 case OID_SKGE_LINK_MODE_STATUS:
5051 case OID_SKGE_LINK_STATUS:
5052 case OID_SKGE_FLOWCTRL_CAP:
5053 case OID_SKGE_FLOWCTRL_MODE:
5054 case OID_SKGE_FLOWCTRL_STATUS:
5055 case OID_SKGE_PHY_OPERATION_CAP:
5056 case OID_SKGE_PHY_OPERATION_MODE:
5057 case OID_SKGE_PHY_OPERATION_STATUS:
5058 case OID_SKGE_SPEED_CAP:
5059 case OID_SKGE_SPEED_MODE:
5060 case OID_SKGE_SPEED_STATUS:
5061 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5062
5063 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5064 return (SK_PNMI_ERR_TOO_SHORT);
5065 }
5066 break;
5067
5068 case OID_SKGE_MTU:
5069 case OID_SKGE_PHY_TYPE:
5070 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5071
5072 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5073 return (SK_PNMI_ERR_TOO_SHORT);
5074 }
5075 break;
5076
5077 default:
5078 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5079 SK_PNMI_ERR041MSG);
5080 *pLen = 0;
5081 return (SK_PNMI_ERR_GENERAL);
5082 }
5083
5084 /*
5085 * Update statistic and increment semaphore to indicate
5086 * that an update was already done.
5087 */
5088 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5089
5090 *pLen = 0;
5091 return (Ret);
5092 }
5093 pAC->Pnmi.SirqUpdatedFlag ++;
5094
5095 /*
5096 * Get value
5097 */
5098 Offset = 0;
5099 for (; LogPortIndex < Limit; LogPortIndex ++) {
5100
5101 pBufPtr = pBuf + Offset;
5102
5103 switch (Id) {
5104
5105 case OID_SKGE_PMD:
5106 *pBufPtr = pAC->Pnmi.PMD;
5107 Offset += sizeof(char);
5108 break;
5109
5110 case OID_SKGE_CONNECTOR:
5111 *pBufPtr = pAC->Pnmi.Connector;
5112 Offset += sizeof(char);
5113 break;
5114
5115 case OID_SKGE_PHY_TYPE:
5116 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5117 if (LogPortIndex == 0) {
5118 continue;
5119 }
5120 else {
5121 /* Get value for physical ports */
5122 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5123 pAC, LogPortIndex);
5124 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5125 SK_PNMI_STORE_U32(pBufPtr, Val32);
5126 }
5127 }
5128 else { /* DualNetMode */
5129
5130 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5131 SK_PNMI_STORE_U32(pBufPtr, Val32);
5132 }
5133 Offset += sizeof(SK_U32);
5134 break;
5135
5136 case OID_SKGE_LINK_CAP:
5137 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5138 if (LogPortIndex == 0) {
5139 /* Get value for virtual port */
5140 VirtualConf(pAC, IoC, Id, pBufPtr);
5141 }
5142 else {
5143 /* Get value for physical ports */
5144 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5145 pAC, LogPortIndex);
5146
5147 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5148 }
5149 }
5150 else { /* DualNetMode */
5151
5152 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5153 }
5154 Offset += sizeof(char);
5155 break;
5156
5157 case OID_SKGE_LINK_MODE:
5158 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5159 if (LogPortIndex == 0) {
5160 /* Get value for virtual port */
5161 VirtualConf(pAC, IoC, Id, pBufPtr);
5162 }
5163 else {
5164 /* Get value for physical ports */
5165 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5166 pAC, LogPortIndex);
5167
5168 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5169 }
5170 }
5171 else { /* DualNetMode */
5172
5173 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5174 }
5175 Offset += sizeof(char);
5176 break;
5177
5178 case OID_SKGE_LINK_MODE_STATUS:
5179 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5180 if (LogPortIndex == 0) {
5181 /* Get value for virtual port */
5182 VirtualConf(pAC, IoC, Id, pBufPtr);
5183 }
5184 else {
5185 /* Get value for physical port */
5186 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5187 pAC, LogPortIndex);
5188
5189 *pBufPtr =
5190 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5191 }
5192 }
5193 else { /* DualNetMode */
5194
5195 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5196 }
5197 Offset += sizeof(char);
5198 break;
5199
5200 case OID_SKGE_LINK_STATUS:
5201 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5202 if (LogPortIndex == 0) {
5203 /* Get value for virtual port */
5204 VirtualConf(pAC, IoC, Id, pBufPtr);
5205 }
5206 else {
5207 /* Get value for physical ports */
5208 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5209 pAC, LogPortIndex);
5210
5211 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5212 }
5213 }
5214 else { /* DualNetMode */
5215
5216 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5217 }
5218 Offset += sizeof(char);
5219 break;
5220
5221 case OID_SKGE_FLOWCTRL_CAP:
5222 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5223 if (LogPortIndex == 0) {
5224 /* Get value for virtual port */
5225 VirtualConf(pAC, IoC, Id, pBufPtr);
5226 }
5227 else {
5228 /* Get value for physical ports */
5229 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5230 pAC, LogPortIndex);
5231
5232 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5233 }
5234 }
5235 else { /* DualNetMode */
5236
5237 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5238 }
5239 Offset += sizeof(char);
5240 break;
5241
5242 case OID_SKGE_FLOWCTRL_MODE:
5243 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5244 if (LogPortIndex == 0) {
5245 /* Get value for virtual port */
5246 VirtualConf(pAC, IoC, Id, pBufPtr);
5247 }
5248 else {
5249 /* Get value for physical port */
5250 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5251 pAC, LogPortIndex);
5252
5253 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5254 }
5255 }
5256 else { /* DualNetMode */
5257
5258 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5259 }
5260 Offset += sizeof(char);
5261 break;
5262
5263 case OID_SKGE_FLOWCTRL_STATUS:
5264 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5265 if (LogPortIndex == 0) {
5266 /* Get value for virtual port */
5267 VirtualConf(pAC, IoC, Id, pBufPtr);
5268 }
5269 else {
5270 /* Get value for physical port */
5271 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5272 pAC, LogPortIndex);
5273
5274 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5275 }
5276 }
5277 else { /* DualNetMode */
5278
5279 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5280 }
5281 Offset += sizeof(char);
5282 break;
5283
5284 case OID_SKGE_PHY_OPERATION_CAP:
5285 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5286 if (LogPortIndex == 0) {
5287 /* Get value for virtual port */
5288 VirtualConf(pAC, IoC, Id, pBufPtr);
5289 }
5290 else {
5291 /* Get value for physical ports */
5292 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5293 pAC, LogPortIndex);
5294
5295 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5296 }
5297 }
5298 else { /* DualNetMode */
5299
5300 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5301 }
5302 Offset += sizeof(char);
5303 break;
5304
5305 case OID_SKGE_PHY_OPERATION_MODE:
5306 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5307 if (LogPortIndex == 0) {
5308 /* Get value for virtual port */
5309 VirtualConf(pAC, IoC, Id, pBufPtr);
5310 }
5311 else {
5312 /* Get value for physical port */
5313 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5314 pAC, LogPortIndex);
5315
5316 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5317 }
5318 }
5319 else { /* DualNetMode */
5320
5321 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5322 }
5323 Offset += sizeof(char);
5324 break;
5325
5326 case OID_SKGE_PHY_OPERATION_STATUS:
5327 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5328 if (LogPortIndex == 0) {
5329 /* Get value for virtual port */
5330 VirtualConf(pAC, IoC, Id, pBufPtr);
5331 }
5332 else {
5333 /* Get value for physical port */
5334 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5335 pAC, LogPortIndex);
5336
5337 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5338 }
5339 }
5340 else {
5341
5342 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5343 }
5344 Offset += sizeof(char);
5345 break;
5346
5347 case OID_SKGE_SPEED_CAP:
5348 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5349 if (LogPortIndex == 0) {
5350 /* Get value for virtual port */
5351 VirtualConf(pAC, IoC, Id, pBufPtr);
5352 }
5353 else {
5354 /* Get value for physical ports */
5355 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5356 pAC, LogPortIndex);
5357
5358 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5359 }
5360 }
5361 else { /* DualNetMode */
5362
5363 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5364 }
5365 Offset += sizeof(char);
5366 break;
5367
5368 case OID_SKGE_SPEED_MODE:
5369 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5370 if (LogPortIndex == 0) {
5371 /* Get value for virtual port */
5372 VirtualConf(pAC, IoC, Id, pBufPtr);
5373 }
5374 else {
5375 /* Get value for physical port */
5376 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5377 pAC, LogPortIndex);
5378
5379 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5380 }
5381 }
5382 else { /* DualNetMode */
5383
5384 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5385 }
5386 Offset += sizeof(char);
5387 break;
5388
5389 case OID_SKGE_SPEED_STATUS:
5390 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5391 if (LogPortIndex == 0) {
5392 /* Get value for virtual port */
5393 VirtualConf(pAC, IoC, Id, pBufPtr);
5394 }
5395 else {
5396 /* Get value for physical port */
5397 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5398 pAC, LogPortIndex);
5399
5400 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5401 }
5402 }
5403 else { /* DualNetMode */
5404
5405 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5406 }
5407 Offset += sizeof(char);
5408 break;
5409
5410 case OID_SKGE_MTU:
5411 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5412 SK_PNMI_STORE_U32(pBufPtr, Val32);
5413 Offset += sizeof(SK_U32);
5414 break;
5415
5416 default:
5417 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5418 ("MacPrivateConf: Unknown OID should be handled before"));
5419
5420 pAC->Pnmi.SirqUpdatedFlag --;
5421 return (SK_PNMI_ERR_GENERAL);
5422 }
5423 }
5424 *pLen = Offset;
5425 pAC->Pnmi.SirqUpdatedFlag --;
5426
5427 return (SK_PNMI_ERR_OK);
5428 }
5429
5430 /*
5431 * From here SET or PRESET action. Check if the passed
5432 * buffer length is plausible.
5433 */
5434 switch (Id) {
5435
5436 case OID_SKGE_LINK_MODE:
5437 case OID_SKGE_FLOWCTRL_MODE:
5438 case OID_SKGE_PHY_OPERATION_MODE:
5439 case OID_SKGE_SPEED_MODE:
5440 if (*pLen < Limit - LogPortIndex) {
5441
5442 *pLen = Limit - LogPortIndex;
5443 return (SK_PNMI_ERR_TOO_SHORT);
5444 }
5445 if (*pLen != Limit - LogPortIndex) {
5446
5447 *pLen = 0;
5448 return (SK_PNMI_ERR_BAD_VALUE);
5449 }
5450 break;
5451
5452 case OID_SKGE_MTU:
5453 if (*pLen < sizeof(SK_U32)) {
5454
5455 *pLen = sizeof(SK_U32);
5456 return (SK_PNMI_ERR_TOO_SHORT);
5457 }
5458 if (*pLen != sizeof(SK_U32)) {
5459
5460 *pLen = 0;
5461 return (SK_PNMI_ERR_BAD_VALUE);
5462 }
5463 break;
5464
5465 default:
5466 *pLen = 0;
5467 return (SK_PNMI_ERR_READ_ONLY);
5468 }
5469
5470 /*
5471 * Perform preset or set
5472 */
5473 Offset = 0;
5474 for (; LogPortIndex < Limit; LogPortIndex ++) {
5475
5476 switch (Id) {
5477
5478 case OID_SKGE_LINK_MODE:
5479 /* Check the value range */
5480 Val8 = *(pBuf + Offset);
5481 if (Val8 == 0) {
5482
5483 Offset += sizeof(char);
5484 break;
5485 }
5486 if (Val8 < SK_LMODE_HALF ||
5487 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5488 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5489
5490 *pLen = 0;
5491 return (SK_PNMI_ERR_BAD_VALUE);
5492 }
5493
5494 /* The preset ends here */
5495 if (Action == SK_PNMI_PRESET) {
5496
5497 return (SK_PNMI_ERR_OK);
5498 }
5499
5500 if (LogPortIndex == 0) {
5501
5502 /*
5503 * The virtual port consists of all currently
5504 * active ports. Find them and send an event
5505 * with the new link mode to SIRQ.
5506 */
5507 for (PhysPortIndex = 0;
5508 PhysPortIndex < PhysPortMax;
5509 PhysPortIndex ++) {
5510
5511 if (!pAC->Pnmi.Port[PhysPortIndex].
5512 ActiveFlag) {
5513
5514 continue;
5515 }
5516
5517 EventParam.Para32[0] = PhysPortIndex;
5518 EventParam.Para32[1] = (SK_U32)Val8;
5519 if (SkGeSirqEvent(pAC, IoC,
5520 SK_HWEV_SET_LMODE,
5521 EventParam) > 0) {
5522
5523 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5524 SK_PNMI_ERR043,
5525 SK_PNMI_ERR043MSG);
5526
5527 *pLen = 0;
5528 return (SK_PNMI_ERR_GENERAL);
5529 }
5530 }
5531 }
5532 else {
5533 /*
5534 * Send an event with the new link mode to
5535 * the SIRQ module.
5536 */
5537 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5538 pAC, LogPortIndex);
5539 EventParam.Para32[1] = (SK_U32)Val8;
5540 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5541 EventParam) > 0) {
5542
5543 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5544 SK_PNMI_ERR043,
5545 SK_PNMI_ERR043MSG);
5546
5547 *pLen = 0;
5548 return (SK_PNMI_ERR_GENERAL);
5549 }
5550 }
5551 Offset += sizeof(char);
5552 break;
5553
5554 case OID_SKGE_FLOWCTRL_MODE:
5555 /* Check the value range */
5556 Val8 = *(pBuf + Offset);
5557 if (Val8 == 0) {
5558
5559 Offset += sizeof(char);
5560 break;
5561 }
5562 if (Val8 < SK_FLOW_MODE_NONE ||
5563 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5564 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5565
5566 *pLen = 0;
5567 return (SK_PNMI_ERR_BAD_VALUE);
5568 }
5569
5570 /* The preset ends here */
5571 if (Action == SK_PNMI_PRESET) {
5572
5573 return (SK_PNMI_ERR_OK);
5574 }
5575
5576 if (LogPortIndex == 0) {
5577
5578 /*
5579 * The virtual port consists of all currently
5580 * active ports. Find them and send an event
5581 * with the new flow control mode to SIRQ.
5582 */
5583 for (PhysPortIndex = 0;
5584 PhysPortIndex < PhysPortMax;
5585 PhysPortIndex ++) {
5586
5587 if (!pAC->Pnmi.Port[PhysPortIndex].
5588 ActiveFlag) {
5589
5590 continue;
5591 }
5592
5593 EventParam.Para32[0] = PhysPortIndex;
5594 EventParam.Para32[1] = (SK_U32)Val8;
5595 if (SkGeSirqEvent(pAC, IoC,
5596 SK_HWEV_SET_FLOWMODE,
5597 EventParam) > 0) {
5598
5599 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5600 SK_PNMI_ERR044,
5601 SK_PNMI_ERR044MSG);
5602
5603 *pLen = 0;
5604 return (SK_PNMI_ERR_GENERAL);
5605 }
5606 }
5607 }
5608 else {
5609 /*
5610 * Send an event with the new flow control
5611 * mode to the SIRQ module.
5612 */
5613 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5614 pAC, LogPortIndex);
5615 EventParam.Para32[1] = (SK_U32)Val8;
5616 if (SkGeSirqEvent(pAC, IoC,
5617 SK_HWEV_SET_FLOWMODE, EventParam)
5618 > 0) {
5619
5620 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5621 SK_PNMI_ERR044,
5622 SK_PNMI_ERR044MSG);
5623
5624 *pLen = 0;
5625 return (SK_PNMI_ERR_GENERAL);
5626 }
5627 }
5628 Offset += sizeof(char);
5629 break;
5630
5631 case OID_SKGE_PHY_OPERATION_MODE :
5632 /* Check the value range */
5633 Val8 = *(pBuf + Offset);
5634 if (Val8 == 0) {
5635 /* mode of this port remains unchanged */
5636 Offset += sizeof(char);
5637 break;
5638 }
5639 if (Val8 < SK_MS_MODE_AUTO ||
5640 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5641 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5642
5643 *pLen = 0;
5644 return (SK_PNMI_ERR_BAD_VALUE);
5645 }
5646
5647 /* The preset ends here */
5648 if (Action == SK_PNMI_PRESET) {
5649
5650 return (SK_PNMI_ERR_OK);
5651 }
5652
5653 if (LogPortIndex == 0) {
5654
5655 /*
5656 * The virtual port consists of all currently
5657 * active ports. Find them and send an event
5658 * with new master/slave (role) mode to SIRQ.
5659 */
5660 for (PhysPortIndex = 0;
5661 PhysPortIndex < PhysPortMax;
5662 PhysPortIndex ++) {
5663
5664 if (!pAC->Pnmi.Port[PhysPortIndex].
5665 ActiveFlag) {
5666
5667 continue;
5668 }
5669
5670 EventParam.Para32[0] = PhysPortIndex;
5671 EventParam.Para32[1] = (SK_U32)Val8;
5672 if (SkGeSirqEvent(pAC, IoC,
5673 SK_HWEV_SET_ROLE,
5674 EventParam) > 0) {
5675
5676 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5677 SK_PNMI_ERR042,
5678 SK_PNMI_ERR042MSG);
5679
5680 *pLen = 0;
5681 return (SK_PNMI_ERR_GENERAL);
5682 }
5683 }
5684 }
5685 else {
5686 /*
5687 * Send an event with the new master/slave
5688 * (role) mode to the SIRQ module.
5689 */
5690 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5691 pAC, LogPortIndex);
5692 EventParam.Para32[1] = (SK_U32)Val8;
5693 if (SkGeSirqEvent(pAC, IoC,
5694 SK_HWEV_SET_ROLE, EventParam) > 0) {
5695
5696 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5697 SK_PNMI_ERR042,
5698 SK_PNMI_ERR042MSG);
5699
5700 *pLen = 0;
5701 return (SK_PNMI_ERR_GENERAL);
5702 }
5703 }
5704
5705 Offset += sizeof(char);
5706 break;
5707
5708 case OID_SKGE_SPEED_MODE:
5709 /* Check the value range */
5710 Val8 = *(pBuf + Offset);
5711 if (Val8 == 0) {
5712
5713 Offset += sizeof(char);
5714 break;
5715 }
5716 if (Val8 < (SK_LSPEED_AUTO) ||
5717 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5718 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5719
5720 *pLen = 0;
5721 return (SK_PNMI_ERR_BAD_VALUE);
5722 }
5723
5724 /* The preset ends here */
5725 if (Action == SK_PNMI_PRESET) {
5726
5727 return (SK_PNMI_ERR_OK);
5728 }
5729
5730 if (LogPortIndex == 0) {
5731
5732 /*
5733 * The virtual port consists of all currently
5734 * active ports. Find them and send an event
5735 * with the new flow control mode to SIRQ.
5736 */
5737 for (PhysPortIndex = 0;
5738 PhysPortIndex < PhysPortMax;
5739 PhysPortIndex ++) {
5740
5741 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5742
5743 continue;
5744 }
5745
5746 EventParam.Para32[0] = PhysPortIndex;
5747 EventParam.Para32[1] = (SK_U32)Val8;
5748 if (SkGeSirqEvent(pAC, IoC,
5749 SK_HWEV_SET_SPEED,
5750 EventParam) > 0) {
5751
5752 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5753 SK_PNMI_ERR045,
5754 SK_PNMI_ERR045MSG);
5755
5756 *pLen = 0;
5757 return (SK_PNMI_ERR_GENERAL);
5758 }
5759 }
5760 }
5761 else {
5762 /*
5763 * Send an event with the new flow control
5764 * mode to the SIRQ module.
5765 */
5766 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5767 pAC, LogPortIndex);
5768 EventParam.Para32[1] = (SK_U32)Val8;
5769 if (SkGeSirqEvent(pAC, IoC,
5770 SK_HWEV_SET_SPEED,
5771 EventParam) > 0) {
5772
5773 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5774 SK_PNMI_ERR045,
5775 SK_PNMI_ERR045MSG);
5776
5777 *pLen = 0;
5778 return (SK_PNMI_ERR_GENERAL);
5779 }
5780 }
5781 Offset += sizeof(char);
5782 break;
5783
5784 case OID_SKGE_MTU :
5785 /* Check the value range */
5786 Val32 = *(SK_U32*)(pBuf + Offset);
5787 if (Val32 == 0) {
5788 /* mtu of this port remains unchanged */
5789 Offset += sizeof(SK_U32);
5790 break;
5791 }
5792 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5793 *pLen = 0;
5794 return (SK_PNMI_ERR_BAD_VALUE);
5795 }
5796
5797 /* The preset ends here */
5798 if (Action == SK_PNMI_PRESET) {
5799 return (SK_PNMI_ERR_OK);
5800 }
5801
5802 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5803 return (SK_PNMI_ERR_GENERAL);
5804 }
5805
5806 Offset += sizeof(SK_U32);
5807 break;
5808
5809 default:
5810 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5811 ("MacPrivateConf: Unknown OID should be handled before set"));
5812
5813 *pLen = 0;
5814 return (SK_PNMI_ERR_GENERAL);
5815 }
5816 }
5817
5818 return (SK_PNMI_ERR_OK);
5819}
5820
5821/*****************************************************************************
5822 *
5823 * Monitor - OID handler function for RLMT_MONITOR_XXX
5824 *
5825 * Description:
5826 * Because RLMT currently does not support the monitoring of
5827 * remote adapter cards, we return always an empty table.
5828 *
5829 * Returns:
5830 * SK_PNMI_ERR_OK The request was successfully performed.
5831 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5832 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5833 * the correct data (e.g. a 32bit value is
5834 * needed, but a 16 bit value was passed).
5835 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5836 * value range.
5837 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5838 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5839 * exist (e.g. port instance 3 on a two port
5840 * adapter.
5841 */
5842PNMI_STATIC int Monitor(
5843SK_AC *pAC, /* Pointer to adapter context */
5844SK_IOC IoC, /* IO context handle */
5845int Action, /* GET/PRESET/SET action */
5846SK_U32 Id, /* Object ID that is to be processed */
5847char *pBuf, /* Buffer used for the management data transfer */
5848unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5849SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5850unsigned int TableIndex, /* Index to the Id table */
5851SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5852{
5853 unsigned int Index;
5854 unsigned int Limit;
5855 unsigned int Offset;
5856 unsigned int Entries;
5857
5858
5859 /*
5860 * Calculate instance if wished.
5861 */
5862 /* XXX Not yet implemented. Return always an empty table. */
5863 Entries = 0;
5864
5865 if ((Instance != (SK_U32)(-1))) {
5866
5867 if ((Instance < 1) || (Instance > Entries)) {
5868
5869 *pLen = 0;
5870 return (SK_PNMI_ERR_UNKNOWN_INST);
5871 }
5872
5873 Index = (unsigned int)Instance - 1;
5874 Limit = (unsigned int)Instance;
5875 }
5876 else {
5877 Index = 0;
5878 Limit = Entries;
5879 }
5880
5881 /*
5882 * Get/Set value
5883 */
5884 if (Action == SK_PNMI_GET) {
5885
5886 for (Offset=0; Index < Limit; Index ++) {
5887
5888 switch (Id) {
5889
5890 case OID_SKGE_RLMT_MONITOR_INDEX:
5891 case OID_SKGE_RLMT_MONITOR_ADDR:
5892 case OID_SKGE_RLMT_MONITOR_ERRS:
5893 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
5894 case OID_SKGE_RLMT_MONITOR_ADMIN:
5895 break;
5896
5897 default:
5898 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
5899 SK_PNMI_ERR046MSG);
5900
5901 *pLen = 0;
5902 return (SK_PNMI_ERR_GENERAL);
5903 }
5904 }
5905 *pLen = Offset;
5906 }
5907 else {
5908 /* Only MONITOR_ADMIN can be set */
5909 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
5910
5911 *pLen = 0;
5912 return (SK_PNMI_ERR_READ_ONLY);
5913 }
5914
5915 /* Check if the length is plausible */
5916 if (*pLen < (Limit - Index)) {
5917
5918 return (SK_PNMI_ERR_TOO_SHORT);
5919 }
5920 /* Okay, we have a wide value range */
5921 if (*pLen != (Limit - Index)) {
5922
5923 *pLen = 0;
5924 return (SK_PNMI_ERR_BAD_VALUE);
5925 }
5926/*
5927 for (Offset=0; Index < Limit; Index ++) {
5928 }
5929*/
5930/*
5931 * XXX Not yet implemented. Return always BAD_VALUE, because the table
5932 * is empty.
5933 */
5934 *pLen = 0;
5935 return (SK_PNMI_ERR_BAD_VALUE);
5936 }
5937
5938 return (SK_PNMI_ERR_OK);
5939}
5940
5941/*****************************************************************************
5942 *
5943 * VirtualConf - Calculates the values of configuration OIDs for virtual port
5944 *
5945 * Description:
5946 * We handle here the get of the configuration group OIDs, which are
5947 * a little bit complicated. The virtual port consists of all currently
5948 * active physical ports. If multiple ports are active and configured
5949 * differently we get in some trouble to return a single value. So we
5950 * get the value of the first active port and compare it with that of
5951 * the other active ports. If they are not the same, we return a value
5952 * that indicates that the state is indeterminated.
5953 *
5954 * Returns:
5955 * Nothing
5956 */
5957PNMI_STATIC void VirtualConf(
5958SK_AC *pAC, /* Pointer to adapter context */
5959SK_IOC IoC, /* IO context handle */
5960SK_U32 Id, /* Object ID that is to be processed */
5961char *pBuf) /* Buffer used for the management data transfer */
5962{
5963 unsigned int PhysPortMax;
5964 unsigned int PhysPortIndex;
5965 SK_U8 Val8;
5966 SK_U32 Val32;
5967 SK_BOOL PortActiveFlag;
5968 SK_GEPORT *pPrt;
5969
5970 *pBuf = 0;
5971 PortActiveFlag = SK_FALSE;
5972 PhysPortMax = pAC->GIni.GIMacsFound;
5973
5974 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
5975 PhysPortIndex ++) {
5976
5977 pPrt = &pAC->GIni.GP[PhysPortIndex];
5978
5979 /* Check if the physical port is active */
5980 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5981
5982 continue;
5983 }
5984
5985 PortActiveFlag = SK_TRUE;
5986
5987 switch (Id) {
5988
5989 case OID_SKGE_PHY_TYPE:
5990 /* Check if it is the first active port */
5991 if (*pBuf == 0) {
5992 Val32 = pPrt->PhyType;
5993 SK_PNMI_STORE_U32(pBuf, Val32);
5994 continue;
5995 }
5996
5997 case OID_SKGE_LINK_CAP:
5998
5999 /*
6000 * Different capabilities should not happen, but
6001 * in the case of the cases OR them all together.
6002 * From a curious point of view the virtual port
6003 * is capable of all found capabilities.
6004 */
6005 *pBuf |= pPrt->PLinkCap;
6006 break;
6007
6008 case OID_SKGE_LINK_MODE:
6009 /* Check if it is the first active port */
6010 if (*pBuf == 0) {
6011
6012 *pBuf = pPrt->PLinkModeConf;
6013 continue;
6014 }
6015
6016 /*
6017 * If we find an active port with a different link
6018 * mode than the first one we return a value that
6019 * indicates that the link mode is indeterminated.
6020 */
6021 if (*pBuf != pPrt->PLinkModeConf) {
6022
6023 *pBuf = SK_LMODE_INDETERMINATED;
6024 }
6025 break;
6026
6027 case OID_SKGE_LINK_MODE_STATUS:
6028 /* Get the link mode of the physical port */
6029 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6030
6031 /* Check if it is the first active port */
6032 if (*pBuf == 0) {
6033
6034 *pBuf = Val8;
6035 continue;
6036 }
6037
6038 /*
6039 * If we find an active port with a different link
6040 * mode status than the first one we return a value
6041 * that indicates that the link mode status is
6042 * indeterminated.
6043 */
6044 if (*pBuf != Val8) {
6045
6046 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6047 }
6048 break;
6049
6050 case OID_SKGE_LINK_STATUS:
6051 /* Get the link status of the physical port */
6052 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6053
6054 /* Check if it is the first active port */
6055 if (*pBuf == 0) {
6056
6057 *pBuf = Val8;
6058 continue;
6059 }
6060
6061 /*
6062 * If we find an active port with a different link
6063 * status than the first one, we return a value
6064 * that indicates that the link status is
6065 * indeterminated.
6066 */
6067 if (*pBuf != Val8) {
6068
6069 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6070 }
6071 break;
6072
6073 case OID_SKGE_FLOWCTRL_CAP:
6074 /* Check if it is the first active port */
6075 if (*pBuf == 0) {
6076
6077 *pBuf = pPrt->PFlowCtrlCap;
6078 continue;
6079 }
6080
6081 /*
6082 * From a curious point of view the virtual port
6083 * is capable of all found capabilities.
6084 */
6085 *pBuf |= pPrt->PFlowCtrlCap;
6086 break;
6087
6088 case OID_SKGE_FLOWCTRL_MODE:
6089 /* Check if it is the first active port */
6090 if (*pBuf == 0) {
6091
6092 *pBuf = pPrt->PFlowCtrlMode;
6093 continue;
6094 }
6095
6096 /*
6097 * If we find an active port with a different flow
6098 * control mode than the first one, we return a value
6099 * that indicates that the mode is indeterminated.
6100 */
6101 if (*pBuf != pPrt->PFlowCtrlMode) {
6102
6103 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6104 }
6105 break;
6106
6107 case OID_SKGE_FLOWCTRL_STATUS:
6108 /* Check if it is the first active port */
6109 if (*pBuf == 0) {
6110
6111 *pBuf = pPrt->PFlowCtrlStatus;
6112 continue;
6113 }
6114
6115 /*
6116 * If we find an active port with a different flow
6117 * control status than the first one, we return a
6118 * value that indicates that the status is
6119 * indeterminated.
6120 */
6121 if (*pBuf != pPrt->PFlowCtrlStatus) {
6122
6123 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6124 }
6125 break;
6126
6127 case OID_SKGE_PHY_OPERATION_CAP:
6128 /* Check if it is the first active port */
6129 if (*pBuf == 0) {
6130
6131 *pBuf = pPrt->PMSCap;
6132 continue;
6133 }
6134
6135 /*
6136 * From a curious point of view the virtual port
6137 * is capable of all found capabilities.
6138 */
6139 *pBuf |= pPrt->PMSCap;
6140 break;
6141
6142 case OID_SKGE_PHY_OPERATION_MODE:
6143 /* Check if it is the first active port */
6144 if (*pBuf == 0) {
6145
6146 *pBuf = pPrt->PMSMode;
6147 continue;
6148 }
6149
6150 /*
6151 * If we find an active port with a different master/
6152 * slave mode than the first one, we return a value
6153 * that indicates that the mode is indeterminated.
6154 */
6155 if (*pBuf != pPrt->PMSMode) {
6156
6157 *pBuf = SK_MS_MODE_INDETERMINATED;
6158 }
6159 break;
6160
6161 case OID_SKGE_PHY_OPERATION_STATUS:
6162 /* Check if it is the first active port */
6163 if (*pBuf == 0) {
6164
6165 *pBuf = pPrt->PMSStatus;
6166 continue;
6167 }
6168
6169 /*
6170 * If we find an active port with a different master/
6171 * slave status than the first one, we return a
6172 * value that indicates that the status is
6173 * indeterminated.
6174 */
6175 if (*pBuf != pPrt->PMSStatus) {
6176
6177 *pBuf = SK_MS_STAT_INDETERMINATED;
6178 }
6179 break;
6180
6181 case OID_SKGE_SPEED_MODE:
6182 /* Check if it is the first active port */
6183 if (*pBuf == 0) {
6184
6185 *pBuf = pPrt->PLinkSpeed;
6186 continue;
6187 }
6188
6189 /*
6190 * If we find an active port with a different flow
6191 * control mode than the first one, we return a value
6192 * that indicates that the mode is indeterminated.
6193 */
6194 if (*pBuf != pPrt->PLinkSpeed) {
6195
6196 *pBuf = SK_LSPEED_INDETERMINATED;
6197 }
6198 break;
6199
6200 case OID_SKGE_SPEED_STATUS:
6201 /* Check if it is the first active port */
6202 if (*pBuf == 0) {
6203
6204 *pBuf = pPrt->PLinkSpeedUsed;
6205 continue;
6206 }
6207
6208 /*
6209 * If we find an active port with a different flow
6210 * control status than the first one, we return a
6211 * value that indicates that the status is
6212 * indeterminated.
6213 */
6214 if (*pBuf != pPrt->PLinkSpeedUsed) {
6215
6216 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6217 }
6218 break;
6219 }
6220 }
6221
6222 /*
6223 * If no port is active return an indeterminated answer
6224 */
6225 if (!PortActiveFlag) {
6226
6227 switch (Id) {
6228
6229 case OID_SKGE_LINK_CAP:
6230 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6231 break;
6232
6233 case OID_SKGE_LINK_MODE:
6234 *pBuf = SK_LMODE_INDETERMINATED;
6235 break;
6236
6237 case OID_SKGE_LINK_MODE_STATUS:
6238 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6239 break;
6240
6241 case OID_SKGE_LINK_STATUS:
6242 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6243 break;
6244
6245 case OID_SKGE_FLOWCTRL_CAP:
6246 case OID_SKGE_FLOWCTRL_MODE:
6247 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6248 break;
6249
6250 case OID_SKGE_FLOWCTRL_STATUS:
6251 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6252 break;
6253
6254 case OID_SKGE_PHY_OPERATION_CAP:
6255 *pBuf = SK_MS_CAP_INDETERMINATED;
6256 break;
6257
6258 case OID_SKGE_PHY_OPERATION_MODE:
6259 *pBuf = SK_MS_MODE_INDETERMINATED;
6260 break;
6261
6262 case OID_SKGE_PHY_OPERATION_STATUS:
6263 *pBuf = SK_MS_STAT_INDETERMINATED;
6264 break;
6265 case OID_SKGE_SPEED_CAP:
6266 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6267 break;
6268
6269 case OID_SKGE_SPEED_MODE:
6270 *pBuf = SK_LSPEED_INDETERMINATED;
6271 break;
6272
6273 case OID_SKGE_SPEED_STATUS:
6274 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6275 break;
6276 }
6277 }
6278}
6279
6280/*****************************************************************************
6281 *
6282 * CalculateLinkStatus - Determins the link status of a physical port
6283 *
6284 * Description:
6285 * Determins the link status the following way:
6286 * LSTAT_PHY_DOWN: Link is down
6287 * LSTAT_AUTONEG: Auto-negotiation failed
6288 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6289 * logically up.
6290 * LSTAT_LOG_UP: RLMT marked the port as up
6291 *
6292 * Returns:
6293 * Link status of physical port
6294 */
6295PNMI_STATIC SK_U8 CalculateLinkStatus(
6296SK_AC *pAC, /* Pointer to adapter context */
6297SK_IOC IoC, /* IO context handle */
6298unsigned int PhysPortIndex) /* Physical port index */
6299{
6300 SK_U8 Result;
6301
6302 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6303
6304 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6305 }
6306 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6307
6308 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6309 }
6310 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6311
6312 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6313 }
6314 else {
6315 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6316 }
6317
6318 return (Result);
6319}
6320
6321/*****************************************************************************
6322 *
6323 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6324 *
6325 * Description:
6326 * The COMMON module only tells us if the mode is half or full duplex.
6327 * But in the decade of auto sensing it is useful for the user to
6328 * know if the mode was negotiated or forced. Therefore we have a
6329 * look to the mode, which was last used by the negotiation process.
6330 *
6331 * Returns:
6332 * The link mode status
6333 */
6334PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6335SK_AC *pAC, /* Pointer to adapter context */
6336SK_IOC IoC, /* IO context handle */
6337unsigned int PhysPortIndex) /* Physical port index */
6338{
6339 SK_U8 Result;
6340
6341 /* Get the current mode, which can be full or half duplex */
6342 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6343
6344 /* Check if no valid mode could be found (link is down) */
6345 if (Result < SK_LMODE_STAT_HALF) {
6346
6347 Result = SK_LMODE_STAT_UNKNOWN;
6348 }
6349 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6350
6351 /*
6352 * Auto-negotiation was used to bring up the link. Change
6353 * the already found duplex status that it indicates
6354 * auto-negotiation was involved.
6355 */
6356 if (Result == SK_LMODE_STAT_HALF) {
6357
6358 Result = SK_LMODE_STAT_AUTOHALF;
6359 }
6360 else if (Result == SK_LMODE_STAT_FULL) {
6361
6362 Result = SK_LMODE_STAT_AUTOFULL;
6363 }
6364 }
6365
6366 return (Result);
6367}
6368
6369/*****************************************************************************
6370 *
6371 * GetVpdKeyArr - Obtain an array of VPD keys
6372 *
6373 * Description:
6374 * Read the VPD keys and build an array of VPD keys, which are
6375 * easy to access.
6376 *
6377 * Returns:
6378 * SK_PNMI_ERR_OK Task successfully performed.
6379 * SK_PNMI_ERR_GENERAL Something went wrong.
6380 */
6381PNMI_STATIC int GetVpdKeyArr(
6382SK_AC *pAC, /* Pointer to adapter context */
6383SK_IOC IoC, /* IO context handle */
6384char *pKeyArr, /* Ptr KeyArray */
6385unsigned int KeyArrLen, /* Length of array in bytes */
6386unsigned int *pKeyNo) /* Number of keys */
6387{
6388 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6389 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6390 unsigned int StartOffset;
6391 unsigned int Offset;
6392 int Index;
6393 int Ret;
6394
6395
6396 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6397
6398 /*
6399 * Get VPD key list
6400 */
6401 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6402 (int *)pKeyNo);
6403 if (Ret > 0) {
6404
6405 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6406 SK_PNMI_ERR014MSG);
6407
6408 return (SK_PNMI_ERR_GENERAL);
6409 }
6410 /* If no keys are available return now */
6411 if (*pKeyNo == 0 || BufKeysLen == 0) {
6412
6413 return (SK_PNMI_ERR_OK);
6414 }
6415 /*
6416 * If the key list is too long for us trunc it and give a
6417 * errorlog notification. This case should not happen because
6418 * the maximum number of keys is limited due to RAM limitations
6419 */
6420 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6421
6422 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6423 SK_PNMI_ERR015MSG);
6424
6425 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6426 }
6427
6428 /*
6429 * Now build an array of fixed string length size and copy
6430 * the keys together.
6431 */
6432 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6433 Offset ++) {
6434
6435 if (BufKeys[Offset] != 0) {
6436
6437 continue;
6438 }
6439
6440 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6441
6442 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6443 SK_PNMI_ERR016MSG);
6444 return (SK_PNMI_ERR_GENERAL);
6445 }
6446
6447 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6448 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6449
6450 Index ++;
6451 StartOffset = Offset + 1;
6452 }
6453
6454 /* Last key not zero terminated? Get it anyway */
6455 if (StartOffset < Offset) {
6456
6457 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6458 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6459 }
6460
6461 return (SK_PNMI_ERR_OK);
6462}
6463
6464/*****************************************************************************
6465 *
6466 * SirqUpdate - Let the SIRQ update its internal values
6467 *
6468 * Description:
6469 * Just to be sure that the SIRQ module holds its internal data
6470 * structures up to date, we send an update event before we make
6471 * any access.
6472 *
6473 * Returns:
6474 * SK_PNMI_ERR_OK Task successfully performed.
6475 * SK_PNMI_ERR_GENERAL Something went wrong.
6476 */
6477PNMI_STATIC int SirqUpdate(
6478SK_AC *pAC, /* Pointer to adapter context */
6479SK_IOC IoC) /* IO context handle */
6480{
6481 SK_EVPARA EventParam;
6482
6483
6484 /* Was the module already updated during the current PNMI call? */
6485 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6486
6487 return (SK_PNMI_ERR_OK);
6488 }
6489
6490 /* Send an synchronuous update event to the module */
6491 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6492 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6493
6494 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6495 SK_PNMI_ERR047MSG);
6496
6497 return (SK_PNMI_ERR_GENERAL);
6498 }
6499
6500 return (SK_PNMI_ERR_OK);
6501}
6502
6503/*****************************************************************************
6504 *
6505 * RlmtUpdate - Let the RLMT update its internal values
6506 *
6507 * Description:
6508 * Just to be sure that the RLMT module holds its internal data
6509 * structures up to date, we send an update event before we make
6510 * any access.
6511 *
6512 * Returns:
6513 * SK_PNMI_ERR_OK Task successfully performed.
6514 * SK_PNMI_ERR_GENERAL Something went wrong.
6515 */
6516PNMI_STATIC int RlmtUpdate(
6517SK_AC *pAC, /* Pointer to adapter context */
6518SK_IOC IoC, /* IO context handle */
6519SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6520{
6521 SK_EVPARA EventParam;
6522
6523
6524 /* Was the module already updated during the current PNMI call? */
6525 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6526
6527 return (SK_PNMI_ERR_OK);
6528 }
6529
6530 /* Send an synchronuous update event to the module */
6531 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6532 EventParam.Para32[0] = NetIndex;
6533 EventParam.Para32[1] = (SK_U32)-1;
6534 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6535
6536 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6537 SK_PNMI_ERR048MSG);
6538
6539 return (SK_PNMI_ERR_GENERAL);
6540 }
6541
6542 return (SK_PNMI_ERR_OK);
6543}
6544
6545/*****************************************************************************
6546 *
6547 * MacUpdate - Force the XMAC to output the current statistic
6548 *
6549 * Description:
6550 * The XMAC holds its statistic internally. To obtain the current
6551 * values we must send a command so that the statistic data will
6552 * be written to a predefined memory area on the adapter.
6553 *
6554 * Returns:
6555 * SK_PNMI_ERR_OK Task successfully performed.
6556 * SK_PNMI_ERR_GENERAL Something went wrong.
6557 */
6558PNMI_STATIC int MacUpdate(
6559SK_AC *pAC, /* Pointer to adapter context */
6560SK_IOC IoC, /* IO context handle */
6561unsigned int FirstMac, /* Index of the first Mac to be updated */
6562unsigned int LastMac) /* Index of the last Mac to be updated */
6563{
6564 unsigned int MacIndex;
6565
6566 /*
6567 * Were the statistics already updated during the
6568 * current PNMI call?
6569 */
6570 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6571
6572 return (SK_PNMI_ERR_OK);
6573 }
6574
6575 /* Send an update command to all MACs specified */
6576 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6577
6578 /*
6579 * 2002-09-13 pweber: Freeze the current SW counters.
6580 * (That should be done as close as
6581 * possible to the update of the
6582 * HW counters)
6583 */
6584 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6585 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6586 }
6587
6588 /* 2002-09-13 pweber: Update the HW counter */
6589 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6590
6591 return (SK_PNMI_ERR_GENERAL);
6592 }
6593 }
6594
6595 return (SK_PNMI_ERR_OK);
6596}
6597
6598/*****************************************************************************
6599 *
6600 * GetStatVal - Retrieve an XMAC statistic counter
6601 *
6602 * Description:
6603 * Retrieves the statistic counter of a virtual or physical port. The
6604 * virtual port is identified by the index 0. It consists of all
6605 * currently active ports. To obtain the counter value for this port
6606 * we must add the statistic counter of all active ports. To grant
6607 * continuous counter values for the virtual port even when port
6608 * switches occur we must additionally add a delta value, which was
6609 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6610 *
6611 * Returns:
6612 * Requested statistic value
6613 */
6614PNMI_STATIC SK_U64 GetStatVal(
6615SK_AC *pAC, /* Pointer to adapter context */
6616SK_IOC IoC, /* IO context handle */
6617unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6618unsigned int StatIndex, /* Index to statistic value */
6619SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6620{
6621 unsigned int PhysPortIndex;
6622 unsigned int PhysPortMax;
6623 SK_U64 Val = 0;
6624
6625
6626 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6627
6628 PhysPortIndex = NetIndex;
6629
6630 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6631 }
6632 else { /* Single Net mode */
6633
6634 if (LogPortIndex == 0) {
6635
6636 PhysPortMax = pAC->GIni.GIMacsFound;
6637
6638 /* Add counter of all active ports */
6639 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6640 PhysPortIndex ++) {
6641
6642 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6643
6644 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6645 }
6646 }
6647
6648 /* Correct value because of port switches */
6649 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6650 }
6651 else {
6652 /* Get counter value of physical port */
6653 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6654
6655 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6656 }
6657 }
6658 return (Val);
6659}
6660
6661/*****************************************************************************
6662 *
6663 * GetPhysStatVal - Get counter value for physical port
6664 *
6665 * Description:
6666 * Builds a 64bit counter value. Except for the octet counters
6667 * the lower 32bit are counted in hardware and the upper 32bit
6668 * in software by monitoring counter overflow interrupts in the
6669 * event handler. To grant continous counter values during XMAC
6670 * resets (caused by a workaround) we must add a delta value.
6671 * The delta was calculated in the event handler when a
6672 * SK_PNMI_EVT_XMAC_RESET was received.
6673 *
6674 * Returns:
6675 * Counter value
6676 */
6677PNMI_STATIC SK_U64 GetPhysStatVal(
6678SK_AC *pAC, /* Pointer to adapter context */
6679SK_IOC IoC, /* IO context handle */
6680unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6681unsigned int StatIndex) /* Index to statistic value */
6682{
6683 SK_U64 Val = 0;
6684 SK_U32 LowVal = 0;
6685 SK_U32 HighVal = 0;
6686 SK_U16 Word;
6687 int MacType;
6688 unsigned int HelpIndex;
6689 SK_GEPORT *pPrt;
6690
6691 SK_PNMI_PORT *pPnmiPrt;
6692 SK_GEMACFUNC *pFnMac;
6693
6694 pPrt = &pAC->GIni.GP[PhysPortIndex];
6695
6696 MacType = pAC->GIni.GIMacType;
6697
6698 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6699 if (MacType == SK_MAC_XMAC) {
6700 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6701 }
6702 else {
6703 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6704 }
6705
6706 pFnMac = &pAC->GIni.GIFunc;
6707
6708 switch (StatIndex) {
6709 case SK_PNMI_HTX:
6710 if (MacType == SK_MAC_GMAC) {
6711 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6712 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6713 &LowVal);
6714 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6715 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6716 &HighVal);
6717 LowVal += HighVal;
6718 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6719 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6720 &HighVal);
6721 LowVal += HighVal;
6722 }
6723 else {
6724 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6725 StatAddr[StatIndex][MacType].Reg,
6726 &LowVal);
6727 }
6728 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6729 break;
6730
6731 case SK_PNMI_HRX:
6732 if (MacType == SK_MAC_GMAC) {
6733 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6734 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6735 &LowVal);
6736 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6737 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6738 &HighVal);
6739 LowVal += HighVal;
6740 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6741 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6742 &HighVal);
6743 LowVal += HighVal;
6744 }
6745 else {
6746 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6747 StatAddr[StatIndex][MacType].Reg,
6748 &LowVal);
6749 }
6750 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6751 break;
6752
6753 case SK_PNMI_HTX_OCTET:
6754 case SK_PNMI_HRX_OCTET:
6755 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6756 StatAddr[StatIndex][MacType].Reg,
6757 &HighVal);
6758 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6759 StatAddr[StatIndex + 1][MacType].Reg,
6760 &LowVal);
6761 break;
6762
6763 case SK_PNMI_HTX_BURST:
6764 case SK_PNMI_HTX_EXCESS_DEF:
6765 case SK_PNMI_HTX_CARRIER:
6766 /* Not supported by GMAC */
6767 if (MacType == SK_MAC_GMAC) {
6768 return (Val);
6769 }
6770
6771 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6772 StatAddr[StatIndex][MacType].Reg,
6773 &LowVal);
6774 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6775 break;
6776
6777 case SK_PNMI_HTX_MACC:
6778 /* GMAC only supports PAUSE MAC control frames */
6779 if (MacType == SK_MAC_GMAC) {
6780 HelpIndex = SK_PNMI_HTX_PMACC;
6781 }
6782 else {
6783 HelpIndex = StatIndex;
6784 }
6785
6786 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6787 StatAddr[HelpIndex][MacType].Reg,
6788 &LowVal);
6789
6790 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6791 break;
6792
6793 case SK_PNMI_HTX_COL:
6794 case SK_PNMI_HRX_UNDERSIZE:
6795 /* Not supported by XMAC */
6796 if (MacType == SK_MAC_XMAC) {
6797 return (Val);
6798 }
6799
6800 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6801 StatAddr[StatIndex][MacType].Reg,
6802 &LowVal);
6803 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6804 break;
6805
6806 case SK_PNMI_HTX_DEFFERAL:
6807 /* Not supported by GMAC */
6808 if (MacType == SK_MAC_GMAC) {
6809 return (Val);
6810 }
6811
6812 /*
6813 * XMAC counts frames with deferred transmission
6814 * even in full-duplex mode.
6815 *
6816 * In full-duplex mode the counter remains constant!
6817 */
6818 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6819 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6820
6821 LowVal = 0;
6822 HighVal = 0;
6823 }
6824 else {
6825 /* Otherwise get contents of hardware register */
6826 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6827 StatAddr[StatIndex][MacType].Reg,
6828 &LowVal);
6829 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6830 }
6831 break;
6832
6833 case SK_PNMI_HRX_BADOCTET:
6834 /* Not supported by XMAC */
6835 if (MacType == SK_MAC_XMAC) {
6836 return (Val);
6837 }
6838
6839 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6840 StatAddr[StatIndex][MacType].Reg,
6841 &HighVal);
6842 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6843 StatAddr[StatIndex + 1][MacType].Reg,
6844 &LowVal);
6845 break;
6846
6847 case SK_PNMI_HTX_OCTETLOW:
6848 case SK_PNMI_HRX_OCTETLOW:
6849 case SK_PNMI_HRX_BADOCTETLOW:
6850 return (Val);
6851
6852 case SK_PNMI_HRX_LONGFRAMES:
6853 /* For XMAC the SW counter is managed by PNMI */
6854 if (MacType == SK_MAC_XMAC) {
6855 return (pPnmiPrt->StatRxLongFrameCts);
6856 }
6857
6858 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6859 StatAddr[StatIndex][MacType].Reg,
6860 &LowVal);
6861 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6862 break;
6863
6864 case SK_PNMI_HRX_TOO_LONG:
6865 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6866 StatAddr[StatIndex][MacType].Reg,
6867 &LowVal);
6868 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6869
6870 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6871
6872 if (MacType == SK_MAC_GMAC) {
6873 /* For GMAC the SW counter is additionally managed by PNMI */
6874 Val += pPnmiPrt->StatRxFrameTooLongCts;
6875 }
6876 else {
6877 /*
6878 * Frames longer than IEEE 802.3 frame max size are counted
6879 * by XMAC in frame_too_long counter even reception of long
6880 * frames was enabled and the frame was correct.
6881 * So correct the value by subtracting RxLongFrame counter.
6882 */
6883 Val -= pPnmiPrt->StatRxLongFrameCts;
6884 }
6885
6886 LowVal = (SK_U32)Val;
6887 HighVal = (SK_U32)(Val >> 32);
6888 break;
6889
6890 case SK_PNMI_HRX_SHORTS:
6891 /* Not supported by GMAC */
6892 if (MacType == SK_MAC_GMAC) {
6893 /* GM_RXE_FRAG?? */
6894 return (Val);
6895 }
6896
6897 /*
6898 * XMAC counts short frame errors even if link down (#10620)
6899 *
6900 * If link-down the counter remains constant
6901 */
6902 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
6903
6904 /* Otherwise get incremental difference */
6905 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6906 StatAddr[StatIndex][MacType].Reg,
6907 &LowVal);
6908 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6909
6910 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6911 Val -= pPnmiPrt->RxShortZeroMark;
6912
6913 LowVal = (SK_U32)Val;
6914 HighVal = (SK_U32)(Val >> 32);
6915 }
6916 break;
6917
6918 case SK_PNMI_HRX_MACC:
6919 case SK_PNMI_HRX_MACC_UNKWN:
6920 case SK_PNMI_HRX_BURST:
6921 case SK_PNMI_HRX_MISSED:
6922 case SK_PNMI_HRX_FRAMING:
6923 case SK_PNMI_HRX_CARRIER:
6924 case SK_PNMI_HRX_IRLENGTH:
6925 case SK_PNMI_HRX_SYMBOL:
6926 case SK_PNMI_HRX_CEXT:
6927 /* Not supported by GMAC */
6928 if (MacType == SK_MAC_GMAC) {
6929 return (Val);
6930 }
6931
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[StatIndex][MacType].Reg,
6934 &LowVal);
6935 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6936 break;
6937
6938 case SK_PNMI_HRX_PMACC_ERR:
6939 /* For GMAC the SW counter is managed by PNMI */
6940 if (MacType == SK_MAC_GMAC) {
6941 return (pPnmiPrt->StatRxPMaccErr);
6942 }
6943
6944 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6945 StatAddr[StatIndex][MacType].Reg,
6946 &LowVal);
6947 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6948 break;
6949
6950 /* SW counter managed by PNMI */
6951 case SK_PNMI_HTX_SYNC:
6952 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
6953 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
6954 break;
6955
6956 /* SW counter managed by PNMI */
6957 case SK_PNMI_HTX_SYNC_OCTET:
6958 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
6959 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
6960 break;
6961
6962 case SK_PNMI_HRX_FCS:
6963 /*
6964 * Broadcom filters FCS errors and counts it in
6965 * Receive Error Counter register
6966 */
6967 if (pPrt->PhyType == SK_PHY_BCOM) {
6968 /* do not read while not initialized (PHY_READ hangs!)*/
6969 if (pPrt->PState != SK_PRT_RESET) {
6970 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
6971
6972 LowVal = Word;
6973 }
6974 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6975 }
6976 else {
6977 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6978 StatAddr[StatIndex][MacType].Reg,
6979 &LowVal);
6980 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6981 }
6982 break;
6983
6984 default:
6985 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6986 StatAddr[StatIndex][MacType].Reg,
6987 &LowVal);
6988 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6989 break;
6990 }
6991
6992 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6993
6994 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
6995 Val += pPnmiPrt->CounterOffset[StatIndex];
6996
6997 return (Val);
6998}
6999
7000/*****************************************************************************
7001 *
7002 * ResetCounter - Set all counters and timestamps to zero
7003 *
7004 * Description:
7005 * Notifies other common modules which store statistic data to
7006 * reset their counters and finally reset our own counters.
7007 *
7008 * Returns:
7009 * Nothing
7010 */
7011PNMI_STATIC void ResetCounter(
7012SK_AC *pAC, /* Pointer to adapter context */
7013SK_IOC IoC, /* IO context handle */
7014SK_U32 NetIndex)
7015{
7016 unsigned int PhysPortIndex;
7017 SK_EVPARA EventParam;
7018
7019
7020 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7021
7022 /* Notify sensor module */
7023 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7024
7025 /* Notify RLMT module */
7026 EventParam.Para32[0] = NetIndex;
7027 EventParam.Para32[1] = (SK_U32)-1;
7028 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7029 EventParam.Para32[1] = 0;
7030
7031 /* Notify SIRQ module */
7032 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7033
7034 /* Notify CSUM module */
7035#ifdef SK_USE_CSUM
7036 EventParam.Para32[0] = NetIndex;
7037 EventParam.Para32[1] = (SK_U32)-1;
7038 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7039 EventParam);
7040#endif /* SK_USE_CSUM */
7041
7042 /* Clear XMAC statistic */
7043 for (PhysPortIndex = 0; PhysPortIndex <
7044 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7045
7046 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7047
7048 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7049 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7050 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7051 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7052 PhysPortIndex].CounterOffset));
7053 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7054 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7055 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7056 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7057 PhysPortIndex].StatSyncOctetsCts));
7058 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7059 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7060 PhysPortIndex].StatRxLongFrameCts));
7061 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7062 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7063 PhysPortIndex].StatRxFrameTooLongCts));
7064 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7065 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7066 PhysPortIndex].StatRxPMaccErr));
7067 }
7068
7069 /*
7070 * Clear local statistics
7071 */
7072 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7073 sizeof(pAC->Pnmi.VirtualCounterOffset));
7074 pAC->Pnmi.RlmtChangeCts = 0;
7075 pAC->Pnmi.RlmtChangeTime = 0;
7076 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7077 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7078 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7079 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7080 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7081 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7082 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7083 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7084 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7085 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7086 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7087 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7088 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7089 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7090}
7091
7092/*****************************************************************************
7093 *
7094 * GetTrapEntry - Get an entry in the trap buffer
7095 *
7096 * Description:
7097 * The trap buffer stores various events. A user application somehow
7098 * gets notified that an event occured and retrieves the trap buffer
7099 * contens (or simply polls the buffer). The buffer is organized as
7100 * a ring which stores the newest traps at the beginning. The oldest
7101 * traps are overwritten by the newest ones. Each trap entry has a
7102 * unique number, so that applications may detect new trap entries.
7103 *
7104 * Returns:
7105 * A pointer to the trap entry
7106 */
7107PNMI_STATIC char* GetTrapEntry(
7108SK_AC *pAC, /* Pointer to adapter context */
7109SK_U32 TrapId, /* SNMP ID of the trap */
7110unsigned int Size) /* Space needed for trap entry */
7111{
7112 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7113 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7114 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7115 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7116 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7117 int Wrap;
7118 unsigned int NeededSpace;
7119 unsigned int EntrySize;
7120 SK_U32 Val32;
7121 SK_U64 Val64;
7122
7123
7124 /* Last byte of entry will get a copy of the entry length */
7125 Size ++;
7126
7127 /*
7128 * Calculate needed buffer space */
7129 if (Beg >= Size) {
7130
7131 NeededSpace = Size;
7132 Wrap = SK_FALSE;
7133 }
7134 else {
7135 NeededSpace = Beg + Size;
7136 Wrap = SK_TRUE;
7137 }
7138
7139 /*
7140 * Check if enough buffer space is provided. Otherwise
7141 * free some entries. Leave one byte space between begin
7142 * and end of buffer to make it possible to detect whether
7143 * the buffer is full or empty
7144 */
7145 while (BufFree < NeededSpace + 1) {
7146
7147 if (End == 0) {
7148
7149 End = SK_PNMI_TRAP_QUEUE_LEN;
7150 }
7151
7152 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7153 BufFree += EntrySize;
7154 End -= EntrySize;
7155#ifdef DEBUG
7156 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7157#endif /* DEBUG */
7158 if (End == BufPad) {
7159#ifdef DEBUG
7160 SK_MEMSET(pBuf, (char)(-1), End);
7161#endif /* DEBUG */
7162 BufFree += End;
7163 End = 0;
7164 BufPad = 0;
7165 }
7166 }
7167
7168 /*
7169 * Insert new entry as first entry. Newest entries are
7170 * stored at the beginning of the queue.
7171 */
7172 if (Wrap) {
7173
7174 BufPad = Beg;
7175 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7176 }
7177 else {
7178 Beg = Beg - Size;
7179 }
7180 BufFree -= NeededSpace;
7181
7182 /* Save the current offsets */
7183 pAC->Pnmi.TrapQueueBeg = Beg;
7184 pAC->Pnmi.TrapQueueEnd = End;
7185 pAC->Pnmi.TrapBufPad = BufPad;
7186 pAC->Pnmi.TrapBufFree = BufFree;
7187
7188 /* Initialize the trap entry */
7189 *(pBuf + Beg + Size - 1) = (char)Size;
7190 *(pBuf + Beg) = (char)Size;
7191 Val32 = (pAC->Pnmi.TrapUnique) ++;
7192 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7193 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7194 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7195 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7196
7197 return (pBuf + Beg);
7198}
7199
7200/*****************************************************************************
7201 *
7202 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7203 *
7204 * Description:
7205 * On a query of the TRAP OID the trap buffer contents will be
7206 * copied continuously to the request buffer, which must be large
7207 * enough. No length check is performed.
7208 *
7209 * Returns:
7210 * Nothing
7211 */
7212PNMI_STATIC void CopyTrapQueue(
7213SK_AC *pAC, /* Pointer to adapter context */
7214char *pDstBuf) /* Buffer to which the queued traps will be copied */
7215{
7216 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7217 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7218 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7219 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7220 unsigned int Len;
7221 unsigned int DstOff = 0;
7222
7223
7224 while (Trap != End) {
7225
7226 Len = (unsigned int)*(pBuf + Trap);
7227
7228 /*
7229 * Last byte containing a copy of the length will
7230 * not be copied.
7231 */
7232 *(pDstBuf + DstOff) = (char)(Len - 1);
7233 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7234 DstOff += Len - 1;
7235
7236 Trap += Len;
7237 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7238
7239 Trap = BufPad;
7240 }
7241 }
7242}
7243
7244/*****************************************************************************
7245 *
7246 * GetTrapQueueLen - Get the length of the trap buffer
7247 *
7248 * Description:
7249 * Evaluates the number of currently stored traps and the needed
7250 * buffer size to retrieve them.
7251 *
7252 * Returns:
7253 * Nothing
7254 */
7255PNMI_STATIC void GetTrapQueueLen(
7256SK_AC *pAC, /* Pointer to adapter context */
7257unsigned int *pLen, /* Length in Bytes of all queued traps */
7258unsigned int *pEntries) /* Returns number of trapes stored in queue */
7259{
7260 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7261 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7262 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7263 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7264 unsigned int Len;
7265 unsigned int Entries = 0;
7266 unsigned int TotalLen = 0;
7267
7268
7269 while (Trap != End) {
7270
7271 Len = (unsigned int)*(pBuf + Trap);
7272 TotalLen += Len - 1;
7273 Entries ++;
7274
7275 Trap += Len;
7276 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7277
7278 Trap = BufPad;
7279 }
7280 }
7281
7282 *pEntries = Entries;
7283 *pLen = TotalLen;
7284}
7285
7286/*****************************************************************************
7287 *
7288 * QueueSimpleTrap - Store a simple trap to the trap buffer
7289 *
7290 * Description:
7291 * A simple trap is a trap with now additional data. It consists
7292 * simply of a trap code.
7293 *
7294 * Returns:
7295 * Nothing
7296 */
7297PNMI_STATIC void QueueSimpleTrap(
7298SK_AC *pAC, /* Pointer to adapter context */
7299SK_U32 TrapId) /* Type of sensor trap */
7300{
7301 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7302}
7303
7304/*****************************************************************************
7305 *
7306 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7307 *
7308 * Description:
7309 * Gets an entry in the trap buffer and fills it with sensor related
7310 * data.
7311 *
7312 * Returns:
7313 * Nothing
7314 */
7315PNMI_STATIC void QueueSensorTrap(
7316SK_AC *pAC, /* Pointer to adapter context */
7317SK_U32 TrapId, /* Type of sensor trap */
7318unsigned int SensorIndex) /* Index of sensor which caused the trap */
7319{
7320 char *pBuf;
7321 unsigned int Offset;
7322 unsigned int DescrLen;
7323 SK_U32 Val32;
7324
7325
7326 /* Get trap buffer entry */
7327 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7328 pBuf = GetTrapEntry(pAC, TrapId,
7329 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7330 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7331
7332 /* Store additionally sensor trap related data */
7333 Val32 = OID_SKGE_SENSOR_INDEX;
7334 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7335 *(pBuf + Offset + 4) = 4;
7336 Val32 = (SK_U32)SensorIndex;
7337 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7338 Offset += 9;
7339
7340 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7341 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7342 *(pBuf + Offset + 4) = (char)DescrLen;
7343 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7344 DescrLen);
7345 Offset += DescrLen + 5;
7346
7347 Val32 = OID_SKGE_SENSOR_TYPE;
7348 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7349 *(pBuf + Offset + 4) = 1;
7350 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7351 Offset += 6;
7352
7353 Val32 = OID_SKGE_SENSOR_VALUE;
7354 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7355 *(pBuf + Offset + 4) = 4;
7356 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7357 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7358}
7359
7360/*****************************************************************************
7361 *
7362 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7363 *
7364 * Description:
7365 * Nothing further to explain.
7366 *
7367 * Returns:
7368 * Nothing
7369 */
7370PNMI_STATIC void QueueRlmtNewMacTrap(
7371SK_AC *pAC, /* Pointer to adapter context */
7372unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7373{
7374 char *pBuf;
7375 SK_U32 Val32;
7376
7377
7378 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7379 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7380
7381 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7382 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7383 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7384 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7385}
7386
7387/*****************************************************************************
7388 *
7389 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7390 *
7391 * Description:
7392 * Nothing further to explain.
7393 *
7394 * Returns:
7395 * Nothing
7396 */
7397PNMI_STATIC void QueueRlmtPortTrap(
7398SK_AC *pAC, /* Pointer to adapter context */
7399SK_U32 TrapId, /* Type of RLMT port trap */
7400unsigned int PortIndex) /* Index of the port, which changed its state */
7401{
7402 char *pBuf;
7403 SK_U32 Val32;
7404
7405
7406 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7407
7408 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7409 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7410 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7411 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7412}
7413
7414/*****************************************************************************
7415 *
7416 * CopyMac - Copies a MAC address
7417 *
7418 * Description:
7419 * Nothing further to explain.
7420 *
7421 * Returns:
7422 * Nothing
7423 */
7424PNMI_STATIC void CopyMac(
7425char *pDst, /* Pointer to destination buffer */
7426SK_MAC_ADDR *pMac) /* Pointer of Source */
7427{
7428 int i;
7429
7430
7431 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7432
7433 *(pDst + i) = pMac->a[i];
7434 }
7435}
7436
7437#ifdef SK_POWER_MGMT
7438/*****************************************************************************
7439 *
7440 * PowerManagement - OID handler function of PowerManagement OIDs
7441 *
7442 * Description:
7443 * The code is simple. No description necessary.
7444 *
7445 * Returns:
7446 * SK_PNMI_ERR_OK The request was successfully performed.
7447 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7448 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7449 * the correct data (e.g. a 32bit value is
7450 * needed, but a 16 bit value was passed).
7451 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7452 * exist (e.g. port instance 3 on a two port
7453 * adapter.
7454 */
7455
7456PNMI_STATIC int PowerManagement(
7457SK_AC *pAC, /* Pointer to adapter context */
7458SK_IOC IoC, /* IO context handle */
7459int Action, /* Get/PreSet/Set action */
7460SK_U32 Id, /* Object ID that is to be processed */
7461char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7462unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7463SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7464unsigned int TableIndex, /* Index to the Id table */
7465SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7466{
7467
7468 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7469
7470 /*
7471 * Check instance. We only handle single instance variables
7472 */
7473 if (Instance != (SK_U32)(-1) && Instance != 1) {
7474
7475 *pLen = 0;
7476 return (SK_PNMI_ERR_UNKNOWN_INST);
7477 }
7478
7479
7480 /* Check length */
7481 switch (Id) {
7482
7483 case OID_PNP_CAPABILITIES:
7484 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7485
7486 *pLen = sizeof(SK_PNP_CAPABILITIES);
7487 return (SK_PNMI_ERR_TOO_SHORT);
7488 }
7489 break;
7490
7491 case OID_PNP_SET_POWER:
7492 case OID_PNP_QUERY_POWER:
7493 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7494 {
7495 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7496 return (SK_PNMI_ERR_TOO_SHORT);
7497 }
7498 break;
7499
7500 case OID_PNP_ADD_WAKE_UP_PATTERN:
7501 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7502 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7503
7504 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7505 return (SK_PNMI_ERR_TOO_SHORT);
7506 }
7507 break;
7508
7509 case OID_PNP_ENABLE_WAKE_UP:
7510 if (*pLen < sizeof(SK_U32)) {
7511
7512 *pLen = sizeof(SK_U32);
7513 return (SK_PNMI_ERR_TOO_SHORT);
7514 }
7515 break;
7516 }
7517
7518 /*
7519 * Perform action
7520 */
7521 if (Action == SK_PNMI_GET) {
7522
7523 /*
7524 * Get value
7525 */
7526 switch (Id) {
7527
7528 case OID_PNP_CAPABILITIES:
7529 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7530 break;
7531
7532 case OID_PNP_QUERY_POWER:
7533 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7534 the miniport to indicate whether it can transition its NIC
7535 to the low-power state.
7536 A miniport driver must always return NDIS_STATUS_SUCCESS
7537 to a query of OID_PNP_QUERY_POWER. */
7538 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7539 RetCode = SK_PNMI_ERR_OK;
7540 break;
7541
7542 /* NDIS handles these OIDs as write-only.
7543 * So in case of get action the buffer with written length = 0
7544 * is returned
7545 */
7546 case OID_PNP_SET_POWER:
7547 case OID_PNP_ADD_WAKE_UP_PATTERN:
7548 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7549 *pLen = 0;
7550 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7551 break;
7552
7553 case OID_PNP_ENABLE_WAKE_UP:
7554 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7555 break;
7556
7557 default:
7558 RetCode = SK_PNMI_ERR_GENERAL;
7559 break;
7560 }
7561
7562 return (RetCode);
7563 }
7564
7565
7566 /*
7567 * Perform preset or set
7568 */
7569
7570 /* POWER module does not support PRESET action */
7571 if (Action == SK_PNMI_PRESET) {
7572 return (SK_PNMI_ERR_OK);
7573 }
7574
7575 switch (Id) {
7576 case OID_PNP_SET_POWER:
7577 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7578 break;
7579
7580 case OID_PNP_ADD_WAKE_UP_PATTERN:
7581 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7582 break;
7583
7584 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7585 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7586 break;
7587
7588 case OID_PNP_ENABLE_WAKE_UP:
7589 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7590 break;
7591
7592 default:
7593 RetCode = SK_PNMI_ERR_READ_ONLY;
7594 }
7595
7596 return (RetCode);
7597}
7598#endif /* SK_POWER_MGMT */
7599
7600#ifdef SK_DIAG_SUPPORT
7601/*****************************************************************************
7602 *
7603 * DiagActions - OID handler function of Diagnostic driver
7604 *
7605 * Description:
7606 * The code is simple. No description necessary.
7607 *
7608 * Returns:
7609 * SK_PNMI_ERR_OK The request was successfully performed.
7610 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7611 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7612 * the correct data (e.g. a 32bit value is
7613 * needed, but a 16 bit value was passed).
7614 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7615 * exist (e.g. port instance 3 on a two port
7616 * adapter.
7617 */
7618
7619PNMI_STATIC int DiagActions(
7620SK_AC *pAC, /* Pointer to adapter context */
7621SK_IOC IoC, /* IO context handle */
7622int Action, /* GET/PRESET/SET action */
7623SK_U32 Id, /* Object ID that is to be processed */
7624char *pBuf, /* Buffer used for the management data transfer */
7625unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7626SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7627unsigned int TableIndex, /* Index to the Id table */
7628SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7629{
7630
7631 SK_U32 DiagStatus;
7632 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7633
7634 /*
7635 * Check instance. We only handle single instance variables.
7636 */
7637 if (Instance != (SK_U32)(-1) && Instance != 1) {
7638
7639 *pLen = 0;
7640 return (SK_PNMI_ERR_UNKNOWN_INST);
7641 }
7642
7643 /*
7644 * Check length.
7645 */
7646 switch (Id) {
7647
7648 case OID_SKGE_DIAG_MODE:
7649 if (*pLen < sizeof(SK_U32)) {
7650
7651 *pLen = sizeof(SK_U32);
7652 return (SK_PNMI_ERR_TOO_SHORT);
7653 }
7654 break;
7655
7656 default:
7657 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7658 *pLen = 0;
7659 return (SK_PNMI_ERR_GENERAL);
7660 }
7661
7662 /* Perform action. */
7663
7664 /* GET value. */
7665 if (Action == SK_PNMI_GET) {
7666
7667 switch (Id) {
7668
7669 case OID_SKGE_DIAG_MODE:
7670 DiagStatus = pAC->Pnmi.DiagAttached;
7671 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7672 *pLen = sizeof(SK_U32);
7673 RetCode = SK_PNMI_ERR_OK;
7674 break;
7675
7676 default:
7677 *pLen = 0;
7678 RetCode = SK_PNMI_ERR_GENERAL;
7679 break;
7680 }
7681 return (RetCode);
7682 }
7683
7684 /* From here SET or PRESET value. */
7685
7686 /* PRESET value is not supported. */
7687 if (Action == SK_PNMI_PRESET) {
7688 return (SK_PNMI_ERR_OK);
7689 }
7690
7691 /* SET value. */
7692 switch (Id) {
7693 case OID_SKGE_DIAG_MODE:
7694
7695 /* Handle the SET. */
7696 switch (*pBuf) {
7697
7698 /* Attach the DIAG to this adapter. */
7699 case SK_DIAG_ATTACHED:
7700 /* Check if we come from running */
7701 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7702
7703 RetCode = SkDrvLeaveDiagMode(pAC);
7704
7705 }
7706 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7707
7708 RetCode = SK_PNMI_ERR_OK;
7709 }
7710
7711 else {
7712
7713 RetCode = SK_PNMI_ERR_GENERAL;
7714
7715 }
7716
7717 if (RetCode == SK_PNMI_ERR_OK) {
7718
7719 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7720 }
7721 break;
7722
7723 /* Enter the DIAG mode in the driver. */
7724 case SK_DIAG_RUNNING:
7725 RetCode = SK_PNMI_ERR_OK;
7726
7727 /*
7728 * If DiagAttached is set, we can tell the driver
7729 * to enter the DIAG mode.
7730 */
7731 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7732 /* If DiagMode is not active, we can enter it. */
7733 if (!pAC->DiagModeActive) {
7734
7735 RetCode = SkDrvEnterDiagMode(pAC);
7736 }
7737 else {
7738
7739 RetCode = SK_PNMI_ERR_GENERAL;
7740 }
7741 }
7742 else {
7743
7744 RetCode = SK_PNMI_ERR_GENERAL;
7745 }
7746
7747 if (RetCode == SK_PNMI_ERR_OK) {
7748
7749 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7750 }
7751 break;
7752
7753 case SK_DIAG_IDLE:
7754 /* Check if we come from running */
7755 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7756
7757 RetCode = SkDrvLeaveDiagMode(pAC);
7758
7759 }
7760 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7761
7762 RetCode = SK_PNMI_ERR_OK;
7763 }
7764
7765 else {
7766
7767 RetCode = SK_PNMI_ERR_GENERAL;
7768
7769 }
7770
7771 if (RetCode == SK_PNMI_ERR_OK) {
7772
7773 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7774 }
7775 break;
7776
7777 default:
7778 RetCode = SK_PNMI_ERR_BAD_VALUE;
7779 break;
7780 }
7781 break;
7782
7783 default:
7784 RetCode = SK_PNMI_ERR_GENERAL;
7785 }
7786
7787 if (RetCode == SK_PNMI_ERR_OK) {
7788 *pLen = sizeof(SK_U32);
7789 }
7790 else {
7791
7792 *pLen = 0;
7793 }
7794 return (RetCode);
7795}
7796#endif /* SK_DIAG_SUPPORT */
7797
7798/*****************************************************************************
7799 *
7800 * Vct - OID handler function of OIDs
7801 *
7802 * Description:
7803 * The code is simple. No description necessary.
7804 *
7805 * Returns:
7806 * SK_PNMI_ERR_OK The request was performed successfully.
7807 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7808 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7809 * the correct data (e.g. a 32bit value is
7810 * needed, but a 16 bit value was passed).
7811 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7812 * exist (e.g. port instance 3 on a two port
7813 * adapter).
7814 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7815 *
7816 */
7817
7818PNMI_STATIC int Vct(
7819SK_AC *pAC, /* Pointer to adapter context */
7820SK_IOC IoC, /* IO context handle */
7821int Action, /* GET/PRESET/SET action */
7822SK_U32 Id, /* Object ID that is to be processed */
7823char *pBuf, /* Buffer used for the management data transfer */
7824unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7825SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7826unsigned int TableIndex, /* Index to the Id table */
7827SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7828{
7829 SK_GEPORT *pPrt;
7830 SK_PNMI_VCT *pVctBackupData;
7831 SK_U32 LogPortMax;
7832 SK_U32 PhysPortMax;
7833 SK_U32 PhysPortIndex;
7834 SK_U32 Limit;
7835 SK_U32 Offset;
7836 SK_BOOL Link;
7837 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7838 int i;
7839 SK_EVPARA Para;
7840 SK_U32 CableLength;
7841
7842 /*
7843 * Calculate the port indexes from the instance.
7844 */
7845 PhysPortMax = pAC->GIni.GIMacsFound;
7846 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7847
7848 /* Dual net mode? */
7849 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7850 LogPortMax--;
7851 }
7852
7853 if ((Instance != (SK_U32) (-1))) {
7854 /* Check instance range. */
7855 if ((Instance < 2) || (Instance > LogPortMax)) {
7856 *pLen = 0;
7857 return (SK_PNMI_ERR_UNKNOWN_INST);
7858 }
7859
7860 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7861 PhysPortIndex = NetIndex;
7862 }
7863 else {
7864 PhysPortIndex = Instance - 2;
7865 }
7866 Limit = PhysPortIndex + 1;
7867 }
7868 else {
7869 /*
7870 * Instance == (SK_U32) (-1), get all Instances of that OID.
7871 *
7872 * Not implemented yet. May be used in future releases.
7873 */
7874 PhysPortIndex = 0;
7875 Limit = PhysPortMax;
7876 }
7877
7878 pPrt = &pAC->GIni.GP[PhysPortIndex];
7879 if (pPrt->PHWLinkUp) {
7880 Link = SK_TRUE;
7881 }
7882 else {
7883 Link = SK_FALSE;
7884 }
7885
7886 /* Check MAC type */
7887 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
7888 *pLen = 0;
7889 return (SK_PNMI_ERR_GENERAL);
7890 }
7891
7892 /* Initialize backup data pointer. */
7893 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
7894
7895 /* Check action type */
7896 if (Action == SK_PNMI_GET) {
7897 /* Check length */
7898 switch (Id) {
7899
7900 case OID_SKGE_VCT_GET:
7901 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
7902 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
7903 return (SK_PNMI_ERR_TOO_SHORT);
7904 }
7905 break;
7906
7907 case OID_SKGE_VCT_STATUS:
7908 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
7909 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
7910 return (SK_PNMI_ERR_TOO_SHORT);
7911 }
7912 break;
7913
7914 default:
7915 *pLen = 0;
7916 return (SK_PNMI_ERR_GENERAL);
7917 }
7918
7919 /* Get value */
7920 Offset = 0;
7921 for (; PhysPortIndex < Limit; PhysPortIndex++) {
7922 switch (Id) {
7923
7924 case OID_SKGE_VCT_GET:
7925 if ((Link == SK_FALSE) &&
7926 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
7927 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
7928 if (RetCode == 0) {
7929 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
7930 pAC->Pnmi.VctStatus[PhysPortIndex] |=
7931 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
7932
7933 /* Copy results for later use to PNMI struct. */
7934 for (i = 0; i < 4; i++) {
7935 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
7936 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
7937 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
7938 }
7939 }
7940 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
7941 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
7942 }
7943 else {
7944 CableLength = 0;
7945 }
7946 pVctBackupData->PMdiPairLen[i] = CableLength;
7947 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
7948 }
7949
7950 Para.Para32[0] = PhysPortIndex;
7951 Para.Para32[1] = -1;
7952 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
7953 SkEventDispatcher(pAC, IoC);
7954 }
7955 else {
7956 ; /* VCT test is running. */
7957 }
7958 }
7959
7960 /* Get all results. */
7961 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7962 Offset += sizeof(SK_U8);
7963 *(pBuf + Offset) = pPrt->PCableLen;
7964 Offset += sizeof(SK_U8);
7965 for (i = 0; i < 4; i++) {
7966 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
7967 Offset += sizeof(SK_U32);
7968 }
7969 for (i = 0; i < 4; i++) {
7970 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
7971 Offset += sizeof(SK_U8);
7972 }
7973
7974 RetCode = SK_PNMI_ERR_OK;
7975 break;
7976
7977 case OID_SKGE_VCT_STATUS:
7978 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7979 Offset += sizeof(SK_U8);
7980 RetCode = SK_PNMI_ERR_OK;
7981 break;
7982
7983 default:
7984 *pLen = 0;
7985 return (SK_PNMI_ERR_GENERAL);
7986 }
7987 } /* for */
7988 *pLen = Offset;
7989 return (RetCode);
7990
7991 } /* if SK_PNMI_GET */
7992
7993 /*
7994 * From here SET or PRESET action. Check if the passed
7995 * buffer length is plausible.
7996 */
7997
7998 /* Check length */
7999 switch (Id) {
8000 case OID_SKGE_VCT_SET:
8001 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8002 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8003 return (SK_PNMI_ERR_TOO_SHORT);
8004 }
8005 break;
8006
8007 default:
8008 *pLen = 0;
8009 return (SK_PNMI_ERR_GENERAL);
8010 }
8011
8012 /*
8013 * Perform preset or set.
8014 */
8015
8016 /* VCT does not support PRESET action. */
8017 if (Action == SK_PNMI_PRESET) {
8018 return (SK_PNMI_ERR_OK);
8019 }
8020
8021 Offset = 0;
8022 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8023 switch (Id) {
8024 case OID_SKGE_VCT_SET: /* Start VCT test. */
8025 if (Link == SK_FALSE) {
8026 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8027
8028 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8029 if (RetCode == 0) { /* RetCode: 0 => Start! */
8030 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8031 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8032 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8033
8034 /*
8035 * Start VCT timer counter.
8036 */
8037 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8038 Para.Para32[0] = PhysPortIndex;
8039 Para.Para32[1] = -1;
8040 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8041 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8042 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8043 RetCode = SK_PNMI_ERR_OK;
8044 }
8045 else { /* RetCode: 2 => Running! */
8046 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8047 RetCode = SK_PNMI_ERR_OK;
8048 }
8049 }
8050 else { /* RetCode: 4 => Link! */
8051 RetCode = 4;
8052 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8053 RetCode = SK_PNMI_ERR_OK;
8054 }
8055 Offset += sizeof(SK_U32);
8056 break;
8057
8058 default:
8059 *pLen = 0;
8060 return (SK_PNMI_ERR_GENERAL);
8061 }
8062 } /* for */
8063 *pLen = Offset;
8064 return (RetCode);
8065
8066} /* Vct */
8067
8068
8069PNMI_STATIC void CheckVctStatus(
8070SK_AC *pAC,
8071SK_IOC IoC,
8072char *pBuf,
8073SK_U32 Offset,
8074SK_U32 PhysPortIndex)
8075{
8076 SK_GEPORT *pPrt;
8077 SK_PNMI_VCT *pVctData;
8078 SK_U32 RetCode;
8079
8080 pPrt = &pAC->GIni.GP[PhysPortIndex];
8081
8082 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8083 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8084
8085 if (!pPrt->PHWLinkUp) {
8086
8087 /* Was a VCT test ever made before? */
8088 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8089 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8090 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8091 }
8092 else {
8093 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8094 }
8095 }
8096
8097 /* Check VCT test status. */
8098 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8099 if (RetCode == 2) { /* VCT test is running. */
8100 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8101 }
8102 else { /* VCT data was copied to pAC here. Check PENDING state. */
8103 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8104 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8105 }
8106 }
8107
8108 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8109 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8110 }
8111 }
8112 else {
8113
8114 /* Was a VCT test ever made before? */
8115 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8116 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8117 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8118 }
8119
8120 /* DSP only valid in 100/1000 modes. */
8121 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8122 SK_LSPEED_STAT_10MBPS) {
8123 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8124 }
8125 }
8126} /* CheckVctStatus */
8127
8128
8129/*****************************************************************************
8130 *
8131 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8132 * PNMI function depending on the subcommand and
8133 * returns all data belonging to the complete database
8134 * or OID request.
8135 *
8136 * Description:
8137 * Looks up the requested subcommand, calls the corresponding handler
8138 * function and passes all required parameters to it.
8139 * The function is called by the driver. It is needed to handle the new
8140 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8141 * the OID and a subcommand to decide what kind of request has to be done.
8142 *
8143 * Returns:
8144 * SK_PNMI_ERR_OK The request was successfully performed
8145 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8146 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8147 * the data.
8148 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8149 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8150 * exist (e.g. port instance 3 on a two port
8151 * adapter.
8152 */
8153int SkPnmiGenIoctl(
8154SK_AC *pAC, /* Pointer to adapter context struct */
8155SK_IOC IoC, /* I/O context */
8156void *pBuf, /* Buffer used for the management data transfer */
8157unsigned int *pLen, /* Length of buffer */
8158SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8159{
8160SK_I32 Mode; /* Store value of subcommand. */
8161SK_U32 Oid; /* Store value of OID. */
8162int ReturnCode; /* Store return value to show status of PNMI action. */
8163int HeaderLength; /* Length of desired action plus OID. */
8164
8165 ReturnCode = SK_PNMI_ERR_GENERAL;
8166
8167 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8168 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8169 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8170 *pLen = *pLen - HeaderLength;
8171 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8172
8173 switch(Mode) {
8174 case SK_GET_SINGLE_VAR:
8175 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8176 (char *) pBuf + sizeof(SK_I32), pLen,
8177 ((SK_U32) (-1)), NetIndex);
8178 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8179 *pLen = *pLen + sizeof(SK_I32);
8180 break;
8181 case SK_PRESET_SINGLE_VAR:
8182 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8183 (char *) pBuf + sizeof(SK_I32), pLen,
8184 ((SK_U32) (-1)), NetIndex);
8185 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8186 *pLen = *pLen + sizeof(SK_I32);
8187 break;
8188 case SK_SET_SINGLE_VAR:
8189 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8190 (char *) pBuf + sizeof(SK_I32), pLen,
8191 ((SK_U32) (-1)), NetIndex);
8192 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8193 *pLen = *pLen + sizeof(SK_I32);
8194 break;
8195 case SK_GET_FULL_MIB:
8196 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8197 break;
8198 case SK_PRESET_FULL_MIB:
8199 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8200 break;
8201 case SK_SET_FULL_MIB:
8202 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8203 break;
8204 default:
8205 break;
8206 }
8207
8208 return (ReturnCode);
8209
8210} /* SkGeIocGen */