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