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