aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/sk98lin/skgepnmi.c
diff options
context:
space:
mode:
authorStephen Hemminger <shemminger@linux-foundation.org>2008-01-31 01:04:05 -0500
committerJeff Garzik <jeff@garzik.org>2008-03-17 07:49:23 -0400
commit548c36e983f346621b5cb9ab031e4383e9996576 (patch)
tree7c341c1513a6d84a06c86f5045c885086a7524eb /drivers/net/sk98lin/skgepnmi.c
parenta978b30af3bab0dd9af9350eeda25e76123fa28e (diff)
sk98lin: remove obsolete driver
All the hardware supported by this driver is now supported by the skge driver. The last remaining issue was support for ancient dual port SysKonnect fiber boards, and the skge driver now does these correctly (p.s. sk98lin was always broken on these old dual port boards anyway). Signed-off-by: Stephen Hemminger <shemminger@linux-foundation.org> Signed-off-by: Jeff Garzik <jeff@garzik.org>
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 */