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 SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
60 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
61 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
62 unsigned int *pLen, SK_U32 NetIndex);
63 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
64 unsigned int *pLen, SK_U32 NetIndex);
65 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
66 unsigned int *pLen, SK_U32 NetIndex);
67 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
68 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
69 unsigned int * pLen, SK_U32 NetIndex);
73 * Private Function prototypes
76 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
78 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
80 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
81 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
82 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
83 unsigned int PhysPortIndex, unsigned int StatIndex);
84 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
85 unsigned int StatIndex, SK_U32 NetIndex);
86 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
87 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
88 unsigned int *pEntries);
89 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
90 unsigned int KeyArrLen, unsigned int *pKeyNo);
91 PNMI_STATIC int LookupId(SK_U32 Id);
92 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
93 unsigned int LastMac);
94 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
95 unsigned int *pLen, SK_U32 NetIndex);
96 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
97 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
98 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
99 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
100 unsigned int PortIndex);
101 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
102 unsigned int SensorIndex);
103 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
104 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
105 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
107 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
108 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
109 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
110 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
113 * Table to correlate OID with handler function and index to
114 * hardware register stored in StatAddress if applicable.
118 /* global variables **********************************************************/
121 * Overflow status register bit table and corresponding counter
122 * dependent on MAC type - the number relates to the size of overflow
123 * mask returned by the pFnMacOverflow function
125 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
126 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
127 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
128 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
129 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
130 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
131 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
132 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
133 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
134 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
135 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
136 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
137 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
138 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
139 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
140 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
141 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
142 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
143 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
144 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
145 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
146 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
147 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
148 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
149 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
150 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
151 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
152 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
153 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
159 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
160 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
161 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
162 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
163 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
164 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
165 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
166 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
167 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
168 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
169 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
170 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
171 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
172 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
173 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
174 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
175 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
176 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
177 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
178 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
179 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
180 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
181 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
182 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
183 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
184 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
185 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
186 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
187 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
188 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
189 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
193 * Table for hardware register saving on resets and port switches
195 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
197 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
198 /* SK_PNMI_HTX_OCTETHIGH */
199 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
200 /* SK_PNMI_HTX_OCTETLOW */
201 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
202 /* SK_PNMI_HTX_BROADCAST */
203 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
204 /* SK_PNMI_HTX_MULTICAST */
205 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
206 /* SK_PNMI_HTX_UNICAST */
207 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
208 /* SK_PNMI_HTX_BURST */
209 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
210 /* SK_PNMI_HTX_PMACC */
211 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
212 /* SK_PNMI_HTX_MACC */
213 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
214 /* SK_PNMI_HTX_COL */
215 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
216 /* SK_PNMI_HTX_SINGLE_COL */
217 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
218 /* SK_PNMI_HTX_MULTI_COL */
219 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
220 /* SK_PNMI_HTX_EXCESS_COL */
221 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
222 /* SK_PNMI_HTX_LATE_COL */
223 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
224 /* SK_PNMI_HTX_DEFFERAL */
225 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
226 /* SK_PNMI_HTX_EXCESS_DEF */
227 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
228 /* SK_PNMI_HTX_UNDERRUN */
229 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
230 /* SK_PNMI_HTX_CARRIER */
231 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
232 /* SK_PNMI_HTX_UTILUNDER */
233 {{0, SK_FALSE}, {0, SK_FALSE}},
234 /* SK_PNMI_HTX_UTILOVER */
235 {{0, SK_FALSE}, {0, SK_FALSE}},
237 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
238 /* SK_PNMI_HTX_127 */
239 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
240 /* SK_PNMI_HTX_255 */
241 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
242 /* SK_PNMI_HTX_511 */
243 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
244 /* SK_PNMI_HTX_1023 */
245 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
246 /* SK_PNMI_HTX_MAX */
247 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
248 /* SK_PNMI_HTX_LONGFRAMES */
249 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
250 /* SK_PNMI_HTX_SYNC */
251 {{0, SK_FALSE}, {0, SK_FALSE}},
252 /* SK_PNMI_HTX_SYNC_OCTET */
253 {{0, SK_FALSE}, {0, SK_FALSE}},
254 /* SK_PNMI_HTX_RESERVED */
255 {{0, SK_FALSE}, {0, SK_FALSE}},
257 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
258 /* SK_PNMI_HRX_OCTETHIGH */
259 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
260 /* SK_PNMI_HRX_OCTETLOW */
261 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
262 /* SK_PNMI_HRX_BADOCTETHIGH */
263 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
264 /* SK_PNMI_HRX_BADOCTETLOW */
265 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
266 /* SK_PNMI_HRX_BROADCAST */
267 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
268 /* SK_PNMI_HRX_MULTICAST */
269 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
270 /* SK_PNMI_HRX_UNICAST */
271 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
272 /* SK_PNMI_HRX_PMACC */
273 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
274 /* SK_PNMI_HRX_MACC */
275 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
276 /* SK_PNMI_HRX_PMACC_ERR */
277 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
278 /* SK_PNMI_HRX_MACC_UNKWN */
279 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
280 /* SK_PNMI_HRX_BURST */
281 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
282 /* SK_PNMI_HRX_MISSED */
283 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
284 /* SK_PNMI_HRX_FRAMING */
285 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
286 /* SK_PNMI_HRX_UNDERSIZE */
287 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
288 /* SK_PNMI_HRX_OVERFLOW */
289 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
290 /* SK_PNMI_HRX_JABBER */
291 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
292 /* SK_PNMI_HRX_CARRIER */
293 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
294 /* SK_PNMI_HRX_IRLENGTH */
295 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
296 /* SK_PNMI_HRX_SYMBOL */
297 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
298 /* SK_PNMI_HRX_SHORTS */
299 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
300 /* SK_PNMI_HRX_RUNT */
301 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
302 /* SK_PNMI_HRX_TOO_LONG */
303 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
304 /* SK_PNMI_HRX_FCS */
305 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
306 /* SK_PNMI_HRX_CEXT */
307 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
308 /* SK_PNMI_HRX_UTILUNDER */
309 {{0, SK_FALSE}, {0, SK_FALSE}},
310 /* SK_PNMI_HRX_UTILOVER */
311 {{0, SK_FALSE}, {0, SK_FALSE}},
313 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
314 /* SK_PNMI_HRX_127 */
315 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
316 /* SK_PNMI_HRX_255 */
317 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
318 /* SK_PNMI_HRX_511 */
319 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
320 /* SK_PNMI_HRX_1023 */
321 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
322 /* SK_PNMI_HRX_MAX */
323 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
324 /* SK_PNMI_HRX_LONGFRAMES */
325 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
326 /* SK_PNMI_HRX_RESERVED */
327 {{0, SK_FALSE}, {0, SK_FALSE}}
331 /*****************************************************************************
337 /*****************************************************************************
339 * SkPnmiInit - Init function of PNMI
342 * SK_INIT_DATA: Initialises the data structures
343 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
345 * SK_INIT_RUN: Starts a timer event for port switch per hour
352 SK_AC *pAC, /* Pointer to adapter context */
353 SK_IOC IoC, /* IO context handle */
354 int Level) /* Initialization level */
356 unsigned int PortMax; /* Number of ports */
357 unsigned int PortIndex; /* Current port index in loop */
358 SK_U16 Val16; /* Multiple purpose 16 bit variable */
359 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
360 SK_EVPARA EventParam; /* Event struct for timer event */
361 SK_PNMI_VCT *pVctBackupData;
364 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
365 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
370 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
371 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
372 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
373 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
374 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
376 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
377 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
381 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
383 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
385 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
386 ("CounterOffset struct size (%d) differs from "
387 "SK_PNMI_MAX_IDX (%d)\n",
388 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
391 #endif /* SK_PNMI_CHECK */
398 PortMax = pAC->GIni.GIMacsFound;
400 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
402 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
405 /* Initialize DSP variables for Vct() to 0xff => Never written! */
406 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
407 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
408 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
409 pVctBackupData->PCableLen = 0xff;
415 SK_IN16(IoC, B0_CTST, &Val16);
416 if ((Val16 & CS_BUS_CLOCK) == 0) {
418 pAC->Pnmi.PciBusSpeed = 33;
421 pAC->Pnmi.PciBusSpeed = 66;
427 SK_IN16(IoC, B0_CTST, &Val16);
428 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
430 pAC->Pnmi.PciBusWidth = 32;
433 pAC->Pnmi.PciBusWidth = 64;
439 switch (pAC->GIni.GIChipId) {
440 case CHIP_ID_GENESIS:
441 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
445 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
453 * Get PMD and DeviceType
455 SK_IN8(IoC, B2_PMD_TYP, &Val8);
459 if (pAC->GIni.GIMacsFound > 1) {
461 pAC->Pnmi.DeviceType = 0x00020002;
464 pAC->Pnmi.DeviceType = 0x00020001;
470 if (pAC->GIni.GIMacsFound > 1) {
472 pAC->Pnmi.DeviceType = 0x00020004;
475 pAC->Pnmi.DeviceType = 0x00020003;
481 if (pAC->GIni.GIMacsFound > 1) {
483 pAC->Pnmi.DeviceType = 0x00020006;
486 pAC->Pnmi.DeviceType = 0x00020005;
492 if (pAC->GIni.GIMacsFound > 1) {
494 pAC->Pnmi.DeviceType = 0x00020008;
497 pAC->Pnmi.DeviceType = 0x00020007;
503 pAC->Pnmi.DeviceType = 0;
510 SK_IN8(IoC, B2_CONN_TYP, &Val8);
513 pAC->Pnmi.Connector = 2;
517 pAC->Pnmi.Connector = 3;
521 pAC->Pnmi.Connector = 4;
525 pAC->Pnmi.Connector = 5;
529 pAC->Pnmi.Connector = 6;
533 pAC->Pnmi.Connector = 1;
540 * Start timer for RLMT change counter
542 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
543 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
544 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
549 break; /* Nothing todo */
555 /*****************************************************************************
557 * SkPnmiGetVar - Retrieves the value of a single OID
560 * Calls a general sub-function for all this stuff. If the instance
561 * -1 is passed, the values of all instances are returned in an
565 * SK_PNMI_ERR_OK The request was successfully performed
566 * SK_PNMI_ERR_GENERAL A general severe internal error occured
567 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
569 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
570 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
571 * exist (e.g. port instance 3 on a two port
574 static int SkPnmiGetVar(
575 SK_AC *pAC, /* Pointer to adapter context */
576 SK_IOC IoC, /* IO context handle */
577 SK_U32 Id, /* Object ID that is to be processed */
578 void *pBuf, /* Buffer to which the management data will be copied */
579 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
580 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
581 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
583 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
584 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
585 Id, *pLen, Instance, NetIndex));
587 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
588 Instance, NetIndex));
591 /*****************************************************************************
593 * SkPnmiPreSetVar - Presets the value of a single OID
596 * Calls a general sub-function for all this stuff. The preset does
597 * the same as a set, but returns just before finally setting the
598 * new value. This is useful to check if a set might be successfull.
599 * If the instance -1 is passed, an array of values is supposed and
600 * all instances of the OID will be set.
603 * SK_PNMI_ERR_OK The request was successfully performed.
604 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
605 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
606 * the correct data (e.g. a 32bit value is
607 * needed, but a 16 bit value was passed).
608 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
610 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
611 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
612 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
613 * exist (e.g. port instance 3 on a two port
616 static int SkPnmiPreSetVar(
617 SK_AC *pAC, /* Pointer to adapter context */
618 SK_IOC IoC, /* IO context handle */
619 SK_U32 Id, /* Object ID that is to be processed */
620 void *pBuf, /* Buffer to which the management data will be copied */
621 unsigned int *pLen, /* Total length of management data */
622 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
623 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
625 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
626 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
627 Id, *pLen, Instance, NetIndex));
630 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
631 Instance, NetIndex));
634 /*****************************************************************************
636 * SkPnmiSetVar - Sets the value of a single OID
639 * Calls a general sub-function for all this stuff. The preset does
640 * the same as a set, but returns just before finally setting the
641 * new value. This is useful to check if a set might be successfull.
642 * If the instance -1 is passed, an array of values is supposed and
643 * all instances of the OID will be set.
646 * SK_PNMI_ERR_OK The request was successfully performed.
647 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
648 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
649 * the correct data (e.g. a 32bit value is
650 * needed, but a 16 bit value was passed).
651 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
653 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
654 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
655 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
656 * exist (e.g. port instance 3 on a two port
660 SK_AC *pAC, /* Pointer to adapter context */
661 SK_IOC IoC, /* IO context handle */
662 SK_U32 Id, /* Object ID that is to be processed */
663 void *pBuf, /* Buffer to which the management data will be copied */
664 unsigned int *pLen, /* Total length of management data */
665 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
666 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
668 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
669 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
670 Id, *pLen, Instance, NetIndex));
672 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
673 Instance, NetIndex));
676 /*****************************************************************************
678 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
681 * Runs through the IdTable, queries the single OIDs and stores the
682 * returned data into the management database structure
683 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
684 * is stored in the IdTable. The return value of the function will also
685 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
686 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
689 * SK_PNMI_ERR_OK The request was successfully performed
690 * SK_PNMI_ERR_GENERAL A general severe internal error occured
691 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
693 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
696 SK_AC *pAC, /* Pointer to adapter context */
697 SK_IOC IoC, /* IO context handle */
698 void *pBuf, /* Buffer to which the management data will be copied. */
699 unsigned int *pLen, /* Length of buffer */
700 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
703 unsigned int TableIndex;
704 unsigned int DstOffset;
705 unsigned int InstanceNo;
706 unsigned int InstanceCnt;
709 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
712 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
713 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
716 if (*pLen < SK_PNMI_STRUCT_SIZE) {
718 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
720 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
724 *pLen = SK_PNMI_STRUCT_SIZE;
725 return (SK_PNMI_ERR_TOO_SHORT);
731 if (NetIndex >= pAC->Rlmt.NumNets) {
732 return (SK_PNMI_ERR_UNKNOWN_NET);
735 /* Update statistic */
736 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
738 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
741 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
742 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
746 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
748 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
749 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
753 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
755 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
756 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
761 * Increment semaphores to indicate that an update was
764 pAC->Pnmi.MacUpdatedFlag ++;
765 pAC->Pnmi.RlmtUpdatedFlag ++;
766 pAC->Pnmi.SirqUpdatedFlag ++;
768 /* Get vpd keys for instance calculation */
769 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
770 if (Ret != SK_PNMI_ERR_OK) {
772 pAC->Pnmi.MacUpdatedFlag --;
773 pAC->Pnmi.RlmtUpdatedFlag --;
774 pAC->Pnmi.SirqUpdatedFlag --;
776 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
777 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
778 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
779 return (SK_PNMI_ERR_GENERAL);
782 /* Retrieve values */
783 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
784 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
786 InstanceNo = IdTable[TableIndex].InstanceNo;
787 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
790 DstOffset = IdTable[TableIndex].Offset +
792 IdTable[TableIndex].StructSize;
795 * For the VPD the instance is not an index number
796 * but the key itself. Determin with the instance
797 * counter the VPD key to be used.
799 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
800 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
801 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
802 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
804 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
807 Instance = (SK_U32)InstanceCnt;
810 TmpLen = *pLen - DstOffset;
811 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
812 IdTable[TableIndex].Id, (char *)pBuf +
813 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
816 * An unknown instance error means that we reached
817 * the last instance of that variable. Proceed with
818 * the next OID in the table and ignore the return
821 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
826 if (Ret != SK_PNMI_ERR_OK) {
828 pAC->Pnmi.MacUpdatedFlag --;
829 pAC->Pnmi.RlmtUpdatedFlag --;
830 pAC->Pnmi.SirqUpdatedFlag --;
832 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
833 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
834 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
840 pAC->Pnmi.MacUpdatedFlag --;
841 pAC->Pnmi.RlmtUpdatedFlag --;
842 pAC->Pnmi.SirqUpdatedFlag --;
844 *pLen = SK_PNMI_STRUCT_SIZE;
845 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
846 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
847 return (SK_PNMI_ERR_OK);
850 /*****************************************************************************
852 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
855 * Calls a general sub-function for all this set stuff. The preset does
856 * the same as a set, but returns just before finally setting the
857 * new value. This is useful to check if a set might be successfull.
858 * The sub-function runs through the IdTable, checks which OIDs are able
859 * to set, and calls the handler function of the OID to perform the
860 * preset. The return value of the function will also be stored in
861 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
862 * SK_PNMI_MIN_STRUCT_SIZE.
865 * SK_PNMI_ERR_OK The request was successfully performed.
866 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
867 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
868 * the correct data (e.g. a 32bit value is
869 * needed, but a 16 bit value was passed).
870 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
873 int SkPnmiPreSetStruct(
874 SK_AC *pAC, /* Pointer to adapter context */
875 SK_IOC IoC, /* IO context handle */
876 void *pBuf, /* Buffer which contains the data to be set */
877 unsigned int *pLen, /* Length of buffer */
878 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
880 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
881 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
884 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
888 /*****************************************************************************
890 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
893 * Calls a general sub-function for all this set stuff. The return value
894 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
895 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
896 * The sub-function runs through the IdTable, checks which OIDs are able
897 * to set, and calls the handler function of the OID to perform the
898 * set. The return value of the function will also be stored in
899 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
900 * SK_PNMI_MIN_STRUCT_SIZE.
903 * SK_PNMI_ERR_OK The request was successfully performed.
904 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
905 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
906 * the correct data (e.g. a 32bit value is
907 * needed, but a 16 bit value was passed).
908 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
912 SK_AC *pAC, /* Pointer to adapter context */
913 SK_IOC IoC, /* IO context handle */
914 void *pBuf, /* Buffer which contains the data to be set */
915 unsigned int *pLen, /* Length of buffer */
916 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
918 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
919 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
922 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
926 /*****************************************************************************
928 * SkPnmiEvent - Event handler
931 * Handles the following events:
932 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
933 * interrupt will be generated which is
934 * first handled by SIRQ which generates a
935 * this event. The event increments the
936 * upper 32 bit of the 64 bit counter.
937 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
938 * when a sensor reports a warning or
939 * error. The event will store a trap
940 * message in the trap buffer.
941 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
942 * module and is used to calculate the
943 * port switches per hour.
944 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
946 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
947 * before a hard reset of the XMAC is
948 * performed. All counters will be saved
949 * and added to the hardware counter
950 * values after reset to grant continuous
952 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
953 * went logically up. A trap message will
954 * be stored to the trap buffer.
955 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
956 * went logically down. A trap message will
957 * be stored to the trap buffer.
958 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
959 * spanning tree root bridges were
960 * detected. A trap message will be stored
961 * to the trap buffer.
962 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
963 * down. PNMI will not further add the
964 * statistic values to the virtual port.
965 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
966 * is now an active port. PNMI will now
967 * add the statistic data of this port to
969 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
970 * contains the number of nets. 1 means single net, 2 means
971 * dual net. The second parameter is -1
977 SK_AC *pAC, /* Pointer to adapter context */
978 SK_IOC IoC, /* IO context handle */
979 SK_U32 Event, /* Event-Id */
980 SK_EVPARA Param) /* Event dependent parameter */
982 unsigned int PhysPortIndex;
983 unsigned int MaxNetNumber;
987 SK_U64 OverflowStatus;
993 SK_EVPARA EventParam;
997 SK_PNMI_ESTIMATE *pEst;
1000 SK_PNMI_VCT *pVctBackupData;
1007 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1009 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1010 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1011 (unsigned int)Event, (unsigned int)Param.Para64));
1014 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1016 MacType = pAC->GIni.GIMacType;
1020 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1021 PhysPortIndex = (int)Param.Para32[0];
1022 MacStatus = (SK_U16)Param.Para32[1];
1024 if (PhysPortIndex >= SK_MAX_MACS) {
1026 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1027 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1028 " wrong, PhysPortIndex=0x%x\n",
1036 * Check which source caused an overflow interrupt.
1038 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1039 MacStatus, &OverflowStatus) != 0) ||
1040 (OverflowStatus == 0)) {
1042 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1047 * Check the overflow status register and increment
1048 * the upper dword of corresponding counter.
1050 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1053 Mask = (SK_U64)1 << CounterIndex;
1054 if ((OverflowStatus & Mask) == 0) {
1059 switch (StatOvrflwBit[CounterIndex][MacType]) {
1061 case SK_PNMI_HTX_UTILUNDER:
1062 case SK_PNMI_HTX_UTILOVER:
1063 if (MacType == SK_MAC_XMAC) {
1064 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1065 Register |= XM_TX_SAM_LINE;
1066 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1070 case SK_PNMI_HRX_UTILUNDER:
1071 case SK_PNMI_HRX_UTILOVER:
1072 if (MacType == SK_MAC_XMAC) {
1073 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1074 Register |= XM_RX_SAM_LINE;
1075 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1079 case SK_PNMI_HTX_OCTETHIGH:
1080 case SK_PNMI_HTX_OCTETLOW:
1081 case SK_PNMI_HTX_RESERVED:
1082 case SK_PNMI_HRX_OCTETHIGH:
1083 case SK_PNMI_HRX_OCTETLOW:
1084 case SK_PNMI_HRX_IRLENGTH:
1085 case SK_PNMI_HRX_RESERVED:
1088 * the following counters aren't be handled (id > 63)
1090 case SK_PNMI_HTX_SYNC:
1091 case SK_PNMI_HTX_SYNC_OCTET:
1094 case SK_PNMI_HRX_LONGFRAMES:
1095 if (MacType == SK_MAC_GMAC) {
1096 pAC->Pnmi.Port[PhysPortIndex].
1097 CounterHigh[CounterIndex] ++;
1102 pAC->Pnmi.Port[PhysPortIndex].
1103 CounterHigh[CounterIndex] ++;
1108 case SK_PNMI_EVT_SEN_WAR_LOW:
1110 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1112 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1113 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1114 (unsigned int)Param.Para64));
1120 * Store a trap message in the trap buffer and generate
1121 * an event for user space applications with the
1122 * SK_DRIVER_SENDEVENT macro.
1124 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1125 (unsigned int)Param.Para64);
1126 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1129 case SK_PNMI_EVT_SEN_WAR_UPP:
1131 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1133 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1134 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1135 (unsigned int)Param.Para64));
1141 * Store a trap message in the trap buffer and generate
1142 * an event for user space applications with the
1143 * SK_DRIVER_SENDEVENT macro.
1145 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1146 (unsigned int)Param.Para64);
1147 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1150 case SK_PNMI_EVT_SEN_ERR_LOW:
1152 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1154 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1155 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1156 (unsigned int)Param.Para64));
1162 * Store a trap message in the trap buffer and generate
1163 * an event for user space applications with the
1164 * SK_DRIVER_SENDEVENT macro.
1166 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1167 (unsigned int)Param.Para64);
1168 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1171 case SK_PNMI_EVT_SEN_ERR_UPP:
1173 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1175 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1176 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1177 (unsigned int)Param.Para64));
1183 * Store a trap message in the trap buffer and generate
1184 * an event for user space applications with the
1185 * SK_DRIVER_SENDEVENT macro.
1187 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1188 (unsigned int)Param.Para64);
1189 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1192 case SK_PNMI_EVT_CHG_EST_TIMER:
1194 * Calculate port switch average on a per hour basis
1195 * Time interval for check : 28125 ms
1196 * Number of values for average : 8
1198 * Be careful in changing these values, on change check
1199 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1200 * array one less than value number)
1201 * - Timer initialization SkTimerStart() in SkPnmiInit
1202 * - Delta value below must be multiplicated with
1206 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1207 CounterIndex = pEst->EstValueIndex + 1;
1208 if (CounterIndex == 7) {
1212 pEst->EstValueIndex = CounterIndex;
1214 NewestValue = pAC->Pnmi.RlmtChangeCts;
1215 OldestValue = pEst->EstValue[CounterIndex];
1216 pEst->EstValue[CounterIndex] = NewestValue;
1219 * Calculate average. Delta stores the number of
1220 * port switches per 28125 * 8 = 225000 ms
1222 if (NewestValue >= OldestValue) {
1224 Delta = NewestValue - OldestValue;
1227 /* Overflow situation */
1228 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1232 * Extrapolate delta to port switches per hour.
1233 * Estimate = Delta * (3600000 / 225000)
1237 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1240 * Check if threshold is exceeded. If the threshold is
1241 * permanently exceeded every 28125 ms an event will be
1242 * generated to remind the user of this condition.
1244 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1245 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1246 pAC->Pnmi.RlmtChangeThreshold)) {
1248 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1249 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1252 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1253 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1254 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1258 case SK_PNMI_EVT_CLEAR_COUNTER:
1260 * Param.Para32[0] contains the NetIndex (0 ..1).
1261 * Param.Para32[1] is reserved, contains -1.
1263 NetIndex = (SK_U32)Param.Para32[0];
1266 if (NetIndex >= pAC->Rlmt.NumNets) {
1268 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1269 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1277 * Set all counters and timestamps to zero.
1278 * The according NetIndex is required as a
1279 * parameter of the event.
1281 ResetCounter(pAC, IoC, NetIndex);
1284 case SK_PNMI_EVT_XMAC_RESET:
1286 * To grant continuous counter values store the current
1287 * XMAC statistic values to the entries 1..n of the
1288 * CounterOffset array. XMAC Errata #2
1291 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1293 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1294 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1295 (unsigned int)Param.Para64));
1299 PhysPortIndex = (unsigned int)Param.Para64;
1302 * Update XMAC statistic to get fresh values
1304 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1305 if (Ret != SK_PNMI_ERR_OK) {
1307 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1311 * Increment semaphore to indicate that an update was
1314 pAC->Pnmi.MacUpdatedFlag ++;
1316 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1319 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1324 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1325 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1327 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1330 pAC->Pnmi.MacUpdatedFlag --;
1333 case SK_PNMI_EVT_RLMT_PORT_UP:
1334 PhysPortIndex = (unsigned int)Param.Para32[0];
1336 if (PhysPortIndex >= SK_MAX_MACS) {
1338 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1339 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1340 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1347 * Store a trap message in the trap buffer and generate an event for
1348 * user space applications with the SK_DRIVER_SENDEVENT macro.
1350 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1351 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1353 /* Bugfix for XMAC errata (#10620)*/
1354 if (MacType == SK_MAC_XMAC) {
1355 /* Add incremental difference to offset (#10620)*/
1356 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1357 XM_RXE_SHT_ERR, &Val32);
1359 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1360 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1361 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1362 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1365 /* Tell VctStatus() that a link was up meanwhile. */
1366 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1369 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1370 PhysPortIndex = (unsigned int)Param.Para32[0];
1373 if (PhysPortIndex >= SK_MAX_MACS) {
1375 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1376 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1377 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1384 * Store a trap message in the trap buffer and generate an event for
1385 * user space applications with the SK_DRIVER_SENDEVENT macro.
1387 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1388 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1390 /* Bugfix #10620 - get zero level for incremental difference */
1391 if (MacType == SK_MAC_XMAC) {
1393 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1394 XM_RXE_SHT_ERR, &Val32);
1396 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1397 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1398 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1402 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1403 PhysPortIndex = (unsigned int)Param.Para32[0];
1404 NetIndex = (SK_U32)Param.Para32[1];
1407 if (PhysPortIndex >= SK_MAX_MACS) {
1409 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1410 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1414 if (NetIndex >= pAC->Rlmt.NumNets) {
1416 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1417 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1423 * For now, ignore event if NetIndex != 0.
1425 if (Param.Para32[1] != 0) {
1431 * Nothing to do if port is already inactive
1433 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1439 * Update statistic counters to calculate new offset for the virtual
1440 * port and increment semaphore to indicate that an update was already
1443 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1446 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1449 pAC->Pnmi.MacUpdatedFlag ++;
1452 * Calculate new counter offset for virtual port to grant continous
1453 * counting on port switches. The virtual port consists of all currently
1454 * active ports. The port down event indicates that a port is removed
1455 * from the virtual port. Therefore add the counter value of the removed
1456 * port to the CounterOffset for the virtual port to grant the same
1459 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1462 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1467 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1469 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1473 * Set port to inactive
1475 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1477 pAC->Pnmi.MacUpdatedFlag --;
1480 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1481 PhysPortIndex = (unsigned int)Param.Para32[0];
1482 NetIndex = (SK_U32)Param.Para32[1];
1485 if (PhysPortIndex >= SK_MAX_MACS) {
1487 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1488 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1492 if (NetIndex >= pAC->Rlmt.NumNets) {
1494 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1495 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1501 * For now, ignore event if NetIndex != 0.
1503 if (Param.Para32[1] != 0) {
1509 * Nothing to do if port is already active
1511 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1517 * Statistic maintenance
1519 pAC->Pnmi.RlmtChangeCts ++;
1520 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1523 * Store a trap message in the trap buffer and generate an event for
1524 * user space applications with the SK_DRIVER_SENDEVENT macro.
1526 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1527 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1530 * Update statistic counters to calculate new offset for the virtual
1531 * port and increment semaphore to indicate that an update was
1534 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1537 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1540 pAC->Pnmi.MacUpdatedFlag ++;
1543 * Calculate new counter offset for virtual port to grant continous
1544 * counting on port switches. A new port is added to the virtual port.
1545 * Therefore substract the counter value of the new port from the
1546 * CounterOffset for the virtual port to grant the same value.
1548 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1551 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1556 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1558 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1561 /* Set port to active */
1562 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1564 pAC->Pnmi.MacUpdatedFlag --;
1567 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1569 * Para.Para32[0] contains the NetIndex.
1573 * Store a trap message in the trap buffer and generate an event for
1574 * user space applications with the SK_DRIVER_SENDEVENT macro.
1576 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1577 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1580 case SK_PNMI_EVT_RLMT_SET_NETS:
1582 * Param.Para32[0] contains the number of Nets.
1583 * Param.Para32[1] is reserved, contains -1.
1586 * Check number of nets
1588 MaxNetNumber = pAC->GIni.GIMacsFound;
1589 if (((unsigned int)Param.Para32[0] < 1)
1590 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1591 return (SK_PNMI_ERR_UNKNOWN_NET);
1594 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1595 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1597 else { /* dual net mode */
1598 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1602 case SK_PNMI_EVT_VCT_RESET:
1603 PhysPortIndex = Param.Para32[0];
1604 pPrt = &pAC->GIni.GP[PhysPortIndex];
1605 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1607 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1608 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1611 * VCT test is still running.
1612 * Start VCT timer counter again.
1614 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1615 Param.Para32[0] = PhysPortIndex;
1616 Param.Para32[1] = -1;
1617 SkTimerStart(pAC, IoC,
1618 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1619 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1622 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1623 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1624 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1626 /* Copy results for later use to PNMI struct. */
1627 for (i = 0; i < 4; i++) {
1628 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1629 if ((pPrt->PMdiPairLen[i] > 35) &&
1630 (pPrt->PMdiPairLen[i] < 0xff)) {
1631 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1634 if ((pPrt->PMdiPairLen[i] > 35) &&
1635 (pPrt->PMdiPairLen[i] != 0xff)) {
1636 CableLength = 1000 *
1637 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1642 pVctBackupData->PMdiPairLen[i] = CableLength;
1643 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1646 Param.Para32[0] = PhysPortIndex;
1647 Param.Para32[1] = -1;
1648 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1649 SkEventDispatcher(pAC, IoC);
1658 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1663 /******************************************************************************
1669 /*****************************************************************************
1671 * PnmiVar - Gets, presets, and sets single OIDs
1674 * Looks up the requested OID, calls the corresponding handler
1675 * function, and passes the parameters with the get, preset, or
1676 * set command. The function is called by SkGePnmiGetVar,
1677 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1680 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1681 * calling functions.
1682 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1684 PNMI_STATIC int PnmiVar(
1685 SK_AC *pAC, /* Pointer to adapter context */
1686 SK_IOC IoC, /* IO context handle */
1687 int Action, /* GET/PRESET/SET action */
1688 SK_U32 Id, /* Object ID that is to be processed */
1689 char *pBuf, /* Buffer used for the management data transfer */
1690 unsigned int *pLen, /* Total length of pBuf management data */
1691 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1692 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1694 unsigned int TableIndex;
1698 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1701 return (SK_PNMI_ERR_UNKNOWN_OID);
1704 /* Check NetIndex */
1705 if (NetIndex >= pAC->Rlmt.NumNets) {
1706 return (SK_PNMI_ERR_UNKNOWN_NET);
1709 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1711 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1712 Instance, TableIndex, NetIndex);
1714 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1719 /*****************************************************************************
1721 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1724 * The return value of the function will also be stored in
1725 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1726 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1727 * checks which OIDs are able to set, and calls the handler function of
1728 * the OID to perform the set. The return value of the function will
1729 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1730 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1731 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1734 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1735 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1737 PNMI_STATIC int PnmiStruct(
1738 SK_AC *pAC, /* Pointer to adapter context */
1739 SK_IOC IoC, /* IO context handle */
1740 int Action, /* PRESET/SET action to be performed */
1741 char *pBuf, /* Buffer used for the management data transfer */
1742 unsigned int *pLen, /* Length of pBuf management data buffer */
1743 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1746 unsigned int TableIndex;
1747 unsigned int DstOffset;
1749 unsigned int InstanceNo;
1750 unsigned int InstanceCnt;
1755 /* Check if the passed buffer has the right size */
1756 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1758 /* Check if we can return the error within the buffer */
1759 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1761 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1765 *pLen = SK_PNMI_STRUCT_SIZE;
1766 return (SK_PNMI_ERR_TOO_SHORT);
1769 /* Check NetIndex */
1770 if (NetIndex >= pAC->Rlmt.NumNets) {
1771 return (SK_PNMI_ERR_UNKNOWN_NET);
1774 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1777 * Update the values of RLMT and SIRQ and increment semaphores to
1778 * indicate that an update was already done.
1780 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1782 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1783 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1787 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1789 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1790 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1794 pAC->Pnmi.RlmtUpdatedFlag ++;
1795 pAC->Pnmi.SirqUpdatedFlag ++;
1797 /* Preset/Set values */
1798 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1800 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1801 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1806 InstanceNo = IdTable[TableIndex].InstanceNo;
1807 Id = IdTable[TableIndex].Id;
1809 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1812 DstOffset = IdTable[TableIndex].Offset +
1814 IdTable[TableIndex].StructSize;
1817 * Because VPD multiple instance variables are
1818 * not setable we do not need to evaluate VPD
1819 * instances. Have a look to VPD instance
1820 * calculation in SkPnmiGetStruct().
1822 Instance = (SK_U32)InstanceCnt;
1825 * Evaluate needed buffer length
1828 Ret = IdTable[TableIndex].Func(pAC, IoC,
1829 SK_PNMI_GET, IdTable[TableIndex].Id,
1830 NULL, &Len, Instance, TableIndex, NetIndex);
1832 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1836 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1838 pAC->Pnmi.RlmtUpdatedFlag --;
1839 pAC->Pnmi.SirqUpdatedFlag --;
1841 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1842 SK_PNMI_SET_STAT(pBuf,
1843 SK_PNMI_ERR_GENERAL, DstOffset);
1844 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1845 return (SK_PNMI_ERR_GENERAL);
1847 if (Id == OID_SKGE_VPD_ACTION) {
1849 switch (*(pBuf + DstOffset)) {
1851 case SK_PNMI_VPD_CREATE:
1852 Len = 3 + *(pBuf + DstOffset + 3);
1855 case SK_PNMI_VPD_DELETE:
1865 /* Call the OID handler function */
1866 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1867 IdTable[TableIndex].Id, pBuf + DstOffset,
1868 &Len, Instance, TableIndex, NetIndex);
1870 if (Ret != SK_PNMI_ERR_OK) {
1872 pAC->Pnmi.RlmtUpdatedFlag --;
1873 pAC->Pnmi.SirqUpdatedFlag --;
1875 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1876 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1878 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1879 return (SK_PNMI_ERR_BAD_VALUE);
1884 pAC->Pnmi.RlmtUpdatedFlag --;
1885 pAC->Pnmi.SirqUpdatedFlag --;
1887 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1888 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1889 return (SK_PNMI_ERR_OK);
1892 /*****************************************************************************
1894 * LookupId - Lookup an OID in the IdTable
1897 * Scans the IdTable to find the table entry of an OID.
1900 * The table index or -1 if not found.
1902 PNMI_STATIC int LookupId(
1903 SK_U32 Id) /* Object identifier to be searched */
1907 for (i = 0; i < ID_TABLE_SIZE; i++) {
1909 if (IdTable[i].Id == Id) {
1918 /*****************************************************************************
1920 * OidStruct - Handler of OID_SKGE_ALL_DATA
1923 * This OID performs a Get/Preset/SetStruct call and returns all data
1924 * in a SK_PNMI_STRUCT_DATA structure.
1927 * SK_PNMI_ERR_OK The request was successfully performed.
1928 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1929 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1930 * the correct data (e.g. a 32bit value is
1931 * needed, but a 16 bit value was passed).
1932 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1934 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1935 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1936 * exist (e.g. port instance 3 on a two port
1939 PNMI_STATIC int OidStruct(
1940 SK_AC *pAC, /* Pointer to adapter context */
1941 SK_IOC IoC, /* IO context handle */
1942 int Action, /* GET/PRESET/SET action */
1943 SK_U32 Id, /* Object ID that is to be processed */
1944 char *pBuf, /* Buffer used for the management data transfer */
1945 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1946 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1947 unsigned int TableIndex, /* Index to the Id table */
1948 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1950 if (Id != OID_SKGE_ALL_DATA) {
1952 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1956 return (SK_PNMI_ERR_GENERAL);
1960 * Check instance. We only handle single instance variables
1962 if (Instance != (SK_U32)(-1) && Instance != 1) {
1965 return (SK_PNMI_ERR_UNKNOWN_INST);
1971 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1973 case SK_PNMI_PRESET:
1974 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1977 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1980 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1983 return (SK_PNMI_ERR_GENERAL);
1986 /*****************************************************************************
1988 * Perform - OID handler of OID_SKGE_ACTION
1994 * SK_PNMI_ERR_OK The request was successfully performed.
1995 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1996 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1997 * the correct data (e.g. a 32bit value is
1998 * needed, but a 16 bit value was passed).
1999 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2001 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2002 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2003 * exist (e.g. port instance 3 on a two port
2006 PNMI_STATIC int Perform(
2007 SK_AC *pAC, /* Pointer to adapter context */
2008 SK_IOC IoC, /* IO context handle */
2009 int Action, /* GET/PRESET/SET action */
2010 SK_U32 Id, /* Object ID that is to be processed */
2011 char *pBuf, /* Buffer used for the management data transfer */
2012 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2013 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2014 unsigned int TableIndex, /* Index to the Id table */
2015 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2022 * Check instance. We only handle single instance variables
2024 if (Instance != (SK_U32)(-1) && Instance != 1) {
2027 return (SK_PNMI_ERR_UNKNOWN_INST);
2030 if (*pLen < sizeof(SK_U32)) {
2032 *pLen = sizeof(SK_U32);
2033 return (SK_PNMI_ERR_TOO_SHORT);
2036 /* Check if a get should be performed */
2037 if (Action == SK_PNMI_GET) {
2039 /* A get is easy. We always return the same value */
2040 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2041 SK_PNMI_STORE_U32(pBuf, ActionOp);
2042 *pLen = sizeof(SK_U32);
2044 return (SK_PNMI_ERR_OK);
2047 /* Continue with PRESET/SET action */
2048 if (*pLen > sizeof(SK_U32)) {
2050 return (SK_PNMI_ERR_BAD_VALUE);
2053 /* Check if the command is a known one */
2054 SK_PNMI_READ_U32(pBuf, ActionOp);
2055 if (*pLen > sizeof(SK_U32) ||
2056 (ActionOp != SK_PNMI_ACT_IDLE &&
2057 ActionOp != SK_PNMI_ACT_RESET &&
2058 ActionOp != SK_PNMI_ACT_SELFTEST &&
2059 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2062 return (SK_PNMI_ERR_BAD_VALUE);
2065 /* A preset ends here */
2066 if (Action == SK_PNMI_PRESET) {
2068 return (SK_PNMI_ERR_OK);
2073 case SK_PNMI_ACT_IDLE:
2077 case SK_PNMI_ACT_RESET:
2079 * Perform a driver reset or something that comes near
2082 Ret = SK_DRIVER_RESET(pAC, IoC);
2085 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2088 return (SK_PNMI_ERR_GENERAL);
2092 case SK_PNMI_ACT_SELFTEST:
2094 * Perform a driver selftest or something similar to this.
2095 * Currently this feature is not used and will probably
2096 * implemented in another way.
2098 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2099 pAC->Pnmi.TestResult = Ret;
2102 case SK_PNMI_ACT_RESETCNT:
2103 /* Set all counters and timestamps to zero */
2104 ResetCounter(pAC, IoC, NetIndex);
2108 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2111 return (SK_PNMI_ERR_GENERAL);
2114 return (SK_PNMI_ERR_OK);
2117 /*****************************************************************************
2119 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2122 * Retrieves the statistic values of the virtual port (logical
2123 * index 0). Only special OIDs of NDIS are handled which consist
2124 * of a 32 bit instead of a 64 bit value. The OIDs are public
2125 * because perhaps some other platform can use them too.
2128 * SK_PNMI_ERR_OK The request was successfully performed.
2129 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2130 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2131 * the correct data (e.g. a 32bit value is
2132 * needed, but a 16 bit value was passed).
2133 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2134 * exist (e.g. port instance 3 on a two port
2137 PNMI_STATIC int Mac8023Stat(
2138 SK_AC *pAC, /* Pointer to adapter context */
2139 SK_IOC IoC, /* IO context handle */
2140 int Action, /* GET/PRESET/SET action */
2141 SK_U32 Id, /* Object ID that is to be processed */
2142 char *pBuf, /* Buffer used for the management data transfer */
2143 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2144 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2145 unsigned int TableIndex, /* Index to the Id table */
2146 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2151 SK_BOOL Is64BitReq = SK_FALSE;
2154 * Only the active Mac is returned
2156 if (Instance != (SK_U32)(-1) && Instance != 1) {
2159 return (SK_PNMI_ERR_UNKNOWN_INST);
2165 if (Action != SK_PNMI_GET) {
2168 return (SK_PNMI_ERR_READ_ONLY);
2174 case OID_802_3_PERMANENT_ADDRESS:
2175 case OID_802_3_CURRENT_ADDRESS:
2176 if (*pLen < sizeof(SK_MAC_ADDR)) {
2178 *pLen = sizeof(SK_MAC_ADDR);
2179 return (SK_PNMI_ERR_TOO_SHORT);
2184 #ifndef SK_NDIS_64BIT_CTR
2185 if (*pLen < sizeof(SK_U32)) {
2186 *pLen = sizeof(SK_U32);
2187 return (SK_PNMI_ERR_TOO_SHORT);
2190 #else /* SK_NDIS_64BIT_CTR */
2192 /* for compatibility, at least 32bit are required for OID */
2193 if (*pLen < sizeof(SK_U32)) {
2195 * but indicate handling for 64bit values,
2196 * if insufficient space is provided
2198 *pLen = sizeof(SK_U64);
2199 return (SK_PNMI_ERR_TOO_SHORT);
2202 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2203 #endif /* SK_NDIS_64BIT_CTR */
2208 * Update all statistics, because we retrieve virtual MAC, which
2209 * consists of multiple physical statistics and increment semaphore
2210 * to indicate that an update was already done.
2212 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2213 if ( Ret != SK_PNMI_ERR_OK) {
2218 pAC->Pnmi.MacUpdatedFlag ++;
2221 * Get value (MAC Index 0 identifies the virtual MAC)
2225 case OID_802_3_PERMANENT_ADDRESS:
2226 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2227 *pLen = sizeof(SK_MAC_ADDR);
2230 case OID_802_3_CURRENT_ADDRESS:
2231 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2232 *pLen = sizeof(SK_MAC_ADDR);
2236 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2238 /* by default 32bit values are evaluated */
2240 StatVal32 = (SK_U32)StatVal;
2241 SK_PNMI_STORE_U32(pBuf, StatVal32);
2242 *pLen = sizeof(SK_U32);
2245 SK_PNMI_STORE_U64(pBuf, StatVal);
2246 *pLen = sizeof(SK_U64);
2251 pAC->Pnmi.MacUpdatedFlag --;
2253 return (SK_PNMI_ERR_OK);
2256 /*****************************************************************************
2258 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2261 * Retrieves the MAC statistic data.
2264 * SK_PNMI_ERR_OK The request was successfully performed.
2265 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2266 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2267 * the correct data (e.g. a 32bit value is
2268 * needed, but a 16 bit value was passed).
2269 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2270 * exist (e.g. port instance 3 on a two port
2273 PNMI_STATIC int MacPrivateStat(
2274 SK_AC *pAC, /* Pointer to adapter context */
2275 SK_IOC IoC, /* IO context handle */
2276 int Action, /* GET/PRESET/SET action */
2277 SK_U32 Id, /* Object ID that is to be processed */
2278 char *pBuf, /* Buffer used for the management data transfer */
2279 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2280 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2281 unsigned int TableIndex, /* Index to the Id table */
2282 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2284 unsigned int LogPortMax;
2285 unsigned int LogPortIndex;
2286 unsigned int PhysPortMax;
2288 unsigned int Offset;
2295 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2296 PhysPortMax = pAC->GIni.GIMacsFound;
2297 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2299 MacType = pAC->GIni.GIMacType;
2301 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2305 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2306 /* Check instance range */
2307 if ((Instance < 1) || (Instance > LogPortMax)) {
2310 return (SK_PNMI_ERR_UNKNOWN_INST);
2312 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2313 Limit = LogPortIndex + 1;
2316 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2323 if (Action != SK_PNMI_GET) {
2326 return (SK_PNMI_ERR_READ_ONLY);
2330 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2332 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2333 return (SK_PNMI_ERR_TOO_SHORT);
2337 * Update MAC statistic and increment semaphore to indicate that
2338 * an update was already done.
2340 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2341 if (Ret != SK_PNMI_ERR_OK) {
2346 pAC->Pnmi.MacUpdatedFlag ++;
2350 for (; LogPortIndex < Limit; LogPortIndex ++) {
2354 /* XXX not yet implemented due to XMAC problems
2355 case OID_SKGE_STAT_TX_UTIL:
2356 return (SK_PNMI_ERR_GENERAL);
2358 /* XXX not yet implemented due to XMAC problems
2359 case OID_SKGE_STAT_RX_UTIL:
2360 return (SK_PNMI_ERR_GENERAL);
2362 case OID_SKGE_STAT_RX:
2363 if (MacType == SK_MAC_GMAC) {
2365 GetStatVal(pAC, IoC, LogPortIndex,
2366 SK_PNMI_HRX_BROADCAST, NetIndex) +
2367 GetStatVal(pAC, IoC, LogPortIndex,
2368 SK_PNMI_HRX_MULTICAST, NetIndex) +
2369 GetStatVal(pAC, IoC, LogPortIndex,
2370 SK_PNMI_HRX_UNICAST, NetIndex) +
2371 GetStatVal(pAC, IoC, LogPortIndex,
2372 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2375 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2376 IdTable[TableIndex].Param, NetIndex);
2380 case OID_SKGE_STAT_TX:
2381 if (MacType == SK_MAC_GMAC) {
2383 GetStatVal(pAC, IoC, LogPortIndex,
2384 SK_PNMI_HTX_BROADCAST, NetIndex) +
2385 GetStatVal(pAC, IoC, LogPortIndex,
2386 SK_PNMI_HTX_MULTICAST, NetIndex) +
2387 GetStatVal(pAC, IoC, LogPortIndex,
2388 SK_PNMI_HTX_UNICAST, NetIndex);
2391 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2392 IdTable[TableIndex].Param, NetIndex);
2397 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2398 IdTable[TableIndex].Param, NetIndex);
2400 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2402 Offset += sizeof(SK_U64);
2406 pAC->Pnmi.MacUpdatedFlag --;
2408 return (SK_PNMI_ERR_OK);
2411 /*****************************************************************************
2413 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2416 * Get/Presets/Sets the current and factory MAC address. The MAC
2417 * address of the virtual port, which is reported to the OS, may
2418 * not be changed, but the physical ones. A set to the virtual port
2419 * will be ignored. No error should be reported because otherwise
2420 * a multiple instance set (-1) would always fail.
2423 * SK_PNMI_ERR_OK The request was successfully performed.
2424 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2425 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2426 * the correct data (e.g. a 32bit value is
2427 * needed, but a 16 bit value was passed).
2428 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2430 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2431 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2432 * exist (e.g. port instance 3 on a two port
2435 PNMI_STATIC int Addr(
2436 SK_AC *pAC, /* Pointer to adapter context */
2437 SK_IOC IoC, /* IO context handle */
2438 int Action, /* GET/PRESET/SET action */
2439 SK_U32 Id, /* Object ID that is to be processed */
2440 char *pBuf, /* Buffer used for the management data transfer */
2441 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2442 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2443 unsigned int TableIndex, /* Index to the Id table */
2444 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2447 unsigned int LogPortMax;
2448 unsigned int PhysPortMax;
2449 unsigned int LogPortIndex;
2450 unsigned int PhysPortIndex;
2452 unsigned int Offset = 0;
2455 * Calculate instance if wished. MAC index 0 is the virtual
2458 PhysPortMax = pAC->GIni.GIMacsFound;
2459 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2461 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2465 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2466 /* Check instance range */
2467 if ((Instance < 1) || (Instance > LogPortMax)) {
2470 return (SK_PNMI_ERR_UNKNOWN_INST);
2472 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2473 Limit = LogPortIndex + 1;
2475 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2484 if (Action == SK_PNMI_GET) {
2487 if (*pLen < (Limit - LogPortIndex) * 6) {
2489 *pLen = (Limit - LogPortIndex) * 6;
2490 return (SK_PNMI_ERR_TOO_SHORT);
2496 for (; LogPortIndex < Limit; LogPortIndex ++) {
2500 case OID_SKGE_PHYS_CUR_ADDR:
2501 if (LogPortIndex == 0) {
2502 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2505 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2507 CopyMac(pBuf + Offset,
2508 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2513 case OID_SKGE_PHYS_FAC_ADDR:
2514 if (LogPortIndex == 0) {
2515 CopyMac(pBuf + Offset,
2516 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2519 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2522 CopyMac(pBuf + Offset,
2523 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2529 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2533 return (SK_PNMI_ERR_GENERAL);
2541 * The logical MAC address may not be changed only
2544 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2547 return (SK_PNMI_ERR_READ_ONLY);
2551 * Only the current address may be changed
2553 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2555 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2559 return (SK_PNMI_ERR_GENERAL);
2563 if (*pLen < (Limit - LogPortIndex) * 6) {
2565 *pLen = (Limit - LogPortIndex) * 6;
2566 return (SK_PNMI_ERR_TOO_SHORT);
2568 if (*pLen > (Limit - LogPortIndex) * 6) {
2571 return (SK_PNMI_ERR_BAD_VALUE);
2577 if (Action == SK_PNMI_PRESET) {
2580 return (SK_PNMI_ERR_OK);
2584 * Set OID_SKGE_MAC_CUR_ADDR
2586 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2589 * A set to virtual port and set of broadcast
2590 * address will be ignored
2592 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2593 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2598 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2601 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2602 (SK_MAC_ADDR *)(pBuf + Offset),
2603 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2604 SK_ADDR_PHYSICAL_ADDRESS));
2605 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2607 return (SK_PNMI_ERR_GENERAL);
2613 return (SK_PNMI_ERR_OK);
2616 /*****************************************************************************
2618 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2621 * Retrieves the statistic values of the CSUM module. The CSUM data
2622 * structure must be available in the SK_AC even if the CSUM module
2623 * is not included, because PNMI reads the statistic data from the
2624 * CSUM part of SK_AC directly.
2627 * SK_PNMI_ERR_OK The request was successfully performed.
2628 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2629 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2630 * the correct data (e.g. a 32bit value is
2631 * needed, but a 16 bit value was passed).
2632 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2633 * exist (e.g. port instance 3 on a two port
2636 PNMI_STATIC int CsumStat(
2637 SK_AC *pAC, /* Pointer to adapter context */
2638 SK_IOC IoC, /* IO context handle */
2639 int Action, /* GET/PRESET/SET action */
2640 SK_U32 Id, /* Object ID that is to be processed */
2641 char *pBuf, /* Buffer used for the management data transfer */
2642 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2643 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2644 unsigned int TableIndex, /* Index to the Id table */
2645 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2649 unsigned int Offset = 0;
2654 * Calculate instance if wished
2656 if (Instance != (SK_U32)(-1)) {
2658 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2661 return (SK_PNMI_ERR_UNKNOWN_INST);
2663 Index = (unsigned int)Instance - 1;
2668 Limit = SKCS_NUM_PROTOCOLS;
2674 if (Action != SK_PNMI_GET) {
2677 return (SK_PNMI_ERR_READ_ONLY);
2681 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2683 *pLen = (Limit - Index) * sizeof(SK_U64);
2684 return (SK_PNMI_ERR_TOO_SHORT);
2690 for (; Index < Limit; Index ++) {
2694 case OID_SKGE_CHKSM_RX_OK_CTS:
2695 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2698 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2699 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2702 case OID_SKGE_CHKSM_RX_ERR_CTS:
2703 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2706 case OID_SKGE_CHKSM_TX_OK_CTS:
2707 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2710 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2711 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2715 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2719 return (SK_PNMI_ERR_GENERAL);
2722 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2723 Offset += sizeof(SK_U64);
2727 * Store used buffer space
2731 return (SK_PNMI_ERR_OK);
2734 /*****************************************************************************
2736 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2739 * Retrieves the statistic values of the I2C module, which handles
2740 * the temperature and voltage sensors.
2743 * SK_PNMI_ERR_OK The request was successfully performed.
2744 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2745 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2746 * the correct data (e.g. a 32bit value is
2747 * needed, but a 16 bit value was passed).
2748 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2749 * exist (e.g. port instance 3 on a two port
2752 PNMI_STATIC int SensorStat(
2753 SK_AC *pAC, /* Pointer to adapter context */
2754 SK_IOC IoC, /* IO context handle */
2755 int Action, /* GET/PRESET/SET action */
2756 SK_U32 Id, /* Object ID that is to be processed */
2757 char *pBuf, /* Buffer used for the management data transfer */
2758 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2759 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2760 unsigned int TableIndex, /* Index to the Id table */
2761 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2766 unsigned int Offset;
2773 * Calculate instance if wished
2775 if ((Instance != (SK_U32)(-1))) {
2777 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2780 return (SK_PNMI_ERR_UNKNOWN_INST);
2783 Index = (unsigned int)Instance -1;
2784 Limit = (unsigned int)Instance;
2788 Limit = (unsigned int) pAC->I2c.MaxSens;
2794 if (Action != SK_PNMI_GET) {
2797 return (SK_PNMI_ERR_READ_ONLY);
2803 case OID_SKGE_SENSOR_VALUE:
2804 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2805 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2806 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2807 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2808 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2810 *pLen = (Limit - Index) * sizeof(SK_U32);
2811 return (SK_PNMI_ERR_TOO_SHORT);
2815 case OID_SKGE_SENSOR_DESCR:
2816 for (Offset = 0, i = Index; i < Limit; i ++) {
2818 Len = (unsigned int)
2819 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2820 if (Len >= SK_PNMI_STRINGLEN2) {
2822 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2826 return (SK_PNMI_ERR_GENERAL);
2830 if (*pLen < Offset) {
2833 return (SK_PNMI_ERR_TOO_SHORT);
2837 case OID_SKGE_SENSOR_INDEX:
2838 case OID_SKGE_SENSOR_TYPE:
2839 case OID_SKGE_SENSOR_STATUS:
2840 if (*pLen < Limit - Index) {
2842 *pLen = Limit - Index;
2843 return (SK_PNMI_ERR_TOO_SHORT);
2847 case OID_SKGE_SENSOR_WAR_CTS:
2848 case OID_SKGE_SENSOR_WAR_TIME:
2849 case OID_SKGE_SENSOR_ERR_CTS:
2850 case OID_SKGE_SENSOR_ERR_TIME:
2851 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2853 *pLen = (Limit - Index) * sizeof(SK_U64);
2854 return (SK_PNMI_ERR_TOO_SHORT);
2859 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2863 return (SK_PNMI_ERR_GENERAL);
2870 for (Offset = 0; Index < Limit; Index ++) {
2874 case OID_SKGE_SENSOR_INDEX:
2875 *(pBuf + Offset) = (char)Index;
2876 Offset += sizeof(char);
2879 case OID_SKGE_SENSOR_DESCR:
2880 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2881 SK_MEMCPY(pBuf + Offset + 1,
2882 pAC->I2c.SenTable[Index].SenDesc, Len);
2883 *(pBuf + Offset) = (char)Len;
2887 case OID_SKGE_SENSOR_TYPE:
2889 (char)pAC->I2c.SenTable[Index].SenType;
2890 Offset += sizeof(char);
2893 case OID_SKGE_SENSOR_VALUE:
2894 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2895 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2896 Offset += sizeof(SK_U32);
2899 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2900 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2902 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2903 Offset += sizeof(SK_U32);
2906 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2907 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2909 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2910 Offset += sizeof(SK_U32);
2913 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2914 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2916 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2917 Offset += sizeof(SK_U32);
2920 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2921 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2922 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2923 Offset += sizeof(SK_U32);
2926 case OID_SKGE_SENSOR_STATUS:
2928 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2929 Offset += sizeof(char);
2932 case OID_SKGE_SENSOR_WAR_CTS:
2933 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2934 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2935 Offset += sizeof(SK_U64);
2938 case OID_SKGE_SENSOR_ERR_CTS:
2939 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2940 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2941 Offset += sizeof(SK_U64);
2944 case OID_SKGE_SENSOR_WAR_TIME:
2945 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2947 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2948 Offset += sizeof(SK_U64);
2951 case OID_SKGE_SENSOR_ERR_TIME:
2952 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2954 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2955 Offset += sizeof(SK_U64);
2959 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2960 ("SensorStat: Unknown OID should be handled before"));
2962 return (SK_PNMI_ERR_GENERAL);
2967 * Store used buffer space
2971 return (SK_PNMI_ERR_OK);
2974 /*****************************************************************************
2976 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2979 * Get/preset/set of VPD data. As instance the name of a VPD key
2980 * can be passed. The Instance parameter is a SK_U32 and can be
2981 * used as a string buffer for the VPD key, because their maximum
2985 * SK_PNMI_ERR_OK The request was successfully performed.
2986 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2987 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2988 * the correct data (e.g. a 32bit value is
2989 * needed, but a 16 bit value was passed).
2990 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2992 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2993 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2994 * exist (e.g. port instance 3 on a two port
2997 PNMI_STATIC int Vpd(
2998 SK_AC *pAC, /* Pointer to adapter context */
2999 SK_IOC IoC, /* IO context handle */
3000 int Action, /* GET/PRESET/SET action */
3001 SK_U32 Id, /* Object ID that is to be processed */
3002 char *pBuf, /* Buffer used for the management data transfer */
3003 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3004 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3005 unsigned int TableIndex, /* Index to the Id table */
3006 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3008 SK_VPD_STATUS *pVpdStatus;
3009 unsigned int BufLen;
3011 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3012 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3014 unsigned int Offset;
3016 unsigned int FirstIndex;
3017 unsigned int LastIndex;
3023 * Get array of all currently stored VPD keys
3025 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3026 if (Ret != SK_PNMI_ERR_OK) {
3032 * If instance is not -1, try to find the requested VPD key for
3033 * the multiple instance variables. The other OIDs as for example
3034 * OID VPD_ACTION are single instance variables and must be
3035 * handled separatly.
3040 if ((Instance != (SK_U32)(-1))) {
3042 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3043 Id == OID_SKGE_VPD_ACCESS) {
3045 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3048 for (Index = 0; Index < KeyNo; Index ++) {
3050 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3052 LastIndex = Index+1;
3056 if (Index == KeyNo) {
3059 return (SK_PNMI_ERR_UNKNOWN_INST);
3062 else if (Instance != 1) {
3065 return (SK_PNMI_ERR_UNKNOWN_INST);
3070 * Get value, if a query should be performed
3072 if (Action == SK_PNMI_GET) {
3076 case OID_SKGE_VPD_FREE_BYTES:
3077 /* Check length of buffer */
3078 if (*pLen < sizeof(SK_U32)) {
3080 *pLen = sizeof(SK_U32);
3081 return (SK_PNMI_ERR_TOO_SHORT);
3083 /* Get number of free bytes */
3084 pVpdStatus = VpdStat(pAC, IoC);
3085 if (pVpdStatus == NULL) {
3087 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3091 return (SK_PNMI_ERR_GENERAL);
3093 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3095 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3099 return (SK_PNMI_ERR_GENERAL);
3102 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3103 SK_PNMI_STORE_U32(pBuf, Val32);
3104 *pLen = sizeof(SK_U32);
3107 case OID_SKGE_VPD_ENTRIES_LIST:
3109 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3111 Len += SK_STRLEN(KeyArr[Index]) + 1;
3116 return (SK_PNMI_ERR_TOO_SHORT);
3120 *(pBuf) = (char)Len - 1;
3121 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3123 Len = SK_STRLEN(KeyArr[Index]);
3124 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3128 if (Index < KeyNo - 1) {
3130 *(pBuf + Offset) = ' ';
3137 case OID_SKGE_VPD_ENTRIES_NUMBER:
3139 if (*pLen < sizeof(SK_U32)) {
3141 *pLen = sizeof(SK_U32);
3142 return (SK_PNMI_ERR_TOO_SHORT);
3145 Val32 = (SK_U32)KeyNo;
3146 SK_PNMI_STORE_U32(pBuf, Val32);
3147 *pLen = sizeof(SK_U32);
3150 case OID_SKGE_VPD_KEY:
3151 /* Check buffer length, if it is large enough */
3152 for (Len = 0, Index = FirstIndex;
3153 Index < LastIndex; Index ++) {
3155 Len += SK_STRLEN(KeyArr[Index]) + 1;
3160 return (SK_PNMI_ERR_TOO_SHORT);
3164 * Get the key to an intermediate buffer, because
3165 * we have to prepend a length byte.
3167 for (Offset = 0, Index = FirstIndex;
3168 Index < LastIndex; Index ++) {
3170 Len = SK_STRLEN(KeyArr[Index]);
3172 *(pBuf + Offset) = (char)Len;
3173 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3180 case OID_SKGE_VPD_VALUE:
3181 /* Check the buffer length if it is large enough */
3182 for (Offset = 0, Index = FirstIndex;
3183 Index < LastIndex; Index ++) {
3186 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3187 (int *)&BufLen) > 0 ||
3188 BufLen >= SK_PNMI_VPD_DATALEN) {
3190 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3194 return (SK_PNMI_ERR_GENERAL);
3196 Offset += BufLen + 1;
3198 if (*pLen < Offset) {
3201 return (SK_PNMI_ERR_TOO_SHORT);
3205 * Get the value to an intermediate buffer, because
3206 * we have to prepend a length byte.
3208 for (Offset = 0, Index = FirstIndex;
3209 Index < LastIndex; Index ++) {
3212 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3213 (int *)&BufLen) > 0 ||
3214 BufLen >= SK_PNMI_VPD_DATALEN) {
3216 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3221 return (SK_PNMI_ERR_GENERAL);
3224 *(pBuf + Offset) = (char)BufLen;
3225 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3226 Offset += BufLen + 1;
3231 case OID_SKGE_VPD_ACCESS:
3232 if (*pLen < LastIndex - FirstIndex) {
3234 *pLen = LastIndex - FirstIndex;
3235 return (SK_PNMI_ERR_TOO_SHORT);
3238 for (Offset = 0, Index = FirstIndex;
3239 Index < LastIndex; Index ++) {
3241 if (VpdMayWrite(KeyArr[Index])) {
3243 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3246 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3253 case OID_SKGE_VPD_ACTION:
3254 Offset = LastIndex - FirstIndex;
3255 if (*pLen < Offset) {
3258 return (SK_PNMI_ERR_TOO_SHORT);
3260 SK_MEMSET(pBuf, 0, Offset);
3265 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3269 return (SK_PNMI_ERR_GENERAL);
3273 /* The only OID which can be set is VPD_ACTION */
3274 if (Id != OID_SKGE_VPD_ACTION) {
3276 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3277 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3278 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3279 Id == OID_SKGE_VPD_KEY ||
3280 Id == OID_SKGE_VPD_VALUE ||
3281 Id == OID_SKGE_VPD_ACCESS) {
3284 return (SK_PNMI_ERR_READ_ONLY);
3287 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3291 return (SK_PNMI_ERR_GENERAL);
3295 * From this point we handle VPD_ACTION. Check the buffer
3296 * length. It should at least have the size of one byte.
3301 return (SK_PNMI_ERR_TOO_SHORT);
3305 * The first byte contains the VPD action type we should
3310 case SK_PNMI_VPD_IGNORE:
3314 case SK_PNMI_VPD_CREATE:
3316 * We have to create a new VPD entry or we modify
3317 * an existing one. Check first the buffer length.
3322 return (SK_PNMI_ERR_TOO_SHORT);
3324 KeyStr[0] = pBuf[1];
3325 KeyStr[1] = pBuf[2];
3329 * Is the entry writable or does it belong to the
3332 if (!VpdMayWrite(KeyStr)) {
3335 return (SK_PNMI_ERR_BAD_VALUE);
3338 Offset = (int)pBuf[3] & 0xFF;
3340 SK_MEMCPY(Buf, pBuf + 4, Offset);
3343 /* A preset ends here */
3344 if (Action == SK_PNMI_PRESET) {
3346 return (SK_PNMI_ERR_OK);
3349 /* Write the new entry or modify an existing one */
3350 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3351 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3354 return (SK_PNMI_ERR_BAD_VALUE);
3356 else if (Ret != SK_PNMI_VPD_OK) {
3358 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3362 return (SK_PNMI_ERR_GENERAL);
3366 * Perform an update of the VPD data. This is
3367 * not mandantory, but just to be sure.
3369 Ret = VpdUpdate(pAC, IoC);
3370 if (Ret != SK_PNMI_VPD_OK) {
3372 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3376 return (SK_PNMI_ERR_GENERAL);
3380 case SK_PNMI_VPD_DELETE:
3381 /* Check if the buffer size is plausible */
3385 return (SK_PNMI_ERR_TOO_SHORT);
3390 return (SK_PNMI_ERR_BAD_VALUE);
3392 KeyStr[0] = pBuf[1];
3393 KeyStr[1] = pBuf[2];
3396 /* Find the passed key in the array */
3397 for (Index = 0; Index < KeyNo; Index ++) {
3399 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3405 * If we cannot find the key it is wrong, so we
3406 * return an appropriate error value.
3408 if (Index == KeyNo) {
3411 return (SK_PNMI_ERR_BAD_VALUE);
3414 if (Action == SK_PNMI_PRESET) {
3416 return (SK_PNMI_ERR_OK);
3419 /* Ok, you wanted it and you will get it */
3420 Ret = VpdDelete(pAC, IoC, KeyStr);
3421 if (Ret != SK_PNMI_VPD_OK) {
3423 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3427 return (SK_PNMI_ERR_GENERAL);
3431 * Perform an update of the VPD data. This is
3432 * not mandantory, but just to be sure.
3434 Ret = VpdUpdate(pAC, IoC);
3435 if (Ret != SK_PNMI_VPD_OK) {
3437 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3441 return (SK_PNMI_ERR_GENERAL);
3447 return (SK_PNMI_ERR_BAD_VALUE);
3451 return (SK_PNMI_ERR_OK);
3454 /*****************************************************************************
3456 * General - OID handler function of various single instance OIDs
3459 * The code is simple. No description necessary.
3462 * SK_PNMI_ERR_OK The request was successfully performed.
3463 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3464 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3465 * the correct data (e.g. a 32bit value is
3466 * needed, but a 16 bit value was passed).
3467 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3468 * exist (e.g. port instance 3 on a two port
3471 PNMI_STATIC int General(
3472 SK_AC *pAC, /* Pointer to adapter context */
3473 SK_IOC IoC, /* IO context handle */
3474 int Action, /* GET/PRESET/SET action */
3475 SK_U32 Id, /* Object ID that is to be processed */
3476 char *pBuf, /* Buffer used for the management data transfer */
3477 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3478 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3479 unsigned int TableIndex, /* Index to the Id table */
3480 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3485 unsigned int Offset;
3491 SK_U64 Val64RxHwErrs = 0;
3492 SK_U64 Val64TxHwErrs = 0;
3493 SK_BOOL Is64BitReq = SK_FALSE;
3498 * Check instance. We only handle single instance variables.
3500 if (Instance != (SK_U32)(-1) && Instance != 1) {
3503 return (SK_PNMI_ERR_UNKNOWN_INST);
3507 * Check action. We only allow get requests.
3509 if (Action != SK_PNMI_GET) {
3512 return (SK_PNMI_ERR_READ_ONLY);
3515 MacType = pAC->GIni.GIMacType;
3518 * Check length for the various supported OIDs
3522 case OID_GEN_XMIT_ERROR:
3523 case OID_GEN_RCV_ERROR:
3524 case OID_GEN_RCV_NO_BUFFER:
3525 #ifndef SK_NDIS_64BIT_CTR
3526 if (*pLen < sizeof(SK_U32)) {
3527 *pLen = sizeof(SK_U32);
3528 return (SK_PNMI_ERR_TOO_SHORT);
3531 #else /* SK_NDIS_64BIT_CTR */
3534 * for compatibility, at least 32bit are required for oid
3536 if (*pLen < sizeof(SK_U32)) {
3538 * but indicate handling for 64bit values,
3539 * if insufficient space is provided
3541 *pLen = sizeof(SK_U64);
3542 return (SK_PNMI_ERR_TOO_SHORT);
3545 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3546 #endif /* SK_NDIS_64BIT_CTR */
3549 case OID_SKGE_PORT_NUMBER:
3550 case OID_SKGE_DEVICE_TYPE:
3551 case OID_SKGE_RESULT:
3552 case OID_SKGE_RLMT_MONITOR_NUMBER:
3553 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3554 case OID_SKGE_TRAP_NUMBER:
3555 case OID_SKGE_MDB_VERSION:
3556 case OID_SKGE_BOARDLEVEL:
3557 case OID_SKGE_CHIPID:
3558 case OID_SKGE_RAMSIZE:
3559 if (*pLen < sizeof(SK_U32)) {
3561 *pLen = sizeof(SK_U32);
3562 return (SK_PNMI_ERR_TOO_SHORT);
3566 case OID_SKGE_CHIPSET:
3567 if (*pLen < sizeof(SK_U16)) {
3569 *pLen = sizeof(SK_U16);
3570 return (SK_PNMI_ERR_TOO_SHORT);
3574 case OID_SKGE_BUS_TYPE:
3575 case OID_SKGE_BUS_SPEED:
3576 case OID_SKGE_BUS_WIDTH:
3577 case OID_SKGE_SENSOR_NUMBER:
3578 case OID_SKGE_CHKSM_NUMBER:
3579 case OID_SKGE_VAUXAVAIL:
3580 if (*pLen < sizeof(SK_U8)) {
3582 *pLen = sizeof(SK_U8);
3583 return (SK_PNMI_ERR_TOO_SHORT);
3587 case OID_SKGE_TX_SW_QUEUE_LEN:
3588 case OID_SKGE_TX_SW_QUEUE_MAX:
3589 case OID_SKGE_TX_RETRY:
3590 case OID_SKGE_RX_INTR_CTS:
3591 case OID_SKGE_TX_INTR_CTS:
3592 case OID_SKGE_RX_NO_BUF_CTS:
3593 case OID_SKGE_TX_NO_BUF_CTS:
3594 case OID_SKGE_TX_USED_DESCR_NO:
3595 case OID_SKGE_RX_DELIVERED_CTS:
3596 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3597 case OID_SKGE_RX_HW_ERROR_CTS:
3598 case OID_SKGE_TX_HW_ERROR_CTS:
3599 case OID_SKGE_IN_ERRORS_CTS:
3600 case OID_SKGE_OUT_ERROR_CTS:
3601 case OID_SKGE_ERR_RECOVERY_CTS:
3602 case OID_SKGE_SYSUPTIME:
3603 if (*pLen < sizeof(SK_U64)) {
3605 *pLen = sizeof(SK_U64);
3606 return (SK_PNMI_ERR_TOO_SHORT);
3615 /* Update statistic */
3616 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3617 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3618 Id == OID_SKGE_IN_ERRORS_CTS ||
3619 Id == OID_SKGE_OUT_ERROR_CTS ||
3620 Id == OID_GEN_XMIT_ERROR ||
3621 Id == OID_GEN_RCV_ERROR) {
3623 /* Force the XMAC to update its statistic counters and
3624 * Increment semaphore to indicate that an update was
3627 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3628 if (Ret != SK_PNMI_ERR_OK) {
3633 pAC->Pnmi.MacUpdatedFlag ++;
3636 * Some OIDs consist of multiple hardware counters. Those
3637 * values which are contained in all of them will be added
3642 case OID_SKGE_RX_HW_ERROR_CTS:
3643 case OID_SKGE_IN_ERRORS_CTS:
3644 case OID_GEN_RCV_ERROR:
3646 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3647 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3648 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3649 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3650 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3651 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3652 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3653 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3654 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3655 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3656 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3657 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3660 case OID_SKGE_TX_HW_ERROR_CTS:
3661 case OID_SKGE_OUT_ERROR_CTS:
3662 case OID_GEN_XMIT_ERROR:
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3677 case OID_SKGE_SUPPORTED_LIST:
3678 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3682 return (SK_PNMI_ERR_TOO_SHORT);
3684 for (Offset = 0, Index = 0; Offset < Len;
3685 Offset += sizeof(SK_U32), Index ++) {
3687 Val32 = (SK_U32)IdTable[Index].Id;
3688 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3693 case OID_SKGE_BOARDLEVEL:
3694 Val32 = (SK_U32)pAC->GIni.GILevel;
3695 SK_PNMI_STORE_U32(pBuf, Val32);
3696 *pLen = sizeof(SK_U32);
3699 case OID_SKGE_PORT_NUMBER:
3700 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3701 SK_PNMI_STORE_U32(pBuf, Val32);
3702 *pLen = sizeof(SK_U32);
3705 case OID_SKGE_DEVICE_TYPE:
3706 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3707 SK_PNMI_STORE_U32(pBuf, Val32);
3708 *pLen = sizeof(SK_U32);
3711 case OID_SKGE_DRIVER_DESCR:
3712 if (pAC->Pnmi.pDriverDescription == NULL) {
3714 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3718 return (SK_PNMI_ERR_GENERAL);
3721 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3722 if (Len > SK_PNMI_STRINGLEN1) {
3724 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3728 return (SK_PNMI_ERR_GENERAL);
3734 return (SK_PNMI_ERR_TOO_SHORT);
3736 *pBuf = (char)(Len - 1);
3737 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3741 case OID_SKGE_DRIVER_VERSION:
3742 if (pAC->Pnmi.pDriverVersion == NULL) {
3744 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3748 return (SK_PNMI_ERR_GENERAL);
3751 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3752 if (Len > SK_PNMI_STRINGLEN1) {
3754 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3758 return (SK_PNMI_ERR_GENERAL);
3764 return (SK_PNMI_ERR_TOO_SHORT);
3766 *pBuf = (char)(Len - 1);
3767 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3771 case OID_SKGE_DRIVER_RELDATE:
3772 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3774 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3778 return (SK_PNMI_ERR_GENERAL);
3781 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3782 if (Len > SK_PNMI_STRINGLEN1) {
3784 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3788 return (SK_PNMI_ERR_GENERAL);
3794 return (SK_PNMI_ERR_TOO_SHORT);
3796 *pBuf = (char)(Len - 1);
3797 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3801 case OID_SKGE_DRIVER_FILENAME:
3802 if (pAC->Pnmi.pDriverFileName == NULL) {
3804 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3808 return (SK_PNMI_ERR_GENERAL);
3811 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3812 if (Len > SK_PNMI_STRINGLEN1) {
3814 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3818 return (SK_PNMI_ERR_GENERAL);
3824 return (SK_PNMI_ERR_TOO_SHORT);
3826 *pBuf = (char)(Len - 1);
3827 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3831 case OID_SKGE_HW_DESCR:
3833 * The hardware description is located in the VPD. This
3834 * query may move to the initialisation routine. But
3835 * the VPD data is cached and therefore a call here
3836 * will not make much difference.
3839 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3841 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3845 return (SK_PNMI_ERR_GENERAL);
3848 if (Len > SK_PNMI_STRINGLEN1) {
3850 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3854 return (SK_PNMI_ERR_GENERAL);
3859 return (SK_PNMI_ERR_TOO_SHORT);
3861 *pBuf = (char)(Len - 1);
3862 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3866 case OID_SKGE_HW_VERSION:
3867 /* Oh, I love to do some string manipulation */
3871 return (SK_PNMI_ERR_TOO_SHORT);
3873 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3876 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3878 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3882 case OID_SKGE_CHIPSET:
3883 Val16 = pAC->Pnmi.Chipset;
3884 SK_PNMI_STORE_U16(pBuf, Val16);
3885 *pLen = sizeof(SK_U16);
3888 case OID_SKGE_CHIPID:
3889 Val32 = pAC->GIni.GIChipId;
3890 SK_PNMI_STORE_U32(pBuf, Val32);
3891 *pLen = sizeof(SK_U32);
3894 case OID_SKGE_RAMSIZE:
3895 Val32 = pAC->GIni.GIRamSize;
3896 SK_PNMI_STORE_U32(pBuf, Val32);
3897 *pLen = sizeof(SK_U32);
3900 case OID_SKGE_VAUXAVAIL:
3901 *pBuf = (char) pAC->GIni.GIVauxAvail;
3902 *pLen = sizeof(char);
3905 case OID_SKGE_BUS_TYPE:
3906 *pBuf = (char) SK_PNMI_BUS_PCI;
3907 *pLen = sizeof(char);
3910 case OID_SKGE_BUS_SPEED:
3911 *pBuf = pAC->Pnmi.PciBusSpeed;
3912 *pLen = sizeof(char);
3915 case OID_SKGE_BUS_WIDTH:
3916 *pBuf = pAC->Pnmi.PciBusWidth;
3917 *pLen = sizeof(char);
3920 case OID_SKGE_RESULT:
3921 Val32 = pAC->Pnmi.TestResult;
3922 SK_PNMI_STORE_U32(pBuf, Val32);
3923 *pLen = sizeof(SK_U32);
3926 case OID_SKGE_SENSOR_NUMBER:
3927 *pBuf = (char)pAC->I2c.MaxSens;
3928 *pLen = sizeof(char);
3931 case OID_SKGE_CHKSM_NUMBER:
3932 *pBuf = SKCS_NUM_PROTOCOLS;
3933 *pLen = sizeof(char);
3936 case OID_SKGE_TRAP_NUMBER:
3937 GetTrapQueueLen(pAC, &Len, &Val);
3938 Val32 = (SK_U32)Val;
3939 SK_PNMI_STORE_U32(pBuf, Val32);
3940 *pLen = sizeof(SK_U32);
3944 GetTrapQueueLen(pAC, &Len, &Val);
3948 return (SK_PNMI_ERR_TOO_SHORT);
3950 CopyTrapQueue(pAC, pBuf);
3954 case OID_SKGE_RLMT_MONITOR_NUMBER:
3955 /* XXX Not yet implemented by RLMT therefore we return zero elements */
3957 SK_PNMI_STORE_U32(pBuf, Val32);
3958 *pLen = sizeof(SK_U32);
3961 case OID_SKGE_TX_SW_QUEUE_LEN:
3962 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3963 if (MacType == SK_MAC_XMAC) {
3965 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3966 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3968 /* Single net mode */
3970 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3971 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3976 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3977 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3979 /* Single net mode */
3981 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3982 pAC->Pnmi.Port[1].TxSwQueueLen;
3985 SK_PNMI_STORE_U64(pBuf, Val64);
3986 *pLen = sizeof(SK_U64);
3990 case OID_SKGE_TX_SW_QUEUE_MAX:
3991 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3992 if (MacType == SK_MAC_XMAC) {
3994 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3995 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
3997 /* Single net mode */
3999 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4000 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4005 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4006 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4008 /* Single net mode */
4010 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4011 pAC->Pnmi.Port[1].TxSwQueueMax;
4014 SK_PNMI_STORE_U64(pBuf, Val64);
4015 *pLen = sizeof(SK_U64);
4018 case OID_SKGE_TX_RETRY:
4019 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4020 if (MacType == SK_MAC_XMAC) {
4022 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4023 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4025 /* Single net mode */
4027 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4028 pAC->Pnmi.BufPort[1].TxRetryCts;
4033 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4034 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4036 /* Single net mode */
4038 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4039 pAC->Pnmi.Port[1].TxRetryCts;
4042 SK_PNMI_STORE_U64(pBuf, Val64);
4043 *pLen = sizeof(SK_U64);
4046 case OID_SKGE_RX_INTR_CTS:
4047 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4048 if (MacType == SK_MAC_XMAC) {
4050 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4051 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4053 /* Single net mode */
4055 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4056 pAC->Pnmi.BufPort[1].RxIntrCts;
4061 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4062 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4064 /* Single net mode */
4066 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4067 pAC->Pnmi.Port[1].RxIntrCts;
4070 SK_PNMI_STORE_U64(pBuf, Val64);
4071 *pLen = sizeof(SK_U64);
4074 case OID_SKGE_TX_INTR_CTS:
4075 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4076 if (MacType == SK_MAC_XMAC) {
4078 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4079 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4081 /* Single net mode */
4083 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4084 pAC->Pnmi.BufPort[1].TxIntrCts;
4089 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4090 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4092 /* Single net mode */
4094 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4095 pAC->Pnmi.Port[1].TxIntrCts;
4098 SK_PNMI_STORE_U64(pBuf, Val64);
4099 *pLen = sizeof(SK_U64);
4102 case OID_SKGE_RX_NO_BUF_CTS:
4103 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4104 if (MacType == SK_MAC_XMAC) {
4106 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4107 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4109 /* Single net mode */
4111 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4112 pAC->Pnmi.BufPort[1].RxNoBufCts;
4117 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4118 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4120 /* Single net mode */
4122 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4123 pAC->Pnmi.Port[1].RxNoBufCts;
4126 SK_PNMI_STORE_U64(pBuf, Val64);
4127 *pLen = sizeof(SK_U64);
4130 case OID_SKGE_TX_NO_BUF_CTS:
4131 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4132 if (MacType == SK_MAC_XMAC) {
4134 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4135 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4137 /* Single net mode */
4139 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4140 pAC->Pnmi.BufPort[1].TxNoBufCts;
4145 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4146 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4148 /* Single net mode */
4150 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4151 pAC->Pnmi.Port[1].TxNoBufCts;
4154 SK_PNMI_STORE_U64(pBuf, Val64);
4155 *pLen = sizeof(SK_U64);
4158 case OID_SKGE_TX_USED_DESCR_NO:
4159 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4160 if (MacType == SK_MAC_XMAC) {
4162 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4163 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4165 /* Single net mode */
4167 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4168 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4173 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4174 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4176 /* Single net mode */
4178 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4179 pAC->Pnmi.Port[1].TxUsedDescrNo;
4182 SK_PNMI_STORE_U64(pBuf, Val64);
4183 *pLen = sizeof(SK_U64);
4186 case OID_SKGE_RX_DELIVERED_CTS:
4187 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4188 if (MacType == SK_MAC_XMAC) {
4190 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4191 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4193 /* Single net mode */
4195 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4196 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4201 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4202 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4204 /* Single net mode */
4206 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4207 pAC->Pnmi.Port[1].RxDeliveredCts;
4210 SK_PNMI_STORE_U64(pBuf, Val64);
4211 *pLen = sizeof(SK_U64);
4214 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4215 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4216 if (MacType == SK_MAC_XMAC) {
4218 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4219 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4221 /* Single net mode */
4223 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4224 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4229 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4230 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4232 /* Single net mode */
4234 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4235 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4238 SK_PNMI_STORE_U64(pBuf, Val64);
4239 *pLen = sizeof(SK_U64);
4242 case OID_SKGE_RX_HW_ERROR_CTS:
4243 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4244 *pLen = sizeof(SK_U64);
4247 case OID_SKGE_TX_HW_ERROR_CTS:
4248 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4249 *pLen = sizeof(SK_U64);
4252 case OID_SKGE_IN_ERRORS_CTS:
4253 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4254 if (MacType == SK_MAC_XMAC) {
4256 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4257 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4259 /* Single net mode */
4261 Val64 = Val64RxHwErrs +
4262 pAC->Pnmi.BufPort[0].RxNoBufCts +
4263 pAC->Pnmi.BufPort[1].RxNoBufCts;
4268 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4269 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4271 /* Single net mode */
4273 Val64 = Val64RxHwErrs +
4274 pAC->Pnmi.Port[0].RxNoBufCts +
4275 pAC->Pnmi.Port[1].RxNoBufCts;
4278 SK_PNMI_STORE_U64(pBuf, Val64);
4279 *pLen = sizeof(SK_U64);
4282 case OID_SKGE_OUT_ERROR_CTS:
4283 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4284 if (MacType == SK_MAC_XMAC) {
4286 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4287 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4289 /* Single net mode */
4291 Val64 = Val64TxHwErrs +
4292 pAC->Pnmi.BufPort[0].TxNoBufCts +
4293 pAC->Pnmi.BufPort[1].TxNoBufCts;
4298 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4299 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4301 /* Single net mode */
4303 Val64 = Val64TxHwErrs +
4304 pAC->Pnmi.Port[0].TxNoBufCts +
4305 pAC->Pnmi.Port[1].TxNoBufCts;
4308 SK_PNMI_STORE_U64(pBuf, Val64);
4309 *pLen = sizeof(SK_U64);
4312 case OID_SKGE_ERR_RECOVERY_CTS:
4313 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4314 if (MacType == SK_MAC_XMAC) {
4316 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4317 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4319 /* Single net mode */
4321 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4322 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4327 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4328 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4330 /* Single net mode */
4332 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4333 pAC->Pnmi.Port[1].ErrRecoveryCts;
4336 SK_PNMI_STORE_U64(pBuf, Val64);
4337 *pLen = sizeof(SK_U64);
4340 case OID_SKGE_SYSUPTIME:
4341 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4342 Val64 -= pAC->Pnmi.StartUpTime;
4343 SK_PNMI_STORE_U64(pBuf, Val64);
4344 *pLen = sizeof(SK_U64);
4347 case OID_SKGE_MDB_VERSION:
4348 Val32 = SK_PNMI_MDB_VERSION;
4349 SK_PNMI_STORE_U32(pBuf, Val32);
4350 *pLen = sizeof(SK_U32);
4353 case OID_GEN_RCV_ERROR:
4354 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4355 if (MacType == SK_MAC_XMAC) {
4356 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4359 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4363 * by default 32bit values are evaluated
4366 Val32 = (SK_U32)Val64;
4367 SK_PNMI_STORE_U32(pBuf, Val32);
4368 *pLen = sizeof(SK_U32);
4371 SK_PNMI_STORE_U64(pBuf, Val64);
4372 *pLen = sizeof(SK_U64);
4376 case OID_GEN_XMIT_ERROR:
4377 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4378 if (MacType == SK_MAC_XMAC) {
4379 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4382 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4386 * by default 32bit values are evaluated
4389 Val32 = (SK_U32)Val64;
4390 SK_PNMI_STORE_U32(pBuf, Val32);
4391 *pLen = sizeof(SK_U32);
4394 SK_PNMI_STORE_U64(pBuf, Val64);
4395 *pLen = sizeof(SK_U64);
4399 case OID_GEN_RCV_NO_BUFFER:
4400 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4401 if (MacType == SK_MAC_XMAC) {
4402 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4405 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4409 * by default 32bit values are evaluated
4412 Val32 = (SK_U32)Val64;
4413 SK_PNMI_STORE_U32(pBuf, Val32);
4414 *pLen = sizeof(SK_U32);
4417 SK_PNMI_STORE_U64(pBuf, Val64);
4418 *pLen = sizeof(SK_U64);
4422 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4423 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4424 SK_PNMI_STORE_U32(pBuf, Val32);
4425 *pLen = sizeof(SK_U32);
4429 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4433 return (SK_PNMI_ERR_GENERAL);
4436 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4437 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4438 Id == OID_SKGE_IN_ERRORS_CTS ||
4439 Id == OID_SKGE_OUT_ERROR_CTS ||
4440 Id == OID_GEN_XMIT_ERROR ||
4441 Id == OID_GEN_RCV_ERROR) {
4443 pAC->Pnmi.MacUpdatedFlag --;
4446 return (SK_PNMI_ERR_OK);
4449 /*****************************************************************************
4451 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4454 * Get/Presets/Sets the RLMT OIDs.
4457 * SK_PNMI_ERR_OK The request was successfully performed.
4458 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4459 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4460 * the correct data (e.g. a 32bit value is
4461 * needed, but a 16 bit value was passed).
4462 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4464 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4465 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4466 * exist (e.g. port instance 3 on a two port
4469 PNMI_STATIC int Rlmt(
4470 SK_AC *pAC, /* Pointer to adapter context */
4471 SK_IOC IoC, /* IO context handle */
4472 int Action, /* GET/PRESET/SET action */
4473 SK_U32 Id, /* Object ID that is to be processed */
4474 char *pBuf, /* Buffer used for the management data transfer */
4475 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4476 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4477 unsigned int TableIndex, /* Index to the Id table */
4478 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4481 unsigned int PhysPortIndex;
4482 unsigned int PhysPortMax;
4483 SK_EVPARA EventParam;
4489 * Check instance. Only single instance OIDs are allowed here.
4491 if (Instance != (SK_U32)(-1) && Instance != 1) {
4494 return (SK_PNMI_ERR_UNKNOWN_INST);
4498 * Perform the requested action.
4500 if (Action == SK_PNMI_GET) {
4503 * Check if the buffer length is large enough.
4508 case OID_SKGE_RLMT_MODE:
4509 case OID_SKGE_RLMT_PORT_ACTIVE:
4510 case OID_SKGE_RLMT_PORT_PREFERRED:
4511 if (*pLen < sizeof(SK_U8)) {
4513 *pLen = sizeof(SK_U8);
4514 return (SK_PNMI_ERR_TOO_SHORT);
4518 case OID_SKGE_RLMT_PORT_NUMBER:
4519 if (*pLen < sizeof(SK_U32)) {
4521 *pLen = sizeof(SK_U32);
4522 return (SK_PNMI_ERR_TOO_SHORT);
4526 case OID_SKGE_RLMT_CHANGE_CTS:
4527 case OID_SKGE_RLMT_CHANGE_TIME:
4528 case OID_SKGE_RLMT_CHANGE_ESTIM:
4529 case OID_SKGE_RLMT_CHANGE_THRES:
4530 if (*pLen < sizeof(SK_U64)) {
4532 *pLen = sizeof(SK_U64);
4533 return (SK_PNMI_ERR_TOO_SHORT);
4538 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4542 return (SK_PNMI_ERR_GENERAL);
4546 * Update RLMT statistic and increment semaphores to indicate
4547 * that an update was already done. Maybe RLMT will hold its
4548 * statistic always up to date some time. Then we can
4549 * remove this type of call.
4551 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4556 pAC->Pnmi.RlmtUpdatedFlag ++;
4563 case OID_SKGE_RLMT_MODE:
4564 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4565 *pLen = sizeof(char);
4568 case OID_SKGE_RLMT_PORT_NUMBER:
4569 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4570 SK_PNMI_STORE_U32(pBuf, Val32);
4571 *pLen = sizeof(SK_U32);
4574 case OID_SKGE_RLMT_PORT_ACTIVE:
4577 * If multiple ports may become active this OID
4578 * doesn't make sense any more. A new variable in
4579 * the port structure should be created. However,
4580 * for this variable the first active port is
4583 PhysPortMax = pAC->GIni.GIMacsFound;
4585 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4588 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4590 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4594 *pLen = sizeof(char);
4597 case OID_SKGE_RLMT_PORT_PREFERRED:
4598 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4599 *pLen = sizeof(char);
4602 case OID_SKGE_RLMT_CHANGE_CTS:
4603 Val64 = pAC->Pnmi.RlmtChangeCts;
4604 SK_PNMI_STORE_U64(pBuf, Val64);
4605 *pLen = sizeof(SK_U64);
4608 case OID_SKGE_RLMT_CHANGE_TIME:
4609 Val64 = pAC->Pnmi.RlmtChangeTime;
4610 SK_PNMI_STORE_U64(pBuf, Val64);
4611 *pLen = sizeof(SK_U64);
4614 case OID_SKGE_RLMT_CHANGE_ESTIM:
4615 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4616 SK_PNMI_STORE_U64(pBuf, Val64);
4617 *pLen = sizeof(SK_U64);
4620 case OID_SKGE_RLMT_CHANGE_THRES:
4621 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4622 SK_PNMI_STORE_U64(pBuf, Val64);
4623 *pLen = sizeof(SK_U64);
4627 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4628 ("Rlmt: Unknown OID should be handled before"));
4630 pAC->Pnmi.RlmtUpdatedFlag --;
4632 return (SK_PNMI_ERR_GENERAL);
4635 pAC->Pnmi.RlmtUpdatedFlag --;
4638 /* Perform a preset or set */
4641 case OID_SKGE_RLMT_MODE:
4642 /* Check if the buffer length is plausible */
4643 if (*pLen < sizeof(char)) {
4645 *pLen = sizeof(char);
4646 return (SK_PNMI_ERR_TOO_SHORT);
4648 /* Check if the value range is correct */
4649 if (*pLen != sizeof(char) ||
4650 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4651 *(SK_U8 *)pBuf > 15) {
4654 return (SK_PNMI_ERR_BAD_VALUE);
4656 /* The preset ends here */
4657 if (Action == SK_PNMI_PRESET) {
4660 return (SK_PNMI_ERR_OK);
4662 /* Send an event to RLMT to change the mode */
4663 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4664 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4665 EventParam.Para32[1] = 0;
4666 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4669 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4673 return (SK_PNMI_ERR_GENERAL);
4677 case OID_SKGE_RLMT_PORT_PREFERRED:
4678 /* Check if the buffer length is plausible */
4679 if (*pLen < sizeof(char)) {
4681 *pLen = sizeof(char);
4682 return (SK_PNMI_ERR_TOO_SHORT);
4684 /* Check if the value range is correct */
4685 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4686 (SK_U8)pAC->GIni.GIMacsFound) {
4689 return (SK_PNMI_ERR_BAD_VALUE);
4691 /* The preset ends here */
4692 if (Action == SK_PNMI_PRESET) {
4695 return (SK_PNMI_ERR_OK);
4699 * Send an event to RLMT change the preferred port.
4700 * A param of -1 means automatic mode. RLMT will
4701 * make the decision which is the preferred port.
4703 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4704 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4705 EventParam.Para32[1] = NetIndex;
4706 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4709 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4713 return (SK_PNMI_ERR_GENERAL);
4717 case OID_SKGE_RLMT_CHANGE_THRES:
4718 /* Check if the buffer length is plausible */
4719 if (*pLen < sizeof(SK_U64)) {
4721 *pLen = sizeof(SK_U64);
4722 return (SK_PNMI_ERR_TOO_SHORT);
4725 * There are not many restrictions to the
4728 if (*pLen != sizeof(SK_U64)) {
4731 return (SK_PNMI_ERR_BAD_VALUE);
4733 /* A preset ends here */
4734 if (Action == SK_PNMI_PRESET) {
4737 return (SK_PNMI_ERR_OK);
4740 * Store the new threshold, which will be taken
4741 * on the next timer event.
4743 SK_PNMI_READ_U64(pBuf, Val64);
4744 pAC->Pnmi.RlmtChangeThreshold = Val64;
4748 /* The other OIDs are not be able for set */
4750 return (SK_PNMI_ERR_READ_ONLY);
4754 return (SK_PNMI_ERR_OK);
4757 /*****************************************************************************
4759 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4762 * Performs get requests on multiple instance variables.
4765 * SK_PNMI_ERR_OK The request was successfully performed.
4766 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4767 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4768 * the correct data (e.g. a 32bit value is
4769 * needed, but a 16 bit value was passed).
4770 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4771 * exist (e.g. port instance 3 on a two port
4774 PNMI_STATIC int RlmtStat(
4775 SK_AC *pAC, /* Pointer to adapter context */
4776 SK_IOC IoC, /* IO context handle */
4777 int Action, /* GET/PRESET/SET action */
4778 SK_U32 Id, /* Object ID that is to be processed */
4779 char *pBuf, /* Buffer used for the management data transfer */
4780 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4781 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4782 unsigned int TableIndex, /* Index to the Id table */
4783 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4785 unsigned int PhysPortMax;
4786 unsigned int PhysPortIndex;
4788 unsigned int Offset;
4794 * Calculate the port indexes from the instance.
4796 PhysPortMax = pAC->GIni.GIMacsFound;
4798 if ((Instance != (SK_U32)(-1))) {
4799 /* Check instance range */
4800 if ((Instance < 1) || (Instance > PhysPortMax)) {
4803 return (SK_PNMI_ERR_UNKNOWN_INST);
4806 /* Single net mode */
4807 PhysPortIndex = Instance - 1;
4810 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4811 PhysPortIndex = NetIndex;
4814 /* Both net modes */
4815 Limit = PhysPortIndex + 1;
4818 /* Single net mode */
4820 Limit = PhysPortMax;
4823 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4824 PhysPortIndex = NetIndex;
4825 Limit = PhysPortIndex + 1;
4830 * Currently only get requests are allowed.
4832 if (Action != SK_PNMI_GET) {
4835 return (SK_PNMI_ERR_READ_ONLY);
4839 * Check if the buffer length is large enough.
4843 case OID_SKGE_RLMT_PORT_INDEX:
4844 case OID_SKGE_RLMT_STATUS:
4845 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4847 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4848 return (SK_PNMI_ERR_TOO_SHORT);
4852 case OID_SKGE_RLMT_TX_HELLO_CTS:
4853 case OID_SKGE_RLMT_RX_HELLO_CTS:
4854 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4855 case OID_SKGE_RLMT_RX_SP_CTS:
4856 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4858 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4859 return (SK_PNMI_ERR_TOO_SHORT);
4864 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4868 return (SK_PNMI_ERR_GENERAL);
4873 * Update statistic and increment semaphores to indicate that
4874 * an update was already done.
4876 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4881 pAC->Pnmi.RlmtUpdatedFlag ++;
4887 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4891 case OID_SKGE_RLMT_PORT_INDEX:
4892 Val32 = PhysPortIndex;
4893 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4894 Offset += sizeof(SK_U32);
4897 case OID_SKGE_RLMT_STATUS:
4898 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4900 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4903 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4905 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4907 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4910 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4912 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4913 Offset += sizeof(SK_U32);
4916 case OID_SKGE_RLMT_TX_HELLO_CTS:
4917 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4918 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4919 Offset += sizeof(SK_U64);
4922 case OID_SKGE_RLMT_RX_HELLO_CTS:
4923 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4924 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4925 Offset += sizeof(SK_U64);
4928 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4929 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4930 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4931 Offset += sizeof(SK_U64);
4934 case OID_SKGE_RLMT_RX_SP_CTS:
4935 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4936 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4937 Offset += sizeof(SK_U64);
4941 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4942 ("RlmtStat: Unknown OID should be errored before"));
4944 pAC->Pnmi.RlmtUpdatedFlag --;
4946 return (SK_PNMI_ERR_GENERAL);
4951 pAC->Pnmi.RlmtUpdatedFlag --;
4953 return (SK_PNMI_ERR_OK);
4956 /*****************************************************************************
4958 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4961 * Get/Presets/Sets the OIDs concerning the configuration.
4964 * SK_PNMI_ERR_OK The request was successfully performed.
4965 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4966 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4967 * the correct data (e.g. a 32bit value is
4968 * needed, but a 16 bit value was passed).
4969 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4971 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4972 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4973 * exist (e.g. port instance 3 on a two port
4976 PNMI_STATIC int MacPrivateConf(
4977 SK_AC *pAC, /* Pointer to adapter context */
4978 SK_IOC IoC, /* IO context handle */
4979 int Action, /* GET/PRESET/SET action */
4980 SK_U32 Id, /* Object ID that is to be processed */
4981 char *pBuf, /* Buffer used for the management data transfer */
4982 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4983 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4984 unsigned int TableIndex, /* Index to the Id table */
4985 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4987 unsigned int PhysPortMax;
4988 unsigned int PhysPortIndex;
4989 unsigned int LogPortMax;
4990 unsigned int LogPortIndex;
4992 unsigned int Offset;
4996 SK_EVPARA EventParam;
5000 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5002 PhysPortMax = pAC->GIni.GIMacsFound;
5003 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5005 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5009 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5010 /* Check instance range */
5011 if ((Instance < 1) || (Instance > LogPortMax)) {
5014 return (SK_PNMI_ERR_UNKNOWN_INST);
5016 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5017 Limit = LogPortIndex + 1;
5020 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5029 if (Action == SK_PNMI_GET) {
5035 case OID_SKGE_CONNECTOR:
5036 case OID_SKGE_LINK_CAP:
5037 case OID_SKGE_LINK_MODE:
5038 case OID_SKGE_LINK_MODE_STATUS:
5039 case OID_SKGE_LINK_STATUS:
5040 case OID_SKGE_FLOWCTRL_CAP:
5041 case OID_SKGE_FLOWCTRL_MODE:
5042 case OID_SKGE_FLOWCTRL_STATUS:
5043 case OID_SKGE_PHY_OPERATION_CAP:
5044 case OID_SKGE_PHY_OPERATION_MODE:
5045 case OID_SKGE_PHY_OPERATION_STATUS:
5046 case OID_SKGE_SPEED_CAP:
5047 case OID_SKGE_SPEED_MODE:
5048 case OID_SKGE_SPEED_STATUS:
5049 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5051 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5052 return (SK_PNMI_ERR_TOO_SHORT);
5057 case OID_SKGE_PHY_TYPE:
5058 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5060 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5061 return (SK_PNMI_ERR_TOO_SHORT);
5066 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5069 return (SK_PNMI_ERR_GENERAL);
5073 * Update statistic and increment semaphore to indicate
5074 * that an update was already done.
5076 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5081 pAC->Pnmi.SirqUpdatedFlag ++;
5087 for (; LogPortIndex < Limit; LogPortIndex ++) {
5089 pBufPtr = pBuf + Offset;
5094 *pBufPtr = pAC->Pnmi.PMD;
5095 Offset += sizeof(char);
5098 case OID_SKGE_CONNECTOR:
5099 *pBufPtr = pAC->Pnmi.Connector;
5100 Offset += sizeof(char);
5103 case OID_SKGE_PHY_TYPE:
5104 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5105 if (LogPortIndex == 0) {
5109 /* Get value for physical ports */
5110 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5112 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5113 SK_PNMI_STORE_U32(pBufPtr, Val32);
5116 else { /* DualNetMode */
5118 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5119 SK_PNMI_STORE_U32(pBufPtr, Val32);
5121 Offset += sizeof(SK_U32);
5124 case OID_SKGE_LINK_CAP:
5125 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5126 if (LogPortIndex == 0) {
5127 /* Get value for virtual port */
5128 VirtualConf(pAC, IoC, Id, pBufPtr);
5131 /* Get value for physical ports */
5132 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5135 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5138 else { /* DualNetMode */
5140 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5142 Offset += sizeof(char);
5145 case OID_SKGE_LINK_MODE:
5146 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5147 if (LogPortIndex == 0) {
5148 /* Get value for virtual port */
5149 VirtualConf(pAC, IoC, Id, pBufPtr);
5152 /* Get value for physical ports */
5153 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5156 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5159 else { /* DualNetMode */
5161 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5163 Offset += sizeof(char);
5166 case OID_SKGE_LINK_MODE_STATUS:
5167 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5168 if (LogPortIndex == 0) {
5169 /* Get value for virtual port */
5170 VirtualConf(pAC, IoC, Id, pBufPtr);
5173 /* Get value for physical port */
5174 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5178 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5181 else { /* DualNetMode */
5183 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5185 Offset += sizeof(char);
5188 case OID_SKGE_LINK_STATUS:
5189 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5190 if (LogPortIndex == 0) {
5191 /* Get value for virtual port */
5192 VirtualConf(pAC, IoC, Id, pBufPtr);
5195 /* Get value for physical ports */
5196 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5199 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5202 else { /* DualNetMode */
5204 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5206 Offset += sizeof(char);
5209 case OID_SKGE_FLOWCTRL_CAP:
5210 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5211 if (LogPortIndex == 0) {
5212 /* Get value for virtual port */
5213 VirtualConf(pAC, IoC, Id, pBufPtr);
5216 /* Get value for physical ports */
5217 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5220 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5223 else { /* DualNetMode */
5225 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5227 Offset += sizeof(char);
5230 case OID_SKGE_FLOWCTRL_MODE:
5231 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5232 if (LogPortIndex == 0) {
5233 /* Get value for virtual port */
5234 VirtualConf(pAC, IoC, Id, pBufPtr);
5237 /* Get value for physical port */
5238 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5241 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5244 else { /* DualNetMode */
5246 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5248 Offset += sizeof(char);
5251 case OID_SKGE_FLOWCTRL_STATUS:
5252 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5253 if (LogPortIndex == 0) {
5254 /* Get value for virtual port */
5255 VirtualConf(pAC, IoC, Id, pBufPtr);
5258 /* Get value for physical port */
5259 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5262 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5265 else { /* DualNetMode */
5267 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5269 Offset += sizeof(char);
5272 case OID_SKGE_PHY_OPERATION_CAP:
5273 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5274 if (LogPortIndex == 0) {
5275 /* Get value for virtual port */
5276 VirtualConf(pAC, IoC, Id, pBufPtr);
5279 /* Get value for physical ports */
5280 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5283 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5286 else { /* DualNetMode */
5288 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5290 Offset += sizeof(char);
5293 case OID_SKGE_PHY_OPERATION_MODE:
5294 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5295 if (LogPortIndex == 0) {
5296 /* Get value for virtual port */
5297 VirtualConf(pAC, IoC, Id, pBufPtr);
5300 /* Get value for physical port */
5301 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5304 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5307 else { /* DualNetMode */
5309 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5311 Offset += sizeof(char);
5314 case OID_SKGE_PHY_OPERATION_STATUS:
5315 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5316 if (LogPortIndex == 0) {
5317 /* Get value for virtual port */
5318 VirtualConf(pAC, IoC, Id, pBufPtr);
5321 /* Get value for physical port */
5322 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5325 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5330 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5332 Offset += sizeof(char);
5335 case OID_SKGE_SPEED_CAP:
5336 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5337 if (LogPortIndex == 0) {
5338 /* Get value for virtual port */
5339 VirtualConf(pAC, IoC, Id, pBufPtr);
5342 /* Get value for physical ports */
5343 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5346 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5349 else { /* DualNetMode */
5351 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5353 Offset += sizeof(char);
5356 case OID_SKGE_SPEED_MODE:
5357 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5358 if (LogPortIndex == 0) {
5359 /* Get value for virtual port */
5360 VirtualConf(pAC, IoC, Id, pBufPtr);
5363 /* Get value for physical port */
5364 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5367 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5370 else { /* DualNetMode */
5372 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5374 Offset += sizeof(char);
5377 case OID_SKGE_SPEED_STATUS:
5378 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5379 if (LogPortIndex == 0) {
5380 /* Get value for virtual port */
5381 VirtualConf(pAC, IoC, Id, pBufPtr);
5384 /* Get value for physical port */
5385 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5388 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5391 else { /* DualNetMode */
5393 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5395 Offset += sizeof(char);
5399 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5400 SK_PNMI_STORE_U32(pBufPtr, Val32);
5401 Offset += sizeof(SK_U32);
5405 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5406 ("MacPrivateConf: Unknown OID should be handled before"));
5408 pAC->Pnmi.SirqUpdatedFlag --;
5409 return (SK_PNMI_ERR_GENERAL);
5413 pAC->Pnmi.SirqUpdatedFlag --;
5415 return (SK_PNMI_ERR_OK);
5419 * From here SET or PRESET action. Check if the passed
5420 * buffer length is plausible.
5424 case OID_SKGE_LINK_MODE:
5425 case OID_SKGE_FLOWCTRL_MODE:
5426 case OID_SKGE_PHY_OPERATION_MODE:
5427 case OID_SKGE_SPEED_MODE:
5428 if (*pLen < Limit - LogPortIndex) {
5430 *pLen = Limit - LogPortIndex;
5431 return (SK_PNMI_ERR_TOO_SHORT);
5433 if (*pLen != Limit - LogPortIndex) {
5436 return (SK_PNMI_ERR_BAD_VALUE);
5441 if (*pLen < sizeof(SK_U32)) {
5443 *pLen = sizeof(SK_U32);
5444 return (SK_PNMI_ERR_TOO_SHORT);
5446 if (*pLen != sizeof(SK_U32)) {
5449 return (SK_PNMI_ERR_BAD_VALUE);
5455 return (SK_PNMI_ERR_READ_ONLY);
5459 * Perform preset or set
5462 for (; LogPortIndex < Limit; LogPortIndex ++) {
5466 case OID_SKGE_LINK_MODE:
5467 /* Check the value range */
5468 Val8 = *(pBuf + Offset);
5471 Offset += sizeof(char);
5474 if (Val8 < SK_LMODE_HALF ||
5475 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5476 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5479 return (SK_PNMI_ERR_BAD_VALUE);
5482 /* The preset ends here */
5483 if (Action == SK_PNMI_PRESET) {
5485 return (SK_PNMI_ERR_OK);
5488 if (LogPortIndex == 0) {
5491 * The virtual port consists of all currently
5492 * active ports. Find them and send an event
5493 * with the new link mode to SIRQ.
5495 for (PhysPortIndex = 0;
5496 PhysPortIndex < PhysPortMax;
5499 if (!pAC->Pnmi.Port[PhysPortIndex].
5505 EventParam.Para32[0] = PhysPortIndex;
5506 EventParam.Para32[1] = (SK_U32)Val8;
5507 if (SkGeSirqEvent(pAC, IoC,
5511 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5516 return (SK_PNMI_ERR_GENERAL);
5522 * Send an event with the new link mode to
5525 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5527 EventParam.Para32[1] = (SK_U32)Val8;
5528 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5531 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5536 return (SK_PNMI_ERR_GENERAL);
5539 Offset += sizeof(char);
5542 case OID_SKGE_FLOWCTRL_MODE:
5543 /* Check the value range */
5544 Val8 = *(pBuf + Offset);
5547 Offset += sizeof(char);
5550 if (Val8 < SK_FLOW_MODE_NONE ||
5551 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5552 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5555 return (SK_PNMI_ERR_BAD_VALUE);
5558 /* The preset ends here */
5559 if (Action == SK_PNMI_PRESET) {
5561 return (SK_PNMI_ERR_OK);
5564 if (LogPortIndex == 0) {
5567 * The virtual port consists of all currently
5568 * active ports. Find them and send an event
5569 * with the new flow control mode to SIRQ.
5571 for (PhysPortIndex = 0;
5572 PhysPortIndex < PhysPortMax;
5575 if (!pAC->Pnmi.Port[PhysPortIndex].
5581 EventParam.Para32[0] = PhysPortIndex;
5582 EventParam.Para32[1] = (SK_U32)Val8;
5583 if (SkGeSirqEvent(pAC, IoC,
5584 SK_HWEV_SET_FLOWMODE,
5587 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5592 return (SK_PNMI_ERR_GENERAL);
5598 * Send an event with the new flow control
5599 * mode to the SIRQ module.
5601 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5603 EventParam.Para32[1] = (SK_U32)Val8;
5604 if (SkGeSirqEvent(pAC, IoC,
5605 SK_HWEV_SET_FLOWMODE, EventParam)
5608 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5613 return (SK_PNMI_ERR_GENERAL);
5616 Offset += sizeof(char);
5619 case OID_SKGE_PHY_OPERATION_MODE :
5620 /* Check the value range */
5621 Val8 = *(pBuf + Offset);
5623 /* mode of this port remains unchanged */
5624 Offset += sizeof(char);
5627 if (Val8 < SK_MS_MODE_AUTO ||
5628 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5629 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5632 return (SK_PNMI_ERR_BAD_VALUE);
5635 /* The preset ends here */
5636 if (Action == SK_PNMI_PRESET) {
5638 return (SK_PNMI_ERR_OK);
5641 if (LogPortIndex == 0) {
5644 * The virtual port consists of all currently
5645 * active ports. Find them and send an event
5646 * with new master/slave (role) mode to SIRQ.
5648 for (PhysPortIndex = 0;
5649 PhysPortIndex < PhysPortMax;
5652 if (!pAC->Pnmi.Port[PhysPortIndex].
5658 EventParam.Para32[0] = PhysPortIndex;
5659 EventParam.Para32[1] = (SK_U32)Val8;
5660 if (SkGeSirqEvent(pAC, IoC,
5664 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5669 return (SK_PNMI_ERR_GENERAL);
5675 * Send an event with the new master/slave
5676 * (role) mode to the SIRQ module.
5678 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5680 EventParam.Para32[1] = (SK_U32)Val8;
5681 if (SkGeSirqEvent(pAC, IoC,
5682 SK_HWEV_SET_ROLE, EventParam) > 0) {
5684 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5689 return (SK_PNMI_ERR_GENERAL);
5693 Offset += sizeof(char);
5696 case OID_SKGE_SPEED_MODE:
5697 /* Check the value range */
5698 Val8 = *(pBuf + Offset);
5701 Offset += sizeof(char);
5704 if (Val8 < (SK_LSPEED_AUTO) ||
5705 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5706 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5709 return (SK_PNMI_ERR_BAD_VALUE);
5712 /* The preset ends here */
5713 if (Action == SK_PNMI_PRESET) {
5715 return (SK_PNMI_ERR_OK);
5718 if (LogPortIndex == 0) {
5721 * The virtual port consists of all currently
5722 * active ports. Find them and send an event
5723 * with the new flow control mode to SIRQ.
5725 for (PhysPortIndex = 0;
5726 PhysPortIndex < PhysPortMax;
5729 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5734 EventParam.Para32[0] = PhysPortIndex;
5735 EventParam.Para32[1] = (SK_U32)Val8;
5736 if (SkGeSirqEvent(pAC, IoC,
5740 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5745 return (SK_PNMI_ERR_GENERAL);
5751 * Send an event with the new flow control
5752 * mode to the SIRQ module.
5754 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5756 EventParam.Para32[1] = (SK_U32)Val8;
5757 if (SkGeSirqEvent(pAC, IoC,
5761 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5766 return (SK_PNMI_ERR_GENERAL);
5769 Offset += sizeof(char);
5773 /* Check the value range */
5774 Val32 = *(SK_U32*)(pBuf + Offset);
5776 /* mtu of this port remains unchanged */
5777 Offset += sizeof(SK_U32);
5780 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5782 return (SK_PNMI_ERR_BAD_VALUE);
5785 /* The preset ends here */
5786 if (Action == SK_PNMI_PRESET) {
5787 return (SK_PNMI_ERR_OK);
5790 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5791 return (SK_PNMI_ERR_GENERAL);
5794 Offset += sizeof(SK_U32);
5798 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5799 ("MacPrivateConf: Unknown OID should be handled before set"));
5802 return (SK_PNMI_ERR_GENERAL);
5806 return (SK_PNMI_ERR_OK);
5809 /*****************************************************************************
5811 * Monitor - OID handler function for RLMT_MONITOR_XXX
5814 * Because RLMT currently does not support the monitoring of
5815 * remote adapter cards, we return always an empty table.
5818 * SK_PNMI_ERR_OK The request was successfully performed.
5819 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5820 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5821 * the correct data (e.g. a 32bit value is
5822 * needed, but a 16 bit value was passed).
5823 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5825 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5826 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5827 * exist (e.g. port instance 3 on a two port
5830 PNMI_STATIC int Monitor(
5831 SK_AC *pAC, /* Pointer to adapter context */
5832 SK_IOC IoC, /* IO context handle */
5833 int Action, /* GET/PRESET/SET action */
5834 SK_U32 Id, /* Object ID that is to be processed */
5835 char *pBuf, /* Buffer used for the management data transfer */
5836 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5837 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5838 unsigned int TableIndex, /* Index to the Id table */
5839 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5843 unsigned int Offset;
5844 unsigned int Entries;
5848 * Calculate instance if wished.
5850 /* XXX Not yet implemented. Return always an empty table. */
5853 if ((Instance != (SK_U32)(-1))) {
5855 if ((Instance < 1) || (Instance > Entries)) {
5858 return (SK_PNMI_ERR_UNKNOWN_INST);
5861 Index = (unsigned int)Instance - 1;
5862 Limit = (unsigned int)Instance;
5872 if (Action == SK_PNMI_GET) {
5874 for (Offset=0; Index < Limit; Index ++) {
5878 case OID_SKGE_RLMT_MONITOR_INDEX:
5879 case OID_SKGE_RLMT_MONITOR_ADDR:
5880 case OID_SKGE_RLMT_MONITOR_ERRS:
5881 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
5882 case OID_SKGE_RLMT_MONITOR_ADMIN:
5886 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
5890 return (SK_PNMI_ERR_GENERAL);
5896 /* Only MONITOR_ADMIN can be set */
5897 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
5900 return (SK_PNMI_ERR_READ_ONLY);
5903 /* Check if the length is plausible */
5904 if (*pLen < (Limit - Index)) {
5906 return (SK_PNMI_ERR_TOO_SHORT);
5908 /* Okay, we have a wide value range */
5909 if (*pLen != (Limit - Index)) {
5912 return (SK_PNMI_ERR_BAD_VALUE);
5915 for (Offset=0; Index < Limit; Index ++) {
5919 * XXX Not yet implemented. Return always BAD_VALUE, because the table
5923 return (SK_PNMI_ERR_BAD_VALUE);
5926 return (SK_PNMI_ERR_OK);
5929 /*****************************************************************************
5931 * VirtualConf - Calculates the values of configuration OIDs for virtual port
5934 * We handle here the get of the configuration group OIDs, which are
5935 * a little bit complicated. The virtual port consists of all currently
5936 * active physical ports. If multiple ports are active and configured
5937 * differently we get in some trouble to return a single value. So we
5938 * get the value of the first active port and compare it with that of
5939 * the other active ports. If they are not the same, we return a value
5940 * that indicates that the state is indeterminated.
5945 PNMI_STATIC void VirtualConf(
5946 SK_AC *pAC, /* Pointer to adapter context */
5947 SK_IOC IoC, /* IO context handle */
5948 SK_U32 Id, /* Object ID that is to be processed */
5949 char *pBuf) /* Buffer used for the management data transfer */
5951 unsigned int PhysPortMax;
5952 unsigned int PhysPortIndex;
5955 SK_BOOL PortActiveFlag;
5959 PortActiveFlag = SK_FALSE;
5960 PhysPortMax = pAC->GIni.GIMacsFound;
5962 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
5965 pPrt = &pAC->GIni.GP[PhysPortIndex];
5967 /* Check if the physical port is active */
5968 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5973 PortActiveFlag = SK_TRUE;
5977 case OID_SKGE_PHY_TYPE:
5978 /* Check if it is the first active port */
5980 Val32 = pPrt->PhyType;
5981 SK_PNMI_STORE_U32(pBuf, Val32);
5985 case OID_SKGE_LINK_CAP:
5988 * Different capabilities should not happen, but
5989 * in the case of the cases OR them all together.
5990 * From a curious point of view the virtual port
5991 * is capable of all found capabilities.
5993 *pBuf |= pPrt->PLinkCap;
5996 case OID_SKGE_LINK_MODE:
5997 /* Check if it is the first active port */
6000 *pBuf = pPrt->PLinkModeConf;
6005 * If we find an active port with a different link
6006 * mode than the first one we return a value that
6007 * indicates that the link mode is indeterminated.
6009 if (*pBuf != pPrt->PLinkModeConf) {
6011 *pBuf = SK_LMODE_INDETERMINATED;
6015 case OID_SKGE_LINK_MODE_STATUS:
6016 /* Get the link mode of the physical port */
6017 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6019 /* Check if it is the first active port */
6027 * If we find an active port with a different link
6028 * mode status than the first one we return a value
6029 * that indicates that the link mode status is
6032 if (*pBuf != Val8) {
6034 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6038 case OID_SKGE_LINK_STATUS:
6039 /* Get the link status of the physical port */
6040 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6042 /* Check if it is the first active port */
6050 * If we find an active port with a different link
6051 * status than the first one, we return a value
6052 * that indicates that the link status is
6055 if (*pBuf != Val8) {
6057 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6061 case OID_SKGE_FLOWCTRL_CAP:
6062 /* Check if it is the first active port */
6065 *pBuf = pPrt->PFlowCtrlCap;
6070 * From a curious point of view the virtual port
6071 * is capable of all found capabilities.
6073 *pBuf |= pPrt->PFlowCtrlCap;
6076 case OID_SKGE_FLOWCTRL_MODE:
6077 /* Check if it is the first active port */
6080 *pBuf = pPrt->PFlowCtrlMode;
6085 * If we find an active port with a different flow
6086 * control mode than the first one, we return a value
6087 * that indicates that the mode is indeterminated.
6089 if (*pBuf != pPrt->PFlowCtrlMode) {
6091 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6095 case OID_SKGE_FLOWCTRL_STATUS:
6096 /* Check if it is the first active port */
6099 *pBuf = pPrt->PFlowCtrlStatus;
6104 * If we find an active port with a different flow
6105 * control status than the first one, we return a
6106 * value that indicates that the status is
6109 if (*pBuf != pPrt->PFlowCtrlStatus) {
6111 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6115 case OID_SKGE_PHY_OPERATION_CAP:
6116 /* Check if it is the first active port */
6119 *pBuf = pPrt->PMSCap;
6124 * From a curious point of view the virtual port
6125 * is capable of all found capabilities.
6127 *pBuf |= pPrt->PMSCap;
6130 case OID_SKGE_PHY_OPERATION_MODE:
6131 /* Check if it is the first active port */
6134 *pBuf = pPrt->PMSMode;
6139 * If we find an active port with a different master/
6140 * slave mode than the first one, we return a value
6141 * that indicates that the mode is indeterminated.
6143 if (*pBuf != pPrt->PMSMode) {
6145 *pBuf = SK_MS_MODE_INDETERMINATED;
6149 case OID_SKGE_PHY_OPERATION_STATUS:
6150 /* Check if it is the first active port */
6153 *pBuf = pPrt->PMSStatus;
6158 * If we find an active port with a different master/
6159 * slave status than the first one, we return a
6160 * value that indicates that the status is
6163 if (*pBuf != pPrt->PMSStatus) {
6165 *pBuf = SK_MS_STAT_INDETERMINATED;
6169 case OID_SKGE_SPEED_MODE:
6170 /* Check if it is the first active port */
6173 *pBuf = pPrt->PLinkSpeed;
6178 * If we find an active port with a different flow
6179 * control mode than the first one, we return a value
6180 * that indicates that the mode is indeterminated.
6182 if (*pBuf != pPrt->PLinkSpeed) {
6184 *pBuf = SK_LSPEED_INDETERMINATED;
6188 case OID_SKGE_SPEED_STATUS:
6189 /* Check if it is the first active port */
6192 *pBuf = pPrt->PLinkSpeedUsed;
6197 * If we find an active port with a different flow
6198 * control status than the first one, we return a
6199 * value that indicates that the status is
6202 if (*pBuf != pPrt->PLinkSpeedUsed) {
6204 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6211 * If no port is active return an indeterminated answer
6213 if (!PortActiveFlag) {
6217 case OID_SKGE_LINK_CAP:
6218 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6221 case OID_SKGE_LINK_MODE:
6222 *pBuf = SK_LMODE_INDETERMINATED;
6225 case OID_SKGE_LINK_MODE_STATUS:
6226 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6229 case OID_SKGE_LINK_STATUS:
6230 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6233 case OID_SKGE_FLOWCTRL_CAP:
6234 case OID_SKGE_FLOWCTRL_MODE:
6235 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6238 case OID_SKGE_FLOWCTRL_STATUS:
6239 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6242 case OID_SKGE_PHY_OPERATION_CAP:
6243 *pBuf = SK_MS_CAP_INDETERMINATED;
6246 case OID_SKGE_PHY_OPERATION_MODE:
6247 *pBuf = SK_MS_MODE_INDETERMINATED;
6250 case OID_SKGE_PHY_OPERATION_STATUS:
6251 *pBuf = SK_MS_STAT_INDETERMINATED;
6253 case OID_SKGE_SPEED_CAP:
6254 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6257 case OID_SKGE_SPEED_MODE:
6258 *pBuf = SK_LSPEED_INDETERMINATED;
6261 case OID_SKGE_SPEED_STATUS:
6262 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6268 /*****************************************************************************
6270 * CalculateLinkStatus - Determins the link status of a physical port
6273 * Determins the link status the following way:
6274 * LSTAT_PHY_DOWN: Link is down
6275 * LSTAT_AUTONEG: Auto-negotiation failed
6276 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6278 * LSTAT_LOG_UP: RLMT marked the port as up
6281 * Link status of physical port
6283 PNMI_STATIC SK_U8 CalculateLinkStatus(
6284 SK_AC *pAC, /* Pointer to adapter context */
6285 SK_IOC IoC, /* IO context handle */
6286 unsigned int PhysPortIndex) /* Physical port index */
6290 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6292 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6294 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6296 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6298 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6300 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6303 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6309 /*****************************************************************************
6311 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6314 * The COMMON module only tells us if the mode is half or full duplex.
6315 * But in the decade of auto sensing it is useful for the user to
6316 * know if the mode was negotiated or forced. Therefore we have a
6317 * look to the mode, which was last used by the negotiation process.
6320 * The link mode status
6322 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6323 SK_AC *pAC, /* Pointer to adapter context */
6324 SK_IOC IoC, /* IO context handle */
6325 unsigned int PhysPortIndex) /* Physical port index */
6329 /* Get the current mode, which can be full or half duplex */
6330 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6332 /* Check if no valid mode could be found (link is down) */
6333 if (Result < SK_LMODE_STAT_HALF) {
6335 Result = SK_LMODE_STAT_UNKNOWN;
6337 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6340 * Auto-negotiation was used to bring up the link. Change
6341 * the already found duplex status that it indicates
6342 * auto-negotiation was involved.
6344 if (Result == SK_LMODE_STAT_HALF) {
6346 Result = SK_LMODE_STAT_AUTOHALF;
6348 else if (Result == SK_LMODE_STAT_FULL) {
6350 Result = SK_LMODE_STAT_AUTOFULL;
6357 /*****************************************************************************
6359 * GetVpdKeyArr - Obtain an array of VPD keys
6362 * Read the VPD keys and build an array of VPD keys, which are
6366 * SK_PNMI_ERR_OK Task successfully performed.
6367 * SK_PNMI_ERR_GENERAL Something went wrong.
6369 PNMI_STATIC int GetVpdKeyArr(
6370 SK_AC *pAC, /* Pointer to adapter context */
6371 SK_IOC IoC, /* IO context handle */
6372 char *pKeyArr, /* Ptr KeyArray */
6373 unsigned int KeyArrLen, /* Length of array in bytes */
6374 unsigned int *pKeyNo) /* Number of keys */
6376 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6377 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6378 unsigned int StartOffset;
6379 unsigned int Offset;
6384 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6389 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6393 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6396 return (SK_PNMI_ERR_GENERAL);
6398 /* If no keys are available return now */
6399 if (*pKeyNo == 0 || BufKeysLen == 0) {
6401 return (SK_PNMI_ERR_OK);
6404 * If the key list is too long for us trunc it and give a
6405 * errorlog notification. This case should not happen because
6406 * the maximum number of keys is limited due to RAM limitations
6408 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6410 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6413 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6417 * Now build an array of fixed string length size and copy
6418 * the keys together.
6420 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6423 if (BufKeys[Offset] != 0) {
6428 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6430 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6432 return (SK_PNMI_ERR_GENERAL);
6435 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6436 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6439 StartOffset = Offset + 1;
6442 /* Last key not zero terminated? Get it anyway */
6443 if (StartOffset < Offset) {
6445 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6446 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6449 return (SK_PNMI_ERR_OK);
6452 /*****************************************************************************
6454 * SirqUpdate - Let the SIRQ update its internal values
6457 * Just to be sure that the SIRQ module holds its internal data
6458 * structures up to date, we send an update event before we make
6462 * SK_PNMI_ERR_OK Task successfully performed.
6463 * SK_PNMI_ERR_GENERAL Something went wrong.
6465 PNMI_STATIC int SirqUpdate(
6466 SK_AC *pAC, /* Pointer to adapter context */
6467 SK_IOC IoC) /* IO context handle */
6469 SK_EVPARA EventParam;
6472 /* Was the module already updated during the current PNMI call? */
6473 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6475 return (SK_PNMI_ERR_OK);
6478 /* Send an synchronuous update event to the module */
6479 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6480 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6482 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6485 return (SK_PNMI_ERR_GENERAL);
6488 return (SK_PNMI_ERR_OK);
6491 /*****************************************************************************
6493 * RlmtUpdate - Let the RLMT update its internal values
6496 * Just to be sure that the RLMT module holds its internal data
6497 * structures up to date, we send an update event before we make
6501 * SK_PNMI_ERR_OK Task successfully performed.
6502 * SK_PNMI_ERR_GENERAL Something went wrong.
6504 PNMI_STATIC int RlmtUpdate(
6505 SK_AC *pAC, /* Pointer to adapter context */
6506 SK_IOC IoC, /* IO context handle */
6507 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6509 SK_EVPARA EventParam;
6512 /* Was the module already updated during the current PNMI call? */
6513 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6515 return (SK_PNMI_ERR_OK);
6518 /* Send an synchronuous update event to the module */
6519 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6520 EventParam.Para32[0] = NetIndex;
6521 EventParam.Para32[1] = (SK_U32)-1;
6522 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6524 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6527 return (SK_PNMI_ERR_GENERAL);
6530 return (SK_PNMI_ERR_OK);
6533 /*****************************************************************************
6535 * MacUpdate - Force the XMAC to output the current statistic
6538 * The XMAC holds its statistic internally. To obtain the current
6539 * values we must send a command so that the statistic data will
6540 * be written to a predefined memory area on the adapter.
6543 * SK_PNMI_ERR_OK Task successfully performed.
6544 * SK_PNMI_ERR_GENERAL Something went wrong.
6546 PNMI_STATIC int MacUpdate(
6547 SK_AC *pAC, /* Pointer to adapter context */
6548 SK_IOC IoC, /* IO context handle */
6549 unsigned int FirstMac, /* Index of the first Mac to be updated */
6550 unsigned int LastMac) /* Index of the last Mac to be updated */
6552 unsigned int MacIndex;
6555 * Were the statistics already updated during the
6556 * current PNMI call?
6558 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6560 return (SK_PNMI_ERR_OK);
6563 /* Send an update command to all MACs specified */
6564 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6567 * 2002-09-13 pweber: Freeze the current SW counters.
6568 * (That should be done as close as
6569 * possible to the update of the
6572 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6573 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6576 /* 2002-09-13 pweber: Update the HW counter */
6577 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6579 return (SK_PNMI_ERR_GENERAL);
6583 return (SK_PNMI_ERR_OK);
6586 /*****************************************************************************
6588 * GetStatVal - Retrieve an XMAC statistic counter
6591 * Retrieves the statistic counter of a virtual or physical port. The
6592 * virtual port is identified by the index 0. It consists of all
6593 * currently active ports. To obtain the counter value for this port
6594 * we must add the statistic counter of all active ports. To grant
6595 * continuous counter values for the virtual port even when port
6596 * switches occur we must additionally add a delta value, which was
6597 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6600 * Requested statistic value
6602 PNMI_STATIC SK_U64 GetStatVal(
6603 SK_AC *pAC, /* Pointer to adapter context */
6604 SK_IOC IoC, /* IO context handle */
6605 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6606 unsigned int StatIndex, /* Index to statistic value */
6607 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6609 unsigned int PhysPortIndex;
6610 unsigned int PhysPortMax;
6614 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6616 PhysPortIndex = NetIndex;
6618 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6620 else { /* Single Net mode */
6622 if (LogPortIndex == 0) {
6624 PhysPortMax = pAC->GIni.GIMacsFound;
6626 /* Add counter of all active ports */
6627 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6630 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6632 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6636 /* Correct value because of port switches */
6637 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6640 /* Get counter value of physical port */
6641 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6643 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6649 /*****************************************************************************
6651 * GetPhysStatVal - Get counter value for physical port
6654 * Builds a 64bit counter value. Except for the octet counters
6655 * the lower 32bit are counted in hardware and the upper 32bit
6656 * in software by monitoring counter overflow interrupts in the
6657 * event handler. To grant continous counter values during XMAC
6658 * resets (caused by a workaround) we must add a delta value.
6659 * The delta was calculated in the event handler when a
6660 * SK_PNMI_EVT_XMAC_RESET was received.
6665 PNMI_STATIC SK_U64 GetPhysStatVal(
6666 SK_AC *pAC, /* Pointer to adapter context */
6667 SK_IOC IoC, /* IO context handle */
6668 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6669 unsigned int StatIndex) /* Index to statistic value */
6676 unsigned int HelpIndex;
6679 SK_PNMI_PORT *pPnmiPrt;
6680 SK_GEMACFUNC *pFnMac;
6682 pPrt = &pAC->GIni.GP[PhysPortIndex];
6684 MacType = pAC->GIni.GIMacType;
6686 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6687 if (MacType == SK_MAC_XMAC) {
6688 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6691 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6694 pFnMac = &pAC->GIni.GIFunc;
6696 switch (StatIndex) {
6698 if (MacType == SK_MAC_GMAC) {
6699 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6700 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6702 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6703 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6706 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6707 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6712 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6713 StatAddr[StatIndex][MacType].Reg,
6716 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6720 if (MacType == SK_MAC_GMAC) {
6721 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6722 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6724 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6725 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6728 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6729 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6734 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6735 StatAddr[StatIndex][MacType].Reg,
6738 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6741 case SK_PNMI_HTX_OCTET:
6742 case SK_PNMI_HRX_OCTET:
6743 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6744 StatAddr[StatIndex][MacType].Reg,
6746 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6747 StatAddr[StatIndex + 1][MacType].Reg,
6751 case SK_PNMI_HTX_BURST:
6752 case SK_PNMI_HTX_EXCESS_DEF:
6753 case SK_PNMI_HTX_CARRIER:
6754 /* Not supported by GMAC */
6755 if (MacType == SK_MAC_GMAC) {
6759 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6760 StatAddr[StatIndex][MacType].Reg,
6762 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6765 case SK_PNMI_HTX_MACC:
6766 /* GMAC only supports PAUSE MAC control frames */
6767 if (MacType == SK_MAC_GMAC) {
6768 HelpIndex = SK_PNMI_HTX_PMACC;
6771 HelpIndex = StatIndex;
6774 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6775 StatAddr[HelpIndex][MacType].Reg,
6778 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6781 case SK_PNMI_HTX_COL:
6782 case SK_PNMI_HRX_UNDERSIZE:
6783 /* Not supported by XMAC */
6784 if (MacType == SK_MAC_XMAC) {
6788 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6789 StatAddr[StatIndex][MacType].Reg,
6791 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6794 case SK_PNMI_HTX_DEFFERAL:
6795 /* Not supported by GMAC */
6796 if (MacType == SK_MAC_GMAC) {
6801 * XMAC counts frames with deferred transmission
6802 * even in full-duplex mode.
6804 * In full-duplex mode the counter remains constant!
6806 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6807 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6813 /* Otherwise get contents of hardware register */
6814 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6815 StatAddr[StatIndex][MacType].Reg,
6817 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6821 case SK_PNMI_HRX_BADOCTET:
6822 /* Not supported by XMAC */
6823 if (MacType == SK_MAC_XMAC) {
6827 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6828 StatAddr[StatIndex][MacType].Reg,
6830 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6831 StatAddr[StatIndex + 1][MacType].Reg,
6835 case SK_PNMI_HTX_OCTETLOW:
6836 case SK_PNMI_HRX_OCTETLOW:
6837 case SK_PNMI_HRX_BADOCTETLOW:
6840 case SK_PNMI_HRX_LONGFRAMES:
6841 /* For XMAC the SW counter is managed by PNMI */
6842 if (MacType == SK_MAC_XMAC) {
6843 return (pPnmiPrt->StatRxLongFrameCts);
6846 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6847 StatAddr[StatIndex][MacType].Reg,
6849 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6852 case SK_PNMI_HRX_TOO_LONG:
6853 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6854 StatAddr[StatIndex][MacType].Reg,
6856 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6858 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6860 if (MacType == SK_MAC_GMAC) {
6861 /* For GMAC the SW counter is additionally managed by PNMI */
6862 Val += pPnmiPrt->StatRxFrameTooLongCts;
6866 * Frames longer than IEEE 802.3 frame max size are counted
6867 * by XMAC in frame_too_long counter even reception of long
6868 * frames was enabled and the frame was correct.
6869 * So correct the value by subtracting RxLongFrame counter.
6871 Val -= pPnmiPrt->StatRxLongFrameCts;
6874 LowVal = (SK_U32)Val;
6875 HighVal = (SK_U32)(Val >> 32);
6878 case SK_PNMI_HRX_SHORTS:
6879 /* Not supported by GMAC */
6880 if (MacType == SK_MAC_GMAC) {
6886 * XMAC counts short frame errors even if link down (#10620)
6888 * If link-down the counter remains constant
6890 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
6892 /* Otherwise get incremental difference */
6893 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6894 StatAddr[StatIndex][MacType].Reg,
6896 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6898 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6899 Val -= pPnmiPrt->RxShortZeroMark;
6901 LowVal = (SK_U32)Val;
6902 HighVal = (SK_U32)(Val >> 32);
6906 case SK_PNMI_HRX_MACC:
6907 case SK_PNMI_HRX_MACC_UNKWN:
6908 case SK_PNMI_HRX_BURST:
6909 case SK_PNMI_HRX_MISSED:
6910 case SK_PNMI_HRX_FRAMING:
6911 case SK_PNMI_HRX_CARRIER:
6912 case SK_PNMI_HRX_IRLENGTH:
6913 case SK_PNMI_HRX_SYMBOL:
6914 case SK_PNMI_HRX_CEXT:
6915 /* Not supported by GMAC */
6916 if (MacType == SK_MAC_GMAC) {
6920 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6921 StatAddr[StatIndex][MacType].Reg,
6923 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6926 case SK_PNMI_HRX_PMACC_ERR:
6927 /* For GMAC the SW counter is managed by PNMI */
6928 if (MacType == SK_MAC_GMAC) {
6929 return (pPnmiPrt->StatRxPMaccErr);
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[StatIndex][MacType].Reg,
6935 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6938 /* SW counter managed by PNMI */
6939 case SK_PNMI_HTX_SYNC:
6940 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
6941 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
6944 /* SW counter managed by PNMI */
6945 case SK_PNMI_HTX_SYNC_OCTET:
6946 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
6947 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
6950 case SK_PNMI_HRX_FCS:
6952 * Broadcom filters FCS errors and counts it in
6953 * Receive Error Counter register
6955 if (pPrt->PhyType == SK_PHY_BCOM) {
6956 /* do not read while not initialized (PHY_READ hangs!)*/
6957 if (pPrt->PState != SK_PRT_RESET) {
6958 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
6962 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6965 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6966 StatAddr[StatIndex][MacType].Reg,
6968 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6973 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6974 StatAddr[StatIndex][MacType].Reg,
6976 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6980 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
6982 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
6983 Val += pPnmiPrt->CounterOffset[StatIndex];
6988 /*****************************************************************************
6990 * ResetCounter - Set all counters and timestamps to zero
6993 * Notifies other common modules which store statistic data to
6994 * reset their counters and finally reset our own counters.
6999 PNMI_STATIC void ResetCounter(
7000 SK_AC *pAC, /* Pointer to adapter context */
7001 SK_IOC IoC, /* IO context handle */
7004 unsigned int PhysPortIndex;
7005 SK_EVPARA EventParam;
7008 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7010 /* Notify sensor module */
7011 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7013 /* Notify RLMT module */
7014 EventParam.Para32[0] = NetIndex;
7015 EventParam.Para32[1] = (SK_U32)-1;
7016 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7017 EventParam.Para32[1] = 0;
7019 /* Notify SIRQ module */
7020 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7022 /* Notify CSUM module */
7024 EventParam.Para32[0] = NetIndex;
7025 EventParam.Para32[1] = (SK_U32)-1;
7026 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7028 #endif /* SK_USE_CSUM */
7030 /* Clear XMAC statistic */
7031 for (PhysPortIndex = 0; PhysPortIndex <
7032 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7034 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7036 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7037 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7038 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7039 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7040 PhysPortIndex].CounterOffset));
7041 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7042 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7043 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7044 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7045 PhysPortIndex].StatSyncOctetsCts));
7046 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7047 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7048 PhysPortIndex].StatRxLongFrameCts));
7049 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7050 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7051 PhysPortIndex].StatRxFrameTooLongCts));
7052 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7053 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7054 PhysPortIndex].StatRxPMaccErr));
7058 * Clear local statistics
7060 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7061 sizeof(pAC->Pnmi.VirtualCounterOffset));
7062 pAC->Pnmi.RlmtChangeCts = 0;
7063 pAC->Pnmi.RlmtChangeTime = 0;
7064 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7065 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7066 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7067 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7068 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7069 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7070 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7071 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7072 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7073 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7074 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7075 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7076 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7077 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7080 /*****************************************************************************
7082 * GetTrapEntry - Get an entry in the trap buffer
7085 * The trap buffer stores various events. A user application somehow
7086 * gets notified that an event occured and retrieves the trap buffer
7087 * contens (or simply polls the buffer). The buffer is organized as
7088 * a ring which stores the newest traps at the beginning. The oldest
7089 * traps are overwritten by the newest ones. Each trap entry has a
7090 * unique number, so that applications may detect new trap entries.
7093 * A pointer to the trap entry
7095 PNMI_STATIC char* GetTrapEntry(
7096 SK_AC *pAC, /* Pointer to adapter context */
7097 SK_U32 TrapId, /* SNMP ID of the trap */
7098 unsigned int Size) /* Space needed for trap entry */
7100 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7101 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7102 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7103 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7104 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7106 unsigned int NeededSpace;
7107 unsigned int EntrySize;
7112 /* Last byte of entry will get a copy of the entry length */
7116 * Calculate needed buffer space */
7123 NeededSpace = Beg + Size;
7128 * Check if enough buffer space is provided. Otherwise
7129 * free some entries. Leave one byte space between begin
7130 * and end of buffer to make it possible to detect whether
7131 * the buffer is full or empty
7133 while (BufFree < NeededSpace + 1) {
7137 End = SK_PNMI_TRAP_QUEUE_LEN;
7140 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7141 BufFree += EntrySize;
7144 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7146 if (End == BufPad) {
7148 SK_MEMSET(pBuf, (char)(-1), End);
7157 * Insert new entry as first entry. Newest entries are
7158 * stored at the beginning of the queue.
7163 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7168 BufFree -= NeededSpace;
7170 /* Save the current offsets */
7171 pAC->Pnmi.TrapQueueBeg = Beg;
7172 pAC->Pnmi.TrapQueueEnd = End;
7173 pAC->Pnmi.TrapBufPad = BufPad;
7174 pAC->Pnmi.TrapBufFree = BufFree;
7176 /* Initialize the trap entry */
7177 *(pBuf + Beg + Size - 1) = (char)Size;
7178 *(pBuf + Beg) = (char)Size;
7179 Val32 = (pAC->Pnmi.TrapUnique) ++;
7180 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7181 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7182 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7183 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7185 return (pBuf + Beg);
7188 /*****************************************************************************
7190 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7193 * On a query of the TRAP OID the trap buffer contents will be
7194 * copied continuously to the request buffer, which must be large
7195 * enough. No length check is performed.
7200 PNMI_STATIC void CopyTrapQueue(
7201 SK_AC *pAC, /* Pointer to adapter context */
7202 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7204 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7205 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7206 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7207 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7209 unsigned int DstOff = 0;
7212 while (Trap != End) {
7214 Len = (unsigned int)*(pBuf + Trap);
7217 * Last byte containing a copy of the length will
7220 *(pDstBuf + DstOff) = (char)(Len - 1);
7221 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7225 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7232 /*****************************************************************************
7234 * GetTrapQueueLen - Get the length of the trap buffer
7237 * Evaluates the number of currently stored traps and the needed
7238 * buffer size to retrieve them.
7243 PNMI_STATIC void GetTrapQueueLen(
7244 SK_AC *pAC, /* Pointer to adapter context */
7245 unsigned int *pLen, /* Length in Bytes of all queued traps */
7246 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7248 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7249 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7250 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7251 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7253 unsigned int Entries = 0;
7254 unsigned int TotalLen = 0;
7257 while (Trap != End) {
7259 Len = (unsigned int)*(pBuf + Trap);
7260 TotalLen += Len - 1;
7264 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7270 *pEntries = Entries;
7274 /*****************************************************************************
7276 * QueueSimpleTrap - Store a simple trap to the trap buffer
7279 * A simple trap is a trap with now additional data. It consists
7280 * simply of a trap code.
7285 PNMI_STATIC void QueueSimpleTrap(
7286 SK_AC *pAC, /* Pointer to adapter context */
7287 SK_U32 TrapId) /* Type of sensor trap */
7289 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7292 /*****************************************************************************
7294 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7297 * Gets an entry in the trap buffer and fills it with sensor related
7303 PNMI_STATIC void QueueSensorTrap(
7304 SK_AC *pAC, /* Pointer to adapter context */
7305 SK_U32 TrapId, /* Type of sensor trap */
7306 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7309 unsigned int Offset;
7310 unsigned int DescrLen;
7314 /* Get trap buffer entry */
7315 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7316 pBuf = GetTrapEntry(pAC, TrapId,
7317 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7318 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7320 /* Store additionally sensor trap related data */
7321 Val32 = OID_SKGE_SENSOR_INDEX;
7322 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7323 *(pBuf + Offset + 4) = 4;
7324 Val32 = (SK_U32)SensorIndex;
7325 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7328 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7329 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7330 *(pBuf + Offset + 4) = (char)DescrLen;
7331 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7333 Offset += DescrLen + 5;
7335 Val32 = OID_SKGE_SENSOR_TYPE;
7336 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7337 *(pBuf + Offset + 4) = 1;
7338 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7341 Val32 = OID_SKGE_SENSOR_VALUE;
7342 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7343 *(pBuf + Offset + 4) = 4;
7344 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7345 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7348 /*****************************************************************************
7350 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7353 * Nothing further to explain.
7358 PNMI_STATIC void QueueRlmtNewMacTrap(
7359 SK_AC *pAC, /* Pointer to adapter context */
7360 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7366 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7367 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7369 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7370 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7371 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7372 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7375 /*****************************************************************************
7377 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7380 * Nothing further to explain.
7385 PNMI_STATIC void QueueRlmtPortTrap(
7386 SK_AC *pAC, /* Pointer to adapter context */
7387 SK_U32 TrapId, /* Type of RLMT port trap */
7388 unsigned int PortIndex) /* Index of the port, which changed its state */
7394 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7396 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7397 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7398 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7399 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7402 /*****************************************************************************
7404 * CopyMac - Copies a MAC address
7407 * Nothing further to explain.
7412 PNMI_STATIC void CopyMac(
7413 char *pDst, /* Pointer to destination buffer */
7414 SK_MAC_ADDR *pMac) /* Pointer of Source */
7419 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7421 *(pDst + i) = pMac->a[i];
7425 #ifdef SK_POWER_MGMT
7426 /*****************************************************************************
7428 * PowerManagement - OID handler function of PowerManagement OIDs
7431 * The code is simple. No description necessary.
7434 * SK_PNMI_ERR_OK The request was successfully performed.
7435 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7436 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7437 * the correct data (e.g. a 32bit value is
7438 * needed, but a 16 bit value was passed).
7439 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7440 * exist (e.g. port instance 3 on a two port
7444 PNMI_STATIC int PowerManagement(
7445 SK_AC *pAC, /* Pointer to adapter context */
7446 SK_IOC IoC, /* IO context handle */
7447 int Action, /* Get/PreSet/Set action */
7448 SK_U32 Id, /* Object ID that is to be processed */
7449 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7450 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7451 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7452 unsigned int TableIndex, /* Index to the Id table */
7453 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7456 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7459 * Check instance. We only handle single instance variables
7461 if (Instance != (SK_U32)(-1) && Instance != 1) {
7464 return (SK_PNMI_ERR_UNKNOWN_INST);
7471 case OID_PNP_CAPABILITIES:
7472 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7474 *pLen = sizeof(SK_PNP_CAPABILITIES);
7475 return (SK_PNMI_ERR_TOO_SHORT);
7479 case OID_PNP_SET_POWER:
7480 case OID_PNP_QUERY_POWER:
7481 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7483 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7484 return (SK_PNMI_ERR_TOO_SHORT);
7488 case OID_PNP_ADD_WAKE_UP_PATTERN:
7489 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7490 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7492 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7493 return (SK_PNMI_ERR_TOO_SHORT);
7497 case OID_PNP_ENABLE_WAKE_UP:
7498 if (*pLen < sizeof(SK_U32)) {
7500 *pLen = sizeof(SK_U32);
7501 return (SK_PNMI_ERR_TOO_SHORT);
7509 if (Action == SK_PNMI_GET) {
7516 case OID_PNP_CAPABILITIES:
7517 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7520 case OID_PNP_QUERY_POWER:
7521 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7522 the miniport to indicate whether it can transition its NIC
7523 to the low-power state.
7524 A miniport driver must always return NDIS_STATUS_SUCCESS
7525 to a query of OID_PNP_QUERY_POWER. */
7526 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7527 RetCode = SK_PNMI_ERR_OK;
7530 /* NDIS handles these OIDs as write-only.
7531 * So in case of get action the buffer with written length = 0
7534 case OID_PNP_SET_POWER:
7535 case OID_PNP_ADD_WAKE_UP_PATTERN:
7536 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7538 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7541 case OID_PNP_ENABLE_WAKE_UP:
7542 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7546 RetCode = SK_PNMI_ERR_GENERAL;
7555 * Perform preset or set
7558 /* POWER module does not support PRESET action */
7559 if (Action == SK_PNMI_PRESET) {
7560 return (SK_PNMI_ERR_OK);
7564 case OID_PNP_SET_POWER:
7565 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7568 case OID_PNP_ADD_WAKE_UP_PATTERN:
7569 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7572 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7573 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7576 case OID_PNP_ENABLE_WAKE_UP:
7577 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7581 RetCode = SK_PNMI_ERR_READ_ONLY;
7586 #endif /* SK_POWER_MGMT */
7588 #ifdef SK_DIAG_SUPPORT
7589 /*****************************************************************************
7591 * DiagActions - OID handler function of Diagnostic driver
7594 * The code is simple. No description necessary.
7597 * SK_PNMI_ERR_OK The request was successfully performed.
7598 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7599 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7600 * the correct data (e.g. a 32bit value is
7601 * needed, but a 16 bit value was passed).
7602 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7603 * exist (e.g. port instance 3 on a two port
7607 PNMI_STATIC int DiagActions(
7608 SK_AC *pAC, /* Pointer to adapter context */
7609 SK_IOC IoC, /* IO context handle */
7610 int Action, /* GET/PRESET/SET action */
7611 SK_U32 Id, /* Object ID that is to be processed */
7612 char *pBuf, /* Buffer used for the management data transfer */
7613 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7614 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7615 unsigned int TableIndex, /* Index to the Id table */
7616 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7620 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7623 * Check instance. We only handle single instance variables.
7625 if (Instance != (SK_U32)(-1) && Instance != 1) {
7628 return (SK_PNMI_ERR_UNKNOWN_INST);
7636 case OID_SKGE_DIAG_MODE:
7637 if (*pLen < sizeof(SK_U32)) {
7639 *pLen = sizeof(SK_U32);
7640 return (SK_PNMI_ERR_TOO_SHORT);
7645 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7647 return (SK_PNMI_ERR_GENERAL);
7650 /* Perform action. */
7653 if (Action == SK_PNMI_GET) {
7657 case OID_SKGE_DIAG_MODE:
7658 DiagStatus = pAC->Pnmi.DiagAttached;
7659 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7660 *pLen = sizeof(SK_U32);
7661 RetCode = SK_PNMI_ERR_OK;
7666 RetCode = SK_PNMI_ERR_GENERAL;
7672 /* From here SET or PRESET value. */
7674 /* PRESET value is not supported. */
7675 if (Action == SK_PNMI_PRESET) {
7676 return (SK_PNMI_ERR_OK);
7681 case OID_SKGE_DIAG_MODE:
7683 /* Handle the SET. */
7686 /* Attach the DIAG to this adapter. */
7687 case SK_DIAG_ATTACHED:
7688 /* Check if we come from running */
7689 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7691 RetCode = SkDrvLeaveDiagMode(pAC);
7694 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7696 RetCode = SK_PNMI_ERR_OK;
7701 RetCode = SK_PNMI_ERR_GENERAL;
7705 if (RetCode == SK_PNMI_ERR_OK) {
7707 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7711 /* Enter the DIAG mode in the driver. */
7712 case SK_DIAG_RUNNING:
7713 RetCode = SK_PNMI_ERR_OK;
7716 * If DiagAttached is set, we can tell the driver
7717 * to enter the DIAG mode.
7719 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7720 /* If DiagMode is not active, we can enter it. */
7721 if (!pAC->DiagModeActive) {
7723 RetCode = SkDrvEnterDiagMode(pAC);
7727 RetCode = SK_PNMI_ERR_GENERAL;
7732 RetCode = SK_PNMI_ERR_GENERAL;
7735 if (RetCode == SK_PNMI_ERR_OK) {
7737 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7742 /* Check if we come from running */
7743 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7745 RetCode = SkDrvLeaveDiagMode(pAC);
7748 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7750 RetCode = SK_PNMI_ERR_OK;
7755 RetCode = SK_PNMI_ERR_GENERAL;
7759 if (RetCode == SK_PNMI_ERR_OK) {
7761 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7766 RetCode = SK_PNMI_ERR_BAD_VALUE;
7772 RetCode = SK_PNMI_ERR_GENERAL;
7775 if (RetCode == SK_PNMI_ERR_OK) {
7776 *pLen = sizeof(SK_U32);
7784 #endif /* SK_DIAG_SUPPORT */
7786 /*****************************************************************************
7788 * Vct - OID handler function of OIDs
7791 * The code is simple. No description necessary.
7794 * SK_PNMI_ERR_OK The request was performed successfully.
7795 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7796 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7797 * the correct data (e.g. a 32bit value is
7798 * needed, but a 16 bit value was passed).
7799 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7800 * exist (e.g. port instance 3 on a two port
7802 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7806 PNMI_STATIC int Vct(
7807 SK_AC *pAC, /* Pointer to adapter context */
7808 SK_IOC IoC, /* IO context handle */
7809 int Action, /* GET/PRESET/SET action */
7810 SK_U32 Id, /* Object ID that is to be processed */
7811 char *pBuf, /* Buffer used for the management data transfer */
7812 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7813 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7814 unsigned int TableIndex, /* Index to the Id table */
7815 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7818 SK_PNMI_VCT *pVctBackupData;
7821 SK_U32 PhysPortIndex;
7825 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7831 * Calculate the port indexes from the instance.
7833 PhysPortMax = pAC->GIni.GIMacsFound;
7834 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7836 /* Dual net mode? */
7837 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7841 if ((Instance != (SK_U32) (-1))) {
7842 /* Check instance range. */
7843 if ((Instance < 2) || (Instance > LogPortMax)) {
7845 return (SK_PNMI_ERR_UNKNOWN_INST);
7848 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7849 PhysPortIndex = NetIndex;
7852 PhysPortIndex = Instance - 2;
7854 Limit = PhysPortIndex + 1;
7858 * Instance == (SK_U32) (-1), get all Instances of that OID.
7860 * Not implemented yet. May be used in future releases.
7863 Limit = PhysPortMax;
7866 pPrt = &pAC->GIni.GP[PhysPortIndex];
7867 if (pPrt->PHWLinkUp) {
7874 /* Check MAC type */
7875 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
7877 return (SK_PNMI_ERR_GENERAL);
7880 /* Initialize backup data pointer. */
7881 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
7883 /* Check action type */
7884 if (Action == SK_PNMI_GET) {
7888 case OID_SKGE_VCT_GET:
7889 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
7890 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
7891 return (SK_PNMI_ERR_TOO_SHORT);
7895 case OID_SKGE_VCT_STATUS:
7896 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
7897 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
7898 return (SK_PNMI_ERR_TOO_SHORT);
7904 return (SK_PNMI_ERR_GENERAL);
7909 for (; PhysPortIndex < Limit; PhysPortIndex++) {
7912 case OID_SKGE_VCT_GET:
7913 if ((Link == SK_FALSE) &&
7914 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
7915 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
7917 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
7918 pAC->Pnmi.VctStatus[PhysPortIndex] |=
7919 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
7921 /* Copy results for later use to PNMI struct. */
7922 for (i = 0; i < 4; i++) {
7923 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
7924 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
7925 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
7928 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
7929 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
7934 pVctBackupData->PMdiPairLen[i] = CableLength;
7935 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
7938 Para.Para32[0] = PhysPortIndex;
7939 Para.Para32[1] = -1;
7940 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
7941 SkEventDispatcher(pAC, IoC);
7944 ; /* VCT test is running. */
7948 /* Get all results. */
7949 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7950 Offset += sizeof(SK_U8);
7951 *(pBuf + Offset) = pPrt->PCableLen;
7952 Offset += sizeof(SK_U8);
7953 for (i = 0; i < 4; i++) {
7954 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
7955 Offset += sizeof(SK_U32);
7957 for (i = 0; i < 4; i++) {
7958 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
7959 Offset += sizeof(SK_U8);
7962 RetCode = SK_PNMI_ERR_OK;
7965 case OID_SKGE_VCT_STATUS:
7966 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
7967 Offset += sizeof(SK_U8);
7968 RetCode = SK_PNMI_ERR_OK;
7973 return (SK_PNMI_ERR_GENERAL);
7979 } /* if SK_PNMI_GET */
7982 * From here SET or PRESET action. Check if the passed
7983 * buffer length is plausible.
7988 case OID_SKGE_VCT_SET:
7989 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
7990 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
7991 return (SK_PNMI_ERR_TOO_SHORT);
7997 return (SK_PNMI_ERR_GENERAL);
8001 * Perform preset or set.
8004 /* VCT does not support PRESET action. */
8005 if (Action == SK_PNMI_PRESET) {
8006 return (SK_PNMI_ERR_OK);
8010 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8012 case OID_SKGE_VCT_SET: /* Start VCT test. */
8013 if (Link == SK_FALSE) {
8014 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8016 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8017 if (RetCode == 0) { /* RetCode: 0 => Start! */
8018 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8019 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8020 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8023 * Start VCT timer counter.
8025 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8026 Para.Para32[0] = PhysPortIndex;
8027 Para.Para32[1] = -1;
8028 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8029 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8030 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8031 RetCode = SK_PNMI_ERR_OK;
8033 else { /* RetCode: 2 => Running! */
8034 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8035 RetCode = SK_PNMI_ERR_OK;
8038 else { /* RetCode: 4 => Link! */
8040 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8041 RetCode = SK_PNMI_ERR_OK;
8043 Offset += sizeof(SK_U32);
8048 return (SK_PNMI_ERR_GENERAL);
8057 PNMI_STATIC void CheckVctStatus(
8062 SK_U32 PhysPortIndex)
8065 SK_PNMI_VCT *pVctData;
8068 pPrt = &pAC->GIni.GP[PhysPortIndex];
8070 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8071 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8073 if (!pPrt->PHWLinkUp) {
8075 /* Was a VCT test ever made before? */
8076 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8077 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8078 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8081 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8085 /* Check VCT test status. */
8086 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8087 if (RetCode == 2) { /* VCT test is running. */
8088 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8090 else { /* VCT data was copied to pAC here. Check PENDING state. */
8091 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8092 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8096 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8097 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8102 /* Was a VCT test ever made before? */
8103 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8104 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8105 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8108 /* DSP only valid in 100/1000 modes. */
8109 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8110 SK_LSPEED_STAT_10MBPS) {
8111 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8114 } /* CheckVctStatus */
8117 /*****************************************************************************
8119 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8120 * PNMI function depending on the subcommand and
8121 * returns all data belonging to the complete database
8125 * Looks up the requested subcommand, calls the corresponding handler
8126 * function and passes all required parameters to it.
8127 * The function is called by the driver. It is needed to handle the new
8128 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8129 * the OID and a subcommand to decide what kind of request has to be done.
8132 * SK_PNMI_ERR_OK The request was successfully performed
8133 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8134 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8136 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8137 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8138 * exist (e.g. port instance 3 on a two port
8142 SK_AC *pAC, /* Pointer to adapter context struct */
8143 SK_IOC IoC, /* I/O context */
8144 void *pBuf, /* Buffer used for the management data transfer */
8145 unsigned int *pLen, /* Length of buffer */
8146 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8148 SK_I32 Mode; /* Store value of subcommand. */
8149 SK_U32 Oid; /* Store value of OID. */
8150 int ReturnCode; /* Store return value to show status of PNMI action. */
8151 int HeaderLength; /* Length of desired action plus OID. */
8153 ReturnCode = SK_PNMI_ERR_GENERAL;
8155 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8156 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8157 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8158 *pLen = *pLen - HeaderLength;
8159 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8162 case SK_GET_SINGLE_VAR:
8163 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8164 (char *) pBuf + sizeof(SK_I32), pLen,
8165 ((SK_U32) (-1)), NetIndex);
8166 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8167 *pLen = *pLen + sizeof(SK_I32);
8169 case SK_PRESET_SINGLE_VAR:
8170 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8171 (char *) pBuf + sizeof(SK_I32), pLen,
8172 ((SK_U32) (-1)), NetIndex);
8173 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8174 *pLen = *pLen + sizeof(SK_I32);
8176 case SK_SET_SINGLE_VAR:
8177 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8178 (char *) pBuf + sizeof(SK_I32), pLen,
8179 ((SK_U32) (-1)), NetIndex);
8180 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8181 *pLen = *pLen + sizeof(SK_I32);
8183 case SK_GET_FULL_MIB:
8184 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8186 case SK_PRESET_FULL_MIB:
8187 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8189 case SK_SET_FULL_MIB:
8190 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8196 return (ReturnCode);