1 /*****************************************************************************
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
9 ****************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
14 * (C)Copyright 2002-2003 Marvell.
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.
21 * The information in this file is provided "AS IS" without warranty.
23 ******************************************************************************/
27 static const char SysKonnectFileId[] =
28 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
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"
41 #include "h/skgeinit.h"
42 #include "h/skdrv2nd.h"
43 #include "h/skgepnm2.h"
45 #include "h/skgepmgt.h"
47 /* defines *******************************************************************/
50 #define PNMI_STATIC static
56 * Public Function prototypes
58 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
59 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
62 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
63 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
64 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
65 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
68 unsigned int *pLen, SK_U32 NetIndex);
69 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
70 unsigned int *pLen, SK_U32 NetIndex);
71 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
72 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
73 unsigned int * pLen, SK_U32 NetIndex);
77 * Private Function prototypes
80 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
82 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
84 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
85 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
86 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
87 unsigned int PhysPortIndex, unsigned int StatIndex);
88 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
89 unsigned int StatIndex, SK_U32 NetIndex);
90 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
91 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
92 unsigned int *pEntries);
93 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
94 unsigned int KeyArrLen, unsigned int *pKeyNo);
95 PNMI_STATIC int LookupId(SK_U32 Id);
96 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
97 unsigned int LastMac);
98 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
99 unsigned int *pLen, SK_U32 NetIndex);
100 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
101 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
102 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
103 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
104 unsigned int PortIndex);
105 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
106 unsigned int SensorIndex);
107 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
108 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
109 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
110 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
111 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
112 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
113 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
114 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
117 * Table to correlate OID with handler function and index to
118 * hardware register stored in StatAddress if applicable.
122 /* global variables **********************************************************/
125 * Overflow status register bit table and corresponding counter
126 * dependent on MAC type - the number relates to the size of overflow
127 * mask returned by the pFnMacOverflow function
129 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
130 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
131 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
132 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
133 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
134 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
135 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
136 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
137 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
138 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
139 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
140 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
141 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
142 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
143 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
144 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
145 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
146 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
147 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
148 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
149 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
150 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
151 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
152 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
153 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
154 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
155 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
156 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
159 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
160 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
161 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
162 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
163 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
164 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
165 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
166 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
167 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
168 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
169 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
170 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
171 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
172 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
173 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
174 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
175 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
176 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
177 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
178 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
179 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
180 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
181 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
182 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
183 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
184 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
185 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
186 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
187 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
188 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
189 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
190 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
191 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
192 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
193 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
197 * Table for hardware register saving on resets and port switches
199 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
201 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
202 /* SK_PNMI_HTX_OCTETHIGH */
203 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
204 /* SK_PNMI_HTX_OCTETLOW */
205 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
206 /* SK_PNMI_HTX_BROADCAST */
207 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_MULTICAST */
209 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
210 /* SK_PNMI_HTX_UNICAST */
211 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
212 /* SK_PNMI_HTX_BURST */
213 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_PMACC */
215 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
216 /* SK_PNMI_HTX_MACC */
217 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
218 /* SK_PNMI_HTX_COL */
219 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_SINGLE_COL */
221 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_MULTI_COL */
223 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_EXCESS_COL */
225 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
226 /* SK_PNMI_HTX_LATE_COL */
227 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
228 /* SK_PNMI_HTX_DEFFERAL */
229 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
230 /* SK_PNMI_HTX_EXCESS_DEF */
231 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UNDERRUN */
233 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
234 /* SK_PNMI_HTX_CARRIER */
235 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
236 /* SK_PNMI_HTX_UTILUNDER */
237 {{0, SK_FALSE}, {0, SK_FALSE}},
238 /* SK_PNMI_HTX_UTILOVER */
239 {{0, SK_FALSE}, {0, SK_FALSE}},
241 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
242 /* SK_PNMI_HTX_127 */
243 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
244 /* SK_PNMI_HTX_255 */
245 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
246 /* SK_PNMI_HTX_511 */
247 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
248 /* SK_PNMI_HTX_1023 */
249 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
250 /* SK_PNMI_HTX_MAX */
251 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
252 /* SK_PNMI_HTX_LONGFRAMES */
253 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
254 /* SK_PNMI_HTX_SYNC */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
256 /* SK_PNMI_HTX_SYNC_OCTET */
257 {{0, SK_FALSE}, {0, SK_FALSE}},
258 /* SK_PNMI_HTX_RESERVED */
259 {{0, SK_FALSE}, {0, SK_FALSE}},
261 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
262 /* SK_PNMI_HRX_OCTETHIGH */
263 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_OCTETLOW */
265 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
266 /* SK_PNMI_HRX_BADOCTETHIGH */
267 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
268 /* SK_PNMI_HRX_BADOCTETLOW */
269 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
270 /* SK_PNMI_HRX_BROADCAST */
271 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_MULTICAST */
273 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
274 /* SK_PNMI_HRX_UNICAST */
275 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
276 /* SK_PNMI_HRX_PMACC */
277 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
278 /* SK_PNMI_HRX_MACC */
279 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_PMACC_ERR */
281 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MACC_UNKWN */
283 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_BURST */
285 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_MISSED */
287 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
288 /* SK_PNMI_HRX_FRAMING */
289 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
290 /* SK_PNMI_HRX_UNDERSIZE */
291 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
292 /* SK_PNMI_HRX_OVERFLOW */
293 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
294 /* SK_PNMI_HRX_JABBER */
295 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
296 /* SK_PNMI_HRX_CARRIER */
297 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_IRLENGTH */
299 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_SYMBOL */
301 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
302 /* SK_PNMI_HRX_SHORTS */
303 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
304 /* SK_PNMI_HRX_RUNT */
305 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
306 /* SK_PNMI_HRX_TOO_LONG */
307 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
308 /* SK_PNMI_HRX_FCS */
309 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
310 /* SK_PNMI_HRX_CEXT */
311 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
312 /* SK_PNMI_HRX_UTILUNDER */
313 {{0, SK_FALSE}, {0, SK_FALSE}},
314 /* SK_PNMI_HRX_UTILOVER */
315 {{0, SK_FALSE}, {0, SK_FALSE}},
317 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
318 /* SK_PNMI_HRX_127 */
319 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
320 /* SK_PNMI_HRX_255 */
321 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
322 /* SK_PNMI_HRX_511 */
323 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
324 /* SK_PNMI_HRX_1023 */
325 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
326 /* SK_PNMI_HRX_MAX */
327 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
328 /* SK_PNMI_HRX_LONGFRAMES */
329 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
330 /* SK_PNMI_HRX_RESERVED */
331 {{0, SK_FALSE}, {0, SK_FALSE}}
335 /*****************************************************************************
341 /*****************************************************************************
343 * SkPnmiInit - Init function of PNMI
346 * SK_INIT_DATA: Initialises the data structures
347 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
349 * SK_INIT_RUN: Starts a timer event for port switch per hour
356 SK_AC *pAC, /* Pointer to adapter context */
357 SK_IOC IoC, /* IO context handle */
358 int Level) /* Initialization level */
360 unsigned int PortMax; /* Number of ports */
361 unsigned int PortIndex; /* Current port index in loop */
362 SK_U16 Val16; /* Multiple purpose 16 bit variable */
363 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
364 SK_EVPARA EventParam; /* Event struct for timer event */
365 SK_PNMI_VCT *pVctBackupData;
368 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
369 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
374 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
375 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
376 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
377 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
378 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
380 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
381 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
385 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
387 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
389 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
390 ("CounterOffset struct size (%d) differs from"
391 "SK_PNMI_MAX_IDX (%d)\n",
392 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
395 if (SK_PNMI_MAX_IDX !=
396 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
398 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
400 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
401 ("StatAddr table size (%d) differs from "
402 "SK_PNMI_MAX_IDX (%d)\n",
404 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
407 #endif /* SK_PNMI_CHECK */
414 PortMax = pAC->GIni.GIMacsFound;
416 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
418 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
421 /* Initialize DSP variables for Vct() to 0xff => Never written! */
422 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
423 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
424 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
425 pVctBackupData->PCableLen = 0xff;
431 SK_IN16(IoC, B0_CTST, &Val16);
432 if ((Val16 & CS_BUS_CLOCK) == 0) {
434 pAC->Pnmi.PciBusSpeed = 33;
437 pAC->Pnmi.PciBusSpeed = 66;
443 SK_IN16(IoC, B0_CTST, &Val16);
444 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
446 pAC->Pnmi.PciBusWidth = 32;
449 pAC->Pnmi.PciBusWidth = 64;
455 switch (pAC->GIni.GIChipId) {
456 case CHIP_ID_GENESIS:
457 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
461 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
469 * Get PMD and DeviceType
471 SK_IN8(IoC, B2_PMD_TYP, &Val8);
475 if (pAC->GIni.GIMacsFound > 1) {
477 pAC->Pnmi.DeviceType = 0x00020002;
480 pAC->Pnmi.DeviceType = 0x00020001;
486 if (pAC->GIni.GIMacsFound > 1) {
488 pAC->Pnmi.DeviceType = 0x00020004;
491 pAC->Pnmi.DeviceType = 0x00020003;
497 if (pAC->GIni.GIMacsFound > 1) {
499 pAC->Pnmi.DeviceType = 0x00020006;
502 pAC->Pnmi.DeviceType = 0x00020005;
508 if (pAC->GIni.GIMacsFound > 1) {
510 pAC->Pnmi.DeviceType = 0x00020008;
513 pAC->Pnmi.DeviceType = 0x00020007;
519 pAC->Pnmi.DeviceType = 0;
526 SK_IN8(IoC, B2_CONN_TYP, &Val8);
529 pAC->Pnmi.Connector = 2;
533 pAC->Pnmi.Connector = 3;
537 pAC->Pnmi.Connector = 4;
541 pAC->Pnmi.Connector = 5;
545 pAC->Pnmi.Connector = 6;
549 pAC->Pnmi.Connector = 1;
556 * Start timer for RLMT change counter
558 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
559 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
560 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
565 break; /* Nothing todo */
571 /*****************************************************************************
573 * SkPnmiGetVar - Retrieves the value of a single OID
576 * Calls a general sub-function for all this stuff. If the instance
577 * -1 is passed, the values of all instances are returned in an
581 * SK_PNMI_ERR_OK The request was successfully performed
582 * SK_PNMI_ERR_GENERAL A general severe internal error occured
583 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
585 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
586 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
587 * exist (e.g. port instance 3 on a two port
591 SK_AC *pAC, /* Pointer to adapter context */
592 SK_IOC IoC, /* IO context handle */
593 SK_U32 Id, /* Object ID that is to be processed */
594 void *pBuf, /* Buffer to which the management data will be copied */
595 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
596 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
597 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
599 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
600 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
601 Id, *pLen, Instance, NetIndex));
603 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
604 Instance, NetIndex));
607 /*****************************************************************************
609 * SkPnmiPreSetVar - Presets the value of a single OID
612 * Calls a general sub-function for all this stuff. The preset does
613 * the same as a set, but returns just before finally setting the
614 * new value. This is useful to check if a set might be successfull.
615 * If the instance -1 is passed, an array of values is supposed and
616 * all instances of the OID will be set.
619 * SK_PNMI_ERR_OK The request was successfully performed.
620 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
621 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
622 * the correct data (e.g. a 32bit value is
623 * needed, but a 16 bit value was passed).
624 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
626 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
627 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
628 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
629 * exist (e.g. port instance 3 on a two port
633 SK_AC *pAC, /* Pointer to adapter context */
634 SK_IOC IoC, /* IO context handle */
635 SK_U32 Id, /* Object ID that is to be processed */
636 void *pBuf, /* Buffer to which the management data will be copied */
637 unsigned int *pLen, /* Total length of management data */
638 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
639 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
641 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
642 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
643 Id, *pLen, Instance, NetIndex));
646 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
647 Instance, NetIndex));
650 /*****************************************************************************
652 * SkPnmiSetVar - Sets the value of a single OID
655 * Calls a general sub-function for all this stuff. The preset does
656 * the same as a set, but returns just before finally setting the
657 * new value. This is useful to check if a set might be successfull.
658 * If the instance -1 is passed, an array of values is supposed and
659 * all instances of the OID will be set.
662 * SK_PNMI_ERR_OK The request was successfully performed.
663 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
664 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
665 * the correct data (e.g. a 32bit value is
666 * needed, but a 16 bit value was passed).
667 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
669 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
670 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
671 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
672 * exist (e.g. port instance 3 on a two port
676 SK_AC *pAC, /* Pointer to adapter context */
677 SK_IOC IoC, /* IO context handle */
678 SK_U32 Id, /* Object ID that is to be processed */
679 void *pBuf, /* Buffer to which the management data will be copied */
680 unsigned int *pLen, /* Total length of management data */
681 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
682 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
684 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
685 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
686 Id, *pLen, Instance, NetIndex));
688 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
689 Instance, NetIndex));
692 /*****************************************************************************
694 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
697 * Runs through the IdTable, queries the single OIDs and stores the
698 * returned data into the management database structure
699 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
700 * is stored in the IdTable. The return value of the function will also
701 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
702 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
705 * SK_PNMI_ERR_OK The request was successfully performed
706 * SK_PNMI_ERR_GENERAL A general severe internal error occured
707 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
709 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
712 SK_AC *pAC, /* Pointer to adapter context */
713 SK_IOC IoC, /* IO context handle */
714 void *pBuf, /* Buffer to which the management data will be copied. */
715 unsigned int *pLen, /* Length of buffer */
716 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
719 unsigned int TableIndex;
720 unsigned int DstOffset;
721 unsigned int InstanceNo;
722 unsigned int InstanceCnt;
725 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
728 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
729 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
732 if (*pLen < SK_PNMI_STRUCT_SIZE) {
734 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
736 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
740 *pLen = SK_PNMI_STRUCT_SIZE;
741 return (SK_PNMI_ERR_TOO_SHORT);
747 if (NetIndex >= pAC->Rlmt.NumNets) {
748 return (SK_PNMI_ERR_UNKNOWN_NET);
751 /* Update statistic */
752 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
754 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
757 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
758 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
762 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
764 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
765 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
769 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
771 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
772 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
777 * Increment semaphores to indicate that an update was
780 pAC->Pnmi.MacUpdatedFlag ++;
781 pAC->Pnmi.RlmtUpdatedFlag ++;
782 pAC->Pnmi.SirqUpdatedFlag ++;
784 /* Get vpd keys for instance calculation */
785 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
786 if (Ret != SK_PNMI_ERR_OK) {
788 pAC->Pnmi.MacUpdatedFlag --;
789 pAC->Pnmi.RlmtUpdatedFlag --;
790 pAC->Pnmi.SirqUpdatedFlag --;
792 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
793 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
794 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
795 return (SK_PNMI_ERR_GENERAL);
798 /* Retrieve values */
799 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
800 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
802 InstanceNo = IdTable[TableIndex].InstanceNo;
803 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
806 DstOffset = IdTable[TableIndex].Offset +
808 IdTable[TableIndex].StructSize;
811 * For the VPD the instance is not an index number
812 * but the key itself. Determin with the instance
813 * counter the VPD key to be used.
815 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
816 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
817 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
818 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
820 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
823 Instance = (SK_U32)InstanceCnt;
826 TmpLen = *pLen - DstOffset;
827 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
828 IdTable[TableIndex].Id, (char *)pBuf +
829 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
832 * An unknown instance error means that we reached
833 * the last instance of that variable. Proceed with
834 * the next OID in the table and ignore the return
837 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
842 if (Ret != SK_PNMI_ERR_OK) {
844 pAC->Pnmi.MacUpdatedFlag --;
845 pAC->Pnmi.RlmtUpdatedFlag --;
846 pAC->Pnmi.SirqUpdatedFlag --;
848 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
849 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
850 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
856 pAC->Pnmi.MacUpdatedFlag --;
857 pAC->Pnmi.RlmtUpdatedFlag --;
858 pAC->Pnmi.SirqUpdatedFlag --;
860 *pLen = SK_PNMI_STRUCT_SIZE;
861 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
862 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
863 return (SK_PNMI_ERR_OK);
866 /*****************************************************************************
868 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
871 * Calls a general sub-function for all this set stuff. The preset does
872 * the same as a set, but returns just before finally setting the
873 * new value. This is useful to check if a set might be successfull.
874 * The sub-function runs through the IdTable, checks which OIDs are able
875 * to set, and calls the handler function of the OID to perform the
876 * preset. The return value of the function will also be stored in
877 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
878 * SK_PNMI_MIN_STRUCT_SIZE.
881 * SK_PNMI_ERR_OK The request was successfully performed.
882 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
883 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
884 * the correct data (e.g. a 32bit value is
885 * needed, but a 16 bit value was passed).
886 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
889 int SkPnmiPreSetStruct(
890 SK_AC *pAC, /* Pointer to adapter context */
891 SK_IOC IoC, /* IO context handle */
892 void *pBuf, /* Buffer which contains the data to be set */
893 unsigned int *pLen, /* Length of buffer */
894 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
896 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
897 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
900 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
904 /*****************************************************************************
906 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
909 * Calls a general sub-function for all this set stuff. The return value
910 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
911 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
912 * The sub-function runs through the IdTable, checks which OIDs are able
913 * to set, and calls the handler function of the OID to perform the
914 * set. The return value of the function will also be stored in
915 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
916 * SK_PNMI_MIN_STRUCT_SIZE.
919 * SK_PNMI_ERR_OK The request was successfully performed.
920 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
921 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
922 * the correct data (e.g. a 32bit value is
923 * needed, but a 16 bit value was passed).
924 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
928 SK_AC *pAC, /* Pointer to adapter context */
929 SK_IOC IoC, /* IO context handle */
930 void *pBuf, /* Buffer which contains the data to be set */
931 unsigned int *pLen, /* Length of buffer */
932 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
934 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
935 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
938 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
942 /*****************************************************************************
944 * SkPnmiEvent - Event handler
947 * Handles the following events:
948 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
949 * interrupt will be generated which is
950 * first handled by SIRQ which generates a
951 * this event. The event increments the
952 * upper 32 bit of the 64 bit counter.
953 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
954 * when a sensor reports a warning or
955 * error. The event will store a trap
956 * message in the trap buffer.
957 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
958 * module and is used to calculate the
959 * port switches per hour.
960 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
962 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
963 * before a hard reset of the XMAC is
964 * performed. All counters will be saved
965 * and added to the hardware counter
966 * values after reset to grant continuous
968 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
969 * went logically up. A trap message will
970 * be stored to the trap buffer.
971 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
972 * went logically down. A trap message will
973 * be stored to the trap buffer.
974 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
975 * spanning tree root bridges were
976 * detected. A trap message will be stored
977 * to the trap buffer.
978 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
979 * down. PNMI will not further add the
980 * statistic values to the virtual port.
981 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
982 * is now an active port. PNMI will now
983 * add the statistic data of this port to
985 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
986 * contains the number of nets. 1 means single net, 2 means
987 * dual net. The second parameter is -1
993 SK_AC *pAC, /* Pointer to adapter context */
994 SK_IOC IoC, /* IO context handle */
995 SK_U32 Event, /* Event-Id */
996 SK_EVPARA Param) /* Event dependent parameter */
998 unsigned int PhysPortIndex;
999 unsigned int MaxNetNumber;
1003 SK_U64 OverflowStatus;
1009 SK_EVPARA EventParam;
1013 SK_PNMI_ESTIMATE *pEst;
1016 SK_PNMI_VCT *pVctBackupData;
1023 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1025 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1026 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1027 (unsigned int)Event, (unsigned int)Param.Para64));
1030 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1032 MacType = pAC->GIni.GIMacType;
1036 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1037 PhysPortIndex = (int)Param.Para32[0];
1038 MacStatus = (SK_U16)Param.Para32[1];
1040 if (PhysPortIndex >= SK_MAX_MACS) {
1042 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1043 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1044 " wrong, PhysPortIndex=0x%x\n",
1052 * Check which source caused an overflow interrupt.
1054 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1055 MacStatus, &OverflowStatus) != 0) ||
1056 (OverflowStatus == 0)) {
1058 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1063 * Check the overflow status register and increment
1064 * the upper dword of corresponding counter.
1066 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1069 Mask = (SK_U64)1 << CounterIndex;
1070 if ((OverflowStatus & Mask) == 0) {
1075 switch (StatOvrflwBit[CounterIndex][MacType]) {
1077 case SK_PNMI_HTX_UTILUNDER:
1078 case SK_PNMI_HTX_UTILOVER:
1079 if (MacType == SK_MAC_XMAC) {
1080 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1081 Register |= XM_TX_SAM_LINE;
1082 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1086 case SK_PNMI_HRX_UTILUNDER:
1087 case SK_PNMI_HRX_UTILOVER:
1088 if (MacType == SK_MAC_XMAC) {
1089 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1090 Register |= XM_RX_SAM_LINE;
1091 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1095 case SK_PNMI_HTX_OCTETHIGH:
1096 case SK_PNMI_HTX_OCTETLOW:
1097 case SK_PNMI_HTX_RESERVED:
1098 case SK_PNMI_HRX_OCTETHIGH:
1099 case SK_PNMI_HRX_OCTETLOW:
1100 case SK_PNMI_HRX_IRLENGTH:
1101 case SK_PNMI_HRX_RESERVED:
1104 * the following counters aren't be handled (id > 63)
1106 case SK_PNMI_HTX_SYNC:
1107 case SK_PNMI_HTX_SYNC_OCTET:
1110 case SK_PNMI_HRX_LONGFRAMES:
1111 if (MacType == SK_MAC_GMAC) {
1112 pAC->Pnmi.Port[PhysPortIndex].
1113 CounterHigh[CounterIndex] ++;
1118 pAC->Pnmi.Port[PhysPortIndex].
1119 CounterHigh[CounterIndex] ++;
1124 case SK_PNMI_EVT_SEN_WAR_LOW:
1126 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1128 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1129 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1130 (unsigned int)Param.Para64));
1136 * Store a trap message in the trap buffer and generate
1137 * an event for user space applications with the
1138 * SK_DRIVER_SENDEVENT macro.
1140 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1141 (unsigned int)Param.Para64);
1142 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1145 case SK_PNMI_EVT_SEN_WAR_UPP:
1147 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1149 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1150 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1151 (unsigned int)Param.Para64));
1157 * Store a trap message in the trap buffer and generate
1158 * an event for user space applications with the
1159 * SK_DRIVER_SENDEVENT macro.
1161 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1162 (unsigned int)Param.Para64);
1163 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1166 case SK_PNMI_EVT_SEN_ERR_LOW:
1168 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1170 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1171 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1172 (unsigned int)Param.Para64));
1178 * Store a trap message in the trap buffer and generate
1179 * an event for user space applications with the
1180 * SK_DRIVER_SENDEVENT macro.
1182 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1183 (unsigned int)Param.Para64);
1184 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1187 case SK_PNMI_EVT_SEN_ERR_UPP:
1189 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1191 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1192 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1193 (unsigned int)Param.Para64));
1199 * Store a trap message in the trap buffer and generate
1200 * an event for user space applications with the
1201 * SK_DRIVER_SENDEVENT macro.
1203 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1204 (unsigned int)Param.Para64);
1205 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1208 case SK_PNMI_EVT_CHG_EST_TIMER:
1210 * Calculate port switch average on a per hour basis
1211 * Time interval for check : 28125 ms
1212 * Number of values for average : 8
1214 * Be careful in changing these values, on change check
1215 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1216 * array one less than value number)
1217 * - Timer initialization SkTimerStart() in SkPnmiInit
1218 * - Delta value below must be multiplicated with
1222 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1223 CounterIndex = pEst->EstValueIndex + 1;
1224 if (CounterIndex == 7) {
1228 pEst->EstValueIndex = CounterIndex;
1230 NewestValue = pAC->Pnmi.RlmtChangeCts;
1231 OldestValue = pEst->EstValue[CounterIndex];
1232 pEst->EstValue[CounterIndex] = NewestValue;
1235 * Calculate average. Delta stores the number of
1236 * port switches per 28125 * 8 = 225000 ms
1238 if (NewestValue >= OldestValue) {
1240 Delta = NewestValue - OldestValue;
1243 /* Overflow situation */
1244 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1248 * Extrapolate delta to port switches per hour.
1249 * Estimate = Delta * (3600000 / 225000)
1253 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1256 * Check if threshold is exceeded. If the threshold is
1257 * permanently exceeded every 28125 ms an event will be
1258 * generated to remind the user of this condition.
1260 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1261 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1262 pAC->Pnmi.RlmtChangeThreshold)) {
1264 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1265 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1268 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1269 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1270 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1274 case SK_PNMI_EVT_CLEAR_COUNTER:
1276 * Param.Para32[0] contains the NetIndex (0 ..1).
1277 * Param.Para32[1] is reserved, contains -1.
1279 NetIndex = (SK_U32)Param.Para32[0];
1282 if (NetIndex >= pAC->Rlmt.NumNets) {
1284 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1285 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1293 * Set all counters and timestamps to zero.
1294 * The according NetIndex is required as a
1295 * parameter of the event.
1297 ResetCounter(pAC, IoC, NetIndex);
1300 case SK_PNMI_EVT_XMAC_RESET:
1302 * To grant continuous counter values store the current
1303 * XMAC statistic values to the entries 1..n of the
1304 * CounterOffset array. XMAC Errata #2
1307 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1309 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1310 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1311 (unsigned int)Param.Para64));
1315 PhysPortIndex = (unsigned int)Param.Para64;
1318 * Update XMAC statistic to get fresh values
1320 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1321 if (Ret != SK_PNMI_ERR_OK) {
1323 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1327 * Increment semaphore to indicate that an update was
1330 pAC->Pnmi.MacUpdatedFlag ++;
1332 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1335 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1340 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1341 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1343 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1346 pAC->Pnmi.MacUpdatedFlag --;
1349 case SK_PNMI_EVT_RLMT_PORT_UP:
1350 PhysPortIndex = (unsigned int)Param.Para32[0];
1352 if (PhysPortIndex >= SK_MAX_MACS) {
1354 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1355 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1356 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1363 * Store a trap message in the trap buffer and generate an event for
1364 * user space applications with the SK_DRIVER_SENDEVENT macro.
1366 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1367 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1369 /* Bugfix for XMAC errata (#10620)*/
1370 if (MacType == SK_MAC_XMAC) {
1371 /* Add incremental difference to offset (#10620)*/
1372 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1373 XM_RXE_SHT_ERR, &Val32);
1375 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1376 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1377 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1378 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1381 /* Tell VctStatus() that a link was up meanwhile. */
1382 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1385 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1386 PhysPortIndex = (unsigned int)Param.Para32[0];
1389 if (PhysPortIndex >= SK_MAX_MACS) {
1391 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1392 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1393 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1400 * Store a trap message in the trap buffer and generate an event for
1401 * user space applications with the SK_DRIVER_SENDEVENT macro.
1403 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1404 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1406 /* Bugfix #10620 - get zero level for incremental difference */
1407 if (MacType == SK_MAC_XMAC) {
1409 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1410 XM_RXE_SHT_ERR, &Val32);
1412 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1413 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1414 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1418 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1419 PhysPortIndex = (unsigned int)Param.Para32[0];
1420 NetIndex = (SK_U32)Param.Para32[1];
1423 if (PhysPortIndex >= SK_MAX_MACS) {
1425 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1426 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1430 if (NetIndex >= pAC->Rlmt.NumNets) {
1432 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1433 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1439 * For now, ignore event if NetIndex != 0.
1441 if (Param.Para32[1] != 0) {
1447 * Nothing to do if port is already inactive
1449 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1455 * Update statistic counters to calculate new offset for the virtual
1456 * port and increment semaphore to indicate that an update was already
1459 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1462 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1465 pAC->Pnmi.MacUpdatedFlag ++;
1468 * Calculate new counter offset for virtual port to grant continous
1469 * counting on port switches. The virtual port consists of all currently
1470 * active ports. The port down event indicates that a port is removed
1471 * from the virtual port. Therefore add the counter value of the removed
1472 * port to the CounterOffset for the virtual port to grant the same
1475 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1478 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1483 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1485 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1489 * Set port to inactive
1491 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1493 pAC->Pnmi.MacUpdatedFlag --;
1496 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1497 PhysPortIndex = (unsigned int)Param.Para32[0];
1498 NetIndex = (SK_U32)Param.Para32[1];
1501 if (PhysPortIndex >= SK_MAX_MACS) {
1503 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1504 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1508 if (NetIndex >= pAC->Rlmt.NumNets) {
1510 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1511 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1517 * For now, ignore event if NetIndex != 0.
1519 if (Param.Para32[1] != 0) {
1525 * Nothing to do if port is already active
1527 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1533 * Statistic maintenance
1535 pAC->Pnmi.RlmtChangeCts ++;
1536 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1539 * Store a trap message in the trap buffer and generate an event for
1540 * user space applications with the SK_DRIVER_SENDEVENT macro.
1542 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1543 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1546 * Update statistic counters to calculate new offset for the virtual
1547 * port and increment semaphore to indicate that an update was
1550 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1553 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1556 pAC->Pnmi.MacUpdatedFlag ++;
1559 * Calculate new counter offset for virtual port to grant continous
1560 * counting on port switches. A new port is added to the virtual port.
1561 * Therefore substract the counter value of the new port from the
1562 * CounterOffset for the virtual port to grant the same value.
1564 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1567 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1572 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1574 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1577 /* Set port to active */
1578 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1580 pAC->Pnmi.MacUpdatedFlag --;
1583 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1585 * Para.Para32[0] contains the NetIndex.
1589 * Store a trap message in the trap buffer and generate an event for
1590 * user space applications with the SK_DRIVER_SENDEVENT macro.
1592 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1593 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1596 case SK_PNMI_EVT_RLMT_SET_NETS:
1598 * Param.Para32[0] contains the number of Nets.
1599 * Param.Para32[1] is reserved, contains -1.
1602 * Check number of nets
1604 MaxNetNumber = pAC->GIni.GIMacsFound;
1605 if (((unsigned int)Param.Para32[0] < 1)
1606 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1607 return (SK_PNMI_ERR_UNKNOWN_NET);
1610 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1611 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1613 else { /* dual net mode */
1614 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1618 case SK_PNMI_EVT_VCT_RESET:
1619 PhysPortIndex = Param.Para32[0];
1620 pPrt = &pAC->GIni.GP[PhysPortIndex];
1621 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1623 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1624 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1627 * VCT test is still running.
1628 * Start VCT timer counter again.
1630 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1631 Param.Para32[0] = PhysPortIndex;
1632 Param.Para32[1] = -1;
1633 SkTimerStart(pAC, IoC,
1634 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1635 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1638 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1639 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1640 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1642 /* Copy results for later use to PNMI struct. */
1643 for (i = 0; i < 4; i++) {
1644 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1645 if ((pPrt->PMdiPairLen[i] > 35) &&
1646 (pPrt->PMdiPairLen[i] < 0xff)) {
1647 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1650 if ((pPrt->PMdiPairLen[i] > 35) &&
1651 (pPrt->PMdiPairLen[i] != 0xff)) {
1652 CableLength = 1000 *
1653 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1658 pVctBackupData->PMdiPairLen[i] = CableLength;
1659 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1662 Param.Para32[0] = PhysPortIndex;
1663 Param.Para32[1] = -1;
1664 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1665 SkEventDispatcher(pAC, IoC);
1674 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1679 /******************************************************************************
1685 /*****************************************************************************
1687 * PnmiVar - Gets, presets, and sets single OIDs
1690 * Looks up the requested OID, calls the corresponding handler
1691 * function, and passes the parameters with the get, preset, or
1692 * set command. The function is called by SkGePnmiGetVar,
1693 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1696 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1697 * calling functions.
1698 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1700 PNMI_STATIC int PnmiVar(
1701 SK_AC *pAC, /* Pointer to adapter context */
1702 SK_IOC IoC, /* IO context handle */
1703 int Action, /* GET/PRESET/SET action */
1704 SK_U32 Id, /* Object ID that is to be processed */
1705 char *pBuf, /* Buffer used for the management data transfer */
1706 unsigned int *pLen, /* Total length of pBuf management data */
1707 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1708 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1710 unsigned int TableIndex;
1714 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1717 return (SK_PNMI_ERR_UNKNOWN_OID);
1720 /* Check NetIndex */
1721 if (NetIndex >= pAC->Rlmt.NumNets) {
1722 return (SK_PNMI_ERR_UNKNOWN_NET);
1725 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1727 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1728 Instance, TableIndex, NetIndex);
1730 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1735 /*****************************************************************************
1737 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1740 * The return value of the function will also be stored in
1741 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1742 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1743 * checks which OIDs are able to set, and calls the handler function of
1744 * the OID to perform the set. The return value of the function will
1745 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1746 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1747 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1750 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1751 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1753 PNMI_STATIC int PnmiStruct(
1754 SK_AC *pAC, /* Pointer to adapter context */
1755 SK_IOC IoC, /* IO context handle */
1756 int Action, /* PRESET/SET action to be performed */
1757 char *pBuf, /* Buffer used for the management data transfer */
1758 unsigned int *pLen, /* Length of pBuf management data buffer */
1759 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1762 unsigned int TableIndex;
1763 unsigned int DstOffset;
1765 unsigned int InstanceNo;
1766 unsigned int InstanceCnt;
1771 /* Check if the passed buffer has the right size */
1772 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1774 /* Check if we can return the error within the buffer */
1775 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1777 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1781 *pLen = SK_PNMI_STRUCT_SIZE;
1782 return (SK_PNMI_ERR_TOO_SHORT);
1785 /* Check NetIndex */
1786 if (NetIndex >= pAC->Rlmt.NumNets) {
1787 return (SK_PNMI_ERR_UNKNOWN_NET);
1790 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1793 * Update the values of RLMT and SIRQ and increment semaphores to
1794 * indicate that an update was already done.
1796 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1798 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1799 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1803 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1805 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1806 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1810 pAC->Pnmi.RlmtUpdatedFlag ++;
1811 pAC->Pnmi.SirqUpdatedFlag ++;
1813 /* Preset/Set values */
1814 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1816 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1817 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1822 InstanceNo = IdTable[TableIndex].InstanceNo;
1823 Id = IdTable[TableIndex].Id;
1825 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1828 DstOffset = IdTable[TableIndex].Offset +
1830 IdTable[TableIndex].StructSize;
1833 * Because VPD multiple instance variables are
1834 * not setable we do not need to evaluate VPD
1835 * instances. Have a look to VPD instance
1836 * calculation in SkPnmiGetStruct().
1838 Instance = (SK_U32)InstanceCnt;
1841 * Evaluate needed buffer length
1844 Ret = IdTable[TableIndex].Func(pAC, IoC,
1845 SK_PNMI_GET, IdTable[TableIndex].Id,
1846 NULL, &Len, Instance, TableIndex, NetIndex);
1848 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1852 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1854 pAC->Pnmi.RlmtUpdatedFlag --;
1855 pAC->Pnmi.SirqUpdatedFlag --;
1857 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1858 SK_PNMI_SET_STAT(pBuf,
1859 SK_PNMI_ERR_GENERAL, DstOffset);
1860 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1861 return (SK_PNMI_ERR_GENERAL);
1863 if (Id == OID_SKGE_VPD_ACTION) {
1865 switch (*(pBuf + DstOffset)) {
1867 case SK_PNMI_VPD_CREATE:
1868 Len = 3 + *(pBuf + DstOffset + 3);
1871 case SK_PNMI_VPD_DELETE:
1881 /* Call the OID handler function */
1882 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1883 IdTable[TableIndex].Id, pBuf + DstOffset,
1884 &Len, Instance, TableIndex, NetIndex);
1886 if (Ret != SK_PNMI_ERR_OK) {
1888 pAC->Pnmi.RlmtUpdatedFlag --;
1889 pAC->Pnmi.SirqUpdatedFlag --;
1891 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1892 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1894 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1895 return (SK_PNMI_ERR_BAD_VALUE);
1900 pAC->Pnmi.RlmtUpdatedFlag --;
1901 pAC->Pnmi.SirqUpdatedFlag --;
1903 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1904 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1905 return (SK_PNMI_ERR_OK);
1908 /*****************************************************************************
1910 * LookupId - Lookup an OID in the IdTable
1913 * Scans the IdTable to find the table entry of an OID.
1916 * The table index or -1 if not found.
1918 PNMI_STATIC int LookupId(
1919 SK_U32 Id) /* Object identifier to be searched */
1923 for (i = 0; i < ID_TABLE_SIZE; i++) {
1925 if (IdTable[i].Id == Id) {
1934 /*****************************************************************************
1936 * OidStruct - Handler of OID_SKGE_ALL_DATA
1939 * This OID performs a Get/Preset/SetStruct call and returns all data
1940 * in a SK_PNMI_STRUCT_DATA structure.
1943 * SK_PNMI_ERR_OK The request was successfully performed.
1944 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1945 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1946 * the correct data (e.g. a 32bit value is
1947 * needed, but a 16 bit value was passed).
1948 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1950 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1951 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1952 * exist (e.g. port instance 3 on a two port
1955 PNMI_STATIC int OidStruct(
1956 SK_AC *pAC, /* Pointer to adapter context */
1957 SK_IOC IoC, /* IO context handle */
1958 int Action, /* GET/PRESET/SET action */
1959 SK_U32 Id, /* Object ID that is to be processed */
1960 char *pBuf, /* Buffer used for the management data transfer */
1961 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1962 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1963 unsigned int TableIndex, /* Index to the Id table */
1964 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1966 if (Id != OID_SKGE_ALL_DATA) {
1968 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1972 return (SK_PNMI_ERR_GENERAL);
1976 * Check instance. We only handle single instance variables
1978 if (Instance != (SK_U32)(-1) && Instance != 1) {
1981 return (SK_PNMI_ERR_UNKNOWN_INST);
1987 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1989 case SK_PNMI_PRESET:
1990 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1993 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1996 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1999 return (SK_PNMI_ERR_GENERAL);
2002 /*****************************************************************************
2004 * Perform - OID handler of OID_SKGE_ACTION
2010 * SK_PNMI_ERR_OK The request was successfully performed.
2011 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2012 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2013 * the correct data (e.g. a 32bit value is
2014 * needed, but a 16 bit value was passed).
2015 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2017 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2018 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2019 * exist (e.g. port instance 3 on a two port
2022 PNMI_STATIC int Perform(
2023 SK_AC *pAC, /* Pointer to adapter context */
2024 SK_IOC IoC, /* IO context handle */
2025 int Action, /* GET/PRESET/SET action */
2026 SK_U32 Id, /* Object ID that is to be processed */
2027 char *pBuf, /* Buffer used for the management data transfer */
2028 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2029 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2030 unsigned int TableIndex, /* Index to the Id table */
2031 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2038 * Check instance. We only handle single instance variables
2040 if (Instance != (SK_U32)(-1) && Instance != 1) {
2043 return (SK_PNMI_ERR_UNKNOWN_INST);
2046 if (*pLen < sizeof(SK_U32)) {
2048 *pLen = sizeof(SK_U32);
2049 return (SK_PNMI_ERR_TOO_SHORT);
2052 /* Check if a get should be performed */
2053 if (Action == SK_PNMI_GET) {
2055 /* A get is easy. We always return the same value */
2056 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2057 SK_PNMI_STORE_U32(pBuf, ActionOp);
2058 *pLen = sizeof(SK_U32);
2060 return (SK_PNMI_ERR_OK);
2063 /* Continue with PRESET/SET action */
2064 if (*pLen > sizeof(SK_U32)) {
2066 return (SK_PNMI_ERR_BAD_VALUE);
2069 /* Check if the command is a known one */
2070 SK_PNMI_READ_U32(pBuf, ActionOp);
2071 if (*pLen > sizeof(SK_U32) ||
2072 (ActionOp != SK_PNMI_ACT_IDLE &&
2073 ActionOp != SK_PNMI_ACT_RESET &&
2074 ActionOp != SK_PNMI_ACT_SELFTEST &&
2075 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2078 return (SK_PNMI_ERR_BAD_VALUE);
2081 /* A preset ends here */
2082 if (Action == SK_PNMI_PRESET) {
2084 return (SK_PNMI_ERR_OK);
2089 case SK_PNMI_ACT_IDLE:
2093 case SK_PNMI_ACT_RESET:
2095 * Perform a driver reset or something that comes near
2098 Ret = SK_DRIVER_RESET(pAC, IoC);
2101 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2104 return (SK_PNMI_ERR_GENERAL);
2108 case SK_PNMI_ACT_SELFTEST:
2110 * Perform a driver selftest or something similar to this.
2111 * Currently this feature is not used and will probably
2112 * implemented in another way.
2114 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2115 pAC->Pnmi.TestResult = Ret;
2118 case SK_PNMI_ACT_RESETCNT:
2119 /* Set all counters and timestamps to zero */
2120 ResetCounter(pAC, IoC, NetIndex);
2124 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2127 return (SK_PNMI_ERR_GENERAL);
2130 return (SK_PNMI_ERR_OK);
2133 /*****************************************************************************
2135 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2138 * Retrieves the statistic values of the virtual port (logical
2139 * index 0). Only special OIDs of NDIS are handled which consist
2140 * of a 32 bit instead of a 64 bit value. The OIDs are public
2141 * because perhaps some other platform can use them too.
2144 * SK_PNMI_ERR_OK The request was successfully performed.
2145 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2146 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2147 * the correct data (e.g. a 32bit value is
2148 * needed, but a 16 bit value was passed).
2149 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2150 * exist (e.g. port instance 3 on a two port
2153 PNMI_STATIC int Mac8023Stat(
2154 SK_AC *pAC, /* Pointer to adapter context */
2155 SK_IOC IoC, /* IO context handle */
2156 int Action, /* GET/PRESET/SET action */
2157 SK_U32 Id, /* Object ID that is to be processed */
2158 char *pBuf, /* Buffer used for the management data transfer */
2159 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2160 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2161 unsigned int TableIndex, /* Index to the Id table */
2162 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2167 SK_BOOL Is64BitReq = SK_FALSE;
2170 * Only the active Mac is returned
2172 if (Instance != (SK_U32)(-1) && Instance != 1) {
2175 return (SK_PNMI_ERR_UNKNOWN_INST);
2181 if (Action != SK_PNMI_GET) {
2184 return (SK_PNMI_ERR_READ_ONLY);
2190 case OID_802_3_PERMANENT_ADDRESS:
2191 case OID_802_3_CURRENT_ADDRESS:
2192 if (*pLen < sizeof(SK_MAC_ADDR)) {
2194 *pLen = sizeof(SK_MAC_ADDR);
2195 return (SK_PNMI_ERR_TOO_SHORT);
2200 #ifndef SK_NDIS_64BIT_CTR
2201 if (*pLen < sizeof(SK_U32)) {
2202 *pLen = sizeof(SK_U32);
2203 return (SK_PNMI_ERR_TOO_SHORT);
2206 #else /* SK_NDIS_64BIT_CTR */
2208 /* for compatibility, at least 32bit are required for OID */
2209 if (*pLen < sizeof(SK_U32)) {
2211 * but indicate handling for 64bit values,
2212 * if insufficient space is provided
2214 *pLen = sizeof(SK_U64);
2215 return (SK_PNMI_ERR_TOO_SHORT);
2218 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2219 #endif /* SK_NDIS_64BIT_CTR */
2224 * Update all statistics, because we retrieve virtual MAC, which
2225 * consists of multiple physical statistics and increment semaphore
2226 * to indicate that an update was already done.
2228 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2229 if ( Ret != SK_PNMI_ERR_OK) {
2234 pAC->Pnmi.MacUpdatedFlag ++;
2237 * Get value (MAC Index 0 identifies the virtual MAC)
2241 case OID_802_3_PERMANENT_ADDRESS:
2242 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2243 *pLen = sizeof(SK_MAC_ADDR);
2246 case OID_802_3_CURRENT_ADDRESS:
2247 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2248 *pLen = sizeof(SK_MAC_ADDR);
2252 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2254 /* by default 32bit values are evaluated */
2256 StatVal32 = (SK_U32)StatVal;
2257 SK_PNMI_STORE_U32(pBuf, StatVal32);
2258 *pLen = sizeof(SK_U32);
2261 SK_PNMI_STORE_U64(pBuf, StatVal);
2262 *pLen = sizeof(SK_U64);
2267 pAC->Pnmi.MacUpdatedFlag --;
2269 return (SK_PNMI_ERR_OK);
2272 /*****************************************************************************
2274 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2277 * Retrieves the MAC statistic data.
2280 * SK_PNMI_ERR_OK The request was successfully performed.
2281 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2282 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2283 * the correct data (e.g. a 32bit value is
2284 * needed, but a 16 bit value was passed).
2285 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2286 * exist (e.g. port instance 3 on a two port
2289 PNMI_STATIC int MacPrivateStat(
2290 SK_AC *pAC, /* Pointer to adapter context */
2291 SK_IOC IoC, /* IO context handle */
2292 int Action, /* GET/PRESET/SET action */
2293 SK_U32 Id, /* Object ID that is to be processed */
2294 char *pBuf, /* Buffer used for the management data transfer */
2295 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2296 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2297 unsigned int TableIndex, /* Index to the Id table */
2298 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2300 unsigned int LogPortMax;
2301 unsigned int LogPortIndex;
2302 unsigned int PhysPortMax;
2304 unsigned int Offset;
2311 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2312 PhysPortMax = pAC->GIni.GIMacsFound;
2313 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2315 MacType = pAC->GIni.GIMacType;
2317 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2321 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2322 /* Check instance range */
2323 if ((Instance < 1) || (Instance > LogPortMax)) {
2326 return (SK_PNMI_ERR_UNKNOWN_INST);
2328 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2329 Limit = LogPortIndex + 1;
2332 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2339 if (Action != SK_PNMI_GET) {
2342 return (SK_PNMI_ERR_READ_ONLY);
2346 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2348 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2349 return (SK_PNMI_ERR_TOO_SHORT);
2353 * Update MAC statistic and increment semaphore to indicate that
2354 * an update was already done.
2356 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2357 if (Ret != SK_PNMI_ERR_OK) {
2362 pAC->Pnmi.MacUpdatedFlag ++;
2366 for (; LogPortIndex < Limit; LogPortIndex ++) {
2370 /* XXX not yet implemented due to XMAC problems
2371 case OID_SKGE_STAT_TX_UTIL:
2372 return (SK_PNMI_ERR_GENERAL);
2374 /* XXX not yet implemented due to XMAC problems
2375 case OID_SKGE_STAT_RX_UTIL:
2376 return (SK_PNMI_ERR_GENERAL);
2378 case OID_SKGE_STAT_RX:
2379 if (MacType == SK_MAC_GMAC) {
2381 GetStatVal(pAC, IoC, LogPortIndex,
2382 SK_PNMI_HRX_BROADCAST, NetIndex) +
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HRX_MULTICAST, NetIndex) +
2385 GetStatVal(pAC, IoC, LogPortIndex,
2386 SK_PNMI_HRX_UNICAST, NetIndex) +
2387 GetStatVal(pAC, IoC, LogPortIndex,
2388 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2391 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2392 IdTable[TableIndex].Param, NetIndex);
2396 case OID_SKGE_STAT_TX:
2397 if (MacType == SK_MAC_GMAC) {
2399 GetStatVal(pAC, IoC, LogPortIndex,
2400 SK_PNMI_HTX_BROADCAST, NetIndex) +
2401 GetStatVal(pAC, IoC, LogPortIndex,
2402 SK_PNMI_HTX_MULTICAST, NetIndex) +
2403 GetStatVal(pAC, IoC, LogPortIndex,
2404 SK_PNMI_HTX_UNICAST, NetIndex);
2407 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2408 IdTable[TableIndex].Param, NetIndex);
2413 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2414 IdTable[TableIndex].Param, NetIndex);
2416 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2418 Offset += sizeof(SK_U64);
2422 pAC->Pnmi.MacUpdatedFlag --;
2424 return (SK_PNMI_ERR_OK);
2427 /*****************************************************************************
2429 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2432 * Get/Presets/Sets the current and factory MAC address. The MAC
2433 * address of the virtual port, which is reported to the OS, may
2434 * not be changed, but the physical ones. A set to the virtual port
2435 * will be ignored. No error should be reported because otherwise
2436 * a multiple instance set (-1) would always fail.
2439 * SK_PNMI_ERR_OK The request was successfully performed.
2440 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2441 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2442 * the correct data (e.g. a 32bit value is
2443 * needed, but a 16 bit value was passed).
2444 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2446 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2447 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2448 * exist (e.g. port instance 3 on a two port
2451 PNMI_STATIC int Addr(
2452 SK_AC *pAC, /* Pointer to adapter context */
2453 SK_IOC IoC, /* IO context handle */
2454 int Action, /* GET/PRESET/SET action */
2455 SK_U32 Id, /* Object ID that is to be processed */
2456 char *pBuf, /* Buffer used for the management data transfer */
2457 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2458 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2459 unsigned int TableIndex, /* Index to the Id table */
2460 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2463 unsigned int LogPortMax;
2464 unsigned int PhysPortMax;
2465 unsigned int LogPortIndex;
2466 unsigned int PhysPortIndex;
2468 unsigned int Offset = 0;
2471 * Calculate instance if wished. MAC index 0 is the virtual
2474 PhysPortMax = pAC->GIni.GIMacsFound;
2475 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2477 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2481 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2482 /* Check instance range */
2483 if ((Instance < 1) || (Instance > LogPortMax)) {
2486 return (SK_PNMI_ERR_UNKNOWN_INST);
2488 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2489 Limit = LogPortIndex + 1;
2491 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2500 if (Action == SK_PNMI_GET) {
2503 if (*pLen < (Limit - LogPortIndex) * 6) {
2505 *pLen = (Limit - LogPortIndex) * 6;
2506 return (SK_PNMI_ERR_TOO_SHORT);
2512 for (; LogPortIndex < Limit; LogPortIndex ++) {
2516 case OID_SKGE_PHYS_CUR_ADDR:
2517 if (LogPortIndex == 0) {
2518 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2521 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2523 CopyMac(pBuf + Offset,
2524 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2529 case OID_SKGE_PHYS_FAC_ADDR:
2530 if (LogPortIndex == 0) {
2531 CopyMac(pBuf + Offset,
2532 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2535 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2538 CopyMac(pBuf + Offset,
2539 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2545 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2549 return (SK_PNMI_ERR_GENERAL);
2557 * The logical MAC address may not be changed only
2560 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2563 return (SK_PNMI_ERR_READ_ONLY);
2567 * Only the current address may be changed
2569 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2571 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2575 return (SK_PNMI_ERR_GENERAL);
2579 if (*pLen < (Limit - LogPortIndex) * 6) {
2581 *pLen = (Limit - LogPortIndex) * 6;
2582 return (SK_PNMI_ERR_TOO_SHORT);
2584 if (*pLen > (Limit - LogPortIndex) * 6) {
2587 return (SK_PNMI_ERR_BAD_VALUE);
2593 if (Action == SK_PNMI_PRESET) {
2596 return (SK_PNMI_ERR_OK);
2600 * Set OID_SKGE_MAC_CUR_ADDR
2602 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2605 * A set to virtual port and set of broadcast
2606 * address will be ignored
2608 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2609 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2614 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2617 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2618 (SK_MAC_ADDR *)(pBuf + Offset),
2619 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2620 SK_ADDR_PHYSICAL_ADDRESS));
2621 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2623 return (SK_PNMI_ERR_GENERAL);
2629 return (SK_PNMI_ERR_OK);
2632 /*****************************************************************************
2634 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2637 * Retrieves the statistic values of the CSUM module. The CSUM data
2638 * structure must be available in the SK_AC even if the CSUM module
2639 * is not included, because PNMI reads the statistic data from the
2640 * CSUM part of SK_AC directly.
2643 * SK_PNMI_ERR_OK The request was successfully performed.
2644 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2645 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2646 * the correct data (e.g. a 32bit value is
2647 * needed, but a 16 bit value was passed).
2648 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2649 * exist (e.g. port instance 3 on a two port
2652 PNMI_STATIC int CsumStat(
2653 SK_AC *pAC, /* Pointer to adapter context */
2654 SK_IOC IoC, /* IO context handle */
2655 int Action, /* GET/PRESET/SET action */
2656 SK_U32 Id, /* Object ID that is to be processed */
2657 char *pBuf, /* Buffer used for the management data transfer */
2658 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2659 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2660 unsigned int TableIndex, /* Index to the Id table */
2661 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2665 unsigned int Offset = 0;
2670 * Calculate instance if wished
2672 if (Instance != (SK_U32)(-1)) {
2674 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2677 return (SK_PNMI_ERR_UNKNOWN_INST);
2679 Index = (unsigned int)Instance - 1;
2684 Limit = SKCS_NUM_PROTOCOLS;
2690 if (Action != SK_PNMI_GET) {
2693 return (SK_PNMI_ERR_READ_ONLY);
2697 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2699 *pLen = (Limit - Index) * sizeof(SK_U64);
2700 return (SK_PNMI_ERR_TOO_SHORT);
2706 for (; Index < Limit; Index ++) {
2710 case OID_SKGE_CHKSM_RX_OK_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2714 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2715 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2718 case OID_SKGE_CHKSM_RX_ERR_CTS:
2719 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2722 case OID_SKGE_CHKSM_TX_OK_CTS:
2723 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2726 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2727 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2731 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2735 return (SK_PNMI_ERR_GENERAL);
2738 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2739 Offset += sizeof(SK_U64);
2743 * Store used buffer space
2747 return (SK_PNMI_ERR_OK);
2750 /*****************************************************************************
2752 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2755 * Retrieves the statistic values of the I2C module, which handles
2756 * the temperature and voltage sensors.
2759 * SK_PNMI_ERR_OK The request was successfully performed.
2760 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2761 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2762 * the correct data (e.g. a 32bit value is
2763 * needed, but a 16 bit value was passed).
2764 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2765 * exist (e.g. port instance 3 on a two port
2768 PNMI_STATIC int SensorStat(
2769 SK_AC *pAC, /* Pointer to adapter context */
2770 SK_IOC IoC, /* IO context handle */
2771 int Action, /* GET/PRESET/SET action */
2772 SK_U32 Id, /* Object ID that is to be processed */
2773 char *pBuf, /* Buffer used for the management data transfer */
2774 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2775 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2776 unsigned int TableIndex, /* Index to the Id table */
2777 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2782 unsigned int Offset;
2789 * Calculate instance if wished
2791 if ((Instance != (SK_U32)(-1))) {
2793 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2796 return (SK_PNMI_ERR_UNKNOWN_INST);
2799 Index = (unsigned int)Instance -1;
2800 Limit = (unsigned int)Instance;
2804 Limit = (unsigned int) pAC->I2c.MaxSens;
2810 if (Action != SK_PNMI_GET) {
2813 return (SK_PNMI_ERR_READ_ONLY);
2819 case OID_SKGE_SENSOR_VALUE:
2820 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2821 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2822 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2823 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2824 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2826 *pLen = (Limit - Index) * sizeof(SK_U32);
2827 return (SK_PNMI_ERR_TOO_SHORT);
2831 case OID_SKGE_SENSOR_DESCR:
2832 for (Offset = 0, i = Index; i < Limit; i ++) {
2834 Len = (unsigned int)
2835 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2836 if (Len >= SK_PNMI_STRINGLEN2) {
2838 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2842 return (SK_PNMI_ERR_GENERAL);
2846 if (*pLen < Offset) {
2849 return (SK_PNMI_ERR_TOO_SHORT);
2853 case OID_SKGE_SENSOR_INDEX:
2854 case OID_SKGE_SENSOR_TYPE:
2855 case OID_SKGE_SENSOR_STATUS:
2856 if (*pLen < Limit - Index) {
2858 *pLen = Limit - Index;
2859 return (SK_PNMI_ERR_TOO_SHORT);
2863 case OID_SKGE_SENSOR_WAR_CTS:
2864 case OID_SKGE_SENSOR_WAR_TIME:
2865 case OID_SKGE_SENSOR_ERR_CTS:
2866 case OID_SKGE_SENSOR_ERR_TIME:
2867 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2869 *pLen = (Limit - Index) * sizeof(SK_U64);
2870 return (SK_PNMI_ERR_TOO_SHORT);
2875 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2879 return (SK_PNMI_ERR_GENERAL);
2886 for (Offset = 0; Index < Limit; Index ++) {
2890 case OID_SKGE_SENSOR_INDEX:
2891 *(pBuf + Offset) = (char)Index;
2892 Offset += sizeof(char);
2895 case OID_SKGE_SENSOR_DESCR:
2896 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2897 SK_MEMCPY(pBuf + Offset + 1,
2898 pAC->I2c.SenTable[Index].SenDesc, Len);
2899 *(pBuf + Offset) = (char)Len;
2903 case OID_SKGE_SENSOR_TYPE:
2905 (char)pAC->I2c.SenTable[Index].SenType;
2906 Offset += sizeof(char);
2909 case OID_SKGE_SENSOR_VALUE:
2910 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2911 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2912 Offset += sizeof(SK_U32);
2915 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2916 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2918 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2919 Offset += sizeof(SK_U32);
2922 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2923 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2925 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2926 Offset += sizeof(SK_U32);
2929 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2930 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2932 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2933 Offset += sizeof(SK_U32);
2936 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2937 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2938 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2939 Offset += sizeof(SK_U32);
2942 case OID_SKGE_SENSOR_STATUS:
2944 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2945 Offset += sizeof(char);
2948 case OID_SKGE_SENSOR_WAR_CTS:
2949 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2950 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2951 Offset += sizeof(SK_U64);
2954 case OID_SKGE_SENSOR_ERR_CTS:
2955 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2956 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2957 Offset += sizeof(SK_U64);
2960 case OID_SKGE_SENSOR_WAR_TIME:
2961 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2963 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2964 Offset += sizeof(SK_U64);
2967 case OID_SKGE_SENSOR_ERR_TIME:
2968 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2970 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2971 Offset += sizeof(SK_U64);
2975 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2976 ("SensorStat: Unknown OID should be handled before"));
2978 return (SK_PNMI_ERR_GENERAL);
2983 * Store used buffer space
2987 return (SK_PNMI_ERR_OK);
2990 /*****************************************************************************
2992 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2995 * Get/preset/set of VPD data. As instance the name of a VPD key
2996 * can be passed. The Instance parameter is a SK_U32 and can be
2997 * used as a string buffer for the VPD key, because their maximum
3001 * SK_PNMI_ERR_OK The request was successfully performed.
3002 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3003 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3004 * the correct data (e.g. a 32bit value is
3005 * needed, but a 16 bit value was passed).
3006 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3008 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3009 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3010 * exist (e.g. port instance 3 on a two port
3013 PNMI_STATIC int Vpd(
3014 SK_AC *pAC, /* Pointer to adapter context */
3015 SK_IOC IoC, /* IO context handle */
3016 int Action, /* GET/PRESET/SET action */
3017 SK_U32 Id, /* Object ID that is to be processed */
3018 char *pBuf, /* Buffer used for the management data transfer */
3019 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3020 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3021 unsigned int TableIndex, /* Index to the Id table */
3022 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3024 SK_VPD_STATUS *pVpdStatus;
3025 unsigned int BufLen;
3027 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3028 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3030 unsigned int Offset;
3032 unsigned int FirstIndex;
3033 unsigned int LastIndex;
3039 * Get array of all currently stored VPD keys
3041 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3042 if (Ret != SK_PNMI_ERR_OK) {
3048 * If instance is not -1, try to find the requested VPD key for
3049 * the multiple instance variables. The other OIDs as for example
3050 * OID VPD_ACTION are single instance variables and must be
3051 * handled separatly.
3056 if ((Instance != (SK_U32)(-1))) {
3058 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3059 Id == OID_SKGE_VPD_ACCESS) {
3061 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3064 for (Index = 0; Index < KeyNo; Index ++) {
3066 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3068 LastIndex = Index+1;
3072 if (Index == KeyNo) {
3075 return (SK_PNMI_ERR_UNKNOWN_INST);
3078 else if (Instance != 1) {
3081 return (SK_PNMI_ERR_UNKNOWN_INST);
3086 * Get value, if a query should be performed
3088 if (Action == SK_PNMI_GET) {
3092 case OID_SKGE_VPD_FREE_BYTES:
3093 /* Check length of buffer */
3094 if (*pLen < sizeof(SK_U32)) {
3096 *pLen = sizeof(SK_U32);
3097 return (SK_PNMI_ERR_TOO_SHORT);
3099 /* Get number of free bytes */
3100 pVpdStatus = VpdStat(pAC, IoC);
3101 if (pVpdStatus == NULL) {
3103 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3107 return (SK_PNMI_ERR_GENERAL);
3109 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3111 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3115 return (SK_PNMI_ERR_GENERAL);
3118 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3119 SK_PNMI_STORE_U32(pBuf, Val32);
3120 *pLen = sizeof(SK_U32);
3123 case OID_SKGE_VPD_ENTRIES_LIST:
3125 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3127 Len += SK_STRLEN(KeyArr[Index]) + 1;
3132 return (SK_PNMI_ERR_TOO_SHORT);
3136 *(pBuf) = (char)Len - 1;
3137 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3139 Len = SK_STRLEN(KeyArr[Index]);
3140 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3144 if (Index < KeyNo - 1) {
3146 *(pBuf + Offset) = ' ';
3153 case OID_SKGE_VPD_ENTRIES_NUMBER:
3155 if (*pLen < sizeof(SK_U32)) {
3157 *pLen = sizeof(SK_U32);
3158 return (SK_PNMI_ERR_TOO_SHORT);
3161 Val32 = (SK_U32)KeyNo;
3162 SK_PNMI_STORE_U32(pBuf, Val32);
3163 *pLen = sizeof(SK_U32);
3166 case OID_SKGE_VPD_KEY:
3167 /* Check buffer length, if it is large enough */
3168 for (Len = 0, Index = FirstIndex;
3169 Index < LastIndex; Index ++) {
3171 Len += SK_STRLEN(KeyArr[Index]) + 1;
3176 return (SK_PNMI_ERR_TOO_SHORT);
3180 * Get the key to an intermediate buffer, because
3181 * we have to prepend a length byte.
3183 for (Offset = 0, Index = FirstIndex;
3184 Index < LastIndex; Index ++) {
3186 Len = SK_STRLEN(KeyArr[Index]);
3188 *(pBuf + Offset) = (char)Len;
3189 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3196 case OID_SKGE_VPD_VALUE:
3197 /* Check the buffer length if it is large enough */
3198 for (Offset = 0, Index = FirstIndex;
3199 Index < LastIndex; Index ++) {
3202 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3203 (int *)&BufLen) > 0 ||
3204 BufLen >= SK_PNMI_VPD_DATALEN) {
3206 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3210 return (SK_PNMI_ERR_GENERAL);
3212 Offset += BufLen + 1;
3214 if (*pLen < Offset) {
3217 return (SK_PNMI_ERR_TOO_SHORT);
3221 * Get the value to an intermediate buffer, because
3222 * we have to prepend a length byte.
3224 for (Offset = 0, Index = FirstIndex;
3225 Index < LastIndex; Index ++) {
3228 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3229 (int *)&BufLen) > 0 ||
3230 BufLen >= SK_PNMI_VPD_DATALEN) {
3232 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3237 return (SK_PNMI_ERR_GENERAL);
3240 *(pBuf + Offset) = (char)BufLen;
3241 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3242 Offset += BufLen + 1;
3247 case OID_SKGE_VPD_ACCESS:
3248 if (*pLen < LastIndex - FirstIndex) {
3250 *pLen = LastIndex - FirstIndex;
3251 return (SK_PNMI_ERR_TOO_SHORT);
3254 for (Offset = 0, Index = FirstIndex;
3255 Index < LastIndex; Index ++) {
3257 if (VpdMayWrite(KeyArr[Index])) {
3259 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3262 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3269 case OID_SKGE_VPD_ACTION:
3270 Offset = LastIndex - FirstIndex;
3271 if (*pLen < Offset) {
3274 return (SK_PNMI_ERR_TOO_SHORT);
3276 SK_MEMSET(pBuf, 0, Offset);
3281 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3285 return (SK_PNMI_ERR_GENERAL);
3289 /* The only OID which can be set is VPD_ACTION */
3290 if (Id != OID_SKGE_VPD_ACTION) {
3292 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3293 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3294 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3295 Id == OID_SKGE_VPD_KEY ||
3296 Id == OID_SKGE_VPD_VALUE ||
3297 Id == OID_SKGE_VPD_ACCESS) {
3300 return (SK_PNMI_ERR_READ_ONLY);
3303 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3307 return (SK_PNMI_ERR_GENERAL);
3311 * From this point we handle VPD_ACTION. Check the buffer
3312 * length. It should at least have the size of one byte.
3317 return (SK_PNMI_ERR_TOO_SHORT);
3321 * The first byte contains the VPD action type we should
3326 case SK_PNMI_VPD_IGNORE:
3330 case SK_PNMI_VPD_CREATE:
3332 * We have to create a new VPD entry or we modify
3333 * an existing one. Check first the buffer length.
3338 return (SK_PNMI_ERR_TOO_SHORT);
3340 KeyStr[0] = pBuf[1];
3341 KeyStr[1] = pBuf[2];
3345 * Is the entry writable or does it belong to the
3348 if (!VpdMayWrite(KeyStr)) {
3351 return (SK_PNMI_ERR_BAD_VALUE);
3354 Offset = (int)pBuf[3] & 0xFF;
3356 SK_MEMCPY(Buf, pBuf + 4, Offset);
3359 /* A preset ends here */
3360 if (Action == SK_PNMI_PRESET) {
3362 return (SK_PNMI_ERR_OK);
3365 /* Write the new entry or modify an existing one */
3366 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3367 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3370 return (SK_PNMI_ERR_BAD_VALUE);
3372 else if (Ret != SK_PNMI_VPD_OK) {
3374 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3378 return (SK_PNMI_ERR_GENERAL);
3382 * Perform an update of the VPD data. This is
3383 * not mandantory, but just to be sure.
3385 Ret = VpdUpdate(pAC, IoC);
3386 if (Ret != SK_PNMI_VPD_OK) {
3388 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3392 return (SK_PNMI_ERR_GENERAL);
3396 case SK_PNMI_VPD_DELETE:
3397 /* Check if the buffer size is plausible */
3401 return (SK_PNMI_ERR_TOO_SHORT);
3406 return (SK_PNMI_ERR_BAD_VALUE);
3408 KeyStr[0] = pBuf[1];
3409 KeyStr[1] = pBuf[2];
3412 /* Find the passed key in the array */
3413 for (Index = 0; Index < KeyNo; Index ++) {
3415 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3421 * If we cannot find the key it is wrong, so we
3422 * return an appropriate error value.
3424 if (Index == KeyNo) {
3427 return (SK_PNMI_ERR_BAD_VALUE);
3430 if (Action == SK_PNMI_PRESET) {
3432 return (SK_PNMI_ERR_OK);
3435 /* Ok, you wanted it and you will get it */
3436 Ret = VpdDelete(pAC, IoC, KeyStr);
3437 if (Ret != SK_PNMI_VPD_OK) {
3439 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3443 return (SK_PNMI_ERR_GENERAL);
3447 * Perform an update of the VPD data. This is
3448 * not mandantory, but just to be sure.
3450 Ret = VpdUpdate(pAC, IoC);
3451 if (Ret != SK_PNMI_VPD_OK) {
3453 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3457 return (SK_PNMI_ERR_GENERAL);
3463 return (SK_PNMI_ERR_BAD_VALUE);
3467 return (SK_PNMI_ERR_OK);
3470 /*****************************************************************************
3472 * General - OID handler function of various single instance OIDs
3475 * The code is simple. No description necessary.
3478 * SK_PNMI_ERR_OK The request was successfully performed.
3479 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3480 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3481 * the correct data (e.g. a 32bit value is
3482 * needed, but a 16 bit value was passed).
3483 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3484 * exist (e.g. port instance 3 on a two port
3487 PNMI_STATIC int General(
3488 SK_AC *pAC, /* Pointer to adapter context */
3489 SK_IOC IoC, /* IO context handle */
3490 int Action, /* GET/PRESET/SET action */
3491 SK_U32 Id, /* Object ID that is to be processed */
3492 char *pBuf, /* Buffer used for the management data transfer */
3493 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3494 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3495 unsigned int TableIndex, /* Index to the Id table */
3496 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3501 unsigned int Offset;
3507 SK_U64 Val64RxHwErrs = 0;
3508 SK_U64 Val64TxHwErrs = 0;
3509 SK_BOOL Is64BitReq = SK_FALSE;
3514 * Check instance. We only handle single instance variables.
3516 if (Instance != (SK_U32)(-1) && Instance != 1) {
3519 return (SK_PNMI_ERR_UNKNOWN_INST);
3523 * Check action. We only allow get requests.
3525 if (Action != SK_PNMI_GET) {
3528 return (SK_PNMI_ERR_READ_ONLY);
3531 MacType = pAC->GIni.GIMacType;
3534 * Check length for the various supported OIDs
3538 case OID_GEN_XMIT_ERROR:
3539 case OID_GEN_RCV_ERROR:
3540 case OID_GEN_RCV_NO_BUFFER:
3541 #ifndef SK_NDIS_64BIT_CTR
3542 if (*pLen < sizeof(SK_U32)) {
3543 *pLen = sizeof(SK_U32);
3544 return (SK_PNMI_ERR_TOO_SHORT);
3547 #else /* SK_NDIS_64BIT_CTR */
3550 * for compatibility, at least 32bit are required for oid
3552 if (*pLen < sizeof(SK_U32)) {
3554 * but indicate handling for 64bit values,
3555 * if insufficient space is provided
3557 *pLen = sizeof(SK_U64);
3558 return (SK_PNMI_ERR_TOO_SHORT);
3561 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3562 #endif /* SK_NDIS_64BIT_CTR */
3565 case OID_SKGE_PORT_NUMBER:
3566 case OID_SKGE_DEVICE_TYPE:
3567 case OID_SKGE_RESULT:
3568 case OID_SKGE_RLMT_MONITOR_NUMBER:
3569 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3570 case OID_SKGE_TRAP_NUMBER:
3571 case OID_SKGE_MDB_VERSION:
3572 case OID_SKGE_BOARDLEVEL:
3573 case OID_SKGE_CHIPID:
3574 case OID_SKGE_RAMSIZE:
3575 if (*pLen < sizeof(SK_U32)) {
3577 *pLen = sizeof(SK_U32);
3578 return (SK_PNMI_ERR_TOO_SHORT);
3582 case OID_SKGE_CHIPSET:
3583 if (*pLen < sizeof(SK_U16)) {
3585 *pLen = sizeof(SK_U16);
3586 return (SK_PNMI_ERR_TOO_SHORT);
3590 case OID_SKGE_BUS_TYPE:
3591 case OID_SKGE_BUS_SPEED:
3592 case OID_SKGE_BUS_WIDTH:
3593 case OID_SKGE_SENSOR_NUMBER:
3594 case OID_SKGE_CHKSM_NUMBER:
3595 case OID_SKGE_VAUXAVAIL:
3596 if (*pLen < sizeof(SK_U8)) {
3598 *pLen = sizeof(SK_U8);
3599 return (SK_PNMI_ERR_TOO_SHORT);
3603 case OID_SKGE_TX_SW_QUEUE_LEN:
3604 case OID_SKGE_TX_SW_QUEUE_MAX:
3605 case OID_SKGE_TX_RETRY:
3606 case OID_SKGE_RX_INTR_CTS:
3607 case OID_SKGE_TX_INTR_CTS:
3608 case OID_SKGE_RX_NO_BUF_CTS:
3609 case OID_SKGE_TX_NO_BUF_CTS:
3610 case OID_SKGE_TX_USED_DESCR_NO:
3611 case OID_SKGE_RX_DELIVERED_CTS:
3612 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3613 case OID_SKGE_RX_HW_ERROR_CTS:
3614 case OID_SKGE_TX_HW_ERROR_CTS:
3615 case OID_SKGE_IN_ERRORS_CTS:
3616 case OID_SKGE_OUT_ERROR_CTS:
3617 case OID_SKGE_ERR_RECOVERY_CTS:
3618 case OID_SKGE_SYSUPTIME:
3619 if (*pLen < sizeof(SK_U64)) {
3621 *pLen = sizeof(SK_U64);
3622 return (SK_PNMI_ERR_TOO_SHORT);
3631 /* Update statistic */
3632 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3633 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3634 Id == OID_SKGE_IN_ERRORS_CTS ||
3635 Id == OID_SKGE_OUT_ERROR_CTS ||
3636 Id == OID_GEN_XMIT_ERROR ||
3637 Id == OID_GEN_RCV_ERROR) {
3639 /* Force the XMAC to update its statistic counters and
3640 * Increment semaphore to indicate that an update was
3643 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3644 if (Ret != SK_PNMI_ERR_OK) {
3649 pAC->Pnmi.MacUpdatedFlag ++;
3652 * Some OIDs consist of multiple hardware counters. Those
3653 * values which are contained in all of them will be added
3658 case OID_SKGE_RX_HW_ERROR_CTS:
3659 case OID_SKGE_IN_ERRORS_CTS:
3660 case OID_GEN_RCV_ERROR:
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3670 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3671 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3672 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3673 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3676 case OID_SKGE_TX_HW_ERROR_CTS:
3677 case OID_SKGE_OUT_ERROR_CTS:
3678 case OID_GEN_XMIT_ERROR:
3680 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3681 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3682 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3683 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3693 case OID_SKGE_SUPPORTED_LIST:
3694 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3698 return (SK_PNMI_ERR_TOO_SHORT);
3700 for (Offset = 0, Index = 0; Offset < Len;
3701 Offset += sizeof(SK_U32), Index ++) {
3703 Val32 = (SK_U32)IdTable[Index].Id;
3704 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3709 case OID_SKGE_BOARDLEVEL:
3710 Val32 = (SK_U32)pAC->GIni.GILevel;
3711 SK_PNMI_STORE_U32(pBuf, Val32);
3712 *pLen = sizeof(SK_U32);
3715 case OID_SKGE_PORT_NUMBER:
3716 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3717 SK_PNMI_STORE_U32(pBuf, Val32);
3718 *pLen = sizeof(SK_U32);
3721 case OID_SKGE_DEVICE_TYPE:
3722 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3723 SK_PNMI_STORE_U32(pBuf, Val32);
3724 *pLen = sizeof(SK_U32);
3727 case OID_SKGE_DRIVER_DESCR:
3728 if (pAC->Pnmi.pDriverDescription == NULL) {
3730 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3734 return (SK_PNMI_ERR_GENERAL);
3737 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3738 if (Len > SK_PNMI_STRINGLEN1) {
3740 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3744 return (SK_PNMI_ERR_GENERAL);
3750 return (SK_PNMI_ERR_TOO_SHORT);
3752 *pBuf = (char)(Len - 1);
3753 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3757 case OID_SKGE_DRIVER_VERSION:
3758 if (pAC->Pnmi.pDriverVersion == NULL) {
3760 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3764 return (SK_PNMI_ERR_GENERAL);
3767 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3768 if (Len > SK_PNMI_STRINGLEN1) {
3770 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3774 return (SK_PNMI_ERR_GENERAL);
3780 return (SK_PNMI_ERR_TOO_SHORT);
3782 *pBuf = (char)(Len - 1);
3783 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3787 case OID_SKGE_DRIVER_RELDATE:
3788 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3790 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3794 return (SK_PNMI_ERR_GENERAL);
3797 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3798 if (Len > SK_PNMI_STRINGLEN1) {
3800 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3804 return (SK_PNMI_ERR_GENERAL);
3810 return (SK_PNMI_ERR_TOO_SHORT);
3812 *pBuf = (char)(Len - 1);
3813 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3817 case OID_SKGE_DRIVER_FILENAME:
3818 if (pAC->Pnmi.pDriverFileName == NULL) {
3820 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3824 return (SK_PNMI_ERR_GENERAL);
3827 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3828 if (Len > SK_PNMI_STRINGLEN1) {
3830 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3834 return (SK_PNMI_ERR_GENERAL);
3840 return (SK_PNMI_ERR_TOO_SHORT);
3842 *pBuf = (char)(Len - 1);
3843 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3847 case OID_SKGE_HW_DESCR:
3849 * The hardware description is located in the VPD. This
3850 * query may move to the initialisation routine. But
3851 * the VPD data is cached and therefore a call here
3852 * will not make much difference.
3855 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3857 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3861 return (SK_PNMI_ERR_GENERAL);
3864 if (Len > SK_PNMI_STRINGLEN1) {
3866 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3870 return (SK_PNMI_ERR_GENERAL);
3875 return (SK_PNMI_ERR_TOO_SHORT);
3877 *pBuf = (char)(Len - 1);
3878 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3882 case OID_SKGE_HW_VERSION:
3883 /* Oh, I love to do some string manipulation */
3887 return (SK_PNMI_ERR_TOO_SHORT);
3889 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3892 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3894 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3898 case OID_SKGE_CHIPSET:
3899 Val16 = pAC->Pnmi.Chipset;
3900 SK_PNMI_STORE_U16(pBuf, Val16);
3901 *pLen = sizeof(SK_U16);
3904 case OID_SKGE_CHIPID:
3905 Val32 = pAC->GIni.GIChipId;
3906 SK_PNMI_STORE_U32(pBuf, Val32);
3907 *pLen = sizeof(SK_U32);
3910 case OID_SKGE_RAMSIZE:
3911 Val32 = pAC->GIni.GIRamSize;
3912 SK_PNMI_STORE_U32(pBuf, Val32);
3913 *pLen = sizeof(SK_U32);
3916 case OID_SKGE_VAUXAVAIL:
3917 *pBuf = (char) pAC->GIni.GIVauxAvail;
3918 *pLen = sizeof(char);
3921 case OID_SKGE_BUS_TYPE:
3922 *pBuf = (char) SK_PNMI_BUS_PCI;
3923 *pLen = sizeof(char);
3926 case OID_SKGE_BUS_SPEED:
3927 *pBuf = pAC->Pnmi.PciBusSpeed;
3928 *pLen = sizeof(char);
3931 case OID_SKGE_BUS_WIDTH:
3932 *pBuf = pAC->Pnmi.PciBusWidth;
3933 *pLen = sizeof(char);
3936 case OID_SKGE_RESULT:
3937 Val32 = pAC->Pnmi.TestResult;
3938 SK_PNMI_STORE_U32(pBuf, Val32);
3939 *pLen = sizeof(SK_U32);
3942 case OID_SKGE_SENSOR_NUMBER:
3943 *pBuf = (char)pAC->I2c.MaxSens;
3944 *pLen = sizeof(char);
3947 case OID_SKGE_CHKSM_NUMBER:
3948 *pBuf = SKCS_NUM_PROTOCOLS;
3949 *pLen = sizeof(char);
3952 case OID_SKGE_TRAP_NUMBER:
3953 GetTrapQueueLen(pAC, &Len, &Val);
3954 Val32 = (SK_U32)Val;
3955 SK_PNMI_STORE_U32(pBuf, Val32);
3956 *pLen = sizeof(SK_U32);
3960 GetTrapQueueLen(pAC, &Len, &Val);
3964 return (SK_PNMI_ERR_TOO_SHORT);
3966 CopyTrapQueue(pAC, pBuf);
3970 case OID_SKGE_RLMT_MONITOR_NUMBER:
3971 /* XXX Not yet implemented by RLMT therefore we return zero elements */
3973 SK_PNMI_STORE_U32(pBuf, Val32);
3974 *pLen = sizeof(SK_U32);
3977 case OID_SKGE_TX_SW_QUEUE_LEN:
3978 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3979 if (MacType == SK_MAC_XMAC) {
3981 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3982 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3984 /* Single net mode */
3986 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3987 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3992 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3993 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3995 /* Single net mode */
3997 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3998 pAC->Pnmi.Port[1].TxSwQueueLen;
4001 SK_PNMI_STORE_U64(pBuf, Val64);
4002 *pLen = sizeof(SK_U64);
4006 case OID_SKGE_TX_SW_QUEUE_MAX:
4007 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4008 if (MacType == SK_MAC_XMAC) {
4010 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4011 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4013 /* Single net mode */
4015 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4016 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4021 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4022 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4024 /* Single net mode */
4026 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4027 pAC->Pnmi.Port[1].TxSwQueueMax;
4030 SK_PNMI_STORE_U64(pBuf, Val64);
4031 *pLen = sizeof(SK_U64);
4034 case OID_SKGE_TX_RETRY:
4035 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4036 if (MacType == SK_MAC_XMAC) {
4038 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4039 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4041 /* Single net mode */
4043 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4044 pAC->Pnmi.BufPort[1].TxRetryCts;
4049 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4050 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4052 /* Single net mode */
4054 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4055 pAC->Pnmi.Port[1].TxRetryCts;
4058 SK_PNMI_STORE_U64(pBuf, Val64);
4059 *pLen = sizeof(SK_U64);
4062 case OID_SKGE_RX_INTR_CTS:
4063 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4064 if (MacType == SK_MAC_XMAC) {
4066 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4067 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4069 /* Single net mode */
4071 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4072 pAC->Pnmi.BufPort[1].RxIntrCts;
4077 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4078 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4080 /* Single net mode */
4082 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4083 pAC->Pnmi.Port[1].RxIntrCts;
4086 SK_PNMI_STORE_U64(pBuf, Val64);
4087 *pLen = sizeof(SK_U64);
4090 case OID_SKGE_TX_INTR_CTS:
4091 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4092 if (MacType == SK_MAC_XMAC) {
4094 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4095 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4097 /* Single net mode */
4099 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4100 pAC->Pnmi.BufPort[1].TxIntrCts;
4105 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4106 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4108 /* Single net mode */
4110 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4111 pAC->Pnmi.Port[1].TxIntrCts;
4114 SK_PNMI_STORE_U64(pBuf, Val64);
4115 *pLen = sizeof(SK_U64);
4118 case OID_SKGE_RX_NO_BUF_CTS:
4119 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4120 if (MacType == SK_MAC_XMAC) {
4122 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4123 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4125 /* Single net mode */
4127 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4128 pAC->Pnmi.BufPort[1].RxNoBufCts;
4133 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4134 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4136 /* Single net mode */
4138 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4139 pAC->Pnmi.Port[1].RxNoBufCts;
4142 SK_PNMI_STORE_U64(pBuf, Val64);
4143 *pLen = sizeof(SK_U64);
4146 case OID_SKGE_TX_NO_BUF_CTS:
4147 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4148 if (MacType == SK_MAC_XMAC) {
4150 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4151 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4153 /* Single net mode */
4155 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4156 pAC->Pnmi.BufPort[1].TxNoBufCts;
4161 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4162 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4164 /* Single net mode */
4166 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4167 pAC->Pnmi.Port[1].TxNoBufCts;
4170 SK_PNMI_STORE_U64(pBuf, Val64);
4171 *pLen = sizeof(SK_U64);
4174 case OID_SKGE_TX_USED_DESCR_NO:
4175 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4176 if (MacType == SK_MAC_XMAC) {
4178 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4179 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4181 /* Single net mode */
4183 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4184 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4189 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4190 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4192 /* Single net mode */
4194 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4195 pAC->Pnmi.Port[1].TxUsedDescrNo;
4198 SK_PNMI_STORE_U64(pBuf, Val64);
4199 *pLen = sizeof(SK_U64);
4202 case OID_SKGE_RX_DELIVERED_CTS:
4203 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4204 if (MacType == SK_MAC_XMAC) {
4206 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4207 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4209 /* Single net mode */
4211 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4212 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4217 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4218 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4220 /* Single net mode */
4222 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4223 pAC->Pnmi.Port[1].RxDeliveredCts;
4226 SK_PNMI_STORE_U64(pBuf, Val64);
4227 *pLen = sizeof(SK_U64);
4230 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4231 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4232 if (MacType == SK_MAC_XMAC) {
4234 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4235 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4237 /* Single net mode */
4239 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4240 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4245 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4246 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4248 /* Single net mode */
4250 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4251 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4254 SK_PNMI_STORE_U64(pBuf, Val64);
4255 *pLen = sizeof(SK_U64);
4258 case OID_SKGE_RX_HW_ERROR_CTS:
4259 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4260 *pLen = sizeof(SK_U64);
4263 case OID_SKGE_TX_HW_ERROR_CTS:
4264 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4265 *pLen = sizeof(SK_U64);
4268 case OID_SKGE_IN_ERRORS_CTS:
4269 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4270 if (MacType == SK_MAC_XMAC) {
4272 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4273 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4275 /* Single net mode */
4277 Val64 = Val64RxHwErrs +
4278 pAC->Pnmi.BufPort[0].RxNoBufCts +
4279 pAC->Pnmi.BufPort[1].RxNoBufCts;
4284 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4285 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4287 /* Single net mode */
4289 Val64 = Val64RxHwErrs +
4290 pAC->Pnmi.Port[0].RxNoBufCts +
4291 pAC->Pnmi.Port[1].RxNoBufCts;
4294 SK_PNMI_STORE_U64(pBuf, Val64);
4295 *pLen = sizeof(SK_U64);
4298 case OID_SKGE_OUT_ERROR_CTS:
4299 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4300 if (MacType == SK_MAC_XMAC) {
4302 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4303 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4305 /* Single net mode */
4307 Val64 = Val64TxHwErrs +
4308 pAC->Pnmi.BufPort[0].TxNoBufCts +
4309 pAC->Pnmi.BufPort[1].TxNoBufCts;
4314 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4315 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4317 /* Single net mode */
4319 Val64 = Val64TxHwErrs +
4320 pAC->Pnmi.Port[0].TxNoBufCts +
4321 pAC->Pnmi.Port[1].TxNoBufCts;
4324 SK_PNMI_STORE_U64(pBuf, Val64);
4325 *pLen = sizeof(SK_U64);
4328 case OID_SKGE_ERR_RECOVERY_CTS:
4329 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4330 if (MacType == SK_MAC_XMAC) {
4332 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4333 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4335 /* Single net mode */
4337 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4338 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4343 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4344 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4346 /* Single net mode */
4348 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4349 pAC->Pnmi.Port[1].ErrRecoveryCts;
4352 SK_PNMI_STORE_U64(pBuf, Val64);
4353 *pLen = sizeof(SK_U64);
4356 case OID_SKGE_SYSUPTIME:
4357 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4358 Val64 -= pAC->Pnmi.StartUpTime;
4359 SK_PNMI_STORE_U64(pBuf, Val64);
4360 *pLen = sizeof(SK_U64);
4363 case OID_SKGE_MDB_VERSION:
4364 Val32 = SK_PNMI_MDB_VERSION;
4365 SK_PNMI_STORE_U32(pBuf, Val32);
4366 *pLen = sizeof(SK_U32);
4369 case OID_GEN_RCV_ERROR:
4370 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4371 if (MacType == SK_MAC_XMAC) {
4372 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4375 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4379 * by default 32bit values are evaluated
4382 Val32 = (SK_U32)Val64;
4383 SK_PNMI_STORE_U32(pBuf, Val32);
4384 *pLen = sizeof(SK_U32);
4387 SK_PNMI_STORE_U64(pBuf, Val64);
4388 *pLen = sizeof(SK_U64);
4392 case OID_GEN_XMIT_ERROR:
4393 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4394 if (MacType == SK_MAC_XMAC) {
4395 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4398 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4402 * by default 32bit values are evaluated
4405 Val32 = (SK_U32)Val64;
4406 SK_PNMI_STORE_U32(pBuf, Val32);
4407 *pLen = sizeof(SK_U32);
4410 SK_PNMI_STORE_U64(pBuf, Val64);
4411 *pLen = sizeof(SK_U64);
4415 case OID_GEN_RCV_NO_BUFFER:
4416 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4417 if (MacType == SK_MAC_XMAC) {
4418 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4421 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4425 * by default 32bit values are evaluated
4428 Val32 = (SK_U32)Val64;
4429 SK_PNMI_STORE_U32(pBuf, Val32);
4430 *pLen = sizeof(SK_U32);
4433 SK_PNMI_STORE_U64(pBuf, Val64);
4434 *pLen = sizeof(SK_U64);
4438 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4439 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4440 SK_PNMI_STORE_U32(pBuf, Val32);
4441 *pLen = sizeof(SK_U32);
4445 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4449 return (SK_PNMI_ERR_GENERAL);
4452 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4453 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4454 Id == OID_SKGE_IN_ERRORS_CTS ||
4455 Id == OID_SKGE_OUT_ERROR_CTS ||
4456 Id == OID_GEN_XMIT_ERROR ||
4457 Id == OID_GEN_RCV_ERROR) {
4459 pAC->Pnmi.MacUpdatedFlag --;
4462 return (SK_PNMI_ERR_OK);
4465 /*****************************************************************************
4467 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4470 * Get/Presets/Sets the RLMT OIDs.
4473 * SK_PNMI_ERR_OK The request was successfully performed.
4474 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4475 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4476 * the correct data (e.g. a 32bit value is
4477 * needed, but a 16 bit value was passed).
4478 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4480 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4481 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4482 * exist (e.g. port instance 3 on a two port
4485 PNMI_STATIC int Rlmt(
4486 SK_AC *pAC, /* Pointer to adapter context */
4487 SK_IOC IoC, /* IO context handle */
4488 int Action, /* GET/PRESET/SET action */
4489 SK_U32 Id, /* Object ID that is to be processed */
4490 char *pBuf, /* Buffer used for the management data transfer */
4491 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4492 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4493 unsigned int TableIndex, /* Index to the Id table */
4494 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4497 unsigned int PhysPortIndex;
4498 unsigned int PhysPortMax;
4499 SK_EVPARA EventParam;
4505 * Check instance. Only single instance OIDs are allowed here.
4507 if (Instance != (SK_U32)(-1) && Instance != 1) {
4510 return (SK_PNMI_ERR_UNKNOWN_INST);
4514 * Perform the requested action.
4516 if (Action == SK_PNMI_GET) {
4519 * Check if the buffer length is large enough.
4524 case OID_SKGE_RLMT_MODE:
4525 case OID_SKGE_RLMT_PORT_ACTIVE:
4526 case OID_SKGE_RLMT_PORT_PREFERRED:
4527 if (*pLen < sizeof(SK_U8)) {
4529 *pLen = sizeof(SK_U8);
4530 return (SK_PNMI_ERR_TOO_SHORT);
4534 case OID_SKGE_RLMT_PORT_NUMBER:
4535 if (*pLen < sizeof(SK_U32)) {
4537 *pLen = sizeof(SK_U32);
4538 return (SK_PNMI_ERR_TOO_SHORT);
4542 case OID_SKGE_RLMT_CHANGE_CTS:
4543 case OID_SKGE_RLMT_CHANGE_TIME:
4544 case OID_SKGE_RLMT_CHANGE_ESTIM:
4545 case OID_SKGE_RLMT_CHANGE_THRES:
4546 if (*pLen < sizeof(SK_U64)) {
4548 *pLen = sizeof(SK_U64);
4549 return (SK_PNMI_ERR_TOO_SHORT);
4554 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4558 return (SK_PNMI_ERR_GENERAL);
4562 * Update RLMT statistic and increment semaphores to indicate
4563 * that an update was already done. Maybe RLMT will hold its
4564 * statistic always up to date some time. Then we can
4565 * remove this type of call.
4567 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4572 pAC->Pnmi.RlmtUpdatedFlag ++;
4579 case OID_SKGE_RLMT_MODE:
4580 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4581 *pLen = sizeof(char);
4584 case OID_SKGE_RLMT_PORT_NUMBER:
4585 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4586 SK_PNMI_STORE_U32(pBuf, Val32);
4587 *pLen = sizeof(SK_U32);
4590 case OID_SKGE_RLMT_PORT_ACTIVE:
4593 * If multiple ports may become active this OID
4594 * doesn't make sense any more. A new variable in
4595 * the port structure should be created. However,
4596 * for this variable the first active port is
4599 PhysPortMax = pAC->GIni.GIMacsFound;
4601 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4604 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4606 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4610 *pLen = sizeof(char);
4613 case OID_SKGE_RLMT_PORT_PREFERRED:
4614 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4615 *pLen = sizeof(char);
4618 case OID_SKGE_RLMT_CHANGE_CTS:
4619 Val64 = pAC->Pnmi.RlmtChangeCts;
4620 SK_PNMI_STORE_U64(pBuf, Val64);
4621 *pLen = sizeof(SK_U64);
4624 case OID_SKGE_RLMT_CHANGE_TIME:
4625 Val64 = pAC->Pnmi.RlmtChangeTime;
4626 SK_PNMI_STORE_U64(pBuf, Val64);
4627 *pLen = sizeof(SK_U64);
4630 case OID_SKGE_RLMT_CHANGE_ESTIM:
4631 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4632 SK_PNMI_STORE_U64(pBuf, Val64);
4633 *pLen = sizeof(SK_U64);
4636 case OID_SKGE_RLMT_CHANGE_THRES:
4637 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4638 SK_PNMI_STORE_U64(pBuf, Val64);
4639 *pLen = sizeof(SK_U64);
4643 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4644 ("Rlmt: Unknown OID should be handled before"));
4646 pAC->Pnmi.RlmtUpdatedFlag --;
4648 return (SK_PNMI_ERR_GENERAL);
4651 pAC->Pnmi.RlmtUpdatedFlag --;
4654 /* Perform a preset or set */
4657 case OID_SKGE_RLMT_MODE:
4658 /* Check if the buffer length is plausible */
4659 if (*pLen < sizeof(char)) {
4661 *pLen = sizeof(char);
4662 return (SK_PNMI_ERR_TOO_SHORT);
4664 /* Check if the value range is correct */
4665 if (*pLen != sizeof(char) ||
4666 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4667 *(SK_U8 *)pBuf > 15) {
4670 return (SK_PNMI_ERR_BAD_VALUE);
4672 /* The preset ends here */
4673 if (Action == SK_PNMI_PRESET) {
4676 return (SK_PNMI_ERR_OK);
4678 /* Send an event to RLMT to change the mode */
4679 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4680 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4681 EventParam.Para32[1] = 0;
4682 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4685 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4689 return (SK_PNMI_ERR_GENERAL);
4693 case OID_SKGE_RLMT_PORT_PREFERRED:
4694 /* Check if the buffer length is plausible */
4695 if (*pLen < sizeof(char)) {
4697 *pLen = sizeof(char);
4698 return (SK_PNMI_ERR_TOO_SHORT);
4700 /* Check if the value range is correct */
4701 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4702 (SK_U8)pAC->GIni.GIMacsFound) {
4705 return (SK_PNMI_ERR_BAD_VALUE);
4707 /* The preset ends here */
4708 if (Action == SK_PNMI_PRESET) {
4711 return (SK_PNMI_ERR_OK);
4715 * Send an event to RLMT change the preferred port.
4716 * A param of -1 means automatic mode. RLMT will
4717 * make the decision which is the preferred port.
4719 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4720 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4721 EventParam.Para32[1] = NetIndex;
4722 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4725 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4729 return (SK_PNMI_ERR_GENERAL);
4733 case OID_SKGE_RLMT_CHANGE_THRES:
4734 /* Check if the buffer length is plausible */
4735 if (*pLen < sizeof(SK_U64)) {
4737 *pLen = sizeof(SK_U64);
4738 return (SK_PNMI_ERR_TOO_SHORT);
4741 * There are not many restrictions to the
4744 if (*pLen != sizeof(SK_U64)) {
4747 return (SK_PNMI_ERR_BAD_VALUE);
4749 /* A preset ends here */
4750 if (Action == SK_PNMI_PRESET) {
4753 return (SK_PNMI_ERR_OK);
4756 * Store the new threshold, which will be taken
4757 * on the next timer event.
4759 SK_PNMI_READ_U64(pBuf, Val64);
4760 pAC->Pnmi.RlmtChangeThreshold = Val64;
4764 /* The other OIDs are not be able for set */
4766 return (SK_PNMI_ERR_READ_ONLY);
4770 return (SK_PNMI_ERR_OK);
4773 /*****************************************************************************
4775 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4778 * Performs get requests on multiple instance variables.
4781 * SK_PNMI_ERR_OK The request was successfully performed.
4782 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4783 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4784 * the correct data (e.g. a 32bit value is
4785 * needed, but a 16 bit value was passed).
4786 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4787 * exist (e.g. port instance 3 on a two port
4790 PNMI_STATIC int RlmtStat(
4791 SK_AC *pAC, /* Pointer to adapter context */
4792 SK_IOC IoC, /* IO context handle */
4793 int Action, /* GET/PRESET/SET action */
4794 SK_U32 Id, /* Object ID that is to be processed */
4795 char *pBuf, /* Buffer used for the management data transfer */
4796 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4797 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4798 unsigned int TableIndex, /* Index to the Id table */
4799 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4801 unsigned int PhysPortMax;
4802 unsigned int PhysPortIndex;
4804 unsigned int Offset;
4810 * Calculate the port indexes from the instance.
4812 PhysPortMax = pAC->GIni.GIMacsFound;
4814 if ((Instance != (SK_U32)(-1))) {
4815 /* Check instance range */
4816 if ((Instance < 1) || (Instance > PhysPortMax)) {
4819 return (SK_PNMI_ERR_UNKNOWN_INST);
4822 /* Single net mode */
4823 PhysPortIndex = Instance - 1;
4826 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4827 PhysPortIndex = NetIndex;
4830 /* Both net modes */
4831 Limit = PhysPortIndex + 1;
4834 /* Single net mode */
4836 Limit = PhysPortMax;
4839 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4840 PhysPortIndex = NetIndex;
4841 Limit = PhysPortIndex + 1;
4846 * Currently only get requests are allowed.
4848 if (Action != SK_PNMI_GET) {
4851 return (SK_PNMI_ERR_READ_ONLY);
4855 * Check if the buffer length is large enough.
4859 case OID_SKGE_RLMT_PORT_INDEX:
4860 case OID_SKGE_RLMT_STATUS:
4861 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4863 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4864 return (SK_PNMI_ERR_TOO_SHORT);
4868 case OID_SKGE_RLMT_TX_HELLO_CTS:
4869 case OID_SKGE_RLMT_RX_HELLO_CTS:
4870 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4871 case OID_SKGE_RLMT_RX_SP_CTS:
4872 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4874 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4875 return (SK_PNMI_ERR_TOO_SHORT);
4880 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4884 return (SK_PNMI_ERR_GENERAL);
4889 * Update statistic and increment semaphores to indicate that
4890 * an update was already done.
4892 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4897 pAC->Pnmi.RlmtUpdatedFlag ++;
4903 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4907 case OID_SKGE_RLMT_PORT_INDEX:
4908 Val32 = PhysPortIndex;
4909 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4910 Offset += sizeof(SK_U32);
4913 case OID_SKGE_RLMT_STATUS:
4914 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4916 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4919 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4921 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4923 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4926 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4928 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4929 Offset += sizeof(SK_U32);
4932 case OID_SKGE_RLMT_TX_HELLO_CTS:
4933 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4934 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4935 Offset += sizeof(SK_U64);
4938 case OID_SKGE_RLMT_RX_HELLO_CTS:
4939 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4940 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4941 Offset += sizeof(SK_U64);
4944 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4945 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4946 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4947 Offset += sizeof(SK_U64);
4950 case OID_SKGE_RLMT_RX_SP_CTS:
4951 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4952 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4953 Offset += sizeof(SK_U64);
4957 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4958 ("RlmtStat: Unknown OID should be errored before"));
4960 pAC->Pnmi.RlmtUpdatedFlag --;
4962 return (SK_PNMI_ERR_GENERAL);
4967 pAC->Pnmi.RlmtUpdatedFlag --;
4969 return (SK_PNMI_ERR_OK);
4972 /*****************************************************************************
4974 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4977 * Get/Presets/Sets the OIDs concerning the configuration.
4980 * SK_PNMI_ERR_OK The request was successfully performed.
4981 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4982 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4983 * the correct data (e.g. a 32bit value is
4984 * needed, but a 16 bit value was passed).
4985 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4987 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4988 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4989 * exist (e.g. port instance 3 on a two port
4992 PNMI_STATIC int MacPrivateConf(
4993 SK_AC *pAC, /* Pointer to adapter context */
4994 SK_IOC IoC, /* IO context handle */
4995 int Action, /* GET/PRESET/SET action */
4996 SK_U32 Id, /* Object ID that is to be processed */
4997 char *pBuf, /* Buffer used for the management data transfer */
4998 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4999 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5000 unsigned int TableIndex, /* Index to the Id table */
5001 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5003 unsigned int PhysPortMax;
5004 unsigned int PhysPortIndex;
5005 unsigned int LogPortMax;
5006 unsigned int LogPortIndex;
5008 unsigned int Offset;
5012 SK_EVPARA EventParam;
5016 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5018 PhysPortMax = pAC->GIni.GIMacsFound;
5019 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5021 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5025 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5026 /* Check instance range */
5027 if ((Instance < 1) || (Instance > LogPortMax)) {
5030 return (SK_PNMI_ERR_UNKNOWN_INST);
5032 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5033 Limit = LogPortIndex + 1;
5036 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5045 if (Action == SK_PNMI_GET) {
5051 case OID_SKGE_CONNECTOR:
5052 case OID_SKGE_LINK_CAP:
5053 case OID_SKGE_LINK_MODE:
5054 case OID_SKGE_LINK_MODE_STATUS:
5055 case OID_SKGE_LINK_STATUS:
5056 case OID_SKGE_FLOWCTRL_CAP:
5057 case OID_SKGE_FLOWCTRL_MODE:
5058 case OID_SKGE_FLOWCTRL_STATUS:
5059 case OID_SKGE_PHY_OPERATION_CAP:
5060 case OID_SKGE_PHY_OPERATION_MODE:
5061 case OID_SKGE_PHY_OPERATION_STATUS:
5062 case OID_SKGE_SPEED_CAP:
5063 case OID_SKGE_SPEED_MODE:
5064 case OID_SKGE_SPEED_STATUS:
5065 #ifdef SK_PHY_LP_MODE
5066 case OID_SKGE_PHY_LP_MODE:
5068 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5070 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5071 return (SK_PNMI_ERR_TOO_SHORT);
5076 case OID_SKGE_PHY_TYPE:
5077 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5079 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5080 return (SK_PNMI_ERR_TOO_SHORT);
5085 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5088 return (SK_PNMI_ERR_GENERAL);
5092 * Update statistic and increment semaphore to indicate
5093 * that an update was already done.
5095 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5100 pAC->Pnmi.SirqUpdatedFlag ++;
5106 for (; LogPortIndex < Limit; LogPortIndex ++) {
5108 pBufPtr = pBuf + Offset;
5113 *pBufPtr = pAC->Pnmi.PMD;
5114 Offset += sizeof(char);
5117 case OID_SKGE_CONNECTOR:
5118 *pBufPtr = pAC->Pnmi.Connector;
5119 Offset += sizeof(char);
5122 case OID_SKGE_PHY_TYPE:
5123 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5124 if (LogPortIndex == 0) {
5128 /* Get value for physical ports */
5129 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5131 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5132 SK_PNMI_STORE_U32(pBufPtr, Val32);
5135 else { /* DualNetMode */
5137 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5138 SK_PNMI_STORE_U32(pBufPtr, Val32);
5140 Offset += sizeof(SK_U32);
5143 #ifdef SK_PHY_LP_MODE
5144 case OID_SKGE_PHY_LP_MODE:
5145 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5146 if (LogPortIndex == 0) {
5150 /* Get value for physical ports */
5151 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5152 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5156 else { /* DualNetMode */
5158 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5161 Offset += sizeof(SK_U8);
5165 case OID_SKGE_LINK_CAP:
5166 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5167 if (LogPortIndex == 0) {
5168 /* Get value for virtual port */
5169 VirtualConf(pAC, IoC, Id, pBufPtr);
5172 /* Get value for physical ports */
5173 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5176 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5179 else { /* DualNetMode */
5181 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5183 Offset += sizeof(char);
5186 case OID_SKGE_LINK_MODE:
5187 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5188 if (LogPortIndex == 0) {
5189 /* Get value for virtual port */
5190 VirtualConf(pAC, IoC, Id, pBufPtr);
5193 /* Get value for physical ports */
5194 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5197 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5200 else { /* DualNetMode */
5202 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5204 Offset += sizeof(char);
5207 case OID_SKGE_LINK_MODE_STATUS:
5208 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5209 if (LogPortIndex == 0) {
5210 /* Get value for virtual port */
5211 VirtualConf(pAC, IoC, Id, pBufPtr);
5214 /* Get value for physical port */
5215 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5219 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5222 else { /* DualNetMode */
5224 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5226 Offset += sizeof(char);
5229 case OID_SKGE_LINK_STATUS:
5230 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5231 if (LogPortIndex == 0) {
5232 /* Get value for virtual port */
5233 VirtualConf(pAC, IoC, Id, pBufPtr);
5236 /* Get value for physical ports */
5237 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5240 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5243 else { /* DualNetMode */
5245 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5247 Offset += sizeof(char);
5250 case OID_SKGE_FLOWCTRL_CAP:
5251 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5252 if (LogPortIndex == 0) {
5253 /* Get value for virtual port */
5254 VirtualConf(pAC, IoC, Id, pBufPtr);
5257 /* Get value for physical ports */
5258 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5261 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5264 else { /* DualNetMode */
5266 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5268 Offset += sizeof(char);
5271 case OID_SKGE_FLOWCTRL_MODE:
5272 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5273 if (LogPortIndex == 0) {
5274 /* Get value for virtual port */
5275 VirtualConf(pAC, IoC, Id, pBufPtr);
5278 /* Get value for physical port */
5279 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5282 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5285 else { /* DualNetMode */
5287 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5289 Offset += sizeof(char);
5292 case OID_SKGE_FLOWCTRL_STATUS:
5293 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5294 if (LogPortIndex == 0) {
5295 /* Get value for virtual port */
5296 VirtualConf(pAC, IoC, Id, pBufPtr);
5299 /* Get value for physical port */
5300 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5303 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5306 else { /* DualNetMode */
5308 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5310 Offset += sizeof(char);
5313 case OID_SKGE_PHY_OPERATION_CAP:
5314 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5315 if (LogPortIndex == 0) {
5316 /* Get value for virtual port */
5317 VirtualConf(pAC, IoC, Id, pBufPtr);
5320 /* Get value for physical ports */
5321 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5324 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5327 else { /* DualNetMode */
5329 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5331 Offset += sizeof(char);
5334 case OID_SKGE_PHY_OPERATION_MODE:
5335 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5336 if (LogPortIndex == 0) {
5337 /* Get value for virtual port */
5338 VirtualConf(pAC, IoC, Id, pBufPtr);
5341 /* Get value for physical port */
5342 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5345 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5348 else { /* DualNetMode */
5350 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5352 Offset += sizeof(char);
5355 case OID_SKGE_PHY_OPERATION_STATUS:
5356 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5357 if (LogPortIndex == 0) {
5358 /* Get value for virtual port */
5359 VirtualConf(pAC, IoC, Id, pBufPtr);
5362 /* Get value for physical port */
5363 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5366 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5371 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5373 Offset += sizeof(char);
5376 case OID_SKGE_SPEED_CAP:
5377 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5378 if (LogPortIndex == 0) {
5379 /* Get value for virtual port */
5380 VirtualConf(pAC, IoC, Id, pBufPtr);
5383 /* Get value for physical ports */
5384 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5387 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5390 else { /* DualNetMode */
5392 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5394 Offset += sizeof(char);
5397 case OID_SKGE_SPEED_MODE:
5398 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5399 if (LogPortIndex == 0) {
5400 /* Get value for virtual port */
5401 VirtualConf(pAC, IoC, Id, pBufPtr);
5404 /* Get value for physical port */
5405 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5408 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5411 else { /* DualNetMode */
5413 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5415 Offset += sizeof(char);
5418 case OID_SKGE_SPEED_STATUS:
5419 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5420 if (LogPortIndex == 0) {
5421 /* Get value for virtual port */
5422 VirtualConf(pAC, IoC, Id, pBufPtr);
5425 /* Get value for physical port */
5426 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5429 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5432 else { /* DualNetMode */
5434 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5436 Offset += sizeof(char);
5440 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5441 SK_PNMI_STORE_U32(pBufPtr, Val32);
5442 Offset += sizeof(SK_U32);
5446 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5447 ("MacPrivateConf: Unknown OID should be handled before"));
5449 pAC->Pnmi.SirqUpdatedFlag --;
5450 return (SK_PNMI_ERR_GENERAL);
5454 pAC->Pnmi.SirqUpdatedFlag --;
5456 return (SK_PNMI_ERR_OK);
5460 * From here SET or PRESET action. Check if the passed
5461 * buffer length is plausible.
5465 case OID_SKGE_LINK_MODE:
5466 case OID_SKGE_FLOWCTRL_MODE:
5467 case OID_SKGE_PHY_OPERATION_MODE:
5468 case OID_SKGE_SPEED_MODE:
5469 if (*pLen < Limit - LogPortIndex) {
5471 *pLen = Limit - LogPortIndex;
5472 return (SK_PNMI_ERR_TOO_SHORT);
5474 if (*pLen != Limit - LogPortIndex) {
5477 return (SK_PNMI_ERR_BAD_VALUE);
5481 #ifdef SK_PHY_LP_MODE
5482 case OID_SKGE_PHY_LP_MODE:
5483 if (*pLen < Limit - LogPortIndex) {
5485 *pLen = Limit - LogPortIndex;
5486 return (SK_PNMI_ERR_TOO_SHORT);
5492 if (*pLen < sizeof(SK_U32)) {
5494 *pLen = sizeof(SK_U32);
5495 return (SK_PNMI_ERR_TOO_SHORT);
5497 if (*pLen != sizeof(SK_U32)) {
5500 return (SK_PNMI_ERR_BAD_VALUE);
5506 return (SK_PNMI_ERR_READ_ONLY);
5510 * Perform preset or set
5513 for (; LogPortIndex < Limit; LogPortIndex ++) {
5517 case OID_SKGE_LINK_MODE:
5518 /* Check the value range */
5519 Val8 = *(pBuf + Offset);
5522 Offset += sizeof(char);
5525 if (Val8 < SK_LMODE_HALF ||
5526 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5527 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5530 return (SK_PNMI_ERR_BAD_VALUE);
5533 /* The preset ends here */
5534 if (Action == SK_PNMI_PRESET) {
5536 return (SK_PNMI_ERR_OK);
5539 if (LogPortIndex == 0) {
5542 * The virtual port consists of all currently
5543 * active ports. Find them and send an event
5544 * with the new link mode to SIRQ.
5546 for (PhysPortIndex = 0;
5547 PhysPortIndex < PhysPortMax;
5550 if (!pAC->Pnmi.Port[PhysPortIndex].
5556 EventParam.Para32[0] = PhysPortIndex;
5557 EventParam.Para32[1] = (SK_U32)Val8;
5558 if (SkGeSirqEvent(pAC, IoC,
5562 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5567 return (SK_PNMI_ERR_GENERAL);
5573 * Send an event with the new link mode to
5576 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5578 EventParam.Para32[1] = (SK_U32)Val8;
5579 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5582 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5587 return (SK_PNMI_ERR_GENERAL);
5590 Offset += sizeof(char);
5593 case OID_SKGE_FLOWCTRL_MODE:
5594 /* Check the value range */
5595 Val8 = *(pBuf + Offset);
5598 Offset += sizeof(char);
5601 if (Val8 < SK_FLOW_MODE_NONE ||
5602 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5603 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5606 return (SK_PNMI_ERR_BAD_VALUE);
5609 /* The preset ends here */
5610 if (Action == SK_PNMI_PRESET) {
5612 return (SK_PNMI_ERR_OK);
5615 if (LogPortIndex == 0) {
5618 * The virtual port consists of all currently
5619 * active ports. Find them and send an event
5620 * with the new flow control mode to SIRQ.
5622 for (PhysPortIndex = 0;
5623 PhysPortIndex < PhysPortMax;
5626 if (!pAC->Pnmi.Port[PhysPortIndex].
5632 EventParam.Para32[0] = PhysPortIndex;
5633 EventParam.Para32[1] = (SK_U32)Val8;
5634 if (SkGeSirqEvent(pAC, IoC,
5635 SK_HWEV_SET_FLOWMODE,
5638 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5643 return (SK_PNMI_ERR_GENERAL);
5649 * Send an event with the new flow control
5650 * mode to the SIRQ module.
5652 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5654 EventParam.Para32[1] = (SK_U32)Val8;
5655 if (SkGeSirqEvent(pAC, IoC,
5656 SK_HWEV_SET_FLOWMODE, EventParam)
5659 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5664 return (SK_PNMI_ERR_GENERAL);
5667 Offset += sizeof(char);
5670 case OID_SKGE_PHY_OPERATION_MODE :
5671 /* Check the value range */
5672 Val8 = *(pBuf + Offset);
5674 /* mode of this port remains unchanged */
5675 Offset += sizeof(char);
5678 if (Val8 < SK_MS_MODE_AUTO ||
5679 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5680 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5683 return (SK_PNMI_ERR_BAD_VALUE);
5686 /* The preset ends here */
5687 if (Action == SK_PNMI_PRESET) {
5689 return (SK_PNMI_ERR_OK);
5692 if (LogPortIndex == 0) {
5695 * The virtual port consists of all currently
5696 * active ports. Find them and send an event
5697 * with new master/slave (role) mode to SIRQ.
5699 for (PhysPortIndex = 0;
5700 PhysPortIndex < PhysPortMax;
5703 if (!pAC->Pnmi.Port[PhysPortIndex].
5709 EventParam.Para32[0] = PhysPortIndex;
5710 EventParam.Para32[1] = (SK_U32)Val8;
5711 if (SkGeSirqEvent(pAC, IoC,
5715 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5720 return (SK_PNMI_ERR_GENERAL);
5726 * Send an event with the new master/slave
5727 * (role) mode to the SIRQ module.
5729 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5731 EventParam.Para32[1] = (SK_U32)Val8;
5732 if (SkGeSirqEvent(pAC, IoC,
5733 SK_HWEV_SET_ROLE, EventParam) > 0) {
5735 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5740 return (SK_PNMI_ERR_GENERAL);
5744 Offset += sizeof(char);
5747 case OID_SKGE_SPEED_MODE:
5748 /* Check the value range */
5749 Val8 = *(pBuf + Offset);
5752 Offset += sizeof(char);
5755 if (Val8 < (SK_LSPEED_AUTO) ||
5756 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5757 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5760 return (SK_PNMI_ERR_BAD_VALUE);
5763 /* The preset ends here */
5764 if (Action == SK_PNMI_PRESET) {
5766 return (SK_PNMI_ERR_OK);
5769 if (LogPortIndex == 0) {
5772 * The virtual port consists of all currently
5773 * active ports. Find them and send an event
5774 * with the new flow control mode to SIRQ.
5776 for (PhysPortIndex = 0;
5777 PhysPortIndex < PhysPortMax;
5780 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5785 EventParam.Para32[0] = PhysPortIndex;
5786 EventParam.Para32[1] = (SK_U32)Val8;
5787 if (SkGeSirqEvent(pAC, IoC,
5791 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5796 return (SK_PNMI_ERR_GENERAL);
5802 * Send an event with the new flow control
5803 * mode to the SIRQ module.
5805 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5807 EventParam.Para32[1] = (SK_U32)Val8;
5808 if (SkGeSirqEvent(pAC, IoC,
5812 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5817 return (SK_PNMI_ERR_GENERAL);
5820 Offset += sizeof(char);
5824 /* Check the value range */
5825 Val32 = *(SK_U32*)(pBuf + Offset);
5827 /* mtu of this port remains unchanged */
5828 Offset += sizeof(SK_U32);
5831 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5833 return (SK_PNMI_ERR_BAD_VALUE);
5836 /* The preset ends here */
5837 if (Action == SK_PNMI_PRESET) {
5838 return (SK_PNMI_ERR_OK);
5841 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5842 return (SK_PNMI_ERR_GENERAL);
5845 Offset += sizeof(SK_U32);
5848 #ifdef SK_PHY_LP_MODE
5849 case OID_SKGE_PHY_LP_MODE:
5850 /* The preset ends here */
5851 if (Action == SK_PNMI_PRESET) {
5853 return (SK_PNMI_ERR_OK);
5856 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5857 if (LogPortIndex == 0) {
5862 /* Set value for physical ports */
5863 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5865 switch (*(pBuf + Offset)) {
5867 /* If LowPowerMode is active, we can leave it. */
5868 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5870 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5872 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5874 SkDrvInitAdapter(pAC);
5880 return (SK_PNMI_ERR_GENERAL);
5886 /* If no LowPowerMode is active, we can enter it. */
5887 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5889 if ((*(pBuf + Offset)) < 3) {
5891 SkDrvDeInitAdapter(pAC);
5894 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5899 return (SK_PNMI_ERR_GENERAL);
5903 return (SK_PNMI_ERR_BAD_VALUE);
5907 else { /* DualNetMode */
5909 switch (*(pBuf + Offset)) {
5911 /* If we are in a LowPowerMode, we can leave it. */
5912 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5914 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5916 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5918 SkDrvInitAdapter(pAC);
5924 return (SK_PNMI_ERR_GENERAL);
5931 /* If we are not already in LowPowerMode, we can enter it. */
5932 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5934 if ((*(pBuf + Offset)) < 3) {
5936 SkDrvDeInitAdapter(pAC);
5940 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5946 return (SK_PNMI_ERR_GENERAL);
5951 return (SK_PNMI_ERR_BAD_VALUE);
5954 Offset += sizeof(SK_U8);
5959 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5960 ("MacPrivateConf: Unknown OID should be handled before set"));
5963 return (SK_PNMI_ERR_GENERAL);
5967 return (SK_PNMI_ERR_OK);
5970 /*****************************************************************************
5972 * Monitor - OID handler function for RLMT_MONITOR_XXX
5975 * Because RLMT currently does not support the monitoring of
5976 * remote adapter cards, we return always an empty table.
5979 * SK_PNMI_ERR_OK The request was successfully performed.
5980 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5981 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5982 * the correct data (e.g. a 32bit value is
5983 * needed, but a 16 bit value was passed).
5984 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5986 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5987 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5988 * exist (e.g. port instance 3 on a two port
5991 PNMI_STATIC int Monitor(
5992 SK_AC *pAC, /* Pointer to adapter context */
5993 SK_IOC IoC, /* IO context handle */
5994 int Action, /* GET/PRESET/SET action */
5995 SK_U32 Id, /* Object ID that is to be processed */
5996 char *pBuf, /* Buffer used for the management data transfer */
5997 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5998 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5999 unsigned int TableIndex, /* Index to the Id table */
6000 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
6004 unsigned int Offset;
6005 unsigned int Entries;
6009 * Calculate instance if wished.
6011 /* XXX Not yet implemented. Return always an empty table. */
6014 if ((Instance != (SK_U32)(-1))) {
6016 if ((Instance < 1) || (Instance > Entries)) {
6019 return (SK_PNMI_ERR_UNKNOWN_INST);
6022 Index = (unsigned int)Instance - 1;
6023 Limit = (unsigned int)Instance;
6033 if (Action == SK_PNMI_GET) {
6035 for (Offset=0; Index < Limit; Index ++) {
6039 case OID_SKGE_RLMT_MONITOR_INDEX:
6040 case OID_SKGE_RLMT_MONITOR_ADDR:
6041 case OID_SKGE_RLMT_MONITOR_ERRS:
6042 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6043 case OID_SKGE_RLMT_MONITOR_ADMIN:
6047 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6051 return (SK_PNMI_ERR_GENERAL);
6057 /* Only MONITOR_ADMIN can be set */
6058 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6061 return (SK_PNMI_ERR_READ_ONLY);
6064 /* Check if the length is plausible */
6065 if (*pLen < (Limit - Index)) {
6067 return (SK_PNMI_ERR_TOO_SHORT);
6069 /* Okay, we have a wide value range */
6070 if (*pLen != (Limit - Index)) {
6073 return (SK_PNMI_ERR_BAD_VALUE);
6076 for (Offset=0; Index < Limit; Index ++) {
6080 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6084 return (SK_PNMI_ERR_BAD_VALUE);
6087 return (SK_PNMI_ERR_OK);
6090 /*****************************************************************************
6092 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6095 * We handle here the get of the configuration group OIDs, which are
6096 * a little bit complicated. The virtual port consists of all currently
6097 * active physical ports. If multiple ports are active and configured
6098 * differently we get in some trouble to return a single value. So we
6099 * get the value of the first active port and compare it with that of
6100 * the other active ports. If they are not the same, we return a value
6101 * that indicates that the state is indeterminated.
6106 PNMI_STATIC void VirtualConf(
6107 SK_AC *pAC, /* Pointer to adapter context */
6108 SK_IOC IoC, /* IO context handle */
6109 SK_U32 Id, /* Object ID that is to be processed */
6110 char *pBuf) /* Buffer used for the management data transfer */
6112 unsigned int PhysPortMax;
6113 unsigned int PhysPortIndex;
6116 SK_BOOL PortActiveFlag;
6120 PortActiveFlag = SK_FALSE;
6121 PhysPortMax = pAC->GIni.GIMacsFound;
6123 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6126 pPrt = &pAC->GIni.GP[PhysPortIndex];
6128 /* Check if the physical port is active */
6129 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6134 PortActiveFlag = SK_TRUE;
6138 case OID_SKGE_PHY_TYPE:
6139 /* Check if it is the first active port */
6141 Val32 = pPrt->PhyType;
6142 SK_PNMI_STORE_U32(pBuf, Val32);
6146 case OID_SKGE_LINK_CAP:
6149 * Different capabilities should not happen, but
6150 * in the case of the cases OR them all together.
6151 * From a curious point of view the virtual port
6152 * is capable of all found capabilities.
6154 *pBuf |= pPrt->PLinkCap;
6157 case OID_SKGE_LINK_MODE:
6158 /* Check if it is the first active port */
6161 *pBuf = pPrt->PLinkModeConf;
6166 * If we find an active port with a different link
6167 * mode than the first one we return a value that
6168 * indicates that the link mode is indeterminated.
6170 if (*pBuf != pPrt->PLinkModeConf) {
6172 *pBuf = SK_LMODE_INDETERMINATED;
6176 case OID_SKGE_LINK_MODE_STATUS:
6177 /* Get the link mode of the physical port */
6178 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6180 /* Check if it is the first active port */
6188 * If we find an active port with a different link
6189 * mode status than the first one we return a value
6190 * that indicates that the link mode status is
6193 if (*pBuf != Val8) {
6195 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6199 case OID_SKGE_LINK_STATUS:
6200 /* Get the link status of the physical port */
6201 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6203 /* Check if it is the first active port */
6211 * If we find an active port with a different link
6212 * status than the first one, we return a value
6213 * that indicates that the link status is
6216 if (*pBuf != Val8) {
6218 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6222 case OID_SKGE_FLOWCTRL_CAP:
6223 /* Check if it is the first active port */
6226 *pBuf = pPrt->PFlowCtrlCap;
6231 * From a curious point of view the virtual port
6232 * is capable of all found capabilities.
6234 *pBuf |= pPrt->PFlowCtrlCap;
6237 case OID_SKGE_FLOWCTRL_MODE:
6238 /* Check if it is the first active port */
6241 *pBuf = pPrt->PFlowCtrlMode;
6246 * If we find an active port with a different flow
6247 * control mode than the first one, we return a value
6248 * that indicates that the mode is indeterminated.
6250 if (*pBuf != pPrt->PFlowCtrlMode) {
6252 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6256 case OID_SKGE_FLOWCTRL_STATUS:
6257 /* Check if it is the first active port */
6260 *pBuf = pPrt->PFlowCtrlStatus;
6265 * If we find an active port with a different flow
6266 * control status than the first one, we return a
6267 * value that indicates that the status is
6270 if (*pBuf != pPrt->PFlowCtrlStatus) {
6272 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6276 case OID_SKGE_PHY_OPERATION_CAP:
6277 /* Check if it is the first active port */
6280 *pBuf = pPrt->PMSCap;
6285 * From a curious point of view the virtual port
6286 * is capable of all found capabilities.
6288 *pBuf |= pPrt->PMSCap;
6291 case OID_SKGE_PHY_OPERATION_MODE:
6292 /* Check if it is the first active port */
6295 *pBuf = pPrt->PMSMode;
6300 * If we find an active port with a different master/
6301 * slave mode than the first one, we return a value
6302 * that indicates that the mode is indeterminated.
6304 if (*pBuf != pPrt->PMSMode) {
6306 *pBuf = SK_MS_MODE_INDETERMINATED;
6310 case OID_SKGE_PHY_OPERATION_STATUS:
6311 /* Check if it is the first active port */
6314 *pBuf = pPrt->PMSStatus;
6319 * If we find an active port with a different master/
6320 * slave status than the first one, we return a
6321 * value that indicates that the status is
6324 if (*pBuf != pPrt->PMSStatus) {
6326 *pBuf = SK_MS_STAT_INDETERMINATED;
6330 case OID_SKGE_SPEED_MODE:
6331 /* Check if it is the first active port */
6334 *pBuf = pPrt->PLinkSpeed;
6339 * If we find an active port with a different flow
6340 * control mode than the first one, we return a value
6341 * that indicates that the mode is indeterminated.
6343 if (*pBuf != pPrt->PLinkSpeed) {
6345 *pBuf = SK_LSPEED_INDETERMINATED;
6349 case OID_SKGE_SPEED_STATUS:
6350 /* Check if it is the first active port */
6353 *pBuf = pPrt->PLinkSpeedUsed;
6358 * If we find an active port with a different flow
6359 * control status than the first one, we return a
6360 * value that indicates that the status is
6363 if (*pBuf != pPrt->PLinkSpeedUsed) {
6365 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6372 * If no port is active return an indeterminated answer
6374 if (!PortActiveFlag) {
6378 case OID_SKGE_LINK_CAP:
6379 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6382 case OID_SKGE_LINK_MODE:
6383 *pBuf = SK_LMODE_INDETERMINATED;
6386 case OID_SKGE_LINK_MODE_STATUS:
6387 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6390 case OID_SKGE_LINK_STATUS:
6391 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6394 case OID_SKGE_FLOWCTRL_CAP:
6395 case OID_SKGE_FLOWCTRL_MODE:
6396 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6399 case OID_SKGE_FLOWCTRL_STATUS:
6400 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6403 case OID_SKGE_PHY_OPERATION_CAP:
6404 *pBuf = SK_MS_CAP_INDETERMINATED;
6407 case OID_SKGE_PHY_OPERATION_MODE:
6408 *pBuf = SK_MS_MODE_INDETERMINATED;
6411 case OID_SKGE_PHY_OPERATION_STATUS:
6412 *pBuf = SK_MS_STAT_INDETERMINATED;
6414 case OID_SKGE_SPEED_CAP:
6415 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6418 case OID_SKGE_SPEED_MODE:
6419 *pBuf = SK_LSPEED_INDETERMINATED;
6422 case OID_SKGE_SPEED_STATUS:
6423 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6429 /*****************************************************************************
6431 * CalculateLinkStatus - Determins the link status of a physical port
6434 * Determins the link status the following way:
6435 * LSTAT_PHY_DOWN: Link is down
6436 * LSTAT_AUTONEG: Auto-negotiation failed
6437 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6439 * LSTAT_LOG_UP: RLMT marked the port as up
6442 * Link status of physical port
6444 PNMI_STATIC SK_U8 CalculateLinkStatus(
6445 SK_AC *pAC, /* Pointer to adapter context */
6446 SK_IOC IoC, /* IO context handle */
6447 unsigned int PhysPortIndex) /* Physical port index */
6451 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6453 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6455 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6457 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6459 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6461 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6464 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6470 /*****************************************************************************
6472 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6475 * The COMMON module only tells us if the mode is half or full duplex.
6476 * But in the decade of auto sensing it is useful for the user to
6477 * know if the mode was negotiated or forced. Therefore we have a
6478 * look to the mode, which was last used by the negotiation process.
6481 * The link mode status
6483 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6484 SK_AC *pAC, /* Pointer to adapter context */
6485 SK_IOC IoC, /* IO context handle */
6486 unsigned int PhysPortIndex) /* Physical port index */
6490 /* Get the current mode, which can be full or half duplex */
6491 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6493 /* Check if no valid mode could be found (link is down) */
6494 if (Result < SK_LMODE_STAT_HALF) {
6496 Result = SK_LMODE_STAT_UNKNOWN;
6498 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6501 * Auto-negotiation was used to bring up the link. Change
6502 * the already found duplex status that it indicates
6503 * auto-negotiation was involved.
6505 if (Result == SK_LMODE_STAT_HALF) {
6507 Result = SK_LMODE_STAT_AUTOHALF;
6509 else if (Result == SK_LMODE_STAT_FULL) {
6511 Result = SK_LMODE_STAT_AUTOFULL;
6518 /*****************************************************************************
6520 * GetVpdKeyArr - Obtain an array of VPD keys
6523 * Read the VPD keys and build an array of VPD keys, which are
6527 * SK_PNMI_ERR_OK Task successfully performed.
6528 * SK_PNMI_ERR_GENERAL Something went wrong.
6530 PNMI_STATIC int GetVpdKeyArr(
6531 SK_AC *pAC, /* Pointer to adapter context */
6532 SK_IOC IoC, /* IO context handle */
6533 char *pKeyArr, /* Ptr KeyArray */
6534 unsigned int KeyArrLen, /* Length of array in bytes */
6535 unsigned int *pKeyNo) /* Number of keys */
6537 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6538 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6539 unsigned int StartOffset;
6540 unsigned int Offset;
6545 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6550 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6554 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6557 return (SK_PNMI_ERR_GENERAL);
6559 /* If no keys are available return now */
6560 if (*pKeyNo == 0 || BufKeysLen == 0) {
6562 return (SK_PNMI_ERR_OK);
6565 * If the key list is too long for us trunc it and give a
6566 * errorlog notification. This case should not happen because
6567 * the maximum number of keys is limited due to RAM limitations
6569 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6571 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6574 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6578 * Now build an array of fixed string length size and copy
6579 * the keys together.
6581 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6584 if (BufKeys[Offset] != 0) {
6589 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6591 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6593 return (SK_PNMI_ERR_GENERAL);
6596 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6597 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6600 StartOffset = Offset + 1;
6603 /* Last key not zero terminated? Get it anyway */
6604 if (StartOffset < Offset) {
6606 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6607 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6610 return (SK_PNMI_ERR_OK);
6613 /*****************************************************************************
6615 * SirqUpdate - Let the SIRQ update its internal values
6618 * Just to be sure that the SIRQ module holds its internal data
6619 * structures up to date, we send an update event before we make
6623 * SK_PNMI_ERR_OK Task successfully performed.
6624 * SK_PNMI_ERR_GENERAL Something went wrong.
6626 PNMI_STATIC int SirqUpdate(
6627 SK_AC *pAC, /* Pointer to adapter context */
6628 SK_IOC IoC) /* IO context handle */
6630 SK_EVPARA EventParam;
6633 /* Was the module already updated during the current PNMI call? */
6634 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6636 return (SK_PNMI_ERR_OK);
6639 /* Send an synchronuous update event to the module */
6640 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6641 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6643 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6646 return (SK_PNMI_ERR_GENERAL);
6649 return (SK_PNMI_ERR_OK);
6652 /*****************************************************************************
6654 * RlmtUpdate - Let the RLMT update its internal values
6657 * Just to be sure that the RLMT module holds its internal data
6658 * structures up to date, we send an update event before we make
6662 * SK_PNMI_ERR_OK Task successfully performed.
6663 * SK_PNMI_ERR_GENERAL Something went wrong.
6665 PNMI_STATIC int RlmtUpdate(
6666 SK_AC *pAC, /* Pointer to adapter context */
6667 SK_IOC IoC, /* IO context handle */
6668 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6670 SK_EVPARA EventParam;
6673 /* Was the module already updated during the current PNMI call? */
6674 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6676 return (SK_PNMI_ERR_OK);
6679 /* Send an synchronuous update event to the module */
6680 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6681 EventParam.Para32[0] = NetIndex;
6682 EventParam.Para32[1] = (SK_U32)-1;
6683 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6685 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6688 return (SK_PNMI_ERR_GENERAL);
6691 return (SK_PNMI_ERR_OK);
6694 /*****************************************************************************
6696 * MacUpdate - Force the XMAC to output the current statistic
6699 * The XMAC holds its statistic internally. To obtain the current
6700 * values we must send a command so that the statistic data will
6701 * be written to a predefined memory area on the adapter.
6704 * SK_PNMI_ERR_OK Task successfully performed.
6705 * SK_PNMI_ERR_GENERAL Something went wrong.
6707 PNMI_STATIC int MacUpdate(
6708 SK_AC *pAC, /* Pointer to adapter context */
6709 SK_IOC IoC, /* IO context handle */
6710 unsigned int FirstMac, /* Index of the first Mac to be updated */
6711 unsigned int LastMac) /* Index of the last Mac to be updated */
6713 unsigned int MacIndex;
6716 * Were the statistics already updated during the
6717 * current PNMI call?
6719 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6721 return (SK_PNMI_ERR_OK);
6724 /* Send an update command to all MACs specified */
6725 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6728 * 2002-09-13 pweber: Freeze the current SW counters.
6729 * (That should be done as close as
6730 * possible to the update of the
6733 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6734 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6737 /* 2002-09-13 pweber: Update the HW counter */
6738 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6740 return (SK_PNMI_ERR_GENERAL);
6744 return (SK_PNMI_ERR_OK);
6747 /*****************************************************************************
6749 * GetStatVal - Retrieve an XMAC statistic counter
6752 * Retrieves the statistic counter of a virtual or physical port. The
6753 * virtual port is identified by the index 0. It consists of all
6754 * currently active ports. To obtain the counter value for this port
6755 * we must add the statistic counter of all active ports. To grant
6756 * continuous counter values for the virtual port even when port
6757 * switches occur we must additionally add a delta value, which was
6758 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6761 * Requested statistic value
6763 PNMI_STATIC SK_U64 GetStatVal(
6764 SK_AC *pAC, /* Pointer to adapter context */
6765 SK_IOC IoC, /* IO context handle */
6766 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6767 unsigned int StatIndex, /* Index to statistic value */
6768 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6770 unsigned int PhysPortIndex;
6771 unsigned int PhysPortMax;
6775 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6777 PhysPortIndex = NetIndex;
6779 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6781 else { /* Single Net mode */
6783 if (LogPortIndex == 0) {
6785 PhysPortMax = pAC->GIni.GIMacsFound;
6787 /* Add counter of all active ports */
6788 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6791 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6793 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6797 /* Correct value because of port switches */
6798 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6801 /* Get counter value of physical port */
6802 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6804 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6810 /*****************************************************************************
6812 * GetPhysStatVal - Get counter value for physical port
6815 * Builds a 64bit counter value. Except for the octet counters
6816 * the lower 32bit are counted in hardware and the upper 32bit
6817 * in software by monitoring counter overflow interrupts in the
6818 * event handler. To grant continous counter values during XMAC
6819 * resets (caused by a workaround) we must add a delta value.
6820 * The delta was calculated in the event handler when a
6821 * SK_PNMI_EVT_XMAC_RESET was received.
6826 PNMI_STATIC SK_U64 GetPhysStatVal(
6827 SK_AC *pAC, /* Pointer to adapter context */
6828 SK_IOC IoC, /* IO context handle */
6829 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6830 unsigned int StatIndex) /* Index to statistic value */
6837 unsigned int HelpIndex;
6840 SK_PNMI_PORT *pPnmiPrt;
6841 SK_GEMACFUNC *pFnMac;
6843 pPrt = &pAC->GIni.GP[PhysPortIndex];
6845 MacType = pAC->GIni.GIMacType;
6847 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6848 if (MacType == SK_MAC_XMAC) {
6849 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6852 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6855 pFnMac = &pAC->GIni.GIFunc;
6857 switch (StatIndex) {
6859 if (MacType == SK_MAC_GMAC) {
6860 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6861 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6863 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6864 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6867 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6868 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6873 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6874 StatAddr[StatIndex][MacType].Reg,
6877 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6881 if (MacType == SK_MAC_GMAC) {
6882 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6883 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6885 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6886 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6889 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6890 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6895 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6896 StatAddr[StatIndex][MacType].Reg,
6899 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6902 case SK_PNMI_HTX_OCTET:
6903 case SK_PNMI_HRX_OCTET:
6904 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6905 StatAddr[StatIndex][MacType].Reg,
6907 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6908 StatAddr[StatIndex + 1][MacType].Reg,
6912 case SK_PNMI_HTX_BURST:
6913 case SK_PNMI_HTX_EXCESS_DEF:
6914 case SK_PNMI_HTX_CARRIER:
6915 /* Not supported by GMAC */
6916 if (MacType == SK_MAC_GMAC) {
6920 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6921 StatAddr[StatIndex][MacType].Reg,
6923 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6926 case SK_PNMI_HTX_MACC:
6927 /* GMAC only supports PAUSE MAC control frames */
6928 if (MacType == SK_MAC_GMAC) {
6929 HelpIndex = SK_PNMI_HTX_PMACC;
6932 HelpIndex = StatIndex;
6935 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6936 StatAddr[HelpIndex][MacType].Reg,
6939 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6942 case SK_PNMI_HTX_COL:
6943 case SK_PNMI_HRX_UNDERSIZE:
6944 /* Not supported by XMAC */
6945 if (MacType == SK_MAC_XMAC) {
6949 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6950 StatAddr[StatIndex][MacType].Reg,
6952 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6955 case SK_PNMI_HTX_DEFFERAL:
6956 /* Not supported by GMAC */
6957 if (MacType == SK_MAC_GMAC) {
6962 * XMAC counts frames with deferred transmission
6963 * even in full-duplex mode.
6965 * In full-duplex mode the counter remains constant!
6967 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6968 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6974 /* Otherwise get contents of hardware register */
6975 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6976 StatAddr[StatIndex][MacType].Reg,
6978 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6982 case SK_PNMI_HRX_BADOCTET:
6983 /* Not supported by XMAC */
6984 if (MacType == SK_MAC_XMAC) {
6988 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6989 StatAddr[StatIndex][MacType].Reg,
6991 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6992 StatAddr[StatIndex + 1][MacType].Reg,
6996 case SK_PNMI_HTX_OCTETLOW:
6997 case SK_PNMI_HRX_OCTETLOW:
6998 case SK_PNMI_HRX_BADOCTETLOW:
7001 case SK_PNMI_HRX_LONGFRAMES:
7002 /* For XMAC the SW counter is managed by PNMI */
7003 if (MacType == SK_MAC_XMAC) {
7004 return (pPnmiPrt->StatRxLongFrameCts);
7007 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7008 StatAddr[StatIndex][MacType].Reg,
7010 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7013 case SK_PNMI_HRX_TOO_LONG:
7014 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7015 StatAddr[StatIndex][MacType].Reg,
7017 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7019 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7021 if (MacType == SK_MAC_GMAC) {
7022 /* For GMAC the SW counter is additionally managed by PNMI */
7023 Val += pPnmiPrt->StatRxFrameTooLongCts;
7027 * Frames longer than IEEE 802.3 frame max size are counted
7028 * by XMAC in frame_too_long counter even reception of long
7029 * frames was enabled and the frame was correct.
7030 * So correct the value by subtracting RxLongFrame counter.
7032 Val -= pPnmiPrt->StatRxLongFrameCts;
7035 LowVal = (SK_U32)Val;
7036 HighVal = (SK_U32)(Val >> 32);
7039 case SK_PNMI_HRX_SHORTS:
7040 /* Not supported by GMAC */
7041 if (MacType == SK_MAC_GMAC) {
7047 * XMAC counts short frame errors even if link down (#10620)
7049 * If link-down the counter remains constant
7051 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7053 /* Otherwise get incremental difference */
7054 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7055 StatAddr[StatIndex][MacType].Reg,
7057 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7059 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7060 Val -= pPnmiPrt->RxShortZeroMark;
7062 LowVal = (SK_U32)Val;
7063 HighVal = (SK_U32)(Val >> 32);
7067 case SK_PNMI_HRX_MACC:
7068 case SK_PNMI_HRX_MACC_UNKWN:
7069 case SK_PNMI_HRX_BURST:
7070 case SK_PNMI_HRX_MISSED:
7071 case SK_PNMI_HRX_FRAMING:
7072 case SK_PNMI_HRX_CARRIER:
7073 case SK_PNMI_HRX_IRLENGTH:
7074 case SK_PNMI_HRX_SYMBOL:
7075 case SK_PNMI_HRX_CEXT:
7076 /* Not supported by GMAC */
7077 if (MacType == SK_MAC_GMAC) {
7081 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7082 StatAddr[StatIndex][MacType].Reg,
7084 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7087 case SK_PNMI_HRX_PMACC_ERR:
7088 /* For GMAC the SW counter is managed by PNMI */
7089 if (MacType == SK_MAC_GMAC) {
7090 return (pPnmiPrt->StatRxPMaccErr);
7093 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7094 StatAddr[StatIndex][MacType].Reg,
7096 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7099 /* SW counter managed by PNMI */
7100 case SK_PNMI_HTX_SYNC:
7101 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7102 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7105 /* SW counter managed by PNMI */
7106 case SK_PNMI_HTX_SYNC_OCTET:
7107 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7108 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7111 case SK_PNMI_HRX_FCS:
7113 * Broadcom filters FCS errors and counts it in
7114 * Receive Error Counter register
7116 if (pPrt->PhyType == SK_PHY_BCOM) {
7117 /* do not read while not initialized (PHY_READ hangs!)*/
7118 if (pPrt->PState != SK_PRT_RESET) {
7119 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7123 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7126 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7127 StatAddr[StatIndex][MacType].Reg,
7129 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7134 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7135 StatAddr[StatIndex][MacType].Reg,
7137 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7141 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7143 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7144 Val += pPnmiPrt->CounterOffset[StatIndex];
7149 /*****************************************************************************
7151 * ResetCounter - Set all counters and timestamps to zero
7154 * Notifies other common modules which store statistic data to
7155 * reset their counters and finally reset our own counters.
7160 PNMI_STATIC void ResetCounter(
7161 SK_AC *pAC, /* Pointer to adapter context */
7162 SK_IOC IoC, /* IO context handle */
7165 unsigned int PhysPortIndex;
7166 SK_EVPARA EventParam;
7169 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7171 /* Notify sensor module */
7172 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7174 /* Notify RLMT module */
7175 EventParam.Para32[0] = NetIndex;
7176 EventParam.Para32[1] = (SK_U32)-1;
7177 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7178 EventParam.Para32[1] = 0;
7180 /* Notify SIRQ module */
7181 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7183 /* Notify CSUM module */
7185 EventParam.Para32[0] = NetIndex;
7186 EventParam.Para32[1] = (SK_U32)-1;
7187 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7189 #endif /* SK_USE_CSUM */
7191 /* Clear XMAC statistic */
7192 for (PhysPortIndex = 0; PhysPortIndex <
7193 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7195 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7197 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7198 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7199 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7200 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7201 PhysPortIndex].CounterOffset));
7202 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7203 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7204 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7205 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7206 PhysPortIndex].StatSyncOctetsCts));
7207 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7208 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7209 PhysPortIndex].StatRxLongFrameCts));
7210 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7211 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7212 PhysPortIndex].StatRxFrameTooLongCts));
7213 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7214 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7215 PhysPortIndex].StatRxPMaccErr));
7219 * Clear local statistics
7221 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7222 sizeof(pAC->Pnmi.VirtualCounterOffset));
7223 pAC->Pnmi.RlmtChangeCts = 0;
7224 pAC->Pnmi.RlmtChangeTime = 0;
7225 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7226 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7227 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7228 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7229 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7230 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7231 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7232 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7233 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7234 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7235 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7236 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7237 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7238 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7241 /*****************************************************************************
7243 * GetTrapEntry - Get an entry in the trap buffer
7246 * The trap buffer stores various events. A user application somehow
7247 * gets notified that an event occured and retrieves the trap buffer
7248 * contens (or simply polls the buffer). The buffer is organized as
7249 * a ring which stores the newest traps at the beginning. The oldest
7250 * traps are overwritten by the newest ones. Each trap entry has a
7251 * unique number, so that applications may detect new trap entries.
7254 * A pointer to the trap entry
7256 PNMI_STATIC char* GetTrapEntry(
7257 SK_AC *pAC, /* Pointer to adapter context */
7258 SK_U32 TrapId, /* SNMP ID of the trap */
7259 unsigned int Size) /* Space needed for trap entry */
7261 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7262 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7263 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7264 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7265 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7267 unsigned int NeededSpace;
7268 unsigned int EntrySize;
7273 /* Last byte of entry will get a copy of the entry length */
7277 * Calculate needed buffer space */
7284 NeededSpace = Beg + Size;
7289 * Check if enough buffer space is provided. Otherwise
7290 * free some entries. Leave one byte space between begin
7291 * and end of buffer to make it possible to detect whether
7292 * the buffer is full or empty
7294 while (BufFree < NeededSpace + 1) {
7298 End = SK_PNMI_TRAP_QUEUE_LEN;
7301 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7302 BufFree += EntrySize;
7305 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7307 if (End == BufPad) {
7309 SK_MEMSET(pBuf, (char)(-1), End);
7318 * Insert new entry as first entry. Newest entries are
7319 * stored at the beginning of the queue.
7324 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7329 BufFree -= NeededSpace;
7331 /* Save the current offsets */
7332 pAC->Pnmi.TrapQueueBeg = Beg;
7333 pAC->Pnmi.TrapQueueEnd = End;
7334 pAC->Pnmi.TrapBufPad = BufPad;
7335 pAC->Pnmi.TrapBufFree = BufFree;
7337 /* Initialize the trap entry */
7338 *(pBuf + Beg + Size - 1) = (char)Size;
7339 *(pBuf + Beg) = (char)Size;
7340 Val32 = (pAC->Pnmi.TrapUnique) ++;
7341 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7342 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7343 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7344 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7346 return (pBuf + Beg);
7349 /*****************************************************************************
7351 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7354 * On a query of the TRAP OID the trap buffer contents will be
7355 * copied continuously to the request buffer, which must be large
7356 * enough. No length check is performed.
7361 PNMI_STATIC void CopyTrapQueue(
7362 SK_AC *pAC, /* Pointer to adapter context */
7363 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7365 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7366 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7367 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7368 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7370 unsigned int DstOff = 0;
7373 while (Trap != End) {
7375 Len = (unsigned int)*(pBuf + Trap);
7378 * Last byte containing a copy of the length will
7381 *(pDstBuf + DstOff) = (char)(Len - 1);
7382 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7386 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7393 /*****************************************************************************
7395 * GetTrapQueueLen - Get the length of the trap buffer
7398 * Evaluates the number of currently stored traps and the needed
7399 * buffer size to retrieve them.
7404 PNMI_STATIC void GetTrapQueueLen(
7405 SK_AC *pAC, /* Pointer to adapter context */
7406 unsigned int *pLen, /* Length in Bytes of all queued traps */
7407 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7409 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7410 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7411 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7412 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7414 unsigned int Entries = 0;
7415 unsigned int TotalLen = 0;
7418 while (Trap != End) {
7420 Len = (unsigned int)*(pBuf + Trap);
7421 TotalLen += Len - 1;
7425 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7431 *pEntries = Entries;
7435 /*****************************************************************************
7437 * QueueSimpleTrap - Store a simple trap to the trap buffer
7440 * A simple trap is a trap with now additional data. It consists
7441 * simply of a trap code.
7446 PNMI_STATIC void QueueSimpleTrap(
7447 SK_AC *pAC, /* Pointer to adapter context */
7448 SK_U32 TrapId) /* Type of sensor trap */
7450 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7453 /*****************************************************************************
7455 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7458 * Gets an entry in the trap buffer and fills it with sensor related
7464 PNMI_STATIC void QueueSensorTrap(
7465 SK_AC *pAC, /* Pointer to adapter context */
7466 SK_U32 TrapId, /* Type of sensor trap */
7467 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7470 unsigned int Offset;
7471 unsigned int DescrLen;
7475 /* Get trap buffer entry */
7476 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7477 pBuf = GetTrapEntry(pAC, TrapId,
7478 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7479 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7481 /* Store additionally sensor trap related data */
7482 Val32 = OID_SKGE_SENSOR_INDEX;
7483 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7484 *(pBuf + Offset + 4) = 4;
7485 Val32 = (SK_U32)SensorIndex;
7486 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7489 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7490 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7491 *(pBuf + Offset + 4) = (char)DescrLen;
7492 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7494 Offset += DescrLen + 5;
7496 Val32 = OID_SKGE_SENSOR_TYPE;
7497 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7498 *(pBuf + Offset + 4) = 1;
7499 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7502 Val32 = OID_SKGE_SENSOR_VALUE;
7503 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7504 *(pBuf + Offset + 4) = 4;
7505 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7506 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7509 /*****************************************************************************
7511 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7514 * Nothing further to explain.
7519 PNMI_STATIC void QueueRlmtNewMacTrap(
7520 SK_AC *pAC, /* Pointer to adapter context */
7521 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7527 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7528 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7530 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7531 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7532 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7533 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7536 /*****************************************************************************
7538 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7541 * Nothing further to explain.
7546 PNMI_STATIC void QueueRlmtPortTrap(
7547 SK_AC *pAC, /* Pointer to adapter context */
7548 SK_U32 TrapId, /* Type of RLMT port trap */
7549 unsigned int PortIndex) /* Index of the port, which changed its state */
7555 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7557 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7558 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7559 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7560 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7563 /*****************************************************************************
7565 * CopyMac - Copies a MAC address
7568 * Nothing further to explain.
7573 PNMI_STATIC void CopyMac(
7574 char *pDst, /* Pointer to destination buffer */
7575 SK_MAC_ADDR *pMac) /* Pointer of Source */
7580 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7582 *(pDst + i) = pMac->a[i];
7586 #ifdef SK_POWER_MGMT
7587 /*****************************************************************************
7589 * PowerManagement - OID handler function of PowerManagement OIDs
7592 * The code is simple. No description necessary.
7595 * SK_PNMI_ERR_OK The request was successfully performed.
7596 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7597 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7598 * the correct data (e.g. a 32bit value is
7599 * needed, but a 16 bit value was passed).
7600 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7601 * exist (e.g. port instance 3 on a two port
7605 PNMI_STATIC int PowerManagement(
7606 SK_AC *pAC, /* Pointer to adapter context */
7607 SK_IOC IoC, /* IO context handle */
7608 int Action, /* Get/PreSet/Set action */
7609 SK_U32 Id, /* Object ID that is to be processed */
7610 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7611 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7612 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7613 unsigned int TableIndex, /* Index to the Id table */
7614 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7617 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7620 * Check instance. We only handle single instance variables
7622 if (Instance != (SK_U32)(-1) && Instance != 1) {
7625 return (SK_PNMI_ERR_UNKNOWN_INST);
7632 case OID_PNP_CAPABILITIES:
7633 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7635 *pLen = sizeof(SK_PNP_CAPABILITIES);
7636 return (SK_PNMI_ERR_TOO_SHORT);
7640 case OID_PNP_SET_POWER:
7641 case OID_PNP_QUERY_POWER:
7642 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7644 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7645 return (SK_PNMI_ERR_TOO_SHORT);
7649 case OID_PNP_ADD_WAKE_UP_PATTERN:
7650 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7651 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7653 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7654 return (SK_PNMI_ERR_TOO_SHORT);
7658 case OID_PNP_ENABLE_WAKE_UP:
7659 if (*pLen < sizeof(SK_U32)) {
7661 *pLen = sizeof(SK_U32);
7662 return (SK_PNMI_ERR_TOO_SHORT);
7670 if (Action == SK_PNMI_GET) {
7677 case OID_PNP_CAPABILITIES:
7678 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7681 case OID_PNP_QUERY_POWER:
7682 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7683 the miniport to indicate whether it can transition its NIC
7684 to the low-power state.
7685 A miniport driver must always return NDIS_STATUS_SUCCESS
7686 to a query of OID_PNP_QUERY_POWER. */
7687 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7688 RetCode = SK_PNMI_ERR_OK;
7691 /* NDIS handles these OIDs as write-only.
7692 * So in case of get action the buffer with written length = 0
7695 case OID_PNP_SET_POWER:
7696 case OID_PNP_ADD_WAKE_UP_PATTERN:
7697 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7699 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7702 case OID_PNP_ENABLE_WAKE_UP:
7703 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7707 RetCode = SK_PNMI_ERR_GENERAL;
7716 * Perform preset or set
7719 /* POWER module does not support PRESET action */
7720 if (Action == SK_PNMI_PRESET) {
7721 return (SK_PNMI_ERR_OK);
7725 case OID_PNP_SET_POWER:
7726 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7729 case OID_PNP_ADD_WAKE_UP_PATTERN:
7730 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7733 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7734 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7737 case OID_PNP_ENABLE_WAKE_UP:
7738 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7742 RetCode = SK_PNMI_ERR_READ_ONLY;
7747 #endif /* SK_POWER_MGMT */
7749 #ifdef SK_DIAG_SUPPORT
7750 /*****************************************************************************
7752 * DiagActions - OID handler function of Diagnostic driver
7755 * The code is simple. No description necessary.
7758 * SK_PNMI_ERR_OK The request was successfully performed.
7759 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7760 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7761 * the correct data (e.g. a 32bit value is
7762 * needed, but a 16 bit value was passed).
7763 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7764 * exist (e.g. port instance 3 on a two port
7768 PNMI_STATIC int DiagActions(
7769 SK_AC *pAC, /* Pointer to adapter context */
7770 SK_IOC IoC, /* IO context handle */
7771 int Action, /* GET/PRESET/SET action */
7772 SK_U32 Id, /* Object ID that is to be processed */
7773 char *pBuf, /* Buffer used for the management data transfer */
7774 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7775 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7776 unsigned int TableIndex, /* Index to the Id table */
7777 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7781 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7784 * Check instance. We only handle single instance variables.
7786 if (Instance != (SK_U32)(-1) && Instance != 1) {
7789 return (SK_PNMI_ERR_UNKNOWN_INST);
7797 case OID_SKGE_DIAG_MODE:
7798 if (*pLen < sizeof(SK_U32)) {
7800 *pLen = sizeof(SK_U32);
7801 return (SK_PNMI_ERR_TOO_SHORT);
7806 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7808 return (SK_PNMI_ERR_GENERAL);
7811 /* Perform action. */
7814 if (Action == SK_PNMI_GET) {
7818 case OID_SKGE_DIAG_MODE:
7819 DiagStatus = pAC->Pnmi.DiagAttached;
7820 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7821 *pLen = sizeof(SK_U32);
7822 RetCode = SK_PNMI_ERR_OK;
7827 RetCode = SK_PNMI_ERR_GENERAL;
7833 /* From here SET or PRESET value. */
7835 /* PRESET value is not supported. */
7836 if (Action == SK_PNMI_PRESET) {
7837 return (SK_PNMI_ERR_OK);
7842 case OID_SKGE_DIAG_MODE:
7844 /* Handle the SET. */
7847 /* Attach the DIAG to this adapter. */
7848 case SK_DIAG_ATTACHED:
7849 /* Check if we come from running */
7850 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7852 RetCode = SkDrvLeaveDiagMode(pAC);
7855 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7857 RetCode = SK_PNMI_ERR_OK;
7862 RetCode = SK_PNMI_ERR_GENERAL;
7866 if (RetCode == SK_PNMI_ERR_OK) {
7868 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7872 /* Enter the DIAG mode in the driver. */
7873 case SK_DIAG_RUNNING:
7874 RetCode = SK_PNMI_ERR_OK;
7877 * If DiagAttached is set, we can tell the driver
7878 * to enter the DIAG mode.
7880 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7881 /* If DiagMode is not active, we can enter it. */
7882 if (!pAC->DiagModeActive) {
7884 RetCode = SkDrvEnterDiagMode(pAC);
7888 RetCode = SK_PNMI_ERR_GENERAL;
7893 RetCode = SK_PNMI_ERR_GENERAL;
7896 if (RetCode == SK_PNMI_ERR_OK) {
7898 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7903 /* Check if we come from running */
7904 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7906 RetCode = SkDrvLeaveDiagMode(pAC);
7909 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7911 RetCode = SK_PNMI_ERR_OK;
7916 RetCode = SK_PNMI_ERR_GENERAL;
7920 if (RetCode == SK_PNMI_ERR_OK) {
7922 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7927 RetCode = SK_PNMI_ERR_BAD_VALUE;
7933 RetCode = SK_PNMI_ERR_GENERAL;
7936 if (RetCode == SK_PNMI_ERR_OK) {
7937 *pLen = sizeof(SK_U32);
7945 #endif /* SK_DIAG_SUPPORT */
7947 /*****************************************************************************
7949 * Vct - OID handler function of OIDs
7952 * The code is simple. No description necessary.
7955 * SK_PNMI_ERR_OK The request was performed successfully.
7956 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7957 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7958 * the correct data (e.g. a 32bit value is
7959 * needed, but a 16 bit value was passed).
7960 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7961 * exist (e.g. port instance 3 on a two port
7963 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7967 PNMI_STATIC int Vct(
7968 SK_AC *pAC, /* Pointer to adapter context */
7969 SK_IOC IoC, /* IO context handle */
7970 int Action, /* GET/PRESET/SET action */
7971 SK_U32 Id, /* Object ID that is to be processed */
7972 char *pBuf, /* Buffer used for the management data transfer */
7973 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7974 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7975 unsigned int TableIndex, /* Index to the Id table */
7976 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7979 SK_PNMI_VCT *pVctBackupData;
7982 SK_U32 PhysPortIndex;
7986 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7992 * Calculate the port indexes from the instance.
7994 PhysPortMax = pAC->GIni.GIMacsFound;
7995 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7997 /* Dual net mode? */
7998 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8002 if ((Instance != (SK_U32) (-1))) {
8003 /* Check instance range. */
8004 if ((Instance < 2) || (Instance > LogPortMax)) {
8006 return (SK_PNMI_ERR_UNKNOWN_INST);
8009 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8010 PhysPortIndex = NetIndex;
8013 PhysPortIndex = Instance - 2;
8015 Limit = PhysPortIndex + 1;
8019 * Instance == (SK_U32) (-1), get all Instances of that OID.
8021 * Not implemented yet. May be used in future releases.
8024 Limit = PhysPortMax;
8027 pPrt = &pAC->GIni.GP[PhysPortIndex];
8028 if (pPrt->PHWLinkUp) {
8035 /* Check MAC type */
8036 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8038 return (SK_PNMI_ERR_GENERAL);
8041 /* Initialize backup data pointer. */
8042 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8044 /* Check action type */
8045 if (Action == SK_PNMI_GET) {
8049 case OID_SKGE_VCT_GET:
8050 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8051 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8052 return (SK_PNMI_ERR_TOO_SHORT);
8056 case OID_SKGE_VCT_STATUS:
8057 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8058 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8059 return (SK_PNMI_ERR_TOO_SHORT);
8065 return (SK_PNMI_ERR_GENERAL);
8070 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8073 case OID_SKGE_VCT_GET:
8074 if ((Link == SK_FALSE) &&
8075 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8076 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8078 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8079 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8080 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8082 /* Copy results for later use to PNMI struct. */
8083 for (i = 0; i < 4; i++) {
8084 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8085 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8086 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8089 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8090 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8095 pVctBackupData->PMdiPairLen[i] = CableLength;
8096 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8099 Para.Para32[0] = PhysPortIndex;
8100 Para.Para32[1] = -1;
8101 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8102 SkEventDispatcher(pAC, IoC);
8105 ; /* VCT test is running. */
8109 /* Get all results. */
8110 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8111 Offset += sizeof(SK_U8);
8112 *(pBuf + Offset) = pPrt->PCableLen;
8113 Offset += sizeof(SK_U8);
8114 for (i = 0; i < 4; i++) {
8115 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8116 Offset += sizeof(SK_U32);
8118 for (i = 0; i < 4; i++) {
8119 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8120 Offset += sizeof(SK_U8);
8123 RetCode = SK_PNMI_ERR_OK;
8126 case OID_SKGE_VCT_STATUS:
8127 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8128 Offset += sizeof(SK_U8);
8129 RetCode = SK_PNMI_ERR_OK;
8134 return (SK_PNMI_ERR_GENERAL);
8140 } /* if SK_PNMI_GET */
8143 * From here SET or PRESET action. Check if the passed
8144 * buffer length is plausible.
8149 case OID_SKGE_VCT_SET:
8150 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8151 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8152 return (SK_PNMI_ERR_TOO_SHORT);
8158 return (SK_PNMI_ERR_GENERAL);
8162 * Perform preset or set.
8165 /* VCT does not support PRESET action. */
8166 if (Action == SK_PNMI_PRESET) {
8167 return (SK_PNMI_ERR_OK);
8171 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8173 case OID_SKGE_VCT_SET: /* Start VCT test. */
8174 if (Link == SK_FALSE) {
8175 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8177 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8178 if (RetCode == 0) { /* RetCode: 0 => Start! */
8179 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8180 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8181 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8184 * Start VCT timer counter.
8186 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8187 Para.Para32[0] = PhysPortIndex;
8188 Para.Para32[1] = -1;
8189 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8190 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8191 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8192 RetCode = SK_PNMI_ERR_OK;
8194 else { /* RetCode: 2 => Running! */
8195 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8196 RetCode = SK_PNMI_ERR_OK;
8199 else { /* RetCode: 4 => Link! */
8201 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8202 RetCode = SK_PNMI_ERR_OK;
8204 Offset += sizeof(SK_U32);
8209 return (SK_PNMI_ERR_GENERAL);
8218 PNMI_STATIC void CheckVctStatus(
8223 SK_U32 PhysPortIndex)
8226 SK_PNMI_VCT *pVctData;
8229 pPrt = &pAC->GIni.GP[PhysPortIndex];
8231 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8232 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8234 if (!pPrt->PHWLinkUp) {
8236 /* Was a VCT test ever made before? */
8237 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8238 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8239 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8242 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8246 /* Check VCT test status. */
8247 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8248 if (RetCode == 2) { /* VCT test is running. */
8249 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8251 else { /* VCT data was copied to pAC here. Check PENDING state. */
8252 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8253 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8257 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8258 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8263 /* Was a VCT test ever made before? */
8264 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8265 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8266 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8269 /* DSP only valid in 100/1000 modes. */
8270 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8271 SK_LSPEED_STAT_10MBPS) {
8272 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8275 } /* CheckVctStatus */
8278 /*****************************************************************************
8280 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8281 * PNMI function depending on the subcommand and
8282 * returns all data belonging to the complete database
8286 * Looks up the requested subcommand, calls the corresponding handler
8287 * function and passes all required parameters to it.
8288 * The function is called by the driver. It is needed to handle the new
8289 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8290 * the OID and a subcommand to decide what kind of request has to be done.
8293 * SK_PNMI_ERR_OK The request was successfully performed
8294 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8295 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8297 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8298 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8299 * exist (e.g. port instance 3 on a two port
8303 SK_AC *pAC, /* Pointer to adapter context struct */
8304 SK_IOC IoC, /* I/O context */
8305 void *pBuf, /* Buffer used for the management data transfer */
8306 unsigned int *pLen, /* Length of buffer */
8307 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8309 SK_I32 Mode; /* Store value of subcommand. */
8310 SK_U32 Oid; /* Store value of OID. */
8311 int ReturnCode; /* Store return value to show status of PNMI action. */
8312 int HeaderLength; /* Length of desired action plus OID. */
8314 ReturnCode = SK_PNMI_ERR_GENERAL;
8316 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8317 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8318 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8319 *pLen = *pLen - HeaderLength;
8320 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8323 case SK_GET_SINGLE_VAR:
8324 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8325 (char *) pBuf + sizeof(SK_I32), pLen,
8326 ((SK_U32) (-1)), NetIndex);
8327 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8328 *pLen = *pLen + sizeof(SK_I32);
8330 case SK_PRESET_SINGLE_VAR:
8331 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8332 (char *) pBuf + sizeof(SK_I32), pLen,
8333 ((SK_U32) (-1)), NetIndex);
8334 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8335 *pLen = *pLen + sizeof(SK_I32);
8337 case SK_SET_SINGLE_VAR:
8338 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8339 (char *) pBuf + sizeof(SK_I32), pLen,
8340 ((SK_U32) (-1)), NetIndex);
8341 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8342 *pLen = *pLen + sizeof(SK_I32);
8344 case SK_GET_FULL_MIB:
8345 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8347 case SK_PRESET_FULL_MIB:
8348 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8350 case SK_SET_FULL_MIB:
8351 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8357 return (ReturnCode);