1 /*****************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Purpose: Private Network Management Interface
7 ****************************************************************************/
9 /******************************************************************************
11 * (C)Copyright 1998-2002 SysKonnect GmbH.
12 * (C)Copyright 2002-2003 Marvell.
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
19 * The information in this file is provided "AS IS" without warranty.
21 ******************************************************************************/
24 static const char SysKonnectFileId[] =
25 "@(#) $Id: skgepnmi.c,v 1.111 2003/09/15 13:35:35 tschilli Exp $ (C) Marvell.";
28 #include "h/skdrv1st.h"
29 #include "h/sktypes.h"
30 #include "h/xmac_ii.h"
31 #include "h/skdebug.h"
32 #include "h/skqueue.h"
33 #include "h/skgepnmi.h"
34 #include "h/skgesirq.h"
38 #include "h/skgeinit.h"
39 #include "h/skdrv2nd.h"
40 #include "h/skgepnm2.h"
42 #include "h/skgepmgt.h"
44 /* defines *******************************************************************/
47 #define PNMI_STATIC static
53 * Public Function prototypes
55 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
56 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
57 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
58 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
59 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
60 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
61 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
62 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
63 unsigned int *pLen, SK_U32 NetIndex);
64 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
65 unsigned int *pLen, SK_U32 NetIndex);
66 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
67 unsigned int *pLen, SK_U32 NetIndex);
68 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
69 int SkPnmiGenIoctl(SK_AC *pAC, SK_IOC IoC, void * pBuf,
70 unsigned int * pLen, SK_U32 NetIndex);
74 * Private Function prototypes
77 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
79 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
81 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
82 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
83 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
84 unsigned int PhysPortIndex, unsigned int StatIndex);
85 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
86 unsigned int StatIndex, SK_U32 NetIndex);
87 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
88 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
89 unsigned int *pEntries);
90 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
91 unsigned int KeyArrLen, unsigned int *pKeyNo);
92 PNMI_STATIC int LookupId(SK_U32 Id);
93 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
94 unsigned int LastMac);
95 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
96 unsigned int *pLen, SK_U32 NetIndex);
97 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
98 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
99 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
100 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
101 unsigned int PortIndex);
102 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
103 unsigned int SensorIndex);
104 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
105 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
106 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
107 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
108 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
109 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
110 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
111 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
114 * Table to correlate OID with handler function and index to
115 * hardware register stored in StatAddress if applicable.
119 /* global variables **********************************************************/
122 * Overflow status register bit table and corresponding counter
123 * dependent on MAC type - the number relates to the size of overflow
124 * mask returned by the pFnMacOverflow function
126 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
127 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
128 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
129 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
130 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
131 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
132 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
133 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
134 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
135 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
136 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
137 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
138 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
139 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
140 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
141 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
142 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
143 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
144 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
145 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
146 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
147 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
148 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
149 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
150 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
151 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
152 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
153 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
154 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
155 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
156 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
157 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
158 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
159 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
160 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
161 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
162 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
163 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
164 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
165 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
166 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
167 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
168 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
169 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
170 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
171 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
172 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
173 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
174 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
175 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
176 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
177 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
178 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
179 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
180 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
181 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
182 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
183 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
184 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
185 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
186 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
187 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
188 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
189 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
190 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
194 * Table for hardware register saving on resets and port switches
196 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
198 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
199 /* SK_PNMI_HTX_OCTETHIGH */
200 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
201 /* SK_PNMI_HTX_OCTETLOW */
202 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
203 /* SK_PNMI_HTX_BROADCAST */
204 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
205 /* SK_PNMI_HTX_MULTICAST */
206 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
207 /* SK_PNMI_HTX_UNICAST */
208 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
209 /* SK_PNMI_HTX_BURST */
210 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
211 /* SK_PNMI_HTX_PMACC */
212 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
213 /* SK_PNMI_HTX_MACC */
214 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
215 /* SK_PNMI_HTX_COL */
216 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
217 /* SK_PNMI_HTX_SINGLE_COL */
218 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
219 /* SK_PNMI_HTX_MULTI_COL */
220 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
221 /* SK_PNMI_HTX_EXCESS_COL */
222 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
223 /* SK_PNMI_HTX_LATE_COL */
224 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
225 /* SK_PNMI_HTX_DEFFERAL */
226 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
227 /* SK_PNMI_HTX_EXCESS_DEF */
228 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
229 /* SK_PNMI_HTX_UNDERRUN */
230 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
231 /* SK_PNMI_HTX_CARRIER */
232 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
233 /* SK_PNMI_HTX_UTILUNDER */
234 {{0, SK_FALSE}, {0, SK_FALSE}},
235 /* SK_PNMI_HTX_UTILOVER */
236 {{0, SK_FALSE}, {0, SK_FALSE}},
238 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
239 /* SK_PNMI_HTX_127 */
240 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
241 /* SK_PNMI_HTX_255 */
242 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
243 /* SK_PNMI_HTX_511 */
244 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
245 /* SK_PNMI_HTX_1023 */
246 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
247 /* SK_PNMI_HTX_MAX */
248 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
249 /* SK_PNMI_HTX_LONGFRAMES */
250 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
251 /* SK_PNMI_HTX_SYNC */
252 {{0, SK_FALSE}, {0, SK_FALSE}},
253 /* SK_PNMI_HTX_SYNC_OCTET */
254 {{0, SK_FALSE}, {0, SK_FALSE}},
255 /* SK_PNMI_HTX_RESERVED */
256 {{0, SK_FALSE}, {0, SK_FALSE}},
258 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
259 /* SK_PNMI_HRX_OCTETHIGH */
260 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
261 /* SK_PNMI_HRX_OCTETLOW */
262 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
263 /* SK_PNMI_HRX_BADOCTETHIGH */
264 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
265 /* SK_PNMI_HRX_BADOCTETLOW */
266 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
267 /* SK_PNMI_HRX_BROADCAST */
268 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
269 /* SK_PNMI_HRX_MULTICAST */
270 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
271 /* SK_PNMI_HRX_UNICAST */
272 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
273 /* SK_PNMI_HRX_PMACC */
274 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
275 /* SK_PNMI_HRX_MACC */
276 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
277 /* SK_PNMI_HRX_PMACC_ERR */
278 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
279 /* SK_PNMI_HRX_MACC_UNKWN */
280 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
281 /* SK_PNMI_HRX_BURST */
282 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
283 /* SK_PNMI_HRX_MISSED */
284 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
285 /* SK_PNMI_HRX_FRAMING */
286 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
287 /* SK_PNMI_HRX_UNDERSIZE */
288 {{0, SK_FALSE}, {GM_RXF_SHT, SK_TRUE}},
289 /* SK_PNMI_HRX_OVERFLOW */
290 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
291 /* SK_PNMI_HRX_JABBER */
292 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
293 /* SK_PNMI_HRX_CARRIER */
294 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
295 /* SK_PNMI_HRX_IRLENGTH */
296 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
297 /* SK_PNMI_HRX_SYMBOL */
298 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
299 /* SK_PNMI_HRX_SHORTS */
300 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
301 /* SK_PNMI_HRX_RUNT */
302 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
303 /* SK_PNMI_HRX_TOO_LONG */
304 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
305 /* SK_PNMI_HRX_FCS */
306 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
307 /* SK_PNMI_HRX_CEXT */
308 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
309 /* SK_PNMI_HRX_UTILUNDER */
310 {{0, SK_FALSE}, {0, SK_FALSE}},
311 /* SK_PNMI_HRX_UTILOVER */
312 {{0, SK_FALSE}, {0, SK_FALSE}},
314 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
315 /* SK_PNMI_HRX_127 */
316 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
317 /* SK_PNMI_HRX_255 */
318 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
319 /* SK_PNMI_HRX_511 */
320 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
321 /* SK_PNMI_HRX_1023 */
322 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
323 /* SK_PNMI_HRX_MAX */
324 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
325 /* SK_PNMI_HRX_LONGFRAMES */
326 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
327 /* SK_PNMI_HRX_RESERVED */
328 {{0, SK_FALSE}, {0, SK_FALSE}}
332 /*****************************************************************************
338 /*****************************************************************************
340 * SkPnmiInit - Init function of PNMI
343 * SK_INIT_DATA: Initialises the data structures
344 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
346 * SK_INIT_RUN: Starts a timer event for port switch per hour
353 SK_AC *pAC, /* Pointer to adapter context */
354 SK_IOC IoC, /* IO context handle */
355 int Level) /* Initialization level */
357 unsigned int PortMax; /* Number of ports */
358 unsigned int PortIndex; /* Current port index in loop */
359 SK_U16 Val16; /* Multiple purpose 16 bit variable */
360 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
361 SK_EVPARA EventParam; /* Event struct for timer event */
362 SK_PNMI_VCT *pVctBackupData;
365 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
366 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
371 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
372 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
373 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
374 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
375 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
377 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
378 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
382 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
384 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
386 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
387 ("CounterOffset struct size (%d) differs from"
388 "SK_PNMI_MAX_IDX (%d)\n",
389 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
392 if (SK_PNMI_MAX_IDX !=
393 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
395 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
397 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
398 ("StatAddr table size (%d) differs from "
399 "SK_PNMI_MAX_IDX (%d)\n",
401 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
404 #endif /* SK_PNMI_CHECK */
411 PortMax = pAC->GIni.GIMacsFound;
413 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
415 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
418 /* Initialize DSP variables for Vct() to 0xff => Never written! */
419 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
420 pAC->GIni.GP[PortIndex].PCableLen = 0xff;
421 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
422 pVctBackupData->PCableLen = 0xff;
428 SK_IN16(IoC, B0_CTST, &Val16);
429 if ((Val16 & CS_BUS_CLOCK) == 0) {
431 pAC->Pnmi.PciBusSpeed = 33;
434 pAC->Pnmi.PciBusSpeed = 66;
440 SK_IN16(IoC, B0_CTST, &Val16);
441 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
443 pAC->Pnmi.PciBusWidth = 32;
446 pAC->Pnmi.PciBusWidth = 64;
452 switch (pAC->GIni.GIChipId) {
453 case CHIP_ID_GENESIS:
454 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
458 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
466 * Get PMD and DeviceType
468 SK_IN8(IoC, B2_PMD_TYP, &Val8);
472 if (pAC->GIni.GIMacsFound > 1) {
474 pAC->Pnmi.DeviceType = 0x00020002;
477 pAC->Pnmi.DeviceType = 0x00020001;
483 if (pAC->GIni.GIMacsFound > 1) {
485 pAC->Pnmi.DeviceType = 0x00020004;
488 pAC->Pnmi.DeviceType = 0x00020003;
494 if (pAC->GIni.GIMacsFound > 1) {
496 pAC->Pnmi.DeviceType = 0x00020006;
499 pAC->Pnmi.DeviceType = 0x00020005;
505 if (pAC->GIni.GIMacsFound > 1) {
507 pAC->Pnmi.DeviceType = 0x00020008;
510 pAC->Pnmi.DeviceType = 0x00020007;
516 pAC->Pnmi.DeviceType = 0;
523 SK_IN8(IoC, B2_CONN_TYP, &Val8);
526 pAC->Pnmi.Connector = 2;
530 pAC->Pnmi.Connector = 3;
534 pAC->Pnmi.Connector = 4;
538 pAC->Pnmi.Connector = 5;
542 pAC->Pnmi.Connector = 6;
546 pAC->Pnmi.Connector = 1;
553 * Start timer for RLMT change counter
555 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
556 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
557 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
562 break; /* Nothing todo */
568 /*****************************************************************************
570 * SkPnmiGetVar - Retrieves the value of a single OID
573 * Calls a general sub-function for all this stuff. If the instance
574 * -1 is passed, the values of all instances are returned in an
578 * SK_PNMI_ERR_OK The request was successfully performed
579 * SK_PNMI_ERR_GENERAL A general severe internal error occured
580 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
582 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
583 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
584 * exist (e.g. port instance 3 on a two port
588 SK_AC *pAC, /* Pointer to adapter context */
589 SK_IOC IoC, /* IO context handle */
590 SK_U32 Id, /* Object ID that is to be processed */
591 void *pBuf, /* Buffer to which the management data will be copied */
592 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
593 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
594 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
596 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
597 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
598 Id, *pLen, Instance, NetIndex));
600 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
601 Instance, NetIndex));
604 /*****************************************************************************
606 * SkPnmiPreSetVar - Presets the value of a single OID
609 * Calls a general sub-function for all this stuff. The preset does
610 * the same as a set, but returns just before finally setting the
611 * new value. This is usefull to check if a set might be successfull.
612 * If the instance -1 is passed, an array of values is supposed and
613 * all instances of the OID will be set.
616 * SK_PNMI_ERR_OK The request was successfully performed.
617 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
618 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
619 * the correct data (e.g. a 32bit value is
620 * needed, but a 16 bit value was passed).
621 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
623 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
624 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
625 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
626 * exist (e.g. port instance 3 on a two port
630 SK_AC *pAC, /* Pointer to adapter context */
631 SK_IOC IoC, /* IO context handle */
632 SK_U32 Id, /* Object ID that is to be processed */
633 void *pBuf, /* Buffer to which the management data will be copied */
634 unsigned int *pLen, /* Total length of management data */
635 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
636 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
638 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
639 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
640 Id, *pLen, Instance, NetIndex));
643 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
644 Instance, NetIndex));
647 /*****************************************************************************
649 * SkPnmiSetVar - Sets the value of a single OID
652 * Calls a general sub-function for all this stuff. The preset does
653 * the same as a set, but returns just before finally setting the
654 * new value. This is usefull to check if a set might be successfull.
655 * If the instance -1 is passed, an array of values is supposed and
656 * all instances of the OID will be set.
659 * SK_PNMI_ERR_OK The request was successfully performed.
660 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
661 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
662 * the correct data (e.g. a 32bit value is
663 * needed, but a 16 bit value was passed).
664 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
666 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
667 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
668 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
669 * exist (e.g. port instance 3 on a two port
673 SK_AC *pAC, /* Pointer to adapter context */
674 SK_IOC IoC, /* IO context handle */
675 SK_U32 Id, /* Object ID that is to be processed */
676 void *pBuf, /* Buffer to which the management data will be copied */
677 unsigned int *pLen, /* Total length of management data */
678 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
679 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
681 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
682 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
683 Id, *pLen, Instance, NetIndex));
685 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
686 Instance, NetIndex));
689 /*****************************************************************************
691 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
694 * Runs through the IdTable, queries the single OIDs and stores the
695 * returned data into the management database structure
696 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
697 * is stored in the IdTable. The return value of the function will also
698 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
699 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
702 * SK_PNMI_ERR_OK The request was successfully performed
703 * SK_PNMI_ERR_GENERAL A general severe internal error occured
704 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
706 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
709 SK_AC *pAC, /* Pointer to adapter context */
710 SK_IOC IoC, /* IO context handle */
711 void *pBuf, /* Buffer to which the management data will be copied. */
712 unsigned int *pLen, /* Length of buffer */
713 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
716 unsigned int TableIndex;
717 unsigned int DstOffset;
718 unsigned int InstanceNo;
719 unsigned int InstanceCnt;
722 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
725 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
726 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
729 if (*pLen < SK_PNMI_STRUCT_SIZE) {
731 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
733 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
737 *pLen = SK_PNMI_STRUCT_SIZE;
738 return (SK_PNMI_ERR_TOO_SHORT);
744 if (NetIndex >= pAC->Rlmt.NumNets) {
745 return (SK_PNMI_ERR_UNKNOWN_NET);
748 /* Update statistic */
749 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
751 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
754 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
755 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
759 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
761 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
762 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
766 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
768 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
769 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
774 * Increment semaphores to indicate that an update was
777 pAC->Pnmi.MacUpdatedFlag ++;
778 pAC->Pnmi.RlmtUpdatedFlag ++;
779 pAC->Pnmi.SirqUpdatedFlag ++;
781 /* Get vpd keys for instance calculation */
782 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
783 if (Ret != SK_PNMI_ERR_OK) {
785 pAC->Pnmi.MacUpdatedFlag --;
786 pAC->Pnmi.RlmtUpdatedFlag --;
787 pAC->Pnmi.SirqUpdatedFlag --;
789 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
790 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
791 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
792 return (SK_PNMI_ERR_GENERAL);
795 /* Retrieve values */
796 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
797 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
799 InstanceNo = IdTable[TableIndex].InstanceNo;
800 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
803 DstOffset = IdTable[TableIndex].Offset +
805 IdTable[TableIndex].StructSize;
808 * For the VPD the instance is not an index number
809 * but the key itself. Determin with the instance
810 * counter the VPD key to be used.
812 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
813 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
814 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
815 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
817 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
820 Instance = (SK_U32)InstanceCnt;
823 TmpLen = *pLen - DstOffset;
824 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
825 IdTable[TableIndex].Id, (char *)pBuf +
826 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
829 * An unknown instance error means that we reached
830 * the last instance of that variable. Proceed with
831 * the next OID in the table and ignore the return
834 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
839 if (Ret != SK_PNMI_ERR_OK) {
841 pAC->Pnmi.MacUpdatedFlag --;
842 pAC->Pnmi.RlmtUpdatedFlag --;
843 pAC->Pnmi.SirqUpdatedFlag --;
845 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
846 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
847 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
853 pAC->Pnmi.MacUpdatedFlag --;
854 pAC->Pnmi.RlmtUpdatedFlag --;
855 pAC->Pnmi.SirqUpdatedFlag --;
857 *pLen = SK_PNMI_STRUCT_SIZE;
858 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
859 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
860 return (SK_PNMI_ERR_OK);
863 /*****************************************************************************
865 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
868 * Calls a general sub-function for all this set stuff. The preset does
869 * the same as a set, but returns just before finally setting the
870 * new value. This is usefull to check if a set might be successfull.
871 * The sub-function runs through the IdTable, checks which OIDs are able
872 * to set, and calls the handler function of the OID to perform the
873 * preset. The return value of the function will also be stored in
874 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
875 * SK_PNMI_MIN_STRUCT_SIZE.
878 * SK_PNMI_ERR_OK The request was successfully performed.
879 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
880 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
881 * the correct data (e.g. a 32bit value is
882 * needed, but a 16 bit value was passed).
883 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
886 int SkPnmiPreSetStruct(
887 SK_AC *pAC, /* Pointer to adapter context */
888 SK_IOC IoC, /* IO context handle */
889 void *pBuf, /* Buffer which contains the data to be set */
890 unsigned int *pLen, /* Length of buffer */
891 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
893 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
894 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
897 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
901 /*****************************************************************************
903 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
906 * Calls a general sub-function for all this set stuff. The return value
907 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
908 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
909 * The sub-function runs through the IdTable, checks which OIDs are able
910 * to set, and calls the handler function of the OID to perform the
911 * set. The return value of the function will also be stored in
912 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
913 * SK_PNMI_MIN_STRUCT_SIZE.
916 * SK_PNMI_ERR_OK The request was successfully performed.
917 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
918 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
919 * the correct data (e.g. a 32bit value is
920 * needed, but a 16 bit value was passed).
921 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
925 SK_AC *pAC, /* Pointer to adapter context */
926 SK_IOC IoC, /* IO context handle */
927 void *pBuf, /* Buffer which contains the data to be set */
928 unsigned int *pLen, /* Length of buffer */
929 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
931 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
932 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
935 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
939 /*****************************************************************************
941 * SkPnmiEvent - Event handler
944 * Handles the following events:
945 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
946 * interrupt will be generated which is
947 * first handled by SIRQ which generates a
948 * this event. The event increments the
949 * upper 32 bit of the 64 bit counter.
950 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
951 * when a sensor reports a warning or
952 * error. The event will store a trap
953 * message in the trap buffer.
954 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
955 * module and is used to calculate the
956 * port switches per hour.
957 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
959 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
960 * before a hard reset of the XMAC is
961 * performed. All counters will be saved
962 * and added to the hardware counter
963 * values after reset to grant continuous
965 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
966 * went logically up. A trap message will
967 * be stored to the trap buffer.
968 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
969 * went logically down. A trap message will
970 * be stored to the trap buffer.
971 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
972 * spanning tree root bridges were
973 * detected. A trap message will be stored
974 * to the trap buffer.
975 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
976 * down. PNMI will not further add the
977 * statistic values to the virtual port.
978 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
979 * is now an active port. PNMI will now
980 * add the statistic data of this port to
982 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first parameter
983 * contains the number of nets. 1 means single net, 2 means
984 * dual net. The second parameter is -1
990 SK_AC *pAC, /* Pointer to adapter context */
991 SK_IOC IoC, /* IO context handle */
992 SK_U32 Event, /* Event-Id */
993 SK_EVPARA Param) /* Event dependent parameter */
995 unsigned int PhysPortIndex;
996 unsigned int MaxNetNumber;
1000 SK_U64 OverflowStatus;
1006 SK_EVPARA EventParam;
1010 SK_PNMI_ESTIMATE *pEst;
1013 SK_PNMI_VCT *pVctBackupData;
1020 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1022 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1023 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1024 (unsigned int)Event, (unsigned int)Param.Para64));
1027 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1029 MacType = pAC->GIni.GIMacType;
1033 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1034 PhysPortIndex = (int)Param.Para32[0];
1035 MacStatus = (SK_U16)Param.Para32[1];
1037 if (PhysPortIndex >= SK_MAX_MACS) {
1039 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1040 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1041 " wrong, PhysPortIndex=0x%x\n",
1049 * Check which source caused an overflow interrupt.
1051 if ((pAC->GIni.GIFunc.pFnMacOverflow(pAC, IoC, PhysPortIndex,
1052 MacStatus, &OverflowStatus) != 0) ||
1053 (OverflowStatus == 0)) {
1055 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1060 * Check the overflow status register and increment
1061 * the upper dword of corresponding counter.
1063 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1066 Mask = (SK_U64)1 << CounterIndex;
1067 if ((OverflowStatus & Mask) == 0) {
1072 switch (StatOvrflwBit[CounterIndex][MacType]) {
1074 case SK_PNMI_HTX_UTILUNDER:
1075 case SK_PNMI_HTX_UTILOVER:
1076 if (MacType == SK_MAC_XMAC) {
1077 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD, &Register);
1078 Register |= XM_TX_SAM_LINE;
1079 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD, Register);
1083 case SK_PNMI_HRX_UTILUNDER:
1084 case SK_PNMI_HRX_UTILOVER:
1085 if (MacType == SK_MAC_XMAC) {
1086 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD, &Register);
1087 Register |= XM_RX_SAM_LINE;
1088 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD, Register);
1092 case SK_PNMI_HTX_OCTETHIGH:
1093 case SK_PNMI_HTX_OCTETLOW:
1094 case SK_PNMI_HTX_RESERVED:
1095 case SK_PNMI_HRX_OCTETHIGH:
1096 case SK_PNMI_HRX_OCTETLOW:
1097 case SK_PNMI_HRX_IRLENGTH:
1098 case SK_PNMI_HRX_RESERVED:
1101 * the following counters aren't be handled (id > 63)
1103 case SK_PNMI_HTX_SYNC:
1104 case SK_PNMI_HTX_SYNC_OCTET:
1107 case SK_PNMI_HRX_LONGFRAMES:
1108 if (MacType == SK_MAC_GMAC) {
1109 pAC->Pnmi.Port[PhysPortIndex].
1110 CounterHigh[CounterIndex] ++;
1115 pAC->Pnmi.Port[PhysPortIndex].
1116 CounterHigh[CounterIndex] ++;
1121 case SK_PNMI_EVT_SEN_WAR_LOW:
1123 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1125 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1126 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1127 (unsigned int)Param.Para64));
1133 * Store a trap message in the trap buffer and generate
1134 * an event for user space applications with the
1135 * SK_DRIVER_SENDEVENT macro.
1137 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1138 (unsigned int)Param.Para64);
1139 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1142 case SK_PNMI_EVT_SEN_WAR_UPP:
1144 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1146 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1147 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1148 (unsigned int)Param.Para64));
1154 * Store a trap message in the trap buffer and generate
1155 * an event for user space applications with the
1156 * SK_DRIVER_SENDEVENT macro.
1158 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1159 (unsigned int)Param.Para64);
1160 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1163 case SK_PNMI_EVT_SEN_ERR_LOW:
1165 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1167 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1168 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1169 (unsigned int)Param.Para64));
1175 * Store a trap message in the trap buffer and generate
1176 * an event for user space applications with the
1177 * SK_DRIVER_SENDEVENT macro.
1179 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1180 (unsigned int)Param.Para64);
1181 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1184 case SK_PNMI_EVT_SEN_ERR_UPP:
1186 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1188 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1189 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1190 (unsigned int)Param.Para64));
1196 * Store a trap message in the trap buffer and generate
1197 * an event for user space applications with the
1198 * SK_DRIVER_SENDEVENT macro.
1200 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1201 (unsigned int)Param.Para64);
1202 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1205 case SK_PNMI_EVT_CHG_EST_TIMER:
1207 * Calculate port switch average on a per hour basis
1208 * Time interval for check : 28125 ms
1209 * Number of values for average : 8
1211 * Be careful in changing these values, on change check
1212 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1213 * array one less than value number)
1214 * - Timer initialization SkTimerStart() in SkPnmiInit
1215 * - Delta value below must be multiplicated with
1219 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1220 CounterIndex = pEst->EstValueIndex + 1;
1221 if (CounterIndex == 7) {
1225 pEst->EstValueIndex = CounterIndex;
1227 NewestValue = pAC->Pnmi.RlmtChangeCts;
1228 OldestValue = pEst->EstValue[CounterIndex];
1229 pEst->EstValue[CounterIndex] = NewestValue;
1232 * Calculate average. Delta stores the number of
1233 * port switches per 28125 * 8 = 225000 ms
1235 if (NewestValue >= OldestValue) {
1237 Delta = NewestValue - OldestValue;
1240 /* Overflow situation */
1241 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1245 * Extrapolate delta to port switches per hour.
1246 * Estimate = Delta * (3600000 / 225000)
1250 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1253 * Check if threshold is exceeded. If the threshold is
1254 * permanently exceeded every 28125 ms an event will be
1255 * generated to remind the user of this condition.
1257 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1258 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1259 pAC->Pnmi.RlmtChangeThreshold)) {
1261 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1262 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1265 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
1266 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1267 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1271 case SK_PNMI_EVT_CLEAR_COUNTER:
1273 * Param.Para32[0] contains the NetIndex (0 ..1).
1274 * Param.Para32[1] is reserved, contains -1.
1276 NetIndex = (SK_U32)Param.Para32[0];
1279 if (NetIndex >= pAC->Rlmt.NumNets) {
1281 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1282 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1290 * Set all counters and timestamps to zero.
1291 * The according NetIndex is required as a
1292 * parameter of the event.
1294 ResetCounter(pAC, IoC, NetIndex);
1297 case SK_PNMI_EVT_XMAC_RESET:
1299 * To grant continuous counter values store the current
1300 * XMAC statistic values to the entries 1..n of the
1301 * CounterOffset array. XMAC Errata #2
1304 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1306 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1307 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1308 (unsigned int)Param.Para64));
1312 PhysPortIndex = (unsigned int)Param.Para64;
1315 * Update XMAC statistic to get fresh values
1317 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1318 if (Ret != SK_PNMI_ERR_OK) {
1320 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1324 * Increment semaphore to indicate that an update was
1327 pAC->Pnmi.MacUpdatedFlag ++;
1329 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1332 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1337 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[CounterIndex] =
1338 GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1340 pAC->Pnmi.Port[PhysPortIndex].CounterHigh[CounterIndex] = 0;
1343 pAC->Pnmi.MacUpdatedFlag --;
1346 case SK_PNMI_EVT_RLMT_PORT_UP:
1347 PhysPortIndex = (unsigned int)Param.Para32[0];
1349 if (PhysPortIndex >= SK_MAX_MACS) {
1351 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1352 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1353 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1360 * Store a trap message in the trap buffer and generate an event for
1361 * user space applications with the SK_DRIVER_SENDEVENT macro.
1363 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1364 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1366 /* Bugfix for XMAC errata (#10620)*/
1367 if (MacType == SK_MAC_XMAC) {
1368 /* Add incremental difference to offset (#10620)*/
1369 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1370 XM_RXE_SHT_ERR, &Val32);
1372 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1373 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1374 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1375 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1378 /* Tell VctStatus() that a link was up meanwhile. */
1379 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1382 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1383 PhysPortIndex = (unsigned int)Param.Para32[0];
1386 if (PhysPortIndex >= SK_MAX_MACS) {
1388 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1389 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1390 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1397 * Store a trap message in the trap buffer and generate an event for
1398 * user space applications with the SK_DRIVER_SENDEVENT macro.
1400 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1401 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1403 /* Bugfix #10620 - get zero level for incremental difference */
1404 if (MacType == SK_MAC_XMAC) {
1406 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1407 XM_RXE_SHT_ERR, &Val32);
1409 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1410 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1411 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1415 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1416 PhysPortIndex = (unsigned int)Param.Para32[0];
1417 NetIndex = (SK_U32)Param.Para32[1];
1420 if (PhysPortIndex >= SK_MAX_MACS) {
1422 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1423 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1427 if (NetIndex >= pAC->Rlmt.NumNets) {
1429 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1430 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1436 * For now, ignore event if NetIndex != 0.
1438 if (Param.Para32[1] != 0) {
1444 * Nothing to do if port is already inactive
1446 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1452 * Update statistic counters to calculate new offset for the virtual
1453 * port and increment semaphore to indicate that an update was already
1456 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1459 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1462 pAC->Pnmi.MacUpdatedFlag ++;
1465 * Calculate new counter offset for virtual port to grant continous
1466 * counting on port switches. The virtual port consists of all currently
1467 * active ports. The port down event indicates that a port is removed
1468 * from the virtual port. Therefore add the counter value of the removed
1469 * port to the CounterOffset for the virtual port to grant the same
1472 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1475 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1480 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1482 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1486 * Set port to inactive
1488 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1490 pAC->Pnmi.MacUpdatedFlag --;
1493 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1494 PhysPortIndex = (unsigned int)Param.Para32[0];
1495 NetIndex = (SK_U32)Param.Para32[1];
1498 if (PhysPortIndex >= SK_MAX_MACS) {
1500 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1501 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1505 if (NetIndex >= pAC->Rlmt.NumNets) {
1507 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1508 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1514 * For now, ignore event if NetIndex != 0.
1516 if (Param.Para32[1] != 0) {
1522 * Nothing to do if port is already active
1524 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1530 * Statistic maintenance
1532 pAC->Pnmi.RlmtChangeCts ++;
1533 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1536 * Store a trap message in the trap buffer and generate an event for
1537 * user space applications with the SK_DRIVER_SENDEVENT macro.
1539 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1540 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1543 * Update statistic counters to calculate new offset for the virtual
1544 * port and increment semaphore to indicate that an update was
1547 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1550 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1553 pAC->Pnmi.MacUpdatedFlag ++;
1556 * Calculate new counter offset for virtual port to grant continous
1557 * counting on port switches. A new port is added to the virtual port.
1558 * Therefore substract the counter value of the new port from the
1559 * CounterOffset for the virtual port to grant the same value.
1561 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1564 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1569 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1571 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1574 /* Set port to active */
1575 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1577 pAC->Pnmi.MacUpdatedFlag --;
1580 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1582 * Para.Para32[0] contains the NetIndex.
1586 * Store a trap message in the trap buffer and generate an event for
1587 * user space applications with the SK_DRIVER_SENDEVENT macro.
1589 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1590 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1593 case SK_PNMI_EVT_RLMT_SET_NETS:
1595 * Param.Para32[0] contains the number of Nets.
1596 * Param.Para32[1] is reserved, contains -1.
1599 * Check number of nets
1601 MaxNetNumber = pAC->GIni.GIMacsFound;
1602 if (((unsigned int)Param.Para32[0] < 1)
1603 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
1604 return (SK_PNMI_ERR_UNKNOWN_NET);
1607 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
1608 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
1610 else { /* dual net mode */
1611 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
1615 case SK_PNMI_EVT_VCT_RESET:
1616 PhysPortIndex = Param.Para32[0];
1617 pPrt = &pAC->GIni.GP[PhysPortIndex];
1618 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
1620 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
1621 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
1624 * VCT test is still running.
1625 * Start VCT timer counter again.
1627 SK_MEMSET((char *) &Param, 0, sizeof(Param));
1628 Param.Para32[0] = PhysPortIndex;
1629 Param.Para32[1] = -1;
1630 SkTimerStart(pAC, IoC,
1631 &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
1632 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
1635 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
1636 pAC->Pnmi.VctStatus[PhysPortIndex] |=
1637 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
1639 /* Copy results for later use to PNMI struct. */
1640 for (i = 0; i < 4; i++) {
1641 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
1642 if ((pPrt->PMdiPairLen[i] > 35) &&
1643 (pPrt->PMdiPairLen[i] < 0xff)) {
1644 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
1647 if ((pPrt->PMdiPairLen[i] > 35) &&
1648 (pPrt->PMdiPairLen[i] != 0xff)) {
1649 CableLength = 1000 *
1650 (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
1655 pVctBackupData->PMdiPairLen[i] = CableLength;
1656 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
1659 Param.Para32[0] = PhysPortIndex;
1660 Param.Para32[1] = -1;
1661 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
1662 SkEventDispatcher(pAC, IoC);
1671 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1676 /******************************************************************************
1682 /*****************************************************************************
1684 * PnmiVar - Gets, presets, and sets single OIDs
1687 * Looks up the requested OID, calls the corresponding handler
1688 * function, and passes the parameters with the get, preset, or
1689 * set command. The function is called by SkGePnmiGetVar,
1690 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
1693 * SK_PNMI_ERR_XXX. For details have a look at the description of the
1694 * calling functions.
1695 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1697 PNMI_STATIC int PnmiVar(
1698 SK_AC *pAC, /* Pointer to adapter context */
1699 SK_IOC IoC, /* IO context handle */
1700 int Action, /* GET/PRESET/SET action */
1701 SK_U32 Id, /* Object ID that is to be processed */
1702 char *pBuf, /* Buffer used for the management data transfer */
1703 unsigned int *pLen, /* Total length of pBuf management data */
1704 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1705 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1707 unsigned int TableIndex;
1711 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
1714 return (SK_PNMI_ERR_UNKNOWN_OID);
1717 /* Check NetIndex */
1718 if (NetIndex >= pAC->Rlmt.NumNets) {
1719 return (SK_PNMI_ERR_UNKNOWN_NET);
1722 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
1724 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
1725 Instance, TableIndex, NetIndex);
1727 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
1732 /*****************************************************************************
1734 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
1737 * The return value of the function will also be stored in
1738 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1739 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
1740 * checks which OIDs are able to set, and calls the handler function of
1741 * the OID to perform the set. The return value of the function will
1742 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1743 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
1744 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
1747 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
1748 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1750 PNMI_STATIC int PnmiStruct(
1751 SK_AC *pAC, /* Pointer to adapter context */
1752 SK_IOC IoC, /* IO context handle */
1753 int Action, /* PRESET/SET action to be performed */
1754 char *pBuf, /* Buffer used for the management data transfer */
1755 unsigned int *pLen, /* Length of pBuf management data buffer */
1756 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1759 unsigned int TableIndex;
1760 unsigned int DstOffset;
1762 unsigned int InstanceNo;
1763 unsigned int InstanceCnt;
1768 /* Check if the passed buffer has the right size */
1769 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1771 /* Check if we can return the error within the buffer */
1772 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1774 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1778 *pLen = SK_PNMI_STRUCT_SIZE;
1779 return (SK_PNMI_ERR_TOO_SHORT);
1782 /* Check NetIndex */
1783 if (NetIndex >= pAC->Rlmt.NumNets) {
1784 return (SK_PNMI_ERR_UNKNOWN_NET);
1787 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
1790 * Update the values of RLMT and SIRQ and increment semaphores to
1791 * indicate that an update was already done.
1793 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1795 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1796 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1800 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1802 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1803 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1807 pAC->Pnmi.RlmtUpdatedFlag ++;
1808 pAC->Pnmi.SirqUpdatedFlag ++;
1810 /* Preset/Set values */
1811 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1813 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
1814 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
1819 InstanceNo = IdTable[TableIndex].InstanceNo;
1820 Id = IdTable[TableIndex].Id;
1822 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1825 DstOffset = IdTable[TableIndex].Offset +
1827 IdTable[TableIndex].StructSize;
1830 * Because VPD multiple instance variables are
1831 * not setable we do not need to evaluate VPD
1832 * instances. Have a look to VPD instance
1833 * calculation in SkPnmiGetStruct().
1835 Instance = (SK_U32)InstanceCnt;
1838 * Evaluate needed buffer length
1841 Ret = IdTable[TableIndex].Func(pAC, IoC,
1842 SK_PNMI_GET, IdTable[TableIndex].Id,
1843 NULL, &Len, Instance, TableIndex, NetIndex);
1845 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1849 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
1851 pAC->Pnmi.RlmtUpdatedFlag --;
1852 pAC->Pnmi.SirqUpdatedFlag --;
1854 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1855 SK_PNMI_SET_STAT(pBuf,
1856 SK_PNMI_ERR_GENERAL, DstOffset);
1857 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1858 return (SK_PNMI_ERR_GENERAL);
1860 if (Id == OID_SKGE_VPD_ACTION) {
1862 switch (*(pBuf + DstOffset)) {
1864 case SK_PNMI_VPD_CREATE:
1865 Len = 3 + *(pBuf + DstOffset + 3);
1868 case SK_PNMI_VPD_DELETE:
1878 /* Call the OID handler function */
1879 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
1880 IdTable[TableIndex].Id, pBuf + DstOffset,
1881 &Len, Instance, TableIndex, NetIndex);
1883 if (Ret != SK_PNMI_ERR_OK) {
1885 pAC->Pnmi.RlmtUpdatedFlag --;
1886 pAC->Pnmi.SirqUpdatedFlag --;
1888 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1889 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
1891 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1892 return (SK_PNMI_ERR_BAD_VALUE);
1897 pAC->Pnmi.RlmtUpdatedFlag --;
1898 pAC->Pnmi.SirqUpdatedFlag --;
1900 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
1901 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1902 return (SK_PNMI_ERR_OK);
1905 /*****************************************************************************
1907 * LookupId - Lookup an OID in the IdTable
1910 * Scans the IdTable to find the table entry of an OID.
1913 * The table index or -1 if not found.
1915 PNMI_STATIC int LookupId(
1916 SK_U32 Id) /* Object identifier to be searched */
1920 for (i = 0; i < ID_TABLE_SIZE; i++) {
1922 if (IdTable[i].Id == Id) {
1931 /*****************************************************************************
1933 * OidStruct - Handler of OID_SKGE_ALL_DATA
1936 * This OID performs a Get/Preset/SetStruct call and returns all data
1937 * in a SK_PNMI_STRUCT_DATA structure.
1940 * SK_PNMI_ERR_OK The request was successfully performed.
1941 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1942 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1943 * the correct data (e.g. a 32bit value is
1944 * needed, but a 16 bit value was passed).
1945 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1947 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1948 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1949 * exist (e.g. port instance 3 on a two port
1952 PNMI_STATIC int OidStruct(
1953 SK_AC *pAC, /* Pointer to adapter context */
1954 SK_IOC IoC, /* IO context handle */
1955 int Action, /* GET/PRESET/SET action */
1956 SK_U32 Id, /* Object ID that is to be processed */
1957 char *pBuf, /* Buffer used for the management data transfer */
1958 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
1959 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1960 unsigned int TableIndex, /* Index to the Id table */
1961 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
1963 if (Id != OID_SKGE_ALL_DATA) {
1965 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
1969 return (SK_PNMI_ERR_GENERAL);
1973 * Check instance. We only handle single instance variables
1975 if (Instance != (SK_U32)(-1) && Instance != 1) {
1978 return (SK_PNMI_ERR_UNKNOWN_INST);
1984 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1986 case SK_PNMI_PRESET:
1987 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1990 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
1993 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
1996 return (SK_PNMI_ERR_GENERAL);
1999 /*****************************************************************************
2001 * Perform - OID handler of OID_SKGE_ACTION
2007 * SK_PNMI_ERR_OK The request was successfully performed.
2008 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2009 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2010 * the correct data (e.g. a 32bit value is
2011 * needed, but a 16 bit value was passed).
2012 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2014 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2015 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2016 * exist (e.g. port instance 3 on a two port
2019 PNMI_STATIC int Perform(
2020 SK_AC *pAC, /* Pointer to adapter context */
2021 SK_IOC IoC, /* IO context handle */
2022 int Action, /* GET/PRESET/SET action */
2023 SK_U32 Id, /* Object ID that is to be processed */
2024 char *pBuf, /* Buffer used for the management data transfer */
2025 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2026 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2027 unsigned int TableIndex, /* Index to the Id table */
2028 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2035 * Check instance. We only handle single instance variables
2037 if (Instance != (SK_U32)(-1) && Instance != 1) {
2040 return (SK_PNMI_ERR_UNKNOWN_INST);
2043 if (*pLen < sizeof(SK_U32)) {
2045 *pLen = sizeof(SK_U32);
2046 return (SK_PNMI_ERR_TOO_SHORT);
2049 /* Check if a get should be performed */
2050 if (Action == SK_PNMI_GET) {
2052 /* A get is easy. We always return the same value */
2053 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2054 SK_PNMI_STORE_U32(pBuf, ActionOp);
2055 *pLen = sizeof(SK_U32);
2057 return (SK_PNMI_ERR_OK);
2060 /* Continue with PRESET/SET action */
2061 if (*pLen > sizeof(SK_U32)) {
2063 return (SK_PNMI_ERR_BAD_VALUE);
2066 /* Check if the command is a known one */
2067 SK_PNMI_READ_U32(pBuf, ActionOp);
2068 if (*pLen > sizeof(SK_U32) ||
2069 (ActionOp != SK_PNMI_ACT_IDLE &&
2070 ActionOp != SK_PNMI_ACT_RESET &&
2071 ActionOp != SK_PNMI_ACT_SELFTEST &&
2072 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2075 return (SK_PNMI_ERR_BAD_VALUE);
2078 /* A preset ends here */
2079 if (Action == SK_PNMI_PRESET) {
2081 return (SK_PNMI_ERR_OK);
2086 case SK_PNMI_ACT_IDLE:
2090 case SK_PNMI_ACT_RESET:
2092 * Perform a driver reset or something that comes near
2095 Ret = SK_DRIVER_RESET(pAC, IoC);
2098 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2101 return (SK_PNMI_ERR_GENERAL);
2105 case SK_PNMI_ACT_SELFTEST:
2107 * Perform a driver selftest or something similar to this.
2108 * Currently this feature is not used and will probably
2109 * implemented in another way.
2111 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2112 pAC->Pnmi.TestResult = Ret;
2115 case SK_PNMI_ACT_RESETCNT:
2116 /* Set all counters and timestamps to zero */
2117 ResetCounter(pAC, IoC, NetIndex);
2121 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2124 return (SK_PNMI_ERR_GENERAL);
2127 return (SK_PNMI_ERR_OK);
2130 /*****************************************************************************
2132 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2135 * Retrieves the statistic values of the virtual port (logical
2136 * index 0). Only special OIDs of NDIS are handled which consist
2137 * of a 32 bit instead of a 64 bit value. The OIDs are public
2138 * because perhaps some other platform can use them too.
2141 * SK_PNMI_ERR_OK The request was successfully performed.
2142 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2143 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2144 * the correct data (e.g. a 32bit value is
2145 * needed, but a 16 bit value was passed).
2146 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2147 * exist (e.g. port instance 3 on a two port
2150 PNMI_STATIC int Mac8023Stat(
2151 SK_AC *pAC, /* Pointer to adapter context */
2152 SK_IOC IoC, /* IO context handle */
2153 int Action, /* GET/PRESET/SET action */
2154 SK_U32 Id, /* Object ID that is to be processed */
2155 char *pBuf, /* Buffer used for the management data transfer */
2156 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2157 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2158 unsigned int TableIndex, /* Index to the Id table */
2159 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2164 SK_BOOL Is64BitReq = SK_FALSE;
2167 * Only the active Mac is returned
2169 if (Instance != (SK_U32)(-1) && Instance != 1) {
2172 return (SK_PNMI_ERR_UNKNOWN_INST);
2178 if (Action != SK_PNMI_GET) {
2181 return (SK_PNMI_ERR_READ_ONLY);
2187 case OID_802_3_PERMANENT_ADDRESS:
2188 case OID_802_3_CURRENT_ADDRESS:
2189 if (*pLen < sizeof(SK_MAC_ADDR)) {
2191 *pLen = sizeof(SK_MAC_ADDR);
2192 return (SK_PNMI_ERR_TOO_SHORT);
2197 #ifndef SK_NDIS_64BIT_CTR
2198 if (*pLen < sizeof(SK_U32)) {
2199 *pLen = sizeof(SK_U32);
2200 return (SK_PNMI_ERR_TOO_SHORT);
2203 #else /* SK_NDIS_64BIT_CTR */
2205 /* for compatibility, at least 32bit are required for OID */
2206 if (*pLen < sizeof(SK_U32)) {
2208 * but indicate handling for 64bit values,
2209 * if insufficient space is provided
2211 *pLen = sizeof(SK_U64);
2212 return (SK_PNMI_ERR_TOO_SHORT);
2215 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2216 #endif /* SK_NDIS_64BIT_CTR */
2221 * Update all statistics, because we retrieve virtual MAC, which
2222 * consists of multiple physical statistics and increment semaphore
2223 * to indicate that an update was already done.
2225 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2226 if ( Ret != SK_PNMI_ERR_OK) {
2231 pAC->Pnmi.MacUpdatedFlag ++;
2234 * Get value (MAC Index 0 identifies the virtual MAC)
2238 case OID_802_3_PERMANENT_ADDRESS:
2239 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2240 *pLen = sizeof(SK_MAC_ADDR);
2243 case OID_802_3_CURRENT_ADDRESS:
2244 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2245 *pLen = sizeof(SK_MAC_ADDR);
2249 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2251 /* by default 32bit values are evaluated */
2253 StatVal32 = (SK_U32)StatVal;
2254 SK_PNMI_STORE_U32(pBuf, StatVal32);
2255 *pLen = sizeof(SK_U32);
2258 SK_PNMI_STORE_U64(pBuf, StatVal);
2259 *pLen = sizeof(SK_U64);
2264 pAC->Pnmi.MacUpdatedFlag --;
2266 return (SK_PNMI_ERR_OK);
2269 /*****************************************************************************
2271 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2274 * Retrieves the MAC statistic data.
2277 * SK_PNMI_ERR_OK The request was successfully performed.
2278 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2279 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2280 * the correct data (e.g. a 32bit value is
2281 * needed, but a 16 bit value was passed).
2282 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2283 * exist (e.g. port instance 3 on a two port
2286 PNMI_STATIC int MacPrivateStat(
2287 SK_AC *pAC, /* Pointer to adapter context */
2288 SK_IOC IoC, /* IO context handle */
2289 int Action, /* GET/PRESET/SET action */
2290 SK_U32 Id, /* Object ID that is to be processed */
2291 char *pBuf, /* Buffer used for the management data transfer */
2292 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2293 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2294 unsigned int TableIndex, /* Index to the Id table */
2295 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2297 unsigned int LogPortMax;
2298 unsigned int LogPortIndex;
2299 unsigned int PhysPortMax;
2301 unsigned int Offset;
2308 /* Calculate instance if wished. MAC index 0 is the virtual MAC */
2309 PhysPortMax = pAC->GIni.GIMacsFound;
2310 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2312 MacType = pAC->GIni.GIMacType;
2314 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2318 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2319 /* Check instance range */
2320 if ((Instance < 1) || (Instance > LogPortMax)) {
2323 return (SK_PNMI_ERR_UNKNOWN_INST);
2325 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2326 Limit = LogPortIndex + 1;
2329 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2336 if (Action != SK_PNMI_GET) {
2339 return (SK_PNMI_ERR_READ_ONLY);
2343 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2345 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2346 return (SK_PNMI_ERR_TOO_SHORT);
2350 * Update MAC statistic and increment semaphore to indicate that
2351 * an update was already done.
2353 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2354 if (Ret != SK_PNMI_ERR_OK) {
2359 pAC->Pnmi.MacUpdatedFlag ++;
2363 for (; LogPortIndex < Limit; LogPortIndex ++) {
2367 /* XXX not yet implemented due to XMAC problems
2368 case OID_SKGE_STAT_TX_UTIL:
2369 return (SK_PNMI_ERR_GENERAL);
2371 /* XXX not yet implemented due to XMAC problems
2372 case OID_SKGE_STAT_RX_UTIL:
2373 return (SK_PNMI_ERR_GENERAL);
2375 case OID_SKGE_STAT_RX:
2376 if (MacType == SK_MAC_GMAC) {
2378 GetStatVal(pAC, IoC, LogPortIndex,
2379 SK_PNMI_HRX_BROADCAST, NetIndex) +
2380 GetStatVal(pAC, IoC, LogPortIndex,
2381 SK_PNMI_HRX_MULTICAST, NetIndex) +
2382 GetStatVal(pAC, IoC, LogPortIndex,
2383 SK_PNMI_HRX_UNICAST, NetIndex) +
2384 GetStatVal(pAC, IoC, LogPortIndex,
2385 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2388 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2389 IdTable[TableIndex].Param, NetIndex);
2393 case OID_SKGE_STAT_TX:
2394 if (MacType == SK_MAC_GMAC) {
2396 GetStatVal(pAC, IoC, LogPortIndex,
2397 SK_PNMI_HTX_BROADCAST, NetIndex) +
2398 GetStatVal(pAC, IoC, LogPortIndex,
2399 SK_PNMI_HTX_MULTICAST, NetIndex) +
2400 GetStatVal(pAC, IoC, LogPortIndex,
2401 SK_PNMI_HTX_UNICAST, NetIndex);
2404 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2405 IdTable[TableIndex].Param, NetIndex);
2410 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2411 IdTable[TableIndex].Param, NetIndex);
2413 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2415 Offset += sizeof(SK_U64);
2419 pAC->Pnmi.MacUpdatedFlag --;
2421 return (SK_PNMI_ERR_OK);
2424 /*****************************************************************************
2426 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2429 * Get/Presets/Sets the current and factory MAC address. The MAC
2430 * address of the virtual port, which is reported to the OS, may
2431 * not be changed, but the physical ones. A set to the virtual port
2432 * will be ignored. No error should be reported because otherwise
2433 * a multiple instance set (-1) would always fail.
2436 * SK_PNMI_ERR_OK The request was successfully performed.
2437 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2438 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2439 * the correct data (e.g. a 32bit value is
2440 * needed, but a 16 bit value was passed).
2441 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2443 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2444 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2445 * exist (e.g. port instance 3 on a two port
2448 PNMI_STATIC int Addr(
2449 SK_AC *pAC, /* Pointer to adapter context */
2450 SK_IOC IoC, /* IO context handle */
2451 int Action, /* GET/PRESET/SET action */
2452 SK_U32 Id, /* Object ID that is to be processed */
2453 char *pBuf, /* Buffer used for the management data transfer */
2454 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2455 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2456 unsigned int TableIndex, /* Index to the Id table */
2457 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2460 unsigned int LogPortMax;
2461 unsigned int PhysPortMax;
2462 unsigned int LogPortIndex;
2463 unsigned int PhysPortIndex;
2465 unsigned int Offset = 0;
2468 * Calculate instance if wished. MAC index 0 is the virtual
2471 PhysPortMax = pAC->GIni.GIMacsFound;
2472 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2474 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2478 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2479 /* Check instance range */
2480 if ((Instance < 1) || (Instance > LogPortMax)) {
2483 return (SK_PNMI_ERR_UNKNOWN_INST);
2485 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2486 Limit = LogPortIndex + 1;
2488 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2497 if (Action == SK_PNMI_GET) {
2500 if (*pLen < (Limit - LogPortIndex) * 6) {
2502 *pLen = (Limit - LogPortIndex) * 6;
2503 return (SK_PNMI_ERR_TOO_SHORT);
2509 for (; LogPortIndex < Limit; LogPortIndex ++) {
2513 case OID_SKGE_PHYS_CUR_ADDR:
2514 if (LogPortIndex == 0) {
2515 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2518 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2520 CopyMac(pBuf + Offset,
2521 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2526 case OID_SKGE_PHYS_FAC_ADDR:
2527 if (LogPortIndex == 0) {
2528 CopyMac(pBuf + Offset,
2529 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2532 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2535 CopyMac(pBuf + Offset,
2536 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2542 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2546 return (SK_PNMI_ERR_GENERAL);
2554 * The logical MAC address may not be changed only
2557 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2560 return (SK_PNMI_ERR_READ_ONLY);
2564 * Only the current address may be changed
2566 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2568 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2572 return (SK_PNMI_ERR_GENERAL);
2576 if (*pLen < (Limit - LogPortIndex) * 6) {
2578 *pLen = (Limit - LogPortIndex) * 6;
2579 return (SK_PNMI_ERR_TOO_SHORT);
2581 if (*pLen > (Limit - LogPortIndex) * 6) {
2584 return (SK_PNMI_ERR_BAD_VALUE);
2590 if (Action == SK_PNMI_PRESET) {
2593 return (SK_PNMI_ERR_OK);
2597 * Set OID_SKGE_MAC_CUR_ADDR
2599 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
2602 * A set to virtual port and set of broadcast
2603 * address will be ignored
2605 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
2606 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
2611 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
2614 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
2615 (SK_MAC_ADDR *)(pBuf + Offset),
2616 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
2617 SK_ADDR_PHYSICAL_ADDRESS));
2618 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
2620 return (SK_PNMI_ERR_GENERAL);
2626 return (SK_PNMI_ERR_OK);
2629 /*****************************************************************************
2631 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
2634 * Retrieves the statistic values of the CSUM module. The CSUM data
2635 * structure must be available in the SK_AC even if the CSUM module
2636 * is not included, because PNMI reads the statistic data from the
2637 * CSUM part of SK_AC directly.
2640 * SK_PNMI_ERR_OK The request was successfully performed.
2641 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2642 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2643 * the correct data (e.g. a 32bit value is
2644 * needed, but a 16 bit value was passed).
2645 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2646 * exist (e.g. port instance 3 on a two port
2649 PNMI_STATIC int CsumStat(
2650 SK_AC *pAC, /* Pointer to adapter context */
2651 SK_IOC IoC, /* IO context handle */
2652 int Action, /* GET/PRESET/SET action */
2653 SK_U32 Id, /* Object ID that is to be processed */
2654 char *pBuf, /* Buffer used for the management data transfer */
2655 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2656 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2657 unsigned int TableIndex, /* Index to the Id table */
2658 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2662 unsigned int Offset = 0;
2667 * Calculate instance if wished
2669 if (Instance != (SK_U32)(-1)) {
2671 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
2674 return (SK_PNMI_ERR_UNKNOWN_INST);
2676 Index = (unsigned int)Instance - 1;
2681 Limit = SKCS_NUM_PROTOCOLS;
2687 if (Action != SK_PNMI_GET) {
2690 return (SK_PNMI_ERR_READ_ONLY);
2694 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2696 *pLen = (Limit - Index) * sizeof(SK_U64);
2697 return (SK_PNMI_ERR_TOO_SHORT);
2703 for (; Index < Limit; Index ++) {
2707 case OID_SKGE_CHKSM_RX_OK_CTS:
2708 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
2711 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
2712 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
2715 case OID_SKGE_CHKSM_RX_ERR_CTS:
2716 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
2719 case OID_SKGE_CHKSM_TX_OK_CTS:
2720 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
2723 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
2724 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
2728 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
2732 return (SK_PNMI_ERR_GENERAL);
2735 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2736 Offset += sizeof(SK_U64);
2740 * Store used buffer space
2744 return (SK_PNMI_ERR_OK);
2747 /*****************************************************************************
2749 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
2752 * Retrieves the statistic values of the I2C module, which handles
2753 * the temperature and voltage sensors.
2756 * SK_PNMI_ERR_OK The request was successfully performed.
2757 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2758 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2759 * the correct data (e.g. a 32bit value is
2760 * needed, but a 16 bit value was passed).
2761 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2762 * exist (e.g. port instance 3 on a two port
2765 PNMI_STATIC int SensorStat(
2766 SK_AC *pAC, /* Pointer to adapter context */
2767 SK_IOC IoC, /* IO context handle */
2768 int Action, /* GET/PRESET/SET action */
2769 SK_U32 Id, /* Object ID that is to be processed */
2770 char *pBuf, /* Buffer used for the management data transfer */
2771 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
2772 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2773 unsigned int TableIndex, /* Index to the Id table */
2774 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
2779 unsigned int Offset;
2786 * Calculate instance if wished
2788 if ((Instance != (SK_U32)(-1))) {
2790 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
2793 return (SK_PNMI_ERR_UNKNOWN_INST);
2796 Index = (unsigned int)Instance -1;
2797 Limit = (unsigned int)Instance;
2801 Limit = (unsigned int) pAC->I2c.MaxSens;
2807 if (Action != SK_PNMI_GET) {
2810 return (SK_PNMI_ERR_READ_ONLY);
2816 case OID_SKGE_SENSOR_VALUE:
2817 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2818 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2819 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2820 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2821 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
2823 *pLen = (Limit - Index) * sizeof(SK_U32);
2824 return (SK_PNMI_ERR_TOO_SHORT);
2828 case OID_SKGE_SENSOR_DESCR:
2829 for (Offset = 0, i = Index; i < Limit; i ++) {
2831 Len = (unsigned int)
2832 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
2833 if (Len >= SK_PNMI_STRINGLEN2) {
2835 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
2839 return (SK_PNMI_ERR_GENERAL);
2843 if (*pLen < Offset) {
2846 return (SK_PNMI_ERR_TOO_SHORT);
2850 case OID_SKGE_SENSOR_INDEX:
2851 case OID_SKGE_SENSOR_TYPE:
2852 case OID_SKGE_SENSOR_STATUS:
2853 if (*pLen < Limit - Index) {
2855 *pLen = Limit - Index;
2856 return (SK_PNMI_ERR_TOO_SHORT);
2860 case OID_SKGE_SENSOR_WAR_CTS:
2861 case OID_SKGE_SENSOR_WAR_TIME:
2862 case OID_SKGE_SENSOR_ERR_CTS:
2863 case OID_SKGE_SENSOR_ERR_TIME:
2864 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
2866 *pLen = (Limit - Index) * sizeof(SK_U64);
2867 return (SK_PNMI_ERR_TOO_SHORT);
2872 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
2876 return (SK_PNMI_ERR_GENERAL);
2883 for (Offset = 0; Index < Limit; Index ++) {
2887 case OID_SKGE_SENSOR_INDEX:
2888 *(pBuf + Offset) = (char)Index;
2889 Offset += sizeof(char);
2892 case OID_SKGE_SENSOR_DESCR:
2893 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
2894 SK_MEMCPY(pBuf + Offset + 1,
2895 pAC->I2c.SenTable[Index].SenDesc, Len);
2896 *(pBuf + Offset) = (char)Len;
2900 case OID_SKGE_SENSOR_TYPE:
2902 (char)pAC->I2c.SenTable[Index].SenType;
2903 Offset += sizeof(char);
2906 case OID_SKGE_SENSOR_VALUE:
2907 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
2908 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2909 Offset += sizeof(SK_U32);
2912 case OID_SKGE_SENSOR_WAR_THRES_LOW:
2913 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2915 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2916 Offset += sizeof(SK_U32);
2919 case OID_SKGE_SENSOR_WAR_THRES_UPP:
2920 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2922 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2923 Offset += sizeof(SK_U32);
2926 case OID_SKGE_SENSOR_ERR_THRES_LOW:
2927 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
2929 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2930 Offset += sizeof(SK_U32);
2933 case OID_SKGE_SENSOR_ERR_THRES_UPP:
2934 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
2935 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
2936 Offset += sizeof(SK_U32);
2939 case OID_SKGE_SENSOR_STATUS:
2941 (char)pAC->I2c.SenTable[Index].SenErrFlag;
2942 Offset += sizeof(char);
2945 case OID_SKGE_SENSOR_WAR_CTS:
2946 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
2947 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2948 Offset += sizeof(SK_U64);
2951 case OID_SKGE_SENSOR_ERR_CTS:
2952 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
2953 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2954 Offset += sizeof(SK_U64);
2957 case OID_SKGE_SENSOR_WAR_TIME:
2958 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2960 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2961 Offset += sizeof(SK_U64);
2964 case OID_SKGE_SENSOR_ERR_TIME:
2965 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
2967 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
2968 Offset += sizeof(SK_U64);
2972 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
2973 ("SensorStat: Unknown OID should be handled before"));
2975 return (SK_PNMI_ERR_GENERAL);
2980 * Store used buffer space
2984 return (SK_PNMI_ERR_OK);
2987 /*****************************************************************************
2989 * Vpd - OID handler function of OID_SKGE_VPD_XXX
2992 * Get/preset/set of VPD data. As instance the name of a VPD key
2993 * can be passed. The Instance parameter is a SK_U32 and can be
2994 * used as a string buffer for the VPD key, because their maximum
2998 * SK_PNMI_ERR_OK The request was successfully performed.
2999 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3000 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3001 * the correct data (e.g. a 32bit value is
3002 * needed, but a 16 bit value was passed).
3003 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3005 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3006 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3007 * exist (e.g. port instance 3 on a two port
3010 PNMI_STATIC int Vpd(
3011 SK_AC *pAC, /* Pointer to adapter context */
3012 SK_IOC IoC, /* IO context handle */
3013 int Action, /* GET/PRESET/SET action */
3014 SK_U32 Id, /* Object ID that is to be processed */
3015 char *pBuf, /* Buffer used for the management data transfer */
3016 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
3017 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3018 unsigned int TableIndex, /* Index to the Id table */
3019 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3021 SK_VPD_STATUS *pVpdStatus;
3022 unsigned int BufLen;
3024 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3025 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3027 unsigned int Offset;
3029 unsigned int FirstIndex;
3030 unsigned int LastIndex;
3036 * Get array of all currently stored VPD keys
3038 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &KeyNo);
3039 if (Ret != SK_PNMI_ERR_OK) {
3045 * If instance is not -1, try to find the requested VPD key for
3046 * the multiple instance variables. The other OIDs as for example
3047 * OID VPD_ACTION are single instance variables and must be
3048 * handled separatly.
3053 if ((Instance != (SK_U32)(-1))) {
3055 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3056 Id == OID_SKGE_VPD_ACCESS) {
3058 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3061 for (Index = 0; Index < KeyNo; Index ++) {
3063 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3065 LastIndex = Index+1;
3069 if (Index == KeyNo) {
3072 return (SK_PNMI_ERR_UNKNOWN_INST);
3075 else if (Instance != 1) {
3078 return (SK_PNMI_ERR_UNKNOWN_INST);
3083 * Get value, if a query should be performed
3085 if (Action == SK_PNMI_GET) {
3089 case OID_SKGE_VPD_FREE_BYTES:
3090 /* Check length of buffer */
3091 if (*pLen < sizeof(SK_U32)) {
3093 *pLen = sizeof(SK_U32);
3094 return (SK_PNMI_ERR_TOO_SHORT);
3096 /* Get number of free bytes */
3097 pVpdStatus = VpdStat(pAC, IoC);
3098 if (pVpdStatus == NULL) {
3100 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3104 return (SK_PNMI_ERR_GENERAL);
3106 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3108 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3112 return (SK_PNMI_ERR_GENERAL);
3115 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3116 SK_PNMI_STORE_U32(pBuf, Val32);
3117 *pLen = sizeof(SK_U32);
3120 case OID_SKGE_VPD_ENTRIES_LIST:
3122 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3124 Len += SK_STRLEN(KeyArr[Index]) + 1;
3129 return (SK_PNMI_ERR_TOO_SHORT);
3133 *(pBuf) = (char)Len - 1;
3134 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3136 Len = SK_STRLEN(KeyArr[Index]);
3137 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3141 if (Index < KeyNo - 1) {
3143 *(pBuf + Offset) = ' ';
3150 case OID_SKGE_VPD_ENTRIES_NUMBER:
3152 if (*pLen < sizeof(SK_U32)) {
3154 *pLen = sizeof(SK_U32);
3155 return (SK_PNMI_ERR_TOO_SHORT);
3158 Val32 = (SK_U32)KeyNo;
3159 SK_PNMI_STORE_U32(pBuf, Val32);
3160 *pLen = sizeof(SK_U32);
3163 case OID_SKGE_VPD_KEY:
3164 /* Check buffer length, if it is large enough */
3165 for (Len = 0, Index = FirstIndex;
3166 Index < LastIndex; Index ++) {
3168 Len += SK_STRLEN(KeyArr[Index]) + 1;
3173 return (SK_PNMI_ERR_TOO_SHORT);
3177 * Get the key to an intermediate buffer, because
3178 * we have to prepend a length byte.
3180 for (Offset = 0, Index = FirstIndex;
3181 Index < LastIndex; Index ++) {
3183 Len = SK_STRLEN(KeyArr[Index]);
3185 *(pBuf + Offset) = (char)Len;
3186 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3193 case OID_SKGE_VPD_VALUE:
3194 /* Check the buffer length if it is large enough */
3195 for (Offset = 0, Index = FirstIndex;
3196 Index < LastIndex; Index ++) {
3199 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3200 (int *)&BufLen) > 0 ||
3201 BufLen >= SK_PNMI_VPD_DATALEN) {
3203 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3207 return (SK_PNMI_ERR_GENERAL);
3209 Offset += BufLen + 1;
3211 if (*pLen < Offset) {
3214 return (SK_PNMI_ERR_TOO_SHORT);
3218 * Get the value to an intermediate buffer, because
3219 * we have to prepend a length byte.
3221 for (Offset = 0, Index = FirstIndex;
3222 Index < LastIndex; Index ++) {
3225 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3226 (int *)&BufLen) > 0 ||
3227 BufLen >= SK_PNMI_VPD_DATALEN) {
3229 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3234 return (SK_PNMI_ERR_GENERAL);
3237 *(pBuf + Offset) = (char)BufLen;
3238 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3239 Offset += BufLen + 1;
3244 case OID_SKGE_VPD_ACCESS:
3245 if (*pLen < LastIndex - FirstIndex) {
3247 *pLen = LastIndex - FirstIndex;
3248 return (SK_PNMI_ERR_TOO_SHORT);
3251 for (Offset = 0, Index = FirstIndex;
3252 Index < LastIndex; Index ++) {
3254 if (VpdMayWrite(KeyArr[Index])) {
3256 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3259 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3266 case OID_SKGE_VPD_ACTION:
3267 Offset = LastIndex - FirstIndex;
3268 if (*pLen < Offset) {
3271 return (SK_PNMI_ERR_TOO_SHORT);
3273 SK_MEMSET(pBuf, 0, Offset);
3278 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3282 return (SK_PNMI_ERR_GENERAL);
3286 /* The only OID which can be set is VPD_ACTION */
3287 if (Id != OID_SKGE_VPD_ACTION) {
3289 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3290 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3291 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3292 Id == OID_SKGE_VPD_KEY ||
3293 Id == OID_SKGE_VPD_VALUE ||
3294 Id == OID_SKGE_VPD_ACCESS) {
3297 return (SK_PNMI_ERR_READ_ONLY);
3300 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3304 return (SK_PNMI_ERR_GENERAL);
3308 * From this point we handle VPD_ACTION. Check the buffer
3309 * length. It should at least have the size of one byte.
3314 return (SK_PNMI_ERR_TOO_SHORT);
3318 * The first byte contains the VPD action type we should
3323 case SK_PNMI_VPD_IGNORE:
3327 case SK_PNMI_VPD_CREATE:
3329 * We have to create a new VPD entry or we modify
3330 * an existing one. Check first the buffer length.
3335 return (SK_PNMI_ERR_TOO_SHORT);
3337 KeyStr[0] = pBuf[1];
3338 KeyStr[1] = pBuf[2];
3342 * Is the entry writable or does it belong to the
3345 if (!VpdMayWrite(KeyStr)) {
3348 return (SK_PNMI_ERR_BAD_VALUE);
3351 Offset = (int)pBuf[3] & 0xFF;
3353 SK_MEMCPY(Buf, pBuf + 4, Offset);
3356 /* A preset ends here */
3357 if (Action == SK_PNMI_PRESET) {
3359 return (SK_PNMI_ERR_OK);
3362 /* Write the new entry or modify an existing one */
3363 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3364 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3367 return (SK_PNMI_ERR_BAD_VALUE);
3369 else if (Ret != SK_PNMI_VPD_OK) {
3371 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3375 return (SK_PNMI_ERR_GENERAL);
3379 * Perform an update of the VPD data. This is
3380 * not mandantory, but just to be sure.
3382 Ret = VpdUpdate(pAC, IoC);
3383 if (Ret != SK_PNMI_VPD_OK) {
3385 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3389 return (SK_PNMI_ERR_GENERAL);
3393 case SK_PNMI_VPD_DELETE:
3394 /* Check if the buffer size is plausible */
3398 return (SK_PNMI_ERR_TOO_SHORT);
3403 return (SK_PNMI_ERR_BAD_VALUE);
3405 KeyStr[0] = pBuf[1];
3406 KeyStr[1] = pBuf[2];
3409 /* Find the passed key in the array */
3410 for (Index = 0; Index < KeyNo; Index ++) {
3412 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3418 * If we cannot find the key it is wrong, so we
3419 * return an appropriate error value.
3421 if (Index == KeyNo) {
3424 return (SK_PNMI_ERR_BAD_VALUE);
3427 if (Action == SK_PNMI_PRESET) {
3429 return (SK_PNMI_ERR_OK);
3432 /* Ok, you wanted it and you will get it */
3433 Ret = VpdDelete(pAC, IoC, KeyStr);
3434 if (Ret != SK_PNMI_VPD_OK) {
3436 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3440 return (SK_PNMI_ERR_GENERAL);
3444 * Perform an update of the VPD data. This is
3445 * not mandantory, but just to be sure.
3447 Ret = VpdUpdate(pAC, IoC);
3448 if (Ret != SK_PNMI_VPD_OK) {
3450 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3454 return (SK_PNMI_ERR_GENERAL);
3460 return (SK_PNMI_ERR_BAD_VALUE);
3464 return (SK_PNMI_ERR_OK);
3467 /*****************************************************************************
3469 * General - OID handler function of various single instance OIDs
3472 * The code is simple. No description necessary.
3475 * SK_PNMI_ERR_OK The request was successfully performed.
3476 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3477 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3478 * the correct data (e.g. a 32bit value is
3479 * needed, but a 16 bit value was passed).
3480 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3481 * exist (e.g. port instance 3 on a two port
3484 PNMI_STATIC int General(
3485 SK_AC *pAC, /* Pointer to adapter context */
3486 SK_IOC IoC, /* IO context handle */
3487 int Action, /* GET/PRESET/SET action */
3488 SK_U32 Id, /* Object ID that is to be processed */
3489 char *pBuf, /* Buffer used for the management data transfer */
3490 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3491 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3492 unsigned int TableIndex, /* Index to the Id table */
3493 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
3498 unsigned int Offset;
3504 SK_U64 Val64RxHwErrs = 0;
3505 SK_U64 Val64TxHwErrs = 0;
3506 SK_BOOL Is64BitReq = SK_FALSE;
3511 * Check instance. We only handle single instance variables.
3513 if (Instance != (SK_U32)(-1) && Instance != 1) {
3516 return (SK_PNMI_ERR_UNKNOWN_INST);
3520 * Check action. We only allow get requests.
3522 if (Action != SK_PNMI_GET) {
3525 return (SK_PNMI_ERR_READ_ONLY);
3528 MacType = pAC->GIni.GIMacType;
3531 * Check length for the various supported OIDs
3535 case OID_GEN_XMIT_ERROR:
3536 case OID_GEN_RCV_ERROR:
3537 case OID_GEN_RCV_NO_BUFFER:
3538 #ifndef SK_NDIS_64BIT_CTR
3539 if (*pLen < sizeof(SK_U32)) {
3540 *pLen = sizeof(SK_U32);
3541 return (SK_PNMI_ERR_TOO_SHORT);
3544 #else /* SK_NDIS_64BIT_CTR */
3547 * for compatibility, at least 32bit are required for oid
3549 if (*pLen < sizeof(SK_U32)) {
3551 * but indicate handling for 64bit values,
3552 * if insufficient space is provided
3554 *pLen = sizeof(SK_U64);
3555 return (SK_PNMI_ERR_TOO_SHORT);
3558 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3559 #endif /* SK_NDIS_64BIT_CTR */
3562 case OID_SKGE_PORT_NUMBER:
3563 case OID_SKGE_DEVICE_TYPE:
3564 case OID_SKGE_RESULT:
3565 case OID_SKGE_RLMT_MONITOR_NUMBER:
3566 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3567 case OID_SKGE_TRAP_NUMBER:
3568 case OID_SKGE_MDB_VERSION:
3569 case OID_SKGE_BOARDLEVEL:
3570 case OID_SKGE_CHIPID:
3571 case OID_SKGE_RAMSIZE:
3572 if (*pLen < sizeof(SK_U32)) {
3574 *pLen = sizeof(SK_U32);
3575 return (SK_PNMI_ERR_TOO_SHORT);
3579 case OID_SKGE_CHIPSET:
3580 if (*pLen < sizeof(SK_U16)) {
3582 *pLen = sizeof(SK_U16);
3583 return (SK_PNMI_ERR_TOO_SHORT);
3587 case OID_SKGE_BUS_TYPE:
3588 case OID_SKGE_BUS_SPEED:
3589 case OID_SKGE_BUS_WIDTH:
3590 case OID_SKGE_SENSOR_NUMBER:
3591 case OID_SKGE_CHKSM_NUMBER:
3592 case OID_SKGE_VAUXAVAIL:
3593 if (*pLen < sizeof(SK_U8)) {
3595 *pLen = sizeof(SK_U8);
3596 return (SK_PNMI_ERR_TOO_SHORT);
3600 case OID_SKGE_TX_SW_QUEUE_LEN:
3601 case OID_SKGE_TX_SW_QUEUE_MAX:
3602 case OID_SKGE_TX_RETRY:
3603 case OID_SKGE_RX_INTR_CTS:
3604 case OID_SKGE_TX_INTR_CTS:
3605 case OID_SKGE_RX_NO_BUF_CTS:
3606 case OID_SKGE_TX_NO_BUF_CTS:
3607 case OID_SKGE_TX_USED_DESCR_NO:
3608 case OID_SKGE_RX_DELIVERED_CTS:
3609 case OID_SKGE_RX_OCTETS_DELIV_CTS:
3610 case OID_SKGE_RX_HW_ERROR_CTS:
3611 case OID_SKGE_TX_HW_ERROR_CTS:
3612 case OID_SKGE_IN_ERRORS_CTS:
3613 case OID_SKGE_OUT_ERROR_CTS:
3614 case OID_SKGE_ERR_RECOVERY_CTS:
3615 case OID_SKGE_SYSUPTIME:
3616 if (*pLen < sizeof(SK_U64)) {
3618 *pLen = sizeof(SK_U64);
3619 return (SK_PNMI_ERR_TOO_SHORT);
3628 /* Update statistic */
3629 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
3630 Id == OID_SKGE_TX_HW_ERROR_CTS ||
3631 Id == OID_SKGE_IN_ERRORS_CTS ||
3632 Id == OID_SKGE_OUT_ERROR_CTS ||
3633 Id == OID_GEN_XMIT_ERROR ||
3634 Id == OID_GEN_RCV_ERROR) {
3636 /* Force the XMAC to update its statistic counters and
3637 * Increment semaphore to indicate that an update was
3640 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
3641 if (Ret != SK_PNMI_ERR_OK) {
3646 pAC->Pnmi.MacUpdatedFlag ++;
3649 * Some OIDs consist of multiple hardware counters. Those
3650 * values which are contained in all of them will be added
3655 case OID_SKGE_RX_HW_ERROR_CTS:
3656 case OID_SKGE_IN_ERRORS_CTS:
3657 case OID_GEN_RCV_ERROR:
3659 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
3660 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
3661 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex) +
3662 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
3663 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
3664 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex) +
3665 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
3666 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
3667 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
3668 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
3669 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
3670 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
3673 case OID_SKGE_TX_HW_ERROR_CTS:
3674 case OID_SKGE_OUT_ERROR_CTS:
3675 case OID_GEN_XMIT_ERROR:
3677 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
3678 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex) +
3679 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex) +
3680 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
3690 case OID_SKGE_SUPPORTED_LIST:
3691 Len = ID_TABLE_SIZE * sizeof(SK_U32);
3695 return (SK_PNMI_ERR_TOO_SHORT);
3697 for (Offset = 0, Index = 0; Offset < Len;
3698 Offset += sizeof(SK_U32), Index ++) {
3700 Val32 = (SK_U32)IdTable[Index].Id;
3701 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3706 case OID_SKGE_BOARDLEVEL:
3707 Val32 = (SK_U32)pAC->GIni.GILevel;
3708 SK_PNMI_STORE_U32(pBuf, Val32);
3709 *pLen = sizeof(SK_U32);
3712 case OID_SKGE_PORT_NUMBER:
3713 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
3714 SK_PNMI_STORE_U32(pBuf, Val32);
3715 *pLen = sizeof(SK_U32);
3718 case OID_SKGE_DEVICE_TYPE:
3719 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
3720 SK_PNMI_STORE_U32(pBuf, Val32);
3721 *pLen = sizeof(SK_U32);
3724 case OID_SKGE_DRIVER_DESCR:
3725 if (pAC->Pnmi.pDriverDescription == NULL) {
3727 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
3731 return (SK_PNMI_ERR_GENERAL);
3734 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
3735 if (Len > SK_PNMI_STRINGLEN1) {
3737 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
3741 return (SK_PNMI_ERR_GENERAL);
3747 return (SK_PNMI_ERR_TOO_SHORT);
3749 *pBuf = (char)(Len - 1);
3750 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
3754 case OID_SKGE_DRIVER_VERSION:
3755 if (pAC->Pnmi.pDriverVersion == NULL) {
3757 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3761 return (SK_PNMI_ERR_GENERAL);
3764 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
3765 if (Len > SK_PNMI_STRINGLEN1) {
3767 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3771 return (SK_PNMI_ERR_GENERAL);
3777 return (SK_PNMI_ERR_TOO_SHORT);
3779 *pBuf = (char)(Len - 1);
3780 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
3784 case OID_SKGE_DRIVER_RELDATE:
3785 if (pAC->Pnmi.pDriverReleaseDate == NULL) {
3787 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3791 return (SK_PNMI_ERR_GENERAL);
3794 Len = SK_STRLEN(pAC->Pnmi.pDriverReleaseDate) + 1;
3795 if (Len > SK_PNMI_STRINGLEN1) {
3797 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3801 return (SK_PNMI_ERR_GENERAL);
3807 return (SK_PNMI_ERR_TOO_SHORT);
3809 *pBuf = (char)(Len - 1);
3810 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverReleaseDate, Len - 1);
3814 case OID_SKGE_DRIVER_FILENAME:
3815 if (pAC->Pnmi.pDriverFileName == NULL) {
3817 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
3821 return (SK_PNMI_ERR_GENERAL);
3824 Len = SK_STRLEN(pAC->Pnmi.pDriverFileName) + 1;
3825 if (Len > SK_PNMI_STRINGLEN1) {
3827 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
3831 return (SK_PNMI_ERR_GENERAL);
3837 return (SK_PNMI_ERR_TOO_SHORT);
3839 *pBuf = (char)(Len - 1);
3840 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverFileName, Len - 1);
3844 case OID_SKGE_HW_DESCR:
3846 * The hardware description is located in the VPD. This
3847 * query may move to the initialisation routine. But
3848 * the VPD data is cached and therefore a call here
3849 * will not make much difference.
3852 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
3854 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
3858 return (SK_PNMI_ERR_GENERAL);
3861 if (Len > SK_PNMI_STRINGLEN1) {
3863 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
3867 return (SK_PNMI_ERR_GENERAL);
3872 return (SK_PNMI_ERR_TOO_SHORT);
3874 *pBuf = (char)(Len - 1);
3875 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
3879 case OID_SKGE_HW_VERSION:
3880 /* Oh, I love to do some string manipulation */
3884 return (SK_PNMI_ERR_TOO_SHORT);
3886 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
3889 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
3891 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
3895 case OID_SKGE_CHIPSET:
3896 Val16 = pAC->Pnmi.Chipset;
3897 SK_PNMI_STORE_U16(pBuf, Val16);
3898 *pLen = sizeof(SK_U16);
3901 case OID_SKGE_CHIPID:
3902 Val32 = pAC->GIni.GIChipId;
3903 SK_PNMI_STORE_U32(pBuf, Val32);
3904 *pLen = sizeof(SK_U32);
3907 case OID_SKGE_RAMSIZE:
3908 Val32 = pAC->GIni.GIRamSize;
3909 SK_PNMI_STORE_U32(pBuf, Val32);
3910 *pLen = sizeof(SK_U32);
3913 case OID_SKGE_VAUXAVAIL:
3914 *pBuf = (char) pAC->GIni.GIVauxAvail;
3915 *pLen = sizeof(char);
3918 case OID_SKGE_BUS_TYPE:
3919 *pBuf = (char) SK_PNMI_BUS_PCI;
3920 *pLen = sizeof(char);
3923 case OID_SKGE_BUS_SPEED:
3924 *pBuf = pAC->Pnmi.PciBusSpeed;
3925 *pLen = sizeof(char);
3928 case OID_SKGE_BUS_WIDTH:
3929 *pBuf = pAC->Pnmi.PciBusWidth;
3930 *pLen = sizeof(char);
3933 case OID_SKGE_RESULT:
3934 Val32 = pAC->Pnmi.TestResult;
3935 SK_PNMI_STORE_U32(pBuf, Val32);
3936 *pLen = sizeof(SK_U32);
3939 case OID_SKGE_SENSOR_NUMBER:
3940 *pBuf = (char)pAC->I2c.MaxSens;
3941 *pLen = sizeof(char);
3944 case OID_SKGE_CHKSM_NUMBER:
3945 *pBuf = SKCS_NUM_PROTOCOLS;
3946 *pLen = sizeof(char);
3949 case OID_SKGE_TRAP_NUMBER:
3950 GetTrapQueueLen(pAC, &Len, &Val);
3951 Val32 = (SK_U32)Val;
3952 SK_PNMI_STORE_U32(pBuf, Val32);
3953 *pLen = sizeof(SK_U32);
3957 GetTrapQueueLen(pAC, &Len, &Val);
3961 return (SK_PNMI_ERR_TOO_SHORT);
3963 CopyTrapQueue(pAC, pBuf);
3967 case OID_SKGE_RLMT_MONITOR_NUMBER:
3968 /* XXX Not yet implemented by RLMT therefore we return zero elements */
3970 SK_PNMI_STORE_U32(pBuf, Val32);
3971 *pLen = sizeof(SK_U32);
3974 case OID_SKGE_TX_SW_QUEUE_LEN:
3975 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
3976 if (MacType == SK_MAC_XMAC) {
3978 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3979 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
3981 /* Single net mode */
3983 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
3984 pAC->Pnmi.BufPort[1].TxSwQueueLen;
3989 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
3990 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
3992 /* Single net mode */
3994 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
3995 pAC->Pnmi.Port[1].TxSwQueueLen;
3998 SK_PNMI_STORE_U64(pBuf, Val64);
3999 *pLen = sizeof(SK_U64);
4003 case OID_SKGE_TX_SW_QUEUE_MAX:
4004 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4005 if (MacType == SK_MAC_XMAC) {
4007 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4008 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4010 /* Single net mode */
4012 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4013 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4019 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4021 /* Single net mode */
4023 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4024 pAC->Pnmi.Port[1].TxSwQueueMax;
4027 SK_PNMI_STORE_U64(pBuf, Val64);
4028 *pLen = sizeof(SK_U64);
4031 case OID_SKGE_TX_RETRY:
4032 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4033 if (MacType == SK_MAC_XMAC) {
4035 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4036 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4038 /* Single net mode */
4040 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4041 pAC->Pnmi.BufPort[1].TxRetryCts;
4046 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4047 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4049 /* Single net mode */
4051 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4052 pAC->Pnmi.Port[1].TxRetryCts;
4055 SK_PNMI_STORE_U64(pBuf, Val64);
4056 *pLen = sizeof(SK_U64);
4059 case OID_SKGE_RX_INTR_CTS:
4060 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4061 if (MacType == SK_MAC_XMAC) {
4063 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4064 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4066 /* Single net mode */
4068 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4069 pAC->Pnmi.BufPort[1].RxIntrCts;
4074 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4075 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4077 /* Single net mode */
4079 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4080 pAC->Pnmi.Port[1].RxIntrCts;
4083 SK_PNMI_STORE_U64(pBuf, Val64);
4084 *pLen = sizeof(SK_U64);
4087 case OID_SKGE_TX_INTR_CTS:
4088 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4089 if (MacType == SK_MAC_XMAC) {
4091 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4092 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4094 /* Single net mode */
4096 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4097 pAC->Pnmi.BufPort[1].TxIntrCts;
4102 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4103 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4105 /* Single net mode */
4107 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4108 pAC->Pnmi.Port[1].TxIntrCts;
4111 SK_PNMI_STORE_U64(pBuf, Val64);
4112 *pLen = sizeof(SK_U64);
4115 case OID_SKGE_RX_NO_BUF_CTS:
4116 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4117 if (MacType == SK_MAC_XMAC) {
4119 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4120 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4122 /* Single net mode */
4124 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4125 pAC->Pnmi.BufPort[1].RxNoBufCts;
4130 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4131 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4133 /* Single net mode */
4135 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4136 pAC->Pnmi.Port[1].RxNoBufCts;
4139 SK_PNMI_STORE_U64(pBuf, Val64);
4140 *pLen = sizeof(SK_U64);
4143 case OID_SKGE_TX_NO_BUF_CTS:
4144 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4145 if (MacType == SK_MAC_XMAC) {
4147 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4148 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4150 /* Single net mode */
4152 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4153 pAC->Pnmi.BufPort[1].TxNoBufCts;
4158 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4159 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4161 /* Single net mode */
4163 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4164 pAC->Pnmi.Port[1].TxNoBufCts;
4167 SK_PNMI_STORE_U64(pBuf, Val64);
4168 *pLen = sizeof(SK_U64);
4171 case OID_SKGE_TX_USED_DESCR_NO:
4172 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4173 if (MacType == SK_MAC_XMAC) {
4175 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4176 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4178 /* Single net mode */
4180 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4181 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4186 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4187 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4189 /* Single net mode */
4191 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4192 pAC->Pnmi.Port[1].TxUsedDescrNo;
4195 SK_PNMI_STORE_U64(pBuf, Val64);
4196 *pLen = sizeof(SK_U64);
4199 case OID_SKGE_RX_DELIVERED_CTS:
4200 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4201 if (MacType == SK_MAC_XMAC) {
4203 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4204 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4206 /* Single net mode */
4208 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4209 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4214 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4215 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4217 /* Single net mode */
4219 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4220 pAC->Pnmi.Port[1].RxDeliveredCts;
4223 SK_PNMI_STORE_U64(pBuf, Val64);
4224 *pLen = sizeof(SK_U64);
4227 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4228 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4229 if (MacType == SK_MAC_XMAC) {
4231 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4232 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4234 /* Single net mode */
4236 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4237 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4242 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4243 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4245 /* Single net mode */
4247 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4248 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4251 SK_PNMI_STORE_U64(pBuf, Val64);
4252 *pLen = sizeof(SK_U64);
4255 case OID_SKGE_RX_HW_ERROR_CTS:
4256 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4257 *pLen = sizeof(SK_U64);
4260 case OID_SKGE_TX_HW_ERROR_CTS:
4261 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4262 *pLen = sizeof(SK_U64);
4265 case OID_SKGE_IN_ERRORS_CTS:
4266 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4267 if (MacType == SK_MAC_XMAC) {
4269 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4270 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4272 /* Single net mode */
4274 Val64 = Val64RxHwErrs +
4275 pAC->Pnmi.BufPort[0].RxNoBufCts +
4276 pAC->Pnmi.BufPort[1].RxNoBufCts;
4281 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4282 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4284 /* Single net mode */
4286 Val64 = Val64RxHwErrs +
4287 pAC->Pnmi.Port[0].RxNoBufCts +
4288 pAC->Pnmi.Port[1].RxNoBufCts;
4291 SK_PNMI_STORE_U64(pBuf, Val64);
4292 *pLen = sizeof(SK_U64);
4295 case OID_SKGE_OUT_ERROR_CTS:
4296 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4297 if (MacType == SK_MAC_XMAC) {
4299 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4300 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4302 /* Single net mode */
4304 Val64 = Val64TxHwErrs +
4305 pAC->Pnmi.BufPort[0].TxNoBufCts +
4306 pAC->Pnmi.BufPort[1].TxNoBufCts;
4311 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4312 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4314 /* Single net mode */
4316 Val64 = Val64TxHwErrs +
4317 pAC->Pnmi.Port[0].TxNoBufCts +
4318 pAC->Pnmi.Port[1].TxNoBufCts;
4321 SK_PNMI_STORE_U64(pBuf, Val64);
4322 *pLen = sizeof(SK_U64);
4325 case OID_SKGE_ERR_RECOVERY_CTS:
4326 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4327 if (MacType == SK_MAC_XMAC) {
4329 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4330 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4332 /* Single net mode */
4334 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4335 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4340 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4341 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4343 /* Single net mode */
4345 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4346 pAC->Pnmi.Port[1].ErrRecoveryCts;
4349 SK_PNMI_STORE_U64(pBuf, Val64);
4350 *pLen = sizeof(SK_U64);
4353 case OID_SKGE_SYSUPTIME:
4354 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4355 Val64 -= pAC->Pnmi.StartUpTime;
4356 SK_PNMI_STORE_U64(pBuf, Val64);
4357 *pLen = sizeof(SK_U64);
4360 case OID_SKGE_MDB_VERSION:
4361 Val32 = SK_PNMI_MDB_VERSION;
4362 SK_PNMI_STORE_U32(pBuf, Val32);
4363 *pLen = sizeof(SK_U32);
4366 case OID_GEN_RCV_ERROR:
4367 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4368 if (MacType == SK_MAC_XMAC) {
4369 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4372 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4376 * by default 32bit values are evaluated
4379 Val32 = (SK_U32)Val64;
4380 SK_PNMI_STORE_U32(pBuf, Val32);
4381 *pLen = sizeof(SK_U32);
4384 SK_PNMI_STORE_U64(pBuf, Val64);
4385 *pLen = sizeof(SK_U64);
4389 case OID_GEN_XMIT_ERROR:
4390 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4391 if (MacType == SK_MAC_XMAC) {
4392 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4395 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4399 * by default 32bit values are evaluated
4402 Val32 = (SK_U32)Val64;
4403 SK_PNMI_STORE_U32(pBuf, Val32);
4404 *pLen = sizeof(SK_U32);
4407 SK_PNMI_STORE_U64(pBuf, Val64);
4408 *pLen = sizeof(SK_U64);
4412 case OID_GEN_RCV_NO_BUFFER:
4413 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
4414 if (MacType == SK_MAC_XMAC) {
4415 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4418 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4422 * by default 32bit values are evaluated
4425 Val32 = (SK_U32)Val64;
4426 SK_PNMI_STORE_U32(pBuf, Val32);
4427 *pLen = sizeof(SK_U32);
4430 SK_PNMI_STORE_U64(pBuf, Val64);
4431 *pLen = sizeof(SK_U64);
4435 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4436 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4437 SK_PNMI_STORE_U32(pBuf, Val32);
4438 *pLen = sizeof(SK_U32);
4442 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4446 return (SK_PNMI_ERR_GENERAL);
4449 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4450 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4451 Id == OID_SKGE_IN_ERRORS_CTS ||
4452 Id == OID_SKGE_OUT_ERROR_CTS ||
4453 Id == OID_GEN_XMIT_ERROR ||
4454 Id == OID_GEN_RCV_ERROR) {
4456 pAC->Pnmi.MacUpdatedFlag --;
4459 return (SK_PNMI_ERR_OK);
4462 /*****************************************************************************
4464 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4467 * Get/Presets/Sets the RLMT OIDs.
4470 * SK_PNMI_ERR_OK The request was successfully performed.
4471 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4472 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4473 * the correct data (e.g. a 32bit value is
4474 * needed, but a 16 bit value was passed).
4475 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4477 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4478 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4479 * exist (e.g. port instance 3 on a two port
4482 PNMI_STATIC int Rlmt(
4483 SK_AC *pAC, /* Pointer to adapter context */
4484 SK_IOC IoC, /* IO context handle */
4485 int Action, /* GET/PRESET/SET action */
4486 SK_U32 Id, /* Object ID that is to be processed */
4487 char *pBuf, /* Buffer used for the management data transfer */
4488 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4489 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4490 unsigned int TableIndex, /* Index to the Id table */
4491 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4494 unsigned int PhysPortIndex;
4495 unsigned int PhysPortMax;
4496 SK_EVPARA EventParam;
4502 * Check instance. Only single instance OIDs are allowed here.
4504 if (Instance != (SK_U32)(-1) && Instance != 1) {
4507 return (SK_PNMI_ERR_UNKNOWN_INST);
4511 * Perform the requested action.
4513 if (Action == SK_PNMI_GET) {
4516 * Check if the buffer length is large enough.
4521 case OID_SKGE_RLMT_MODE:
4522 case OID_SKGE_RLMT_PORT_ACTIVE:
4523 case OID_SKGE_RLMT_PORT_PREFERRED:
4524 if (*pLen < sizeof(SK_U8)) {
4526 *pLen = sizeof(SK_U8);
4527 return (SK_PNMI_ERR_TOO_SHORT);
4531 case OID_SKGE_RLMT_PORT_NUMBER:
4532 if (*pLen < sizeof(SK_U32)) {
4534 *pLen = sizeof(SK_U32);
4535 return (SK_PNMI_ERR_TOO_SHORT);
4539 case OID_SKGE_RLMT_CHANGE_CTS:
4540 case OID_SKGE_RLMT_CHANGE_TIME:
4541 case OID_SKGE_RLMT_CHANGE_ESTIM:
4542 case OID_SKGE_RLMT_CHANGE_THRES:
4543 if (*pLen < sizeof(SK_U64)) {
4545 *pLen = sizeof(SK_U64);
4546 return (SK_PNMI_ERR_TOO_SHORT);
4551 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4555 return (SK_PNMI_ERR_GENERAL);
4559 * Update RLMT statistic and increment semaphores to indicate
4560 * that an update was already done. Maybe RLMT will hold its
4561 * statistic always up to date some time. Then we can
4562 * remove this type of call.
4564 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4569 pAC->Pnmi.RlmtUpdatedFlag ++;
4576 case OID_SKGE_RLMT_MODE:
4577 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4578 *pLen = sizeof(char);
4581 case OID_SKGE_RLMT_PORT_NUMBER:
4582 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4583 SK_PNMI_STORE_U32(pBuf, Val32);
4584 *pLen = sizeof(SK_U32);
4587 case OID_SKGE_RLMT_PORT_ACTIVE:
4590 * If multiple ports may become active this OID
4591 * doesn't make sense any more. A new variable in
4592 * the port structure should be created. However,
4593 * for this variable the first active port is
4596 PhysPortMax = pAC->GIni.GIMacsFound;
4598 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4601 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4603 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4607 *pLen = sizeof(char);
4610 case OID_SKGE_RLMT_PORT_PREFERRED:
4611 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4612 *pLen = sizeof(char);
4615 case OID_SKGE_RLMT_CHANGE_CTS:
4616 Val64 = pAC->Pnmi.RlmtChangeCts;
4617 SK_PNMI_STORE_U64(pBuf, Val64);
4618 *pLen = sizeof(SK_U64);
4621 case OID_SKGE_RLMT_CHANGE_TIME:
4622 Val64 = pAC->Pnmi.RlmtChangeTime;
4623 SK_PNMI_STORE_U64(pBuf, Val64);
4624 *pLen = sizeof(SK_U64);
4627 case OID_SKGE_RLMT_CHANGE_ESTIM:
4628 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4629 SK_PNMI_STORE_U64(pBuf, Val64);
4630 *pLen = sizeof(SK_U64);
4633 case OID_SKGE_RLMT_CHANGE_THRES:
4634 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4635 SK_PNMI_STORE_U64(pBuf, Val64);
4636 *pLen = sizeof(SK_U64);
4640 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4641 ("Rlmt: Unknown OID should be handled before"));
4643 pAC->Pnmi.RlmtUpdatedFlag --;
4645 return (SK_PNMI_ERR_GENERAL);
4648 pAC->Pnmi.RlmtUpdatedFlag --;
4651 /* Perform a preset or set */
4654 case OID_SKGE_RLMT_MODE:
4655 /* Check if the buffer length is plausible */
4656 if (*pLen < sizeof(char)) {
4658 *pLen = sizeof(char);
4659 return (SK_PNMI_ERR_TOO_SHORT);
4661 /* Check if the value range is correct */
4662 if (*pLen != sizeof(char) ||
4663 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
4664 *(SK_U8 *)pBuf > 15) {
4667 return (SK_PNMI_ERR_BAD_VALUE);
4669 /* The preset ends here */
4670 if (Action == SK_PNMI_PRESET) {
4673 return (SK_PNMI_ERR_OK);
4675 /* Send an event to RLMT to change the mode */
4676 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4677 EventParam.Para32[0] |= (SK_U32)(*pBuf);
4678 EventParam.Para32[1] = 0;
4679 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
4682 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
4686 return (SK_PNMI_ERR_GENERAL);
4690 case OID_SKGE_RLMT_PORT_PREFERRED:
4691 /* Check if the buffer length is plausible */
4692 if (*pLen < sizeof(char)) {
4694 *pLen = sizeof(char);
4695 return (SK_PNMI_ERR_TOO_SHORT);
4697 /* Check if the value range is correct */
4698 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
4699 (SK_U8)pAC->GIni.GIMacsFound) {
4702 return (SK_PNMI_ERR_BAD_VALUE);
4704 /* The preset ends here */
4705 if (Action == SK_PNMI_PRESET) {
4708 return (SK_PNMI_ERR_OK);
4712 * Send an event to RLMT change the preferred port.
4713 * A param of -1 means automatic mode. RLMT will
4714 * make the decision which is the preferred port.
4716 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
4717 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
4718 EventParam.Para32[1] = NetIndex;
4719 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
4722 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
4726 return (SK_PNMI_ERR_GENERAL);
4730 case OID_SKGE_RLMT_CHANGE_THRES:
4731 /* Check if the buffer length is plausible */
4732 if (*pLen < sizeof(SK_U64)) {
4734 *pLen = sizeof(SK_U64);
4735 return (SK_PNMI_ERR_TOO_SHORT);
4738 * There are not many restrictions to the
4741 if (*pLen != sizeof(SK_U64)) {
4744 return (SK_PNMI_ERR_BAD_VALUE);
4746 /* A preset ends here */
4747 if (Action == SK_PNMI_PRESET) {
4750 return (SK_PNMI_ERR_OK);
4753 * Store the new threshold, which will be taken
4754 * on the next timer event.
4756 SK_PNMI_READ_U64(pBuf, Val64);
4757 pAC->Pnmi.RlmtChangeThreshold = Val64;
4761 /* The other OIDs are not be able for set */
4763 return (SK_PNMI_ERR_READ_ONLY);
4767 return (SK_PNMI_ERR_OK);
4770 /*****************************************************************************
4772 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
4775 * Performs get requests on multiple instance variables.
4778 * SK_PNMI_ERR_OK The request was successfully performed.
4779 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4780 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4781 * the correct data (e.g. a 32bit value is
4782 * needed, but a 16 bit value was passed).
4783 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4784 * exist (e.g. port instance 3 on a two port
4787 PNMI_STATIC int RlmtStat(
4788 SK_AC *pAC, /* Pointer to adapter context */
4789 SK_IOC IoC, /* IO context handle */
4790 int Action, /* GET/PRESET/SET action */
4791 SK_U32 Id, /* Object ID that is to be processed */
4792 char *pBuf, /* Buffer used for the management data transfer */
4793 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4794 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4795 unsigned int TableIndex, /* Index to the Id table */
4796 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
4798 unsigned int PhysPortMax;
4799 unsigned int PhysPortIndex;
4801 unsigned int Offset;
4807 * Calculate the port indexes from the instance.
4809 PhysPortMax = pAC->GIni.GIMacsFound;
4811 if ((Instance != (SK_U32)(-1))) {
4812 /* Check instance range */
4813 if ((Instance < 1) || (Instance > PhysPortMax)) {
4816 return (SK_PNMI_ERR_UNKNOWN_INST);
4819 /* Single net mode */
4820 PhysPortIndex = Instance - 1;
4823 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4824 PhysPortIndex = NetIndex;
4827 /* Both net modes */
4828 Limit = PhysPortIndex + 1;
4831 /* Single net mode */
4833 Limit = PhysPortMax;
4836 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4837 PhysPortIndex = NetIndex;
4838 Limit = PhysPortIndex + 1;
4843 * Currently only get requests are allowed.
4845 if (Action != SK_PNMI_GET) {
4848 return (SK_PNMI_ERR_READ_ONLY);
4852 * Check if the buffer length is large enough.
4856 case OID_SKGE_RLMT_PORT_INDEX:
4857 case OID_SKGE_RLMT_STATUS:
4858 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
4860 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
4861 return (SK_PNMI_ERR_TOO_SHORT);
4865 case OID_SKGE_RLMT_TX_HELLO_CTS:
4866 case OID_SKGE_RLMT_RX_HELLO_CTS:
4867 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4868 case OID_SKGE_RLMT_RX_SP_CTS:
4869 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
4871 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
4872 return (SK_PNMI_ERR_TOO_SHORT);
4877 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
4881 return (SK_PNMI_ERR_GENERAL);
4886 * Update statistic and increment semaphores to indicate that
4887 * an update was already done.
4889 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4894 pAC->Pnmi.RlmtUpdatedFlag ++;
4900 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
4904 case OID_SKGE_RLMT_PORT_INDEX:
4905 Val32 = PhysPortIndex;
4906 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4907 Offset += sizeof(SK_U32);
4910 case OID_SKGE_RLMT_STATUS:
4911 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
4913 pAC->Rlmt.Port[PhysPortIndex].PortState ==
4916 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
4918 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4920 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
4923 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
4925 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4926 Offset += sizeof(SK_U32);
4929 case OID_SKGE_RLMT_TX_HELLO_CTS:
4930 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
4931 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4932 Offset += sizeof(SK_U64);
4935 case OID_SKGE_RLMT_RX_HELLO_CTS:
4936 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
4937 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4938 Offset += sizeof(SK_U64);
4941 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
4942 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
4943 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4944 Offset += sizeof(SK_U64);
4947 case OID_SKGE_RLMT_RX_SP_CTS:
4948 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
4949 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
4950 Offset += sizeof(SK_U64);
4954 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4955 ("RlmtStat: Unknown OID should be errored before"));
4957 pAC->Pnmi.RlmtUpdatedFlag --;
4959 return (SK_PNMI_ERR_GENERAL);
4964 pAC->Pnmi.RlmtUpdatedFlag --;
4966 return (SK_PNMI_ERR_OK);
4969 /*****************************************************************************
4971 * MacPrivateConf - OID handler function of OIDs concerning the configuration
4974 * Get/Presets/Sets the OIDs concerning the configuration.
4977 * SK_PNMI_ERR_OK The request was successfully performed.
4978 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4979 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4980 * the correct data (e.g. a 32bit value is
4981 * needed, but a 16 bit value was passed).
4982 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4984 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4985 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4986 * exist (e.g. port instance 3 on a two port
4989 PNMI_STATIC int MacPrivateConf(
4990 SK_AC *pAC, /* Pointer to adapter context */
4991 SK_IOC IoC, /* IO context handle */
4992 int Action, /* GET/PRESET/SET action */
4993 SK_U32 Id, /* Object ID that is to be processed */
4994 char *pBuf, /* Buffer used for the management data transfer */
4995 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
4996 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4997 unsigned int TableIndex, /* Index to the Id table */
4998 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
5000 unsigned int PhysPortMax;
5001 unsigned int PhysPortIndex;
5002 unsigned int LogPortMax;
5003 unsigned int LogPortIndex;
5005 unsigned int Offset;
5009 SK_EVPARA EventParam;
5013 * Calculate instance if wished. MAC index 0 is the virtual MAC.
5015 PhysPortMax = pAC->GIni.GIMacsFound;
5016 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5022 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5023 /* Check instance range */
5024 if ((Instance < 1) || (Instance > LogPortMax)) {
5027 return (SK_PNMI_ERR_UNKNOWN_INST);
5029 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5030 Limit = LogPortIndex + 1;
5033 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5042 if (Action == SK_PNMI_GET) {
5048 case OID_SKGE_CONNECTOR:
5049 case OID_SKGE_LINK_CAP:
5050 case OID_SKGE_LINK_MODE:
5051 case OID_SKGE_LINK_MODE_STATUS:
5052 case OID_SKGE_LINK_STATUS:
5053 case OID_SKGE_FLOWCTRL_CAP:
5054 case OID_SKGE_FLOWCTRL_MODE:
5055 case OID_SKGE_FLOWCTRL_STATUS:
5056 case OID_SKGE_PHY_OPERATION_CAP:
5057 case OID_SKGE_PHY_OPERATION_MODE:
5058 case OID_SKGE_PHY_OPERATION_STATUS:
5059 case OID_SKGE_SPEED_CAP:
5060 case OID_SKGE_SPEED_MODE:
5061 case OID_SKGE_SPEED_STATUS:
5062 #ifdef SK_PHY_LP_MODE
5063 case OID_SKGE_PHY_LP_MODE:
5065 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5067 *pLen = (Limit - LogPortIndex) * sizeof(SK_U8);
5068 return (SK_PNMI_ERR_TOO_SHORT);
5073 case OID_SKGE_PHY_TYPE:
5074 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U32)) {
5076 *pLen = (Limit - LogPortIndex) * sizeof(SK_U32);
5077 return (SK_PNMI_ERR_TOO_SHORT);
5082 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5085 return (SK_PNMI_ERR_GENERAL);
5089 * Update statistic and increment semaphore to indicate
5090 * that an update was already done.
5092 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5097 pAC->Pnmi.SirqUpdatedFlag ++;
5103 for (; LogPortIndex < Limit; LogPortIndex ++) {
5105 pBufPtr = pBuf + Offset;
5110 *pBufPtr = pAC->Pnmi.PMD;
5111 Offset += sizeof(char);
5114 case OID_SKGE_CONNECTOR:
5115 *pBufPtr = pAC->Pnmi.Connector;
5116 Offset += sizeof(char);
5119 case OID_SKGE_PHY_TYPE:
5120 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5121 if (LogPortIndex == 0) {
5125 /* Get value for physical ports */
5126 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5128 Val32 = pAC->GIni.GP[PhysPortIndex].PhyType;
5129 SK_PNMI_STORE_U32(pBufPtr, Val32);
5132 else { /* DualNetMode */
5134 Val32 = pAC->GIni.GP[NetIndex].PhyType;
5135 SK_PNMI_STORE_U32(pBufPtr, Val32);
5137 Offset += sizeof(SK_U32);
5140 #ifdef SK_PHY_LP_MODE
5141 case OID_SKGE_PHY_LP_MODE:
5142 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5143 if (LogPortIndex == 0) {
5147 /* Get value for physical ports */
5148 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5149 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5153 else { /* DualNetMode */
5155 Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState;
5158 Offset += sizeof(SK_U8);
5162 case OID_SKGE_LINK_CAP:
5163 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5164 if (LogPortIndex == 0) {
5165 /* Get value for virtual port */
5166 VirtualConf(pAC, IoC, Id, pBufPtr);
5169 /* Get value for physical ports */
5170 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5173 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkCap;
5176 else { /* DualNetMode */
5178 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkCap;
5180 Offset += sizeof(char);
5183 case OID_SKGE_LINK_MODE:
5184 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5185 if (LogPortIndex == 0) {
5186 /* Get value for virtual port */
5187 VirtualConf(pAC, IoC, Id, pBufPtr);
5190 /* Get value for physical ports */
5191 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5194 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
5197 else { /* DualNetMode */
5199 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkModeConf;
5201 Offset += sizeof(char);
5204 case OID_SKGE_LINK_MODE_STATUS:
5205 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5206 if (LogPortIndex == 0) {
5207 /* Get value for virtual port */
5208 VirtualConf(pAC, IoC, Id, pBufPtr);
5211 /* Get value for physical port */
5212 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5216 CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
5219 else { /* DualNetMode */
5221 *pBufPtr = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5223 Offset += sizeof(char);
5226 case OID_SKGE_LINK_STATUS:
5227 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5228 if (LogPortIndex == 0) {
5229 /* Get value for virtual port */
5230 VirtualConf(pAC, IoC, Id, pBufPtr);
5233 /* Get value for physical ports */
5234 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5237 *pBufPtr = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
5240 else { /* DualNetMode */
5242 *pBufPtr = CalculateLinkStatus(pAC, IoC, NetIndex);
5244 Offset += sizeof(char);
5247 case OID_SKGE_FLOWCTRL_CAP:
5248 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5249 if (LogPortIndex == 0) {
5250 /* Get value for virtual port */
5251 VirtualConf(pAC, IoC, Id, pBufPtr);
5254 /* Get value for physical ports */
5255 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5258 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
5261 else { /* DualNetMode */
5263 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5265 Offset += sizeof(char);
5268 case OID_SKGE_FLOWCTRL_MODE:
5269 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5270 if (LogPortIndex == 0) {
5271 /* Get value for virtual port */
5272 VirtualConf(pAC, IoC, Id, pBufPtr);
5275 /* Get value for physical port */
5276 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5279 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
5282 else { /* DualNetMode */
5284 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5286 Offset += sizeof(char);
5289 case OID_SKGE_FLOWCTRL_STATUS:
5290 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5291 if (LogPortIndex == 0) {
5292 /* Get value for virtual port */
5293 VirtualConf(pAC, IoC, Id, pBufPtr);
5296 /* Get value for physical port */
5297 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5300 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
5303 else { /* DualNetMode */
5305 *pBufPtr = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5307 Offset += sizeof(char);
5310 case OID_SKGE_PHY_OPERATION_CAP:
5311 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5312 if (LogPortIndex == 0) {
5313 /* Get value for virtual port */
5314 VirtualConf(pAC, IoC, Id, pBufPtr);
5317 /* Get value for physical ports */
5318 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5321 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSCap;
5324 else { /* DualNetMode */
5326 *pBufPtr = pAC->GIni.GP[NetIndex].PMSCap;
5328 Offset += sizeof(char);
5331 case OID_SKGE_PHY_OPERATION_MODE:
5332 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5333 if (LogPortIndex == 0) {
5334 /* Get value for virtual port */
5335 VirtualConf(pAC, IoC, Id, pBufPtr);
5338 /* Get value for physical port */
5339 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5342 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSMode;
5345 else { /* DualNetMode */
5347 *pBufPtr = pAC->GIni.GP[NetIndex].PMSMode;
5349 Offset += sizeof(char);
5352 case OID_SKGE_PHY_OPERATION_STATUS:
5353 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5354 if (LogPortIndex == 0) {
5355 /* Get value for virtual port */
5356 VirtualConf(pAC, IoC, Id, pBufPtr);
5359 /* Get value for physical port */
5360 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5363 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PMSStatus;
5368 *pBufPtr = pAC->GIni.GP[NetIndex].PMSStatus;
5370 Offset += sizeof(char);
5373 case OID_SKGE_SPEED_CAP:
5374 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5375 if (LogPortIndex == 0) {
5376 /* Get value for virtual port */
5377 VirtualConf(pAC, IoC, Id, pBufPtr);
5380 /* Get value for physical ports */
5381 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5384 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedCap;
5387 else { /* DualNetMode */
5389 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5391 Offset += sizeof(char);
5394 case OID_SKGE_SPEED_MODE:
5395 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5396 if (LogPortIndex == 0) {
5397 /* Get value for virtual port */
5398 VirtualConf(pAC, IoC, Id, pBufPtr);
5401 /* Get value for physical port */
5402 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5405 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
5408 else { /* DualNetMode */
5410 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeed;
5412 Offset += sizeof(char);
5415 case OID_SKGE_SPEED_STATUS:
5416 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5417 if (LogPortIndex == 0) {
5418 /* Get value for virtual port */
5419 VirtualConf(pAC, IoC, Id, pBufPtr);
5422 /* Get value for physical port */
5423 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5426 *pBufPtr = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
5429 else { /* DualNetMode */
5431 *pBufPtr = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5433 Offset += sizeof(char);
5437 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5438 SK_PNMI_STORE_U32(pBufPtr, Val32);
5439 Offset += sizeof(SK_U32);
5443 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5444 ("MacPrivateConf: Unknown OID should be handled before"));
5446 pAC->Pnmi.SirqUpdatedFlag --;
5447 return (SK_PNMI_ERR_GENERAL);
5451 pAC->Pnmi.SirqUpdatedFlag --;
5453 return (SK_PNMI_ERR_OK);
5457 * From here SET or PRESET action. Check if the passed
5458 * buffer length is plausible.
5462 case OID_SKGE_LINK_MODE:
5463 case OID_SKGE_FLOWCTRL_MODE:
5464 case OID_SKGE_PHY_OPERATION_MODE:
5465 case OID_SKGE_SPEED_MODE:
5466 if (*pLen < Limit - LogPortIndex) {
5468 *pLen = Limit - LogPortIndex;
5469 return (SK_PNMI_ERR_TOO_SHORT);
5471 if (*pLen != Limit - LogPortIndex) {
5474 return (SK_PNMI_ERR_BAD_VALUE);
5478 #ifdef SK_PHY_LP_MODE
5479 case OID_SKGE_PHY_LP_MODE:
5480 if (*pLen < Limit - LogPortIndex) {
5482 *pLen = Limit - LogPortIndex;
5483 return (SK_PNMI_ERR_TOO_SHORT);
5489 if (*pLen < sizeof(SK_U32)) {
5491 *pLen = sizeof(SK_U32);
5492 return (SK_PNMI_ERR_TOO_SHORT);
5494 if (*pLen != sizeof(SK_U32)) {
5497 return (SK_PNMI_ERR_BAD_VALUE);
5503 return (SK_PNMI_ERR_READ_ONLY);
5507 * Perform preset or set
5510 for (; LogPortIndex < Limit; LogPortIndex ++) {
5514 case OID_SKGE_LINK_MODE:
5515 /* Check the value range */
5516 Val8 = *(pBuf + Offset);
5519 Offset += sizeof(char);
5522 if (Val8 < SK_LMODE_HALF ||
5523 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5524 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5527 return (SK_PNMI_ERR_BAD_VALUE);
5530 /* The preset ends here */
5531 if (Action == SK_PNMI_PRESET) {
5533 return (SK_PNMI_ERR_OK);
5536 if (LogPortIndex == 0) {
5539 * The virtual port consists of all currently
5540 * active ports. Find them and send an event
5541 * with the new link mode to SIRQ.
5543 for (PhysPortIndex = 0;
5544 PhysPortIndex < PhysPortMax;
5547 if (!pAC->Pnmi.Port[PhysPortIndex].
5553 EventParam.Para32[0] = PhysPortIndex;
5554 EventParam.Para32[1] = (SK_U32)Val8;
5555 if (SkGeSirqEvent(pAC, IoC,
5559 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5564 return (SK_PNMI_ERR_GENERAL);
5570 * Send an event with the new link mode to
5573 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5575 EventParam.Para32[1] = (SK_U32)Val8;
5576 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5579 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5584 return (SK_PNMI_ERR_GENERAL);
5587 Offset += sizeof(char);
5590 case OID_SKGE_FLOWCTRL_MODE:
5591 /* Check the value range */
5592 Val8 = *(pBuf + Offset);
5595 Offset += sizeof(char);
5598 if (Val8 < SK_FLOW_MODE_NONE ||
5599 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5600 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5603 return (SK_PNMI_ERR_BAD_VALUE);
5606 /* The preset ends here */
5607 if (Action == SK_PNMI_PRESET) {
5609 return (SK_PNMI_ERR_OK);
5612 if (LogPortIndex == 0) {
5615 * The virtual port consists of all currently
5616 * active ports. Find them and send an event
5617 * with the new flow control mode to SIRQ.
5619 for (PhysPortIndex = 0;
5620 PhysPortIndex < PhysPortMax;
5623 if (!pAC->Pnmi.Port[PhysPortIndex].
5629 EventParam.Para32[0] = PhysPortIndex;
5630 EventParam.Para32[1] = (SK_U32)Val8;
5631 if (SkGeSirqEvent(pAC, IoC,
5632 SK_HWEV_SET_FLOWMODE,
5635 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5640 return (SK_PNMI_ERR_GENERAL);
5646 * Send an event with the new flow control
5647 * mode to the SIRQ module.
5649 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5651 EventParam.Para32[1] = (SK_U32)Val8;
5652 if (SkGeSirqEvent(pAC, IoC,
5653 SK_HWEV_SET_FLOWMODE, EventParam)
5656 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5661 return (SK_PNMI_ERR_GENERAL);
5664 Offset += sizeof(char);
5667 case OID_SKGE_PHY_OPERATION_MODE :
5668 /* Check the value range */
5669 Val8 = *(pBuf + Offset);
5671 /* mode of this port remains unchanged */
5672 Offset += sizeof(char);
5675 if (Val8 < SK_MS_MODE_AUTO ||
5676 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
5677 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
5680 return (SK_PNMI_ERR_BAD_VALUE);
5683 /* The preset ends here */
5684 if (Action == SK_PNMI_PRESET) {
5686 return (SK_PNMI_ERR_OK);
5689 if (LogPortIndex == 0) {
5692 * The virtual port consists of all currently
5693 * active ports. Find them and send an event
5694 * with new master/slave (role) mode to SIRQ.
5696 for (PhysPortIndex = 0;
5697 PhysPortIndex < PhysPortMax;
5700 if (!pAC->Pnmi.Port[PhysPortIndex].
5706 EventParam.Para32[0] = PhysPortIndex;
5707 EventParam.Para32[1] = (SK_U32)Val8;
5708 if (SkGeSirqEvent(pAC, IoC,
5712 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5717 return (SK_PNMI_ERR_GENERAL);
5723 * Send an event with the new master/slave
5724 * (role) mode to the SIRQ module.
5726 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5728 EventParam.Para32[1] = (SK_U32)Val8;
5729 if (SkGeSirqEvent(pAC, IoC,
5730 SK_HWEV_SET_ROLE, EventParam) > 0) {
5732 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5737 return (SK_PNMI_ERR_GENERAL);
5741 Offset += sizeof(char);
5744 case OID_SKGE_SPEED_MODE:
5745 /* Check the value range */
5746 Val8 = *(pBuf + Offset);
5749 Offset += sizeof(char);
5752 if (Val8 < (SK_LSPEED_AUTO) ||
5753 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
5754 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
5757 return (SK_PNMI_ERR_BAD_VALUE);
5760 /* The preset ends here */
5761 if (Action == SK_PNMI_PRESET) {
5763 return (SK_PNMI_ERR_OK);
5766 if (LogPortIndex == 0) {
5769 * The virtual port consists of all currently
5770 * active ports. Find them and send an event
5771 * with the new flow control mode to SIRQ.
5773 for (PhysPortIndex = 0;
5774 PhysPortIndex < PhysPortMax;
5777 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5782 EventParam.Para32[0] = PhysPortIndex;
5783 EventParam.Para32[1] = (SK_U32)Val8;
5784 if (SkGeSirqEvent(pAC, IoC,
5788 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5793 return (SK_PNMI_ERR_GENERAL);
5799 * Send an event with the new flow control
5800 * mode to the SIRQ module.
5802 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5804 EventParam.Para32[1] = (SK_U32)Val8;
5805 if (SkGeSirqEvent(pAC, IoC,
5809 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5814 return (SK_PNMI_ERR_GENERAL);
5817 Offset += sizeof(char);
5821 /* Check the value range */
5822 Val32 = *(SK_U32*)(pBuf + Offset);
5824 /* mtu of this port remains unchanged */
5825 Offset += sizeof(SK_U32);
5828 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5830 return (SK_PNMI_ERR_BAD_VALUE);
5833 /* The preset ends here */
5834 if (Action == SK_PNMI_PRESET) {
5835 return (SK_PNMI_ERR_OK);
5838 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
5839 return (SK_PNMI_ERR_GENERAL);
5842 Offset += sizeof(SK_U32);
5845 #ifdef SK_PHY_LP_MODE
5846 case OID_SKGE_PHY_LP_MODE:
5847 /* The preset ends here */
5848 if (Action == SK_PNMI_PRESET) {
5850 return (SK_PNMI_ERR_OK);
5853 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5854 if (LogPortIndex == 0) {
5859 /* Set value for physical ports */
5860 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
5862 switch (*(pBuf + Offset)) {
5864 /* If LowPowerMode is active, we can leave it. */
5865 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5867 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5869 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5871 SkDrvInitAdapter(pAC);
5877 return (SK_PNMI_ERR_GENERAL);
5883 /* If no LowPowerMode is active, we can enter it. */
5884 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5886 if ((*(pBuf + Offset)) < 3) {
5888 SkDrvDeInitAdapter(pAC);
5891 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5896 return (SK_PNMI_ERR_GENERAL);
5900 return (SK_PNMI_ERR_BAD_VALUE);
5904 else { /* DualNetMode */
5906 switch (*(pBuf + Offset)) {
5908 /* If we are in a LowPowerMode, we can leave it. */
5909 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5911 Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex);
5913 if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) {
5915 SkDrvInitAdapter(pAC);
5921 return (SK_PNMI_ERR_GENERAL);
5928 /* If we are not already in LowPowerMode, we can enter it. */
5929 if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) {
5931 if ((*(pBuf + Offset)) < 3) {
5933 SkDrvDeInitAdapter(pAC);
5937 Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf);
5943 return (SK_PNMI_ERR_GENERAL);
5948 return (SK_PNMI_ERR_BAD_VALUE);
5951 Offset += sizeof(SK_U8);
5956 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5957 ("MacPrivateConf: Unknown OID should be handled before set"));
5960 return (SK_PNMI_ERR_GENERAL);
5964 return (SK_PNMI_ERR_OK);
5967 /*****************************************************************************
5969 * Monitor - OID handler function for RLMT_MONITOR_XXX
5972 * Because RLMT currently does not support the monitoring of
5973 * remote adapter cards, we return always an empty table.
5976 * SK_PNMI_ERR_OK The request was successfully performed.
5977 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5978 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5979 * the correct data (e.g. a 32bit value is
5980 * needed, but a 16 bit value was passed).
5981 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5983 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5984 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5985 * exist (e.g. port instance 3 on a two port
5988 PNMI_STATIC int Monitor(
5989 SK_AC *pAC, /* Pointer to adapter context */
5990 SK_IOC IoC, /* IO context handle */
5991 int Action, /* GET/PRESET/SET action */
5992 SK_U32 Id, /* Object ID that is to be processed */
5993 char *pBuf, /* Buffer used for the management data transfer */
5994 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
5995 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5996 unsigned int TableIndex, /* Index to the Id table */
5997 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
6001 unsigned int Offset;
6002 unsigned int Entries;
6006 * Calculate instance if wished.
6008 /* XXX Not yet implemented. Return always an empty table. */
6011 if ((Instance != (SK_U32)(-1))) {
6013 if ((Instance < 1) || (Instance > Entries)) {
6016 return (SK_PNMI_ERR_UNKNOWN_INST);
6019 Index = (unsigned int)Instance - 1;
6020 Limit = (unsigned int)Instance;
6030 if (Action == SK_PNMI_GET) {
6032 for (Offset=0; Index < Limit; Index ++) {
6036 case OID_SKGE_RLMT_MONITOR_INDEX:
6037 case OID_SKGE_RLMT_MONITOR_ADDR:
6038 case OID_SKGE_RLMT_MONITOR_ERRS:
6039 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6040 case OID_SKGE_RLMT_MONITOR_ADMIN:
6044 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6048 return (SK_PNMI_ERR_GENERAL);
6054 /* Only MONITOR_ADMIN can be set */
6055 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6058 return (SK_PNMI_ERR_READ_ONLY);
6061 /* Check if the length is plausible */
6062 if (*pLen < (Limit - Index)) {
6064 return (SK_PNMI_ERR_TOO_SHORT);
6066 /* Okay, we have a wide value range */
6067 if (*pLen != (Limit - Index)) {
6070 return (SK_PNMI_ERR_BAD_VALUE);
6073 for (Offset=0; Index < Limit; Index ++) {
6077 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6081 return (SK_PNMI_ERR_BAD_VALUE);
6084 return (SK_PNMI_ERR_OK);
6087 /*****************************************************************************
6089 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6092 * We handle here the get of the configuration group OIDs, which are
6093 * a little bit complicated. The virtual port consists of all currently
6094 * active physical ports. If multiple ports are active and configured
6095 * differently we get in some trouble to return a single value. So we
6096 * get the value of the first active port and compare it with that of
6097 * the other active ports. If they are not the same, we return a value
6098 * that indicates that the state is indeterminated.
6103 PNMI_STATIC void VirtualConf(
6104 SK_AC *pAC, /* Pointer to adapter context */
6105 SK_IOC IoC, /* IO context handle */
6106 SK_U32 Id, /* Object ID that is to be processed */
6107 char *pBuf) /* Buffer used for the management data transfer */
6109 unsigned int PhysPortMax;
6110 unsigned int PhysPortIndex;
6113 SK_BOOL PortActiveFlag;
6117 PortActiveFlag = SK_FALSE;
6118 PhysPortMax = pAC->GIni.GIMacsFound;
6120 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6123 pPrt = &pAC->GIni.GP[PhysPortIndex];
6125 /* Check if the physical port is active */
6126 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6131 PortActiveFlag = SK_TRUE;
6135 case OID_SKGE_PHY_TYPE:
6136 /* Check if it is the first active port */
6138 Val32 = pPrt->PhyType;
6139 SK_PNMI_STORE_U32(pBuf, Val32);
6143 case OID_SKGE_LINK_CAP:
6146 * Different capabilities should not happen, but
6147 * in the case of the cases OR them all together.
6148 * From a curious point of view the virtual port
6149 * is capable of all found capabilities.
6151 *pBuf |= pPrt->PLinkCap;
6154 case OID_SKGE_LINK_MODE:
6155 /* Check if it is the first active port */
6158 *pBuf = pPrt->PLinkModeConf;
6163 * If we find an active port with a different link
6164 * mode than the first one we return a value that
6165 * indicates that the link mode is indeterminated.
6167 if (*pBuf != pPrt->PLinkModeConf) {
6169 *pBuf = SK_LMODE_INDETERMINATED;
6173 case OID_SKGE_LINK_MODE_STATUS:
6174 /* Get the link mode of the physical port */
6175 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6177 /* Check if it is the first active port */
6185 * If we find an active port with a different link
6186 * mode status than the first one we return a value
6187 * that indicates that the link mode status is
6190 if (*pBuf != Val8) {
6192 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6196 case OID_SKGE_LINK_STATUS:
6197 /* Get the link status of the physical port */
6198 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6200 /* Check if it is the first active port */
6208 * If we find an active port with a different link
6209 * status than the first one, we return a value
6210 * that indicates that the link status is
6213 if (*pBuf != Val8) {
6215 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6219 case OID_SKGE_FLOWCTRL_CAP:
6220 /* Check if it is the first active port */
6223 *pBuf = pPrt->PFlowCtrlCap;
6228 * From a curious point of view the virtual port
6229 * is capable of all found capabilities.
6231 *pBuf |= pPrt->PFlowCtrlCap;
6234 case OID_SKGE_FLOWCTRL_MODE:
6235 /* Check if it is the first active port */
6238 *pBuf = pPrt->PFlowCtrlMode;
6243 * If we find an active port with a different flow
6244 * control mode than the first one, we return a value
6245 * that indicates that the mode is indeterminated.
6247 if (*pBuf != pPrt->PFlowCtrlMode) {
6249 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6253 case OID_SKGE_FLOWCTRL_STATUS:
6254 /* Check if it is the first active port */
6257 *pBuf = pPrt->PFlowCtrlStatus;
6262 * If we find an active port with a different flow
6263 * control status than the first one, we return a
6264 * value that indicates that the status is
6267 if (*pBuf != pPrt->PFlowCtrlStatus) {
6269 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6273 case OID_SKGE_PHY_OPERATION_CAP:
6274 /* Check if it is the first active port */
6277 *pBuf = pPrt->PMSCap;
6282 * From a curious point of view the virtual port
6283 * is capable of all found capabilities.
6285 *pBuf |= pPrt->PMSCap;
6288 case OID_SKGE_PHY_OPERATION_MODE:
6289 /* Check if it is the first active port */
6292 *pBuf = pPrt->PMSMode;
6297 * If we find an active port with a different master/
6298 * slave mode than the first one, we return a value
6299 * that indicates that the mode is indeterminated.
6301 if (*pBuf != pPrt->PMSMode) {
6303 *pBuf = SK_MS_MODE_INDETERMINATED;
6307 case OID_SKGE_PHY_OPERATION_STATUS:
6308 /* Check if it is the first active port */
6311 *pBuf = pPrt->PMSStatus;
6316 * If we find an active port with a different master/
6317 * slave status than the first one, we return a
6318 * value that indicates that the status is
6321 if (*pBuf != pPrt->PMSStatus) {
6323 *pBuf = SK_MS_STAT_INDETERMINATED;
6327 case OID_SKGE_SPEED_MODE:
6328 /* Check if it is the first active port */
6331 *pBuf = pPrt->PLinkSpeed;
6336 * If we find an active port with a different flow
6337 * control mode than the first one, we return a value
6338 * that indicates that the mode is indeterminated.
6340 if (*pBuf != pPrt->PLinkSpeed) {
6342 *pBuf = SK_LSPEED_INDETERMINATED;
6346 case OID_SKGE_SPEED_STATUS:
6347 /* Check if it is the first active port */
6350 *pBuf = pPrt->PLinkSpeedUsed;
6355 * If we find an active port with a different flow
6356 * control status than the first one, we return a
6357 * value that indicates that the status is
6360 if (*pBuf != pPrt->PLinkSpeedUsed) {
6362 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6369 * If no port is active return an indeterminated answer
6371 if (!PortActiveFlag) {
6375 case OID_SKGE_LINK_CAP:
6376 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6379 case OID_SKGE_LINK_MODE:
6380 *pBuf = SK_LMODE_INDETERMINATED;
6383 case OID_SKGE_LINK_MODE_STATUS:
6384 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6387 case OID_SKGE_LINK_STATUS:
6388 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6391 case OID_SKGE_FLOWCTRL_CAP:
6392 case OID_SKGE_FLOWCTRL_MODE:
6393 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6396 case OID_SKGE_FLOWCTRL_STATUS:
6397 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6400 case OID_SKGE_PHY_OPERATION_CAP:
6401 *pBuf = SK_MS_CAP_INDETERMINATED;
6404 case OID_SKGE_PHY_OPERATION_MODE:
6405 *pBuf = SK_MS_MODE_INDETERMINATED;
6408 case OID_SKGE_PHY_OPERATION_STATUS:
6409 *pBuf = SK_MS_STAT_INDETERMINATED;
6411 case OID_SKGE_SPEED_CAP:
6412 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6415 case OID_SKGE_SPEED_MODE:
6416 *pBuf = SK_LSPEED_INDETERMINATED;
6419 case OID_SKGE_SPEED_STATUS:
6420 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6426 /*****************************************************************************
6428 * CalculateLinkStatus - Determins the link status of a physical port
6431 * Determins the link status the following way:
6432 * LSTAT_PHY_DOWN: Link is down
6433 * LSTAT_AUTONEG: Auto-negotiation failed
6434 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6436 * LSTAT_LOG_UP: RLMT marked the port as up
6439 * Link status of physical port
6441 PNMI_STATIC SK_U8 CalculateLinkStatus(
6442 SK_AC *pAC, /* Pointer to adapter context */
6443 SK_IOC IoC, /* IO context handle */
6444 unsigned int PhysPortIndex) /* Physical port index */
6448 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6450 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6452 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6454 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6456 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6458 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6461 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6467 /*****************************************************************************
6469 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6472 * The COMMON module only tells us if the mode is half or full duplex.
6473 * But in the decade of auto sensing it is usefull for the user to
6474 * know if the mode was negotiated or forced. Therefore we have a
6475 * look to the mode, which was last used by the negotiation process.
6478 * The link mode status
6480 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6481 SK_AC *pAC, /* Pointer to adapter context */
6482 SK_IOC IoC, /* IO context handle */
6483 unsigned int PhysPortIndex) /* Physical port index */
6487 /* Get the current mode, which can be full or half duplex */
6488 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6490 /* Check if no valid mode could be found (link is down) */
6491 if (Result < SK_LMODE_STAT_HALF) {
6493 Result = SK_LMODE_STAT_UNKNOWN;
6495 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6498 * Auto-negotiation was used to bring up the link. Change
6499 * the already found duplex status that it indicates
6500 * auto-negotiation was involved.
6502 if (Result == SK_LMODE_STAT_HALF) {
6504 Result = SK_LMODE_STAT_AUTOHALF;
6506 else if (Result == SK_LMODE_STAT_FULL) {
6508 Result = SK_LMODE_STAT_AUTOFULL;
6515 /*****************************************************************************
6517 * GetVpdKeyArr - Obtain an array of VPD keys
6520 * Read the VPD keys and build an array of VPD keys, which are
6524 * SK_PNMI_ERR_OK Task successfully performed.
6525 * SK_PNMI_ERR_GENERAL Something went wrong.
6527 PNMI_STATIC int GetVpdKeyArr(
6528 SK_AC *pAC, /* Pointer to adapter context */
6529 SK_IOC IoC, /* IO context handle */
6530 char *pKeyArr, /* Ptr KeyArray */
6531 unsigned int KeyArrLen, /* Length of array in bytes */
6532 unsigned int *pKeyNo) /* Number of keys */
6534 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6535 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6536 unsigned int StartOffset;
6537 unsigned int Offset;
6542 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6547 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6551 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6554 return (SK_PNMI_ERR_GENERAL);
6556 /* If no keys are available return now */
6557 if (*pKeyNo == 0 || BufKeysLen == 0) {
6559 return (SK_PNMI_ERR_OK);
6562 * If the key list is too long for us trunc it and give a
6563 * errorlog notification. This case should not happen because
6564 * the maximum number of keys is limited due to RAM limitations
6566 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6568 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6571 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6575 * Now build an array of fixed string length size and copy
6576 * the keys together.
6578 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6581 if (BufKeys[Offset] != 0) {
6586 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6588 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6590 return (SK_PNMI_ERR_GENERAL);
6593 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6594 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6597 StartOffset = Offset + 1;
6600 /* Last key not zero terminated? Get it anyway */
6601 if (StartOffset < Offset) {
6603 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6604 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6607 return (SK_PNMI_ERR_OK);
6610 /*****************************************************************************
6612 * SirqUpdate - Let the SIRQ update its internal values
6615 * Just to be sure that the SIRQ module holds its internal data
6616 * structures up to date, we send an update event before we make
6620 * SK_PNMI_ERR_OK Task successfully performed.
6621 * SK_PNMI_ERR_GENERAL Something went wrong.
6623 PNMI_STATIC int SirqUpdate(
6624 SK_AC *pAC, /* Pointer to adapter context */
6625 SK_IOC IoC) /* IO context handle */
6627 SK_EVPARA EventParam;
6630 /* Was the module already updated during the current PNMI call? */
6631 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6633 return (SK_PNMI_ERR_OK);
6636 /* Send an synchronuous update event to the module */
6637 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6638 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6640 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6643 return (SK_PNMI_ERR_GENERAL);
6646 return (SK_PNMI_ERR_OK);
6649 /*****************************************************************************
6651 * RlmtUpdate - Let the RLMT update its internal values
6654 * Just to be sure that the RLMT module holds its internal data
6655 * structures up to date, we send an update event before we make
6659 * SK_PNMI_ERR_OK Task successfully performed.
6660 * SK_PNMI_ERR_GENERAL Something went wrong.
6662 PNMI_STATIC int RlmtUpdate(
6663 SK_AC *pAC, /* Pointer to adapter context */
6664 SK_IOC IoC, /* IO context handle */
6665 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6667 SK_EVPARA EventParam;
6670 /* Was the module already updated during the current PNMI call? */
6671 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6673 return (SK_PNMI_ERR_OK);
6676 /* Send an synchronuous update event to the module */
6677 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6678 EventParam.Para32[0] = NetIndex;
6679 EventParam.Para32[1] = (SK_U32)-1;
6680 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6682 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6685 return (SK_PNMI_ERR_GENERAL);
6688 return (SK_PNMI_ERR_OK);
6691 /*****************************************************************************
6693 * MacUpdate - Force the XMAC to output the current statistic
6696 * The XMAC holds its statistic internally. To obtain the current
6697 * values we must send a command so that the statistic data will
6698 * be written to a predefined memory area on the adapter.
6701 * SK_PNMI_ERR_OK Task successfully performed.
6702 * SK_PNMI_ERR_GENERAL Something went wrong.
6704 PNMI_STATIC int MacUpdate(
6705 SK_AC *pAC, /* Pointer to adapter context */
6706 SK_IOC IoC, /* IO context handle */
6707 unsigned int FirstMac, /* Index of the first Mac to be updated */
6708 unsigned int LastMac) /* Index of the last Mac to be updated */
6710 unsigned int MacIndex;
6713 * Were the statistics already updated during the
6714 * current PNMI call?
6716 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6718 return (SK_PNMI_ERR_OK);
6721 /* Send an update command to all MACs specified */
6722 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6725 * 2002-09-13 pweber: Freeze the current SW counters.
6726 * (That should be done as close as
6727 * possible to the update of the
6730 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6731 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6734 /* 2002-09-13 pweber: Update the HW counter */
6735 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6737 return (SK_PNMI_ERR_GENERAL);
6741 return (SK_PNMI_ERR_OK);
6744 /*****************************************************************************
6746 * GetStatVal - Retrieve an XMAC statistic counter
6749 * Retrieves the statistic counter of a virtual or physical port. The
6750 * virtual port is identified by the index 0. It consists of all
6751 * currently active ports. To obtain the counter value for this port
6752 * we must add the statistic counter of all active ports. To grant
6753 * continuous counter values for the virtual port even when port
6754 * switches occur we must additionally add a delta value, which was
6755 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6758 * Requested statistic value
6760 PNMI_STATIC SK_U64 GetStatVal(
6761 SK_AC *pAC, /* Pointer to adapter context */
6762 SK_IOC IoC, /* IO context handle */
6763 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6764 unsigned int StatIndex, /* Index to statistic value */
6765 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6767 unsigned int PhysPortIndex;
6768 unsigned int PhysPortMax;
6772 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6774 PhysPortIndex = NetIndex;
6776 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6778 else { /* Single Net mode */
6780 if (LogPortIndex == 0) {
6782 PhysPortMax = pAC->GIni.GIMacsFound;
6784 /* Add counter of all active ports */
6785 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6788 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6790 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6794 /* Correct value because of port switches */
6795 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
6798 /* Get counter value of physical port */
6799 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
6801 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6807 /*****************************************************************************
6809 * GetPhysStatVal - Get counter value for physical port
6812 * Builds a 64bit counter value. Except for the octet counters
6813 * the lower 32bit are counted in hardware and the upper 32bit
6814 * in software by monitoring counter overflow interrupts in the
6815 * event handler. To grant continous counter values during XMAC
6816 * resets (caused by a workaround) we must add a delta value.
6817 * The delta was calculated in the event handler when a
6818 * SK_PNMI_EVT_XMAC_RESET was received.
6823 PNMI_STATIC SK_U64 GetPhysStatVal(
6824 SK_AC *pAC, /* Pointer to adapter context */
6825 SK_IOC IoC, /* IO context handle */
6826 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
6827 unsigned int StatIndex) /* Index to statistic value */
6834 unsigned int HelpIndex;
6837 SK_PNMI_PORT *pPnmiPrt;
6838 SK_GEMACFUNC *pFnMac;
6840 pPrt = &pAC->GIni.GP[PhysPortIndex];
6842 MacType = pAC->GIni.GIMacType;
6844 /* 2002-09-17 pweber: For XMAC, use the frozen SW counters (BufPort) */
6845 if (MacType == SK_MAC_XMAC) {
6846 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
6849 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
6852 pFnMac = &pAC->GIni.GIFunc;
6854 switch (StatIndex) {
6856 if (MacType == SK_MAC_GMAC) {
6857 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6858 StatAddr[SK_PNMI_HTX_BROADCAST][MacType].Reg,
6860 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6861 StatAddr[SK_PNMI_HTX_MULTICAST][MacType].Reg,
6864 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6865 StatAddr[SK_PNMI_HTX_UNICAST][MacType].Reg,
6870 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6871 StatAddr[StatIndex][MacType].Reg,
6874 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6878 if (MacType == SK_MAC_GMAC) {
6879 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6880 StatAddr[SK_PNMI_HRX_BROADCAST][MacType].Reg,
6882 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6883 StatAddr[SK_PNMI_HRX_MULTICAST][MacType].Reg,
6886 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6887 StatAddr[SK_PNMI_HRX_UNICAST][MacType].Reg,
6892 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6893 StatAddr[StatIndex][MacType].Reg,
6896 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6899 case SK_PNMI_HTX_OCTET:
6900 case SK_PNMI_HRX_OCTET:
6901 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6902 StatAddr[StatIndex][MacType].Reg,
6904 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6905 StatAddr[StatIndex + 1][MacType].Reg,
6909 case SK_PNMI_HTX_BURST:
6910 case SK_PNMI_HTX_EXCESS_DEF:
6911 case SK_PNMI_HTX_CARRIER:
6912 /* Not supported by GMAC */
6913 if (MacType == SK_MAC_GMAC) {
6917 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6918 StatAddr[StatIndex][MacType].Reg,
6920 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6923 case SK_PNMI_HTX_MACC:
6924 /* GMAC only supports PAUSE MAC control frames */
6925 if (MacType == SK_MAC_GMAC) {
6926 HelpIndex = SK_PNMI_HTX_PMACC;
6929 HelpIndex = StatIndex;
6932 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6933 StatAddr[HelpIndex][MacType].Reg,
6936 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6939 case SK_PNMI_HTX_COL:
6940 case SK_PNMI_HRX_UNDERSIZE:
6941 /* Not supported by XMAC */
6942 if (MacType == SK_MAC_XMAC) {
6946 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6947 StatAddr[StatIndex][MacType].Reg,
6949 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6952 case SK_PNMI_HTX_DEFFERAL:
6953 /* Not supported by GMAC */
6954 if (MacType == SK_MAC_GMAC) {
6959 * XMAC counts frames with deferred transmission
6960 * even in full-duplex mode.
6962 * In full-duplex mode the counter remains constant!
6964 if ((pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
6965 (pPrt->PLinkModeStatus == SK_LMODE_STAT_FULL)) {
6971 /* Otherwise get contents of hardware register */
6972 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6973 StatAddr[StatIndex][MacType].Reg,
6975 HighVal = pPnmiPrt->CounterHigh[StatIndex];
6979 case SK_PNMI_HRX_BADOCTET:
6980 /* Not supported by XMAC */
6981 if (MacType == SK_MAC_XMAC) {
6985 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6986 StatAddr[StatIndex][MacType].Reg,
6988 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
6989 StatAddr[StatIndex + 1][MacType].Reg,
6993 case SK_PNMI_HTX_OCTETLOW:
6994 case SK_PNMI_HRX_OCTETLOW:
6995 case SK_PNMI_HRX_BADOCTETLOW:
6998 case SK_PNMI_HRX_LONGFRAMES:
6999 /* For XMAC the SW counter is managed by PNMI */
7000 if (MacType == SK_MAC_XMAC) {
7001 return (pPnmiPrt->StatRxLongFrameCts);
7004 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7005 StatAddr[StatIndex][MacType].Reg,
7007 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7010 case SK_PNMI_HRX_TOO_LONG:
7011 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7012 StatAddr[StatIndex][MacType].Reg,
7014 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7016 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7018 if (MacType == SK_MAC_GMAC) {
7019 /* For GMAC the SW counter is additionally managed by PNMI */
7020 Val += pPnmiPrt->StatRxFrameTooLongCts;
7024 * Frames longer than IEEE 802.3 frame max size are counted
7025 * by XMAC in frame_too_long counter even reception of long
7026 * frames was enabled and the frame was correct.
7027 * So correct the value by subtracting RxLongFrame counter.
7029 Val -= pPnmiPrt->StatRxLongFrameCts;
7032 LowVal = (SK_U32)Val;
7033 HighVal = (SK_U32)(Val >> 32);
7036 case SK_PNMI_HRX_SHORTS:
7037 /* Not supported by GMAC */
7038 if (MacType == SK_MAC_GMAC) {
7044 * XMAC counts short frame errors even if link down (#10620)
7046 * If link-down the counter remains constant
7048 if (pPrt->PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7050 /* Otherwise get incremental difference */
7051 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7052 StatAddr[StatIndex][MacType].Reg,
7054 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7056 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7057 Val -= pPnmiPrt->RxShortZeroMark;
7059 LowVal = (SK_U32)Val;
7060 HighVal = (SK_U32)(Val >> 32);
7064 case SK_PNMI_HRX_MACC:
7065 case SK_PNMI_HRX_MACC_UNKWN:
7066 case SK_PNMI_HRX_BURST:
7067 case SK_PNMI_HRX_MISSED:
7068 case SK_PNMI_HRX_FRAMING:
7069 case SK_PNMI_HRX_CARRIER:
7070 case SK_PNMI_HRX_IRLENGTH:
7071 case SK_PNMI_HRX_SYMBOL:
7072 case SK_PNMI_HRX_CEXT:
7073 /* Not supported by GMAC */
7074 if (MacType == SK_MAC_GMAC) {
7078 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7079 StatAddr[StatIndex][MacType].Reg,
7081 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7084 case SK_PNMI_HRX_PMACC_ERR:
7085 /* For GMAC the SW counter is managed by PNMI */
7086 if (MacType == SK_MAC_GMAC) {
7087 return (pPnmiPrt->StatRxPMaccErr);
7090 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7091 StatAddr[StatIndex][MacType].Reg,
7093 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7096 /* SW counter managed by PNMI */
7097 case SK_PNMI_HTX_SYNC:
7098 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7099 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7102 /* SW counter managed by PNMI */
7103 case SK_PNMI_HTX_SYNC_OCTET:
7104 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7105 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7108 case SK_PNMI_HRX_FCS:
7110 * Broadcom filters FCS errors and counts it in
7111 * Receive Error Counter register
7113 if (pPrt->PhyType == SK_PHY_BCOM) {
7114 /* do not read while not initialized (PHY_READ hangs!)*/
7115 if (pPrt->PState != SK_PRT_RESET) {
7116 SkXmPhyRead(pAC, IoC, PhysPortIndex, PHY_BCOM_RE_CTR, &Word);
7120 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7123 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7124 StatAddr[StatIndex][MacType].Reg,
7126 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7131 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7132 StatAddr[StatIndex][MacType].Reg,
7134 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7138 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7140 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7141 Val += pPnmiPrt->CounterOffset[StatIndex];
7146 /*****************************************************************************
7148 * ResetCounter - Set all counters and timestamps to zero
7151 * Notifies other common modules which store statistic data to
7152 * reset their counters and finally reset our own counters.
7157 PNMI_STATIC void ResetCounter(
7158 SK_AC *pAC, /* Pointer to adapter context */
7159 SK_IOC IoC, /* IO context handle */
7162 unsigned int PhysPortIndex;
7163 SK_EVPARA EventParam;
7166 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7168 /* Notify sensor module */
7169 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7171 /* Notify RLMT module */
7172 EventParam.Para32[0] = NetIndex;
7173 EventParam.Para32[1] = (SK_U32)-1;
7174 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7175 EventParam.Para32[1] = 0;
7177 /* Notify SIRQ module */
7178 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7180 /* Notify CSUM module */
7182 EventParam.Para32[0] = NetIndex;
7183 EventParam.Para32[1] = (SK_U32)-1;
7184 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7186 #endif /* SK_USE_CSUM */
7188 /* Clear XMAC statistic */
7189 for (PhysPortIndex = 0; PhysPortIndex <
7190 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7192 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7194 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7195 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7196 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7197 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7198 PhysPortIndex].CounterOffset));
7199 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7200 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7201 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7202 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7203 PhysPortIndex].StatSyncOctetsCts));
7204 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7205 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7206 PhysPortIndex].StatRxLongFrameCts));
7207 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7208 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7209 PhysPortIndex].StatRxFrameTooLongCts));
7210 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7211 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7212 PhysPortIndex].StatRxPMaccErr));
7216 * Clear local statistics
7218 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7219 sizeof(pAC->Pnmi.VirtualCounterOffset));
7220 pAC->Pnmi.RlmtChangeCts = 0;
7221 pAC->Pnmi.RlmtChangeTime = 0;
7222 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7223 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7224 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7225 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7226 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7227 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7228 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7229 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7230 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7231 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7232 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7233 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7234 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7235 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7238 /*****************************************************************************
7240 * GetTrapEntry - Get an entry in the trap buffer
7243 * The trap buffer stores various events. A user application somehow
7244 * gets notified that an event occured and retrieves the trap buffer
7245 * contens (or simply polls the buffer). The buffer is organized as
7246 * a ring which stores the newest traps at the beginning. The oldest
7247 * traps are overwritten by the newest ones. Each trap entry has a
7248 * unique number, so that applications may detect new trap entries.
7251 * A pointer to the trap entry
7253 PNMI_STATIC char* GetTrapEntry(
7254 SK_AC *pAC, /* Pointer to adapter context */
7255 SK_U32 TrapId, /* SNMP ID of the trap */
7256 unsigned int Size) /* Space needed for trap entry */
7258 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7259 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7260 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7261 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7262 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7264 unsigned int NeededSpace;
7265 unsigned int EntrySize;
7270 /* Last byte of entry will get a copy of the entry length */
7274 * Calculate needed buffer space */
7281 NeededSpace = Beg + Size;
7286 * Check if enough buffer space is provided. Otherwise
7287 * free some entries. Leave one byte space between begin
7288 * and end of buffer to make it possible to detect whether
7289 * the buffer is full or empty
7291 while (BufFree < NeededSpace + 1) {
7295 End = SK_PNMI_TRAP_QUEUE_LEN;
7298 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7299 BufFree += EntrySize;
7302 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7304 if (End == BufPad) {
7306 SK_MEMSET(pBuf, (char)(-1), End);
7315 * Insert new entry as first entry. Newest entries are
7316 * stored at the beginning of the queue.
7321 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7326 BufFree -= NeededSpace;
7328 /* Save the current offsets */
7329 pAC->Pnmi.TrapQueueBeg = Beg;
7330 pAC->Pnmi.TrapQueueEnd = End;
7331 pAC->Pnmi.TrapBufPad = BufPad;
7332 pAC->Pnmi.TrapBufFree = BufFree;
7334 /* Initialize the trap entry */
7335 *(pBuf + Beg + Size - 1) = (char)Size;
7336 *(pBuf + Beg) = (char)Size;
7337 Val32 = (pAC->Pnmi.TrapUnique) ++;
7338 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7339 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7340 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7341 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7343 return (pBuf + Beg);
7346 /*****************************************************************************
7348 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7351 * On a query of the TRAP OID the trap buffer contents will be
7352 * copied continuously to the request buffer, which must be large
7353 * enough. No length check is performed.
7358 PNMI_STATIC void CopyTrapQueue(
7359 SK_AC *pAC, /* Pointer to adapter context */
7360 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7362 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7363 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7364 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7365 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7367 unsigned int DstOff = 0;
7370 while (Trap != End) {
7372 Len = (unsigned int)*(pBuf + Trap);
7375 * Last byte containing a copy of the length will
7378 *(pDstBuf + DstOff) = (char)(Len - 1);
7379 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7383 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7390 /*****************************************************************************
7392 * GetTrapQueueLen - Get the length of the trap buffer
7395 * Evaluates the number of currently stored traps and the needed
7396 * buffer size to retrieve them.
7401 PNMI_STATIC void GetTrapQueueLen(
7402 SK_AC *pAC, /* Pointer to adapter context */
7403 unsigned int *pLen, /* Length in Bytes of all queued traps */
7404 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7406 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7407 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7408 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7409 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7411 unsigned int Entries = 0;
7412 unsigned int TotalLen = 0;
7415 while (Trap != End) {
7417 Len = (unsigned int)*(pBuf + Trap);
7418 TotalLen += Len - 1;
7422 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7428 *pEntries = Entries;
7432 /*****************************************************************************
7434 * QueueSimpleTrap - Store a simple trap to the trap buffer
7437 * A simple trap is a trap with now additional data. It consists
7438 * simply of a trap code.
7443 PNMI_STATIC void QueueSimpleTrap(
7444 SK_AC *pAC, /* Pointer to adapter context */
7445 SK_U32 TrapId) /* Type of sensor trap */
7447 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7450 /*****************************************************************************
7452 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7455 * Gets an entry in the trap buffer and fills it with sensor related
7461 PNMI_STATIC void QueueSensorTrap(
7462 SK_AC *pAC, /* Pointer to adapter context */
7463 SK_U32 TrapId, /* Type of sensor trap */
7464 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7467 unsigned int Offset;
7468 unsigned int DescrLen;
7472 /* Get trap buffer entry */
7473 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7474 pBuf = GetTrapEntry(pAC, TrapId,
7475 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7476 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7478 /* Store additionally sensor trap related data */
7479 Val32 = OID_SKGE_SENSOR_INDEX;
7480 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7481 *(pBuf + Offset + 4) = 4;
7482 Val32 = (SK_U32)SensorIndex;
7483 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7486 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7487 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7488 *(pBuf + Offset + 4) = (char)DescrLen;
7489 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7491 Offset += DescrLen + 5;
7493 Val32 = OID_SKGE_SENSOR_TYPE;
7494 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7495 *(pBuf + Offset + 4) = 1;
7496 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7499 Val32 = OID_SKGE_SENSOR_VALUE;
7500 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7501 *(pBuf + Offset + 4) = 4;
7502 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7503 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7506 /*****************************************************************************
7508 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7511 * Nothing further to explain.
7516 PNMI_STATIC void QueueRlmtNewMacTrap(
7517 SK_AC *pAC, /* Pointer to adapter context */
7518 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7524 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7525 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7527 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7528 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7529 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7530 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7533 /*****************************************************************************
7535 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7538 * Nothing further to explain.
7543 PNMI_STATIC void QueueRlmtPortTrap(
7544 SK_AC *pAC, /* Pointer to adapter context */
7545 SK_U32 TrapId, /* Type of RLMT port trap */
7546 unsigned int PortIndex) /* Index of the port, which changed its state */
7552 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7554 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7555 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7556 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7557 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7560 /*****************************************************************************
7562 * CopyMac - Copies a MAC address
7565 * Nothing further to explain.
7570 PNMI_STATIC void CopyMac(
7571 char *pDst, /* Pointer to destination buffer */
7572 SK_MAC_ADDR *pMac) /* Pointer of Source */
7577 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7579 *(pDst + i) = pMac->a[i];
7583 #ifdef SK_POWER_MGMT
7584 /*****************************************************************************
7586 * PowerManagement - OID handler function of PowerManagement OIDs
7589 * The code is simple. No description necessary.
7592 * SK_PNMI_ERR_OK The request was successfully performed.
7593 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7594 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7595 * the correct data (e.g. a 32bit value is
7596 * needed, but a 16 bit value was passed).
7597 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7598 * exist (e.g. port instance 3 on a two port
7602 PNMI_STATIC int PowerManagement(
7603 SK_AC *pAC, /* Pointer to adapter context */
7604 SK_IOC IoC, /* IO context handle */
7605 int Action, /* Get/PreSet/Set action */
7606 SK_U32 Id, /* Object ID that is to be processed */
7607 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7608 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7609 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7610 unsigned int TableIndex, /* Index to the Id table */
7611 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7614 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7617 * Check instance. We only handle single instance variables
7619 if (Instance != (SK_U32)(-1) && Instance != 1) {
7622 return (SK_PNMI_ERR_UNKNOWN_INST);
7629 case OID_PNP_CAPABILITIES:
7630 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7632 *pLen = sizeof(SK_PNP_CAPABILITIES);
7633 return (SK_PNMI_ERR_TOO_SHORT);
7637 case OID_PNP_SET_POWER:
7638 case OID_PNP_QUERY_POWER:
7639 if (*pLen < sizeof(SK_DEVICE_POWER_STATE))
7641 *pLen = sizeof(SK_DEVICE_POWER_STATE);
7642 return (SK_PNMI_ERR_TOO_SHORT);
7646 case OID_PNP_ADD_WAKE_UP_PATTERN:
7647 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7648 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7650 *pLen = sizeof(SK_PM_PACKET_PATTERN);
7651 return (SK_PNMI_ERR_TOO_SHORT);
7655 case OID_PNP_ENABLE_WAKE_UP:
7656 if (*pLen < sizeof(SK_U32)) {
7658 *pLen = sizeof(SK_U32);
7659 return (SK_PNMI_ERR_TOO_SHORT);
7667 if (Action == SK_PNMI_GET) {
7674 case OID_PNP_CAPABILITIES:
7675 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7678 case OID_PNP_QUERY_POWER:
7679 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7680 the miniport to indicate whether it can transition its NIC
7681 to the low-power state.
7682 A miniport driver must always return NDIS_STATUS_SUCCESS
7683 to a query of OID_PNP_QUERY_POWER. */
7684 *pLen = sizeof(SK_DEVICE_POWER_STATE);;
7685 RetCode = SK_PNMI_ERR_OK;
7688 /* NDIS handles these OIDs as write-only.
7689 * So in case of get action the buffer with written length = 0
7692 case OID_PNP_SET_POWER:
7693 case OID_PNP_ADD_WAKE_UP_PATTERN:
7694 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7696 RetCode = SK_PNMI_ERR_NOT_SUPPORTED;
7699 case OID_PNP_ENABLE_WAKE_UP:
7700 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7704 RetCode = SK_PNMI_ERR_GENERAL;
7713 * Perform preset or set
7716 /* POWER module does not support PRESET action */
7717 if (Action == SK_PNMI_PRESET) {
7718 return (SK_PNMI_ERR_OK);
7722 case OID_PNP_SET_POWER:
7723 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7726 case OID_PNP_ADD_WAKE_UP_PATTERN:
7727 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7730 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7731 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7734 case OID_PNP_ENABLE_WAKE_UP:
7735 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7739 RetCode = SK_PNMI_ERR_READ_ONLY;
7744 #endif /* SK_POWER_MGMT */
7746 #ifdef SK_DIAG_SUPPORT
7747 /*****************************************************************************
7749 * DiagActions - OID handler function of Diagnostic driver
7752 * The code is simple. No description necessary.
7755 * SK_PNMI_ERR_OK The request was successfully performed.
7756 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7757 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7758 * the correct data (e.g. a 32bit value is
7759 * needed, but a 16 bit value was passed).
7760 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7761 * exist (e.g. port instance 3 on a two port
7765 PNMI_STATIC int DiagActions(
7766 SK_AC *pAC, /* Pointer to adapter context */
7767 SK_IOC IoC, /* IO context handle */
7768 int Action, /* GET/PRESET/SET action */
7769 SK_U32 Id, /* Object ID that is to be processed */
7770 char *pBuf, /* Buffer used for the management data transfer */
7771 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7772 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7773 unsigned int TableIndex, /* Index to the Id table */
7774 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7778 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7781 * Check instance. We only handle single instance variables.
7783 if (Instance != (SK_U32)(-1) && Instance != 1) {
7786 return (SK_PNMI_ERR_UNKNOWN_INST);
7794 case OID_SKGE_DIAG_MODE:
7795 if (*pLen < sizeof(SK_U32)) {
7797 *pLen = sizeof(SK_U32);
7798 return (SK_PNMI_ERR_TOO_SHORT);
7803 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040, SK_PNMI_ERR040MSG);
7805 return (SK_PNMI_ERR_GENERAL);
7808 /* Perform action. */
7811 if (Action == SK_PNMI_GET) {
7815 case OID_SKGE_DIAG_MODE:
7816 DiagStatus = pAC->Pnmi.DiagAttached;
7817 SK_PNMI_STORE_U32(pBuf, DiagStatus);
7818 *pLen = sizeof(SK_U32);
7819 RetCode = SK_PNMI_ERR_OK;
7824 RetCode = SK_PNMI_ERR_GENERAL;
7830 /* From here SET or PRESET value. */
7832 /* PRESET value is not supported. */
7833 if (Action == SK_PNMI_PRESET) {
7834 return (SK_PNMI_ERR_OK);
7839 case OID_SKGE_DIAG_MODE:
7841 /* Handle the SET. */
7844 /* Attach the DIAG to this adapter. */
7845 case SK_DIAG_ATTACHED:
7846 /* Check if we come from running */
7847 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7849 RetCode = SkDrvLeaveDiagMode(pAC);
7852 else if (pAC->Pnmi.DiagAttached == SK_DIAG_IDLE) {
7854 RetCode = SK_PNMI_ERR_OK;
7859 RetCode = SK_PNMI_ERR_GENERAL;
7863 if (RetCode == SK_PNMI_ERR_OK) {
7865 pAC->Pnmi.DiagAttached = SK_DIAG_ATTACHED;
7869 /* Enter the DIAG mode in the driver. */
7870 case SK_DIAG_RUNNING:
7871 RetCode = SK_PNMI_ERR_OK;
7874 * If DiagAttached is set, we can tell the driver
7875 * to enter the DIAG mode.
7877 if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7878 /* If DiagMode is not active, we can enter it. */
7879 if (!pAC->DiagModeActive) {
7881 RetCode = SkDrvEnterDiagMode(pAC);
7885 RetCode = SK_PNMI_ERR_GENERAL;
7890 RetCode = SK_PNMI_ERR_GENERAL;
7893 if (RetCode == SK_PNMI_ERR_OK) {
7895 pAC->Pnmi.DiagAttached = SK_DIAG_RUNNING;
7900 /* Check if we come from running */
7901 if (pAC->Pnmi.DiagAttached == SK_DIAG_RUNNING) {
7903 RetCode = SkDrvLeaveDiagMode(pAC);
7906 else if (pAC->Pnmi.DiagAttached == SK_DIAG_ATTACHED) {
7908 RetCode = SK_PNMI_ERR_OK;
7913 RetCode = SK_PNMI_ERR_GENERAL;
7917 if (RetCode == SK_PNMI_ERR_OK) {
7919 pAC->Pnmi.DiagAttached = SK_DIAG_IDLE;
7924 RetCode = SK_PNMI_ERR_BAD_VALUE;
7930 RetCode = SK_PNMI_ERR_GENERAL;
7933 if (RetCode == SK_PNMI_ERR_OK) {
7934 *pLen = sizeof(SK_U32);
7942 #endif /* SK_DIAG_SUPPORT */
7944 /*****************************************************************************
7946 * Vct - OID handler function of OIDs
7949 * The code is simple. No description necessary.
7952 * SK_PNMI_ERR_OK The request was performed successfully.
7953 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7954 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7955 * the correct data (e.g. a 32bit value is
7956 * needed, but a 16 bit value was passed).
7957 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7958 * exist (e.g. port instance 3 on a two port
7960 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7964 PNMI_STATIC int Vct(
7965 SK_AC *pAC, /* Pointer to adapter context */
7966 SK_IOC IoC, /* IO context handle */
7967 int Action, /* GET/PRESET/SET action */
7968 SK_U32 Id, /* Object ID that is to be processed */
7969 char *pBuf, /* Buffer used for the management data transfer */
7970 unsigned int *pLen, /* On call: pBuf buffer length. On return: used buffer */
7971 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7972 unsigned int TableIndex, /* Index to the Id table */
7973 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7976 SK_PNMI_VCT *pVctBackupData;
7979 SK_U32 PhysPortIndex;
7983 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7989 * Calculate the port indexes from the instance.
7991 PhysPortMax = pAC->GIni.GIMacsFound;
7992 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
7994 /* Dual net mode? */
7995 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
7999 if ((Instance != (SK_U32) (-1))) {
8000 /* Check instance range. */
8001 if ((Instance < 2) || (Instance > LogPortMax)) {
8003 return (SK_PNMI_ERR_UNKNOWN_INST);
8006 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8007 PhysPortIndex = NetIndex;
8010 PhysPortIndex = Instance - 2;
8012 Limit = PhysPortIndex + 1;
8016 * Instance == (SK_U32) (-1), get all Instances of that OID.
8018 * Not implemented yet. May be used in future releases.
8021 Limit = PhysPortMax;
8024 pPrt = &pAC->GIni.GP[PhysPortIndex];
8025 if (pPrt->PHWLinkUp) {
8032 /* Check MAC type */
8033 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8035 return (SK_PNMI_ERR_GENERAL);
8038 /* Initialize backup data pointer. */
8039 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8041 /* Check action type */
8042 if (Action == SK_PNMI_GET) {
8046 case OID_SKGE_VCT_GET:
8047 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8048 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8049 return (SK_PNMI_ERR_TOO_SHORT);
8053 case OID_SKGE_VCT_STATUS:
8054 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8055 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8056 return (SK_PNMI_ERR_TOO_SHORT);
8062 return (SK_PNMI_ERR_GENERAL);
8067 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8070 case OID_SKGE_VCT_GET:
8071 if ((Link == SK_FALSE) &&
8072 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8073 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8075 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8076 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8077 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8079 /* Copy results for later use to PNMI struct. */
8080 for (i = 0; i < 4; i++) {
8081 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8082 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8083 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8086 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8087 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8092 pVctBackupData->PMdiPairLen[i] = CableLength;
8093 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8096 Para.Para32[0] = PhysPortIndex;
8097 Para.Para32[1] = -1;
8098 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8099 SkEventDispatcher(pAC, IoC);
8102 ; /* VCT test is running. */
8106 /* Get all results. */
8107 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8108 Offset += sizeof(SK_U8);
8109 *(pBuf + Offset) = pPrt->PCableLen;
8110 Offset += sizeof(SK_U8);
8111 for (i = 0; i < 4; i++) {
8112 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8113 Offset += sizeof(SK_U32);
8115 for (i = 0; i < 4; i++) {
8116 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8117 Offset += sizeof(SK_U8);
8120 RetCode = SK_PNMI_ERR_OK;
8123 case OID_SKGE_VCT_STATUS:
8124 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8125 Offset += sizeof(SK_U8);
8126 RetCode = SK_PNMI_ERR_OK;
8131 return (SK_PNMI_ERR_GENERAL);
8137 } /* if SK_PNMI_GET */
8140 * From here SET or PRESET action. Check if the passed
8141 * buffer length is plausible.
8146 case OID_SKGE_VCT_SET:
8147 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8148 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8149 return (SK_PNMI_ERR_TOO_SHORT);
8155 return (SK_PNMI_ERR_GENERAL);
8159 * Perform preset or set.
8162 /* VCT does not support PRESET action. */
8163 if (Action == SK_PNMI_PRESET) {
8164 return (SK_PNMI_ERR_OK);
8168 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8170 case OID_SKGE_VCT_SET: /* Start VCT test. */
8171 if (Link == SK_FALSE) {
8172 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8174 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8175 if (RetCode == 0) { /* RetCode: 0 => Start! */
8176 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8177 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8178 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8181 * Start VCT timer counter.
8183 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8184 Para.Para32[0] = PhysPortIndex;
8185 Para.Para32[1] = -1;
8186 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8187 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8188 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8189 RetCode = SK_PNMI_ERR_OK;
8191 else { /* RetCode: 2 => Running! */
8192 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8193 RetCode = SK_PNMI_ERR_OK;
8196 else { /* RetCode: 4 => Link! */
8198 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8199 RetCode = SK_PNMI_ERR_OK;
8201 Offset += sizeof(SK_U32);
8206 return (SK_PNMI_ERR_GENERAL);
8215 PNMI_STATIC void CheckVctStatus(
8220 SK_U32 PhysPortIndex)
8223 SK_PNMI_VCT *pVctData;
8226 pPrt = &pAC->GIni.GP[PhysPortIndex];
8228 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8229 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8231 if (!pPrt->PHWLinkUp) {
8233 /* Was a VCT test ever made before? */
8234 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8235 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8236 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8239 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8243 /* Check VCT test status. */
8244 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8245 if (RetCode == 2) { /* VCT test is running. */
8246 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8248 else { /* VCT data was copied to pAC here. Check PENDING state. */
8249 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8250 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8254 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8255 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8260 /* Was a VCT test ever made before? */
8261 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8262 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8263 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8266 /* DSP only valid in 100/1000 modes. */
8267 if (pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed !=
8268 SK_LSPEED_STAT_10MBPS) {
8269 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8272 } /* CheckVctStatus */
8275 /*****************************************************************************
8277 * SkPnmiGenIoctl - Handles new generic PNMI IOCTL, calls the needed
8278 * PNMI function depending on the subcommand and
8279 * returns all data belonging to the complete database
8283 * Looks up the requested subcommand, calls the corresponding handler
8284 * function and passes all required parameters to it.
8285 * The function is called by the driver. It is needed to handle the new
8286 * generic PNMI IOCTL. This IOCTL is given to the driver and contains both
8287 * the OID and a subcommand to decide what kind of request has to be done.
8290 * SK_PNMI_ERR_OK The request was successfully performed
8291 * SK_PNMI_ERR_GENERAL A general severe internal error occured
8292 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
8294 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
8295 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
8296 * exist (e.g. port instance 3 on a two port
8300 SK_AC *pAC, /* Pointer to adapter context struct */
8301 SK_IOC IoC, /* I/O context */
8302 void *pBuf, /* Buffer used for the management data transfer */
8303 unsigned int *pLen, /* Length of buffer */
8304 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
8306 SK_I32 Mode; /* Store value of subcommand. */
8307 SK_U32 Oid; /* Store value of OID. */
8308 int ReturnCode; /* Store return value to show status of PNMI action. */
8309 int HeaderLength; /* Length of desired action plus OID. */
8311 ReturnCode = SK_PNMI_ERR_GENERAL;
8313 SK_MEMCPY(&Mode, pBuf, sizeof(SK_I32));
8314 SK_MEMCPY(&Oid, (char *) pBuf + sizeof(SK_I32), sizeof(SK_U32));
8315 HeaderLength = sizeof(SK_I32) + sizeof(SK_U32);
8316 *pLen = *pLen - HeaderLength;
8317 SK_MEMCPY((char *) pBuf + sizeof(SK_I32), (char *) pBuf + HeaderLength, *pLen);
8320 case SK_GET_SINGLE_VAR:
8321 ReturnCode = SkPnmiGetVar(pAC, IoC, Oid,
8322 (char *) pBuf + sizeof(SK_I32), pLen,
8323 ((SK_U32) (-1)), NetIndex);
8324 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8325 *pLen = *pLen + sizeof(SK_I32);
8327 case SK_PRESET_SINGLE_VAR:
8328 ReturnCode = SkPnmiPreSetVar(pAC, IoC, Oid,
8329 (char *) pBuf + sizeof(SK_I32), pLen,
8330 ((SK_U32) (-1)), NetIndex);
8331 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8332 *pLen = *pLen + sizeof(SK_I32);
8334 case SK_SET_SINGLE_VAR:
8335 ReturnCode = SkPnmiSetVar(pAC, IoC, Oid,
8336 (char *) pBuf + sizeof(SK_I32), pLen,
8337 ((SK_U32) (-1)), NetIndex);
8338 SK_PNMI_STORE_U32(pBuf, ReturnCode);
8339 *pLen = *pLen + sizeof(SK_I32);
8341 case SK_GET_FULL_MIB:
8342 ReturnCode = SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8344 case SK_PRESET_FULL_MIB:
8345 ReturnCode = SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8347 case SK_SET_FULL_MIB:
8348 ReturnCode = SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex);
8354 return (ReturnCode);