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