1 /*****************************************************************************
4 * Project: GEnesis, PCI Gigabit Ethernet Adapter
5 * Version: $Revision: 1.102 $
6 * Date: $Date: 2002/12/16 14:03:24 $
7 * Purpose: Private Network Management Interface
9 ****************************************************************************/
11 /******************************************************************************
13 * (C)Copyright 1998-2002 SysKonnect GmbH.
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.
20 * The information in this file is provided "AS IS" without warranty.
22 ******************************************************************************/
24 /*****************************************************************************
28 * $Log: skgepnmi.c,v $
29 * Revision 1.102 2002/12/16 14:03:24 tschilli
30 * VCT code in Vct() changed.
32 * Revision 1.101 2002/12/16 09:04:10 tschilli
33 * Code for VCT handling added.
35 * Revision 1.100 2002/09/26 14:28:13 tschilli
36 * For XMAC the values in the SK_PNMI_PORT Port struct are copied to
37 * the new SK_PNMI_PORT BufPort struct during a MacUpdate() call.
38 * These values are used when GetPhysStatVal() is called. With this
39 * mechanism you get the best results when software corrections for
40 * counters are needed. Example: RX_LONGFRAMES.
42 * Revision 1.99 2002/09/17 12:31:19 tschilli
43 * OID_SKGE_TX_HW_ERROR_CTS, OID_SKGE_OUT_ERROR_CTS, OID_GEN_XMIT_ERROR:
44 * Double count of SK_PNMI_HTX_EXCESS_COL in function General() removed.
45 * OID_PNP_CAPABILITIES: sizeof(SK_PM_WAKE_UP_CAPABILITIES) changed to
46 * sizeof(SK_PNP_CAPABILITIES) in function PowerManagement().
48 * Revision 1.98 2002/09/10 09:00:03 rwahl
49 * Adapted boolean definitions according sktypes.
51 * Revision 1.97 2002/09/05 15:07:03 rwahl
54 * Revision 1.96 2002/09/05 11:04:14 rwahl
55 * - Rx/Tx packets statistics of virtual port were zero on link down (#10750)
56 * - For GMAC the overflow IRQ for Rx longframe counter was not counted.
57 * - Incorrect calculation for oids OID_SKGE_RX_HW_ERROR_CTS,
58 * OID_SKGE_IN_ERRORS_CTS, OID_GEN_RCV_ERROR.
59 * - Moved correction for OID_SKGE_STAT_RX_TOO_LONG to GetPhysStatVal().
60 * - Editorial changes.
62 * Revision 1.95 2002/09/04 08:53:37 rwahl
63 * - Incorrect statistics for Rx_too_long counter with jumbo frame (#10751)
64 * - StatRxFrameTooLong & StatRxPMaccErr counters were not reset.
65 * - Fixed compiler warning for debug msg arg types.
67 * Revision 1.94 2002/08/09 15:42:14 rwahl
68 * - Fixed StatAddr table for GMAC.
69 * - VirtualConf(): returned indeterminated status for speed oids if no
72 * Revision 1.93 2002/08/09 11:04:59 rwahl
73 * Added handler for link speed caps.
75 * Revision 1.92 2002/08/09 09:43:03 rwahl
76 * - Added handler for NDIS OID_PNP_xxx ids.
78 * Revision 1.91 2002/07/17 19:53:03 rwahl
79 * - Added StatOvrflwBit table for XMAC & GMAC.
80 * - Extended StatAddr table for GMAC. Added check of number of counters
81 * in enumeration and size of StatAddr table on init level.
82 * - Added use of GIFunc table.
83 * - ChipSet is not static anymore,
84 * - Extended SIRQ event handler for both mac types.
85 * - Fixed rx short counter bug (#10620)
86 * - Added handler for oids SKGE_SPEED_MODE & SKGE_SPEED_STATUS.
87 * - Extendet GetPhysStatVal() for GMAC.
88 * - Editorial changes.
90 * Revision 1.90 2002/05/22 08:56:25 rwahl
91 * - Moved OID table to separate source file.
92 * - Fix: TX_DEFFERAL counter incremented in full-duplex mode.
93 * - Use string definitions for error msgs.
95 * Revision 1.89 2001/09/18 10:01:30 mkunz
96 * some OID's fixed for dualnetmode
98 * Revision 1.88 2001/08/02 07:58:08 rwahl
99 * - Fixed NetIndex to csum module at ResetCounter().
101 * Revision 1.87 2001/04/06 13:35:09 mkunz
102 * -Bugs fixed in handling of OID_SKGE_MTU and the VPD OID's
104 * Revision 1.86 2001/03/09 09:18:03 mkunz
105 * Changes in SK_DBG_MSG
107 * Revision 1.85 2001/03/08 09:37:31 mkunz
108 * Bugfix in ResetCounter for Pnmi.Port structure
110 * Revision 1.84 2001/03/06 09:04:55 mkunz
111 * Made some changes in instance calculation
113 * Revision 1.83 2001/02/15 09:15:32 mkunz
114 * Necessary changes for dual net mode added
116 * Revision 1.82 2001/02/07 08:24:19 mkunz
117 * -Made changes in handling of OID_SKGE_MTU
119 * Revision 1.81 2001/02/06 09:58:00 mkunz
121 * -OID_SKGE_MTU added
122 * -pnmi support for dual net mode. Interface function and macros extended
124 * Revision 1.80 2001/01/22 13:41:35 rassmann
125 * Supporting two nets on dual-port adapters.
127 * Revision 1.79 2000/12/05 14:57:40 cgoos
128 * SetStruct failed before first Link Up (link mode of virtual
129 * port "INDETERMINATED").
131 * Revision 1.78 2000/09/12 10:44:58 cgoos
132 * Fixed SK_PNMI_STORE_U32 calls with typecasted argument.
134 * Revision 1.77 2000/09/07 08:10:19 rwahl
135 * - Modified algorithm for 64bit NDIS statistic counters;
136 * returns 64bit or 32bit value depending on passed buffer
137 * size. Indicate capability for 64bit NDIS counter, if passed
138 * buffer size is zero. OID_GEN_XMIT_ERROR, OID_GEN_RCV_ERROR,
139 * and OID_GEN_RCV_NO_BUFFER handled as 64bit counter, too.
140 * - corrected OID_SKGE_RLMT_PORT_PREFERRED.
142 * Revision 1.76 2000/08/03 15:23:39 rwahl
143 * - Correction for FrameTooLong counter has to be moved to OID handling
144 * routines (instead of statistic counter routine).
145 * - Fix in XMAC Reset Event handling: Only offset counter for hardware
146 * statistic registers are updated.
148 * Revision 1.75 2000/08/01 16:46:05 rwahl
149 * - Added StatRxLongFrames counter and correction of FrameTooLong counter.
150 * - Added directive to control width (default = 32bit) of NDIS statistic
151 * counters (SK_NDIS_64BIT_CTR).
153 * Revision 1.74 2000/07/04 11:41:53 rwahl
154 * - Added volition connector type.
156 * Revision 1.73 2000/03/15 16:33:10 rwahl
157 * Fixed bug 10510; wrong reset of virtual port statistic counters.
159 * Revision 1.72 1999/12/06 16:15:53 rwahl
160 * Fixed problem of instance range for current and factory MAC address.
162 * Revision 1.71 1999/12/06 10:14:20 rwahl
163 * Fixed bug 10476; set operation for PHY_OPERATION_MODE.
165 * Revision 1.70 1999/11/22 13:33:34 cgoos
166 * Changed license header to GPL.
168 * Revision 1.69 1999/10/18 11:42:15 rwahl
169 * Added typecasts for checking event dependent param (debug only).
171 * Revision 1.68 1999/10/06 09:35:59 cgoos
172 * Added state check to PHY_READ call (hanged if called during startup).
174 * Revision 1.67 1999/09/22 09:53:20 rwahl
175 * - Read Broadcom register for updating fcs error counter (1000Base-T).
177 * Revision 1.66 1999/08/26 13:47:56 rwahl
178 * Added SK_DRIVER_SENDEVENT when queueing RLMT_CHANGE_THRES trap.
180 * Revision 1.65 1999/07/26 07:49:35 cgoos
181 * Added two typecasts to avoid compiler warnings.
183 * Revision 1.64 1999/05/20 09:24:12 cgoos
184 * Changes for 1000Base-T (sensors, Master/Slave).
186 * Revision 1.63 1999/04/13 15:11:58 mhaveman
187 * Moved include of rlmt.h to header skgepnmi.h because some macros
190 * Revision 1.62 1999/04/13 15:08:07 mhaveman
191 * Replaced again SK_RLMT_CHECK_LINK with SK_PNMI_RLMT_MODE_CHK_LINK
192 * to grant unified interface by only using the PNMI header file.
193 * SK_PNMI_RLMT_MODE_CHK_LINK is defined the same as SK_RLMT_CHECK_LINK.
195 * Revision 1.61 1999/04/13 15:02:48 mhaveman
196 * Changes caused by review:
197 * -Changed some comments
198 * -Removed redundant check for OID_SKGE_PHYS_FAC_ADDR
199 * -Optimized PRESET check.
200 * -Meaning of error SK_ADDR_DUPLICATE_ADDRESS changed. Set of same
201 * address will now not cause this error. Removed corresponding check.
203 * Revision 1.60 1999/03/23 10:41:23 mhaveman
206 * Revision 1.59 1999/02/19 08:01:28 mhaveman
207 * Fixed bug 10372 that after counter reset all ports were displayed
210 * Revision 1.58 1999/02/16 18:04:47 mhaveman
211 * Fixed problem of twisted OIDs SENSOR_WAR_TIME and SENSOR_ERR_TIME.
213 * Revision 1.56 1999/01/27 12:29:11 mhaveman
214 * SkTimerStart was called with time value in milli seconds but needs
217 * Revision 1.55 1999/01/25 15:00:38 mhaveman
218 * Added support to allow multiple ports to be active. If this feature in
219 * future will be used, the Management Data Base variables PORT_ACTIVE
220 * and PORT_PREFERED should be moved to the port specific part of RLMT.
221 * Currently they return the values of the first active physical port
222 * found. A set to the virtual port will actually change all active
223 * physical ports. A get returns the melted values of all active physical
224 * ports. If the port values differ a return value INDETERMINATED will
225 * be returned. This effects especially the CONF group.
227 * Revision 1.54 1999/01/19 10:10:22 mhaveman
228 * -Fixed bug 10354: Counter values of virtual port were wrong after port
230 * -Added check if a switch to the same port is notified.
232 * Revision 1.53 1999/01/07 09:25:21 mhaveman
233 * Forgot to initialize a variable.
235 * Revision 1.52 1999/01/05 10:34:33 mhaveman
236 * Fixed little error in RlmtChangeEstimate calculation.
238 * Revision 1.51 1999/01/05 09:59:07 mhaveman
239 * -Moved timer start to init level 2
240 * -Redesigned port switch average calculation to avoid 64bit
243 * Revision 1.50 1998/12/10 15:13:59 mhaveman
244 * -Fixed: PHYS_CUR_ADDR returned wrong addresses
245 * -Fixed: RLMT_PORT_PREFERED and RLMT_CHANGE_THRES preset returned
247 * -Fixed: TRAP buffer seemed to sometimes suddenly empty
249 * Revision 1.49 1998/12/09 16:17:07 mhaveman
250 * Fixed: Couldnot delete VPD keys on UNIX.
252 * Revision 1.48 1998/12/09 14:11:10 mhaveman
253 * -Add: Debugmessage for XMAC_RESET supressed to minimize output.
254 * -Fixed: RlmtChangeThreshold will now be initialized.
255 * -Fixed: VPD_ENTRIES_LIST extended value with unnecessary space char.
256 * -Fixed: On VPD key creation an invalid key name could be created
258 * -Some minor changes in comments and code.
260 * Revision 1.47 1998/12/08 16:00:31 mhaveman
261 * -Fixed: For RLMT_PORT_ACTIVE will now be returned a 0 if no port
263 * -Fixed: For the RLMT statistics group only the last value was
264 * returned and the rest of the buffer was filled with 0xff
265 * -Fixed: Mysteriously the preset on RLMT_MODE still returned
267 * Revision 1.46 1998/12/08 10:04:56 mhaveman
268 * -Fixed: Preset on RLMT_MODE returned always BAD_VALUE error.
269 * -Fixed: Alignment error in GetStruct
270 * -Fixed: If for Get/Preset/SetStruct the buffer size is equal or
271 * larger than SK_PNMI_MIN_STRUCT_SIZE the return value is stored
272 * to the buffer. In this case the caller should always return
273 * ok to its upper routines. Only if the buffer size is less
274 * than SK_PNMI_MIN_STRUCT_SIZE and the return value is unequal
275 * to 0, an error should be returned by the caller.
276 * -Fixed: Wrong number of instances with RLMT statistic.
277 * -Fixed: Return now SK_LMODE_STAT_UNKNOWN if the LinkModeStatus is 0.
279 * Revision 1.45 1998/12/03 17:17:24 mhaveman
280 * -Removed for VPD create action the buffer size limitation to 4 bytes.
281 * -Pass now physical/active physical port to ADDR for CUR_ADDR set
283 * Revision 1.44 1998/12/03 15:14:35 mhaveman
284 * Another change to Vpd instance evaluation.
286 * Revision 1.43 1998/12/03 14:18:10 mhaveman
287 * -Fixed problem in PnmiSetStruct. It was impossible to set any value.
288 * -Removed VPD key evaluation for VPD_FREE_BYTES and VPD_ACTION.
290 * Revision 1.42 1998/12/03 11:31:47 mhaveman
291 * Inserted cast to satisfy lint.
293 * Revision 1.41 1998/12/03 11:28:16 mhaveman
294 * Removed SK_PNMI_CHECKPTR
296 * Revision 1.40 1998/12/03 11:19:07 mhaveman
298 * -A set to virtual port will now be ignored. A set with broadcast
299 * address to any port will be ignored.
300 * -GetStruct function made VPD instance calculation wrong.
301 * -Prefered port returned -1 instead of 0.
303 * Revision 1.39 1998/11/26 15:30:29 mhaveman
304 * Added sense mode to link mode.
306 * Revision 1.38 1998/11/23 15:34:00 mhaveman
307 * -Fixed bug for RX counters. On an RX overflow interrupt the high
308 * words of all RX counters were incremented.
309 * -SET operations on FLOWCTRL_MODE and LINK_MODE accept now the
310 * value 0, which has no effect. It is usefull for multiple instance
313 * Revision 1.37 1998/11/20 08:02:04 mhaveman
314 * -Fixed: Ports were compared with MAX_SENSORS
315 * -Fixed: Crash in GetTrapEntry with MEMSET macro
316 * -Fixed: Conversions between physical, logical port index and instance
318 * Revision 1.36 1998/11/16 07:48:53 mhaveman
319 * Casted SK_DRIVER_SENDEVENT with (void) to eleminate compiler warnings
322 * Revision 1.35 1998/11/16 07:45:34 mhaveman
323 * SkAddrOverride now returns value and will be checked.
325 * Revision 1.34 1998/11/10 13:40:37 mhaveman
326 * Needed to change interface, because NT driver needs a return value
327 * of needed buffer space on TOO_SHORT errors. Therefore all
328 * SkPnmiGet/Preset/Set functions now have a pointer to the length
329 * parameter, where the needed space on error is returned.
331 * Revision 1.33 1998/11/03 13:52:46 mhaveman
332 * Made file lint conform.
334 * Revision 1.32 1998/11/03 13:19:07 mhaveman
335 * The events SK_HWEV_SET_LMODE and SK_HWEV_SET_FLOWMODE pass now in
336 * Para32[0] the physical MAC index and in Para32[1] the new mode.
338 * Revision 1.31 1998/11/03 12:30:40 gklug
339 * fix: compiler warning memset
341 * Revision 1.30 1998/11/03 12:04:46 mhaveman
342 * Fixed problem in SENSOR_VALUE, which wrote beyond the buffer end
343 * Fixed alignment problem with CHIPSET.
345 * Revision 1.29 1998/11/02 11:23:54 mhaveman
346 * Corrected SK_ERROR_LOG to SK_ERR_LOG. Sorry.
348 * Revision 1.28 1998/11/02 10:47:16 mhaveman
349 * Added syslog messages for internal errors.
351 * Revision 1.27 1998/10/30 15:48:06 mhaveman
352 * Fixed problems after simulation of SK_PNMI_EVT_CHG_EST_TIMER and
353 * RlmtChangeThreshold calculation.
355 * Revision 1.26 1998/10/29 15:36:55 mhaveman
356 * -Fixed bug in trap buffer handling.
357 * -OID_SKGE_DRIVER_DESCR, OID_SKGE_DRIVER_VERSION, OID_SKGE_HW_DESCR,
358 * OID_SKGE_HW_VERSION, OID_SKGE_VPD_ENTRIES_LIST, OID_SKGE_VPD_KEY,
359 * OID_SKGE_VPD_VALUE, and OID_SKGE_SENSOR_DESCR return values with
360 * a leading octet before each string storing the string length.
361 * -Perform a RlmtUpdate during SK_PNMI_EVT_XMAC_RESET to minimize
362 * RlmtUpdate calls in GetStatVal.
363 * -Inserted SK_PNMI_CHECKFLAGS macro increase readability.
365 * Revision 1.25 1998/10/29 08:50:36 mhaveman
366 * Fixed problems after second event simulation.
368 * Revision 1.24 1998/10/28 08:44:37 mhaveman
369 * -Fixed alignment problem
370 * -Fixed problems during event simulation
371 * -Fixed sequence of error return code (INSTANCE -> ACCESS -> SHORT)
372 * -Changed type of parameter Instance back to SK_U32 because of VPD
373 * -Updated new VPD function calls
375 * Revision 1.23 1998/10/23 10:16:37 mhaveman
376 * Fixed bugs after buffer test simulation.
378 * Revision 1.22 1998/10/21 13:23:52 mhaveman
379 * -Call syntax of SkOsGetTime() changed to SkOsGetTime(pAc).
380 * -Changed calculation of hundrets of seconds.
382 * Revision 1.20 1998/10/20 07:30:45 mhaveman
383 * Made type changes to unsigned integer where possible.
385 * Revision 1.19 1998/10/19 10:51:30 mhaveman
386 * -Made Bug fixes after simulation run
387 * -Renamed RlmtMAC... to RlmtPort...
388 * -Marked workarounds with Errata comments
390 * Revision 1.18 1998/10/14 07:50:08 mhaveman
391 * -For OID_SKGE_LINK_STATUS the link down detection has moved from RLMT
393 * -Provided all MEMCPY/MEMSET macros with (char *) pointers, because
394 * Solaris throwed warnings when mapping to bcopy/bset.
396 * Revision 1.17 1998/10/13 07:42:01 mhaveman
397 * -Added OIDs OID_SKGE_TRAP_NUMBER and OID_SKGE_ALL_DATA
398 * -Removed old cvs history entries
399 * -Renamed MacNumber to PortNumber
401 * Revision 1.16 1998/10/07 10:52:49 mhaveman
402 * -Inserted handling of some OID_GEN_ Ids for windows
403 * -Fixed problem with 803.2 statistic.
405 * Revision 1.15 1998/10/01 09:16:29 mhaveman
406 * Added Debug messages for function call and UpdateFlag tracing.
408 * Revision 1.14 1998/09/30 13:39:09 mhaveman
409 * -Reduced namings of 'MAC' by replacing them with 'PORT'.
410 * -Completed counting of OID_SKGE_RX_HW_ERROR_CTS,
411 * OID_SKGE_TX_HW_ERROR_CTS,
412 * OID_SKGE_IN_ERRORS_CTS, and OID_SKGE_OUT_ERROR_CTS.
413 * -SET check for RlmtMode
415 * Revision 1.13 1998/09/28 13:13:08 mhaveman
416 * Hide strcmp, strlen, and strncpy behind macros SK_STRCMP, SK_STRLEN,
417 * and SK_STRNCPY. (Same reasons as for mem.. and MEM..)
419 * Revision 1.12 1998/09/16 08:18:36 cgoos
420 * Fix: XM_INxx and XM_OUTxx called with different parameter order:
421 * sometimes IoC,Mac,... sometimes Mac,IoC,... Now always first variant.
422 * Fix: inserted "Pnmi." into some pAC->pDriverDescription / Version.
423 * Change: memset, memcpy to makros SK_MEMSET, SK_MEMCPY
425 * Revision 1.11 1998/09/04 17:01:45 mhaveman
426 * Added SyncCounter as macro and OID_SKGE_.._NO_DESCR_CTS to
427 * OID_SKGE_RX_NO_BUF_CTS.
429 * Revision 1.10 1998/09/04 14:35:35 mhaveman
430 * Added macro counters, that are counted by driver.
432 ****************************************************************************/
437 static const char SysKonnectFileId[] =
438 "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
441 #include "h/skdrv1st.h"
442 #include "h/sktypes.h"
443 #include "h/xmac_ii.h"
444 #include "h/skdebug.h"
445 #include "h/skqueue.h"
446 #include "h/skgepnmi.h"
447 #include "h/skgesirq.h"
448 #include "h/skcsum.h"
450 #include "h/skgehw.h"
451 #include "h/skgeinit.h"
452 #include "h/skdrv2nd.h"
453 #include "h/skgepnm2.h"
455 #include "h/skgepmgt.h"
457 /* defines *******************************************************************/
460 #define PNMI_STATIC static
466 * Public Function prototypes
468 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
469 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
470 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
471 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
472 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
473 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
474 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
475 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
476 unsigned int *pLen, SK_U32 NetIndex);
477 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
478 unsigned int *pLen, SK_U32 NetIndex);
479 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
480 unsigned int *pLen, SK_U32 NetIndex);
481 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
485 * Private Function prototypes
488 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
490 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
492 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
493 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
494 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
495 unsigned int PhysPortIndex, unsigned int StatIndex);
496 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
497 unsigned int StatIndex, SK_U32 NetIndex);
498 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
499 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
500 unsigned int *pEntries);
501 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
502 unsigned int KeyArrLen, unsigned int *pKeyNo);
503 PNMI_STATIC int LookupId(SK_U32 Id);
504 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
505 unsigned int LastMac);
506 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
507 unsigned int *pLen, SK_U32 NetIndex);
508 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
509 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
510 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
511 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
512 unsigned int PortIndex);
513 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
514 unsigned int SensorIndex);
515 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
516 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
517 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
518 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
519 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
520 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
521 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
522 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
525 * Table to correlate OID with handler function and index to
526 * hardware register stored in StatAddress if applicable.
530 /* global variables **********************************************************/
533 * Overflow status register bit table and corresponding counter
534 * dependent on MAC type - the number relates to the size of overflow
535 * mask returned by the pFnMacOverflow function
537 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
538 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
539 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
540 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
541 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
542 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
543 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
544 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
545 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
546 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
547 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
548 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
549 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
550 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
551 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
552 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
553 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
554 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
555 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
556 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
557 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
558 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
559 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
560 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
561 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
562 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
563 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
564 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
565 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
566 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
567 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
568 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
569 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
570 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
571 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
572 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
573 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
574 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
575 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
576 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
577 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
578 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
579 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
580 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
581 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
582 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
583 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
584 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
585 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
586 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
587 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
588 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
589 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
590 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
591 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
592 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
593 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
594 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
595 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
596 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
597 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
598 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
599 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
600 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
601 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
605 * Table for hardware register saving on resets and port switches
607 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
609 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
610 /* SK_PNMI_HTX_OCTETHIGH */
611 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
612 /* SK_PNMI_HTX_OCTETLOW */
613 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
614 /* SK_PNMI_HTX_BROADCAST */
615 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
616 /* SK_PNMI_HTX_MULTICAST */
617 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
618 /* SK_PNMI_HTX_UNICAST */
619 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
620 /* SK_PNMI_HTX_BURST */
621 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
622 /* SK_PNMI_HTX_PMACC */
623 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
624 /* SK_PNMI_HTX_MACC */
625 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
626 /* SK_PNMI_HTX_COL */
627 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
628 /* SK_PNMI_HTX_SINGLE_COL */
629 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
630 /* SK_PNMI_HTX_MULTI_COL */
631 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
632 /* SK_PNMI_HTX_EXCESS_COL */
633 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
634 /* SK_PNMI_HTX_LATE_COL */
635 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
636 /* SK_PNMI_HTX_DEFFERAL */
637 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
638 /* SK_PNMI_HTX_EXCESS_DEF */
639 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
640 /* SK_PNMI_HTX_UNDERRUN */
641 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
642 /* SK_PNMI_HTX_CARRIER */
643 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
644 /* SK_PNMI_HTX_UTILUNDER */
645 {{0, SK_FALSE}, {0, SK_FALSE}},
646 /* SK_PNMI_HTX_UTILOVER */
647 {{0, SK_FALSE}, {0, SK_FALSE}},
649 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
650 /* SK_PNMI_HTX_127 */
651 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
652 /* SK_PNMI_HTX_255 */
653 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
654 /* SK_PNMI_HTX_511 */
655 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
656 /* SK_PNMI_HTX_1023 */
657 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
658 /* SK_PNMI_HTX_MAX */
659 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
660 /* SK_PNMI_HTX_LONGFRAMES */
661 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
662 /* SK_PNMI_HTX_SYNC */
663 {{0, SK_FALSE}, {0, SK_FALSE}},
664 /* SK_PNMI_HTX_SYNC_OCTET */
665 {{0, SK_FALSE}, {0, SK_FALSE}},
666 /* SK_PNMI_HTX_RESERVED */
667 {{0, SK_FALSE}, {0, SK_FALSE}},
669 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
670 /* SK_PNMI_HRX_OCTETHIGH */
671 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
672 /* SK_PNMI_HRX_OCTETLOW */
673 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
674 /* SK_PNMI_HRX_BADOCTETHIGH */
675 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
676 /* SK_PNMI_HRX_BADOCTETLOW */
677 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
678 /* SK_PNMI_HRX_BROADCAST */
679 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
680 /* SK_PNMI_HRX_MULTICAST */
681 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
682 /* SK_PNMI_HRX_UNICAST */
683 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
684 /* SK_PNMI_HRX_PMACC */
685 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
686 /* SK_PNMI_HRX_MACC */
687 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
688 /* SK_PNMI_HRX_PMACC_ERR */
689 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
690 /* SK_PNMI_HRX_MACC_UNKWN */
691 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
692 /* SK_PNMI_HRX_BURST */
693 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
694 /* SK_PNMI_HRX_MISSED */
695 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
696 /* SK_PNMI_HRX_FRAMING */
697 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
698 /* SK_PNMI_HRX_UNDERSIZE */
699 {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
700 /* SK_PNMI_HRX_OVERFLOW */
701 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
702 /* SK_PNMI_HRX_JABBER */
703 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
704 /* SK_PNMI_HRX_CARRIER */
705 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
706 /* SK_PNMI_HRX_IRLENGTH */
707 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
708 /* SK_PNMI_HRX_SYMBOL */
709 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
710 /* SK_PNMI_HRX_SHORTS */
711 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
712 /* SK_PNMI_HRX_RUNT */
713 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
714 /* SK_PNMI_HRX_TOO_LONG */
715 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
716 /* SK_PNMI_HRX_FCS */
717 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
718 /* SK_PNMI_HRX_CEXT */
719 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
720 /* SK_PNMI_HRX_UTILUNDER */
721 {{0, SK_FALSE}, {0, SK_FALSE}},
722 /* SK_PNMI_HRX_UTILOVER */
723 {{0, SK_FALSE}, {0, SK_FALSE}},
725 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
726 /* SK_PNMI_HRX_127 */
727 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
728 /* SK_PNMI_HRX_255 */
729 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
730 /* SK_PNMI_HRX_511 */
731 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
732 /* SK_PNMI_HRX_1023 */
733 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
734 /* SK_PNMI_HRX_MAX */
735 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
736 /* SK_PNMI_HRX_LONGFRAMES */
737 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
738 /* SK_PNMI_HRX_RESERVED */
739 {{0, SK_FALSE}, {0, SK_FALSE}}
743 /*****************************************************************************
749 /*****************************************************************************
751 * SkPnmiInit - Init function of PNMI
754 * SK_INIT_DATA: Initialises the data structures
755 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
757 * SK_INIT_RUN: Starts a timer event for port switch per hour
764 SK_AC *pAC, /* Pointer to adapter context */
765 SK_IOC IoC, /* IO context handle */
766 int Level) /* Initialization level */
768 unsigned int PortMax; /* Number of ports */
769 unsigned int PortIndex; /* Current port index in loop */
770 SK_U16 Val16; /* Multiple purpose 16 bit variable */
771 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
772 SK_EVPARA EventParam; /* Event struct for timer event */
774 SK_PNMI_VCT *pVctBackupData;
777 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
778 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
783 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
784 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
785 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
786 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
787 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
789 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
790 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
794 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
796 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
798 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
799 ("CounterOffset struct size (%d) differs from"
800 "SK_PNMI_MAX_IDX (%d)\n",
801 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
805 if (SK_PNMI_MAX_IDX !=
806 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
808 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
810 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
811 ("StatAddr table size (%d) differs from "
812 "SK_PNMI_MAX_IDX (%d)\n",
814 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
818 #endif /* SK_PNMI_CHECK */
825 PortMax = pAC->GIni.GIMacsFound;
827 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
829 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
832 /* Initialize DSP variables for Vct() to 0xff => Never written! */
833 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
834 pPrt = &pAC->GIni.GP[PortIndex];
835 pPrt->PCableLen =0xff;
836 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
837 pVctBackupData->PCableLen = 0xff;
843 SK_IN16(IoC, B0_CTST, &Val16);
844 if ((Val16 & CS_BUS_CLOCK) == 0) {
846 pAC->Pnmi.PciBusSpeed = 33;
849 pAC->Pnmi.PciBusSpeed = 66;
855 SK_IN16(IoC, B0_CTST, &Val16);
856 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
858 pAC->Pnmi.PciBusWidth = 32;
861 pAC->Pnmi.PciBusWidth = 64;
867 switch (pAC->GIni.GIChipId) {
868 case CHIP_ID_GENESIS:
869 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
873 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
881 * Get PMD and DeviceType
883 SK_IN8(IoC, B2_PMD_TYP, &Val8);
887 if (pAC->GIni.GIMacsFound > 1) {
889 pAC->Pnmi.DeviceType = 0x00020002;
892 pAC->Pnmi.DeviceType = 0x00020001;
898 if (pAC->GIni.GIMacsFound > 1) {
900 pAC->Pnmi.DeviceType = 0x00020004;
903 pAC->Pnmi.DeviceType = 0x00020003;
909 if (pAC->GIni.GIMacsFound > 1) {
911 pAC->Pnmi.DeviceType = 0x00020006;
914 pAC->Pnmi.DeviceType = 0x00020005;
920 if (pAC->GIni.GIMacsFound > 1) {
922 pAC->Pnmi.DeviceType = 0x00020008;
925 pAC->Pnmi.DeviceType = 0x00020007;
931 pAC->Pnmi.DeviceType = 0;
938 SK_IN8(IoC, B2_CONN_TYP, &Val8);
941 pAC->Pnmi.Connector = 2;
945 pAC->Pnmi.Connector = 3;
949 pAC->Pnmi.Connector = 4;
953 pAC->Pnmi.Connector = 5;
957 pAC->Pnmi.Connector = 6;
961 pAC->Pnmi.Connector = 1;
968 * Start timer for RLMT change counter
970 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
971 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
972 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
977 break; /* Nothing todo */
983 /*****************************************************************************
985 * SkPnmiGetVar - Retrieves the value of a single OID
988 * Calls a general sub-function for all this stuff. If the instance
989 * -1 is passed, the values of all instances are returned in an
993 * SK_PNMI_ERR_OK The request was successfully performed
994 * SK_PNMI_ERR_GENERAL A general severe internal error occured
995 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
997 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
998 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
999 * exist (e.g. port instance 3 on a two port
1003 SK_AC *pAC, /* Pointer to adapter context */
1004 SK_IOC IoC, /* IO context handle */
1005 SK_U32 Id, /* Object ID that is to be processed */
1006 void *pBuf, /* Buffer to which to mgmt data will be retrieved */
1007 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1008 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1009 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1011 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1012 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1013 Id, *pLen, Instance, NetIndex));
1015 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1016 Instance, NetIndex));
1019 /*****************************************************************************
1021 * SkPnmiPreSetVar - Presets the value of a single OID
1024 * Calls a general sub-function for all this stuff. The preset does
1025 * the same as a set, but returns just before finally setting the
1026 * new value. This is usefull to check if a set might be successfull.
1027 * If as instance a -1 is passed, an array of values is supposed and
1028 * all instance of the OID will be set.
1031 * SK_PNMI_ERR_OK The request was successfully performed.
1032 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1033 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1034 * the correct data (e.g. a 32bit value is
1035 * needed, but a 16 bit value was passed).
1036 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1038 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1039 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1040 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1041 * exist (e.g. port instance 3 on a two port
1044 int SkPnmiPreSetVar(
1045 SK_AC *pAC, /* Pointer to adapter context */
1046 SK_IOC IoC, /* IO context handle */
1047 SK_U32 Id, /* Object ID that is to be processed */
1048 void *pBuf, /* Buffer which stores the mgmt data to be set */
1049 unsigned int *pLen, /* Total length of mgmt data */
1050 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1051 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1053 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1054 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1055 Id, *pLen, Instance, NetIndex));
1058 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1059 Instance, NetIndex));
1062 /*****************************************************************************
1064 * SkPnmiSetVar - Sets the value of a single OID
1067 * Calls a general sub-function for all this stuff. The preset does
1068 * the same as a set, but returns just before finally setting the
1069 * new value. This is usefull to check if a set might be successfull.
1070 * If as instance a -1 is passed, an array of values is supposed and
1071 * all instance of the OID will be set.
1074 * SK_PNMI_ERR_OK The request was successfully performed.
1075 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1076 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1077 * the correct data (e.g. a 32bit value is
1078 * needed, but a 16 bit value was passed).
1079 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1081 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1082 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1083 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1084 * exist (e.g. port instance 3 on a two port
1088 SK_AC *pAC, /* Pointer to adapter context */
1089 SK_IOC IoC, /* IO context handle */
1090 SK_U32 Id, /* Object ID that is to be processed */
1091 void *pBuf, /* Buffer which stores the mgmt data to be set */
1092 unsigned int *pLen, /* Total length of mgmt data */
1093 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1094 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1096 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1097 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1098 Id, *pLen, Instance, NetIndex));
1100 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1101 Instance, NetIndex));
1104 /*****************************************************************************
1106 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1109 * Runs through the IdTable, queries the single OIDs and stores the
1110 * returned data into the management database structure
1111 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1112 * is stored in the IdTable. The return value of the function will also
1113 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1114 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1117 * SK_PNMI_ERR_OK The request was successfully performed
1118 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1119 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1121 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1123 int SkPnmiGetStruct(
1124 SK_AC *pAC, /* Pointer to adapter context */
1125 SK_IOC IoC, /* IO context handle */
1126 void *pBuf, /* Buffer which will store the retrieved data */
1127 unsigned int *pLen, /* Length of buffer */
1128 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1131 unsigned int TableIndex;
1132 unsigned int DstOffset;
1133 unsigned int InstanceNo;
1134 unsigned int InstanceCnt;
1136 unsigned int TmpLen;
1137 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1140 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1141 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1144 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1146 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1148 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1152 *pLen = SK_PNMI_STRUCT_SIZE;
1153 return (SK_PNMI_ERR_TOO_SHORT);
1159 if (NetIndex >= pAC->Rlmt.NumNets) {
1160 return (SK_PNMI_ERR_UNKNOWN_NET);
1163 /* Update statistic */
1164 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1166 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1169 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1170 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1174 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1176 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1177 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1181 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1183 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1184 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1189 * Increment semaphores to indicate that an update was
1192 pAC->Pnmi.MacUpdatedFlag ++;
1193 pAC->Pnmi.RlmtUpdatedFlag ++;
1194 pAC->Pnmi.SirqUpdatedFlag ++;
1196 /* Get vpd keys for instance calculation */
1197 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1198 if (Ret != SK_PNMI_ERR_OK) {
1200 pAC->Pnmi.MacUpdatedFlag --;
1201 pAC->Pnmi.RlmtUpdatedFlag --;
1202 pAC->Pnmi.SirqUpdatedFlag --;
1204 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1205 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1206 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1207 return (SK_PNMI_ERR_GENERAL);
1210 /* Retrieve values */
1211 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1212 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1214 InstanceNo = IdTable[TableIndex].InstanceNo;
1215 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1218 DstOffset = IdTable[TableIndex].Offset +
1220 IdTable[TableIndex].StructSize;
1223 * For the VPD the instance is not an index number
1224 * but the key itself. Determin with the instance
1225 * counter the VPD key to be used.
1227 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1228 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1229 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1230 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1232 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1235 Instance = (SK_U32)InstanceCnt;
1238 TmpLen = *pLen - DstOffset;
1239 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1240 IdTable[TableIndex].Id, (char *)pBuf +
1241 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1244 * An unknown instance error means that we reached
1245 * the last instance of that variable. Proceed with
1246 * the next OID in the table and ignore the return
1249 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1254 if (Ret != SK_PNMI_ERR_OK) {
1256 pAC->Pnmi.MacUpdatedFlag --;
1257 pAC->Pnmi.RlmtUpdatedFlag --;
1258 pAC->Pnmi.SirqUpdatedFlag --;
1260 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1261 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1262 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1268 pAC->Pnmi.MacUpdatedFlag --;
1269 pAC->Pnmi.RlmtUpdatedFlag --;
1270 pAC->Pnmi.SirqUpdatedFlag --;
1272 *pLen = SK_PNMI_STRUCT_SIZE;
1273 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1274 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1275 return (SK_PNMI_ERR_OK);
1278 /*****************************************************************************
1280 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1283 * Calls a general sub-function for all this set stuff. The preset does
1284 * the same as a set, but returns just before finally setting the
1285 * new value. This is usefull to check if a set might be successfull.
1286 * The sub-function runs through the IdTable, checks which OIDs are able
1287 * to set, and calls the handler function of the OID to perform the
1288 * preset. The return value of the function will also be stored in
1289 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1290 * SK_PNMI_MIN_STRUCT_SIZE.
1293 * SK_PNMI_ERR_OK The request was successfully performed.
1294 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1295 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1296 * the correct data (e.g. a 32bit value is
1297 * needed, but a 16 bit value was passed).
1298 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1301 int SkPnmiPreSetStruct(
1302 SK_AC *pAC, /* Pointer to adapter context */
1303 SK_IOC IoC, /* IO context handle */
1304 void *pBuf, /* Buffer which contains the data to be set */
1305 unsigned int *pLen, /* Length of buffer */
1306 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1308 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1309 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1312 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1316 /*****************************************************************************
1318 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1321 * Calls a general sub-function for all this set stuff. The return value
1322 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1323 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1324 * The sub-function runs through the IdTable, checks which OIDs are able
1325 * to set, and calls the handler function of the OID to perform the
1326 * set. The return value of the function will also be stored in
1327 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1328 * SK_PNMI_MIN_STRUCT_SIZE.
1331 * SK_PNMI_ERR_OK The request was successfully performed.
1332 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1333 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1334 * the correct data (e.g. a 32bit value is
1335 * needed, but a 16 bit value was passed).
1336 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1339 int SkPnmiSetStruct(
1340 SK_AC *pAC, /* Pointer to adapter context */
1341 SK_IOC IoC, /* IO context handle */
1342 void *pBuf, /* Buffer which contains the data to be set */
1343 unsigned int *pLen, /* Length of buffer */
1344 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1346 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1347 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1350 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1354 /*****************************************************************************
1356 * SkPnmiEvent - Event handler
1359 * Handles the following events:
1360 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1361 * interrupt will be generated which is
1362 * first handled by SIRQ which generates a
1363 * this event. The event increments the
1364 * upper 32 bit of the 64 bit counter.
1365 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1366 * when a sensor reports a warning or
1367 * error. The event will store a trap
1368 * message in the trap buffer.
1369 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1370 * module and is used to calculate the
1371 * port switches per hour.
1372 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1374 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1375 * before a hard reset of the XMAC is
1376 * performed. All counters will be saved
1377 * and added to the hardware counter
1378 * values after reset to grant continuous
1380 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1381 * went logically up. A trap message will
1382 * be stored to the trap buffer.
1383 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1384 * went logically down. A trap message will
1385 * be stored to the trap buffer.
1386 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1387 * spanning tree root bridges were
1388 * detected. A trap message will be stored
1389 * to the trap buffer.
1390 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1391 * down. PNMI will not further add the
1392 * statistic values to the virtual port.
1393 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1394 * is now an active port. PNMI will now
1395 * add the statistic data of this port to
1397 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
1398 * contains the number of nets. 1 means single net, 2 means
1399 * dual net. The second Parameter is -1
1405 SK_AC *pAC, /* Pointer to adapter context */
1406 SK_IOC IoC, /* IO context handle */
1407 SK_U32 Event, /* Event-Id */
1408 SK_EVPARA Param) /* Event dependent parameter */
1410 unsigned int PhysPortIndex;
1411 unsigned int MaxNetNumber;
1415 SK_U64 OverflowStatus;
1421 SK_EVPARA EventParam;
1425 SK_PNMI_ESTIMATE *pEst;
1428 SK_PNMI_VCT *pVctBackupData;
1435 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1437 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1438 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1439 (unsigned int)Event, (unsigned int)Param.Para64));
1442 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1444 MacType = pAC->GIni.GIMacType;
1448 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1449 PhysPortIndex = (int)Param.Para32[0];
1450 MacStatus = (SK_U16)Param.Para32[1];
1452 if (PhysPortIndex >= SK_MAX_MACS) {
1454 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1455 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1456 " wrong, PhysPortIndex=0x%x\n",
1464 * Check which source caused an overflow interrupt.
1466 if ((pAC->GIni.GIFunc.pFnMacOverflow(
1467 pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
1468 (OverflowStatus == 0)) {
1470 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1475 * Check the overflow status register and increment
1476 * the upper dword of corresponding counter.
1478 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1481 Mask = (SK_U64)1 << CounterIndex;
1482 if ((OverflowStatus & Mask) == 0) {
1487 switch (StatOvrflwBit[CounterIndex][MacType]) {
1489 case SK_PNMI_HTX_UTILUNDER:
1490 case SK_PNMI_HTX_UTILOVER:
1491 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
1493 Register |= XM_TX_SAM_LINE;
1494 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
1498 case SK_PNMI_HRX_UTILUNDER:
1499 case SK_PNMI_HRX_UTILOVER:
1500 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
1502 Register |= XM_RX_SAM_LINE;
1503 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
1507 case SK_PNMI_HTX_OCTETHIGH:
1508 case SK_PNMI_HTX_OCTETLOW:
1509 case SK_PNMI_HTX_RESERVED:
1510 case SK_PNMI_HRX_OCTETHIGH:
1511 case SK_PNMI_HRX_OCTETLOW:
1512 case SK_PNMI_HRX_IRLENGTH:
1513 case SK_PNMI_HRX_RESERVED:
1516 * the following counters aren't be handled (id > 63)
1518 case SK_PNMI_HTX_SYNC:
1519 case SK_PNMI_HTX_SYNC_OCTET:
1522 case SK_PNMI_HRX_LONGFRAMES:
1523 if (MacType == SK_MAC_GMAC) {
1524 pAC->Pnmi.Port[PhysPortIndex].
1525 CounterHigh[CounterIndex] ++;
1530 pAC->Pnmi.Port[PhysPortIndex].
1531 CounterHigh[CounterIndex] ++;
1536 case SK_PNMI_EVT_SEN_WAR_LOW:
1538 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1540 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1541 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1542 (unsigned int)Param.Para64));
1547 * Store a trap message in the trap buffer and generate
1548 * an event for user space applications with the
1549 * SK_DRIVER_SENDEVENT macro.
1551 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1552 (unsigned int)Param.Para64);
1553 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1556 case SK_PNMI_EVT_SEN_WAR_UPP:
1558 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1560 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1561 ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1562 (unsigned int)Param.Para64));
1567 * Store a trap message in the trap buffer and generate
1568 * an event for user space applications with the
1569 * SK_DRIVER_SENDEVENT macro.
1571 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1572 (unsigned int)Param.Para64);
1573 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1576 case SK_PNMI_EVT_SEN_ERR_LOW:
1578 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1580 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1581 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1582 (unsigned int)Param.Para64));
1587 * Store a trap message in the trap buffer and generate
1588 * an event for user space applications with the
1589 * SK_DRIVER_SENDEVENT macro.
1591 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1592 (unsigned int)Param.Para64);
1593 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1596 case SK_PNMI_EVT_SEN_ERR_UPP:
1598 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1600 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1601 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1602 (unsigned int)Param.Para64));
1607 * Store a trap message in the trap buffer and generate
1608 * an event for user space applications with the
1609 * SK_DRIVER_SENDEVENT macro.
1611 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1612 (unsigned int)Param.Para64);
1613 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1616 case SK_PNMI_EVT_CHG_EST_TIMER:
1618 * Calculate port switch average on a per hour basis
1619 * Time interval for check : 28125 ms
1620 * Number of values for average : 8
1622 * Be careful in changing these values, on change check
1623 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1624 * array one less than value number)
1625 * - Timer initilization SkTimerStart() in SkPnmiInit
1626 * - Delta value below must be multiplicated with
1630 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1631 CounterIndex = pEst->EstValueIndex + 1;
1632 if (CounterIndex == 7) {
1636 pEst->EstValueIndex = CounterIndex;
1638 NewestValue = pAC->Pnmi.RlmtChangeCts;
1639 OldestValue = pEst->EstValue[CounterIndex];
1640 pEst->EstValue[CounterIndex] = NewestValue;
1643 * Calculate average. Delta stores the number of
1644 * port switches per 28125 * 8 = 225000 ms
1646 if (NewestValue >= OldestValue) {
1648 Delta = NewestValue - OldestValue;
1651 /* Overflow situation */
1652 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1656 * Extrapolate delta to port switches per hour.
1657 * Estimate = Delta * (3600000 / 225000)
1661 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1664 * Check if threshold is exceeded. If the threshold is
1665 * permanently exceeded every 28125 ms an event will be
1666 * generated to remind the user of this condition.
1668 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1669 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1670 pAC->Pnmi.RlmtChangeThreshold)) {
1672 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1673 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1676 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
1677 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1678 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1682 case SK_PNMI_EVT_CLEAR_COUNTER:
1684 * Param.Para32[0] contains the NetIndex (0 ..1).
1685 * Param.Para32[1] is reserved, contains -1.
1687 NetIndex = (SK_U32)Param.Para32[0];
1690 if (NetIndex >= pAC->Rlmt.NumNets) {
1692 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1693 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1701 * Set all counters and timestamps to zero
1703 ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
1704 as a Parameter of the Event */
1707 case SK_PNMI_EVT_XMAC_RESET:
1709 * To grant continuous counter values store the current
1710 * XMAC statistic values to the entries 1..n of the
1711 * CounterOffset array. XMAC Errata #2
1714 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1716 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1717 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1718 (unsigned int)Param.Para64));
1722 PhysPortIndex = (unsigned int)Param.Para64;
1725 * Update XMAC statistic to get fresh values
1727 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1728 if (Ret != SK_PNMI_ERR_OK) {
1730 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1734 * Increment semaphore to indicate that an update was
1737 pAC->Pnmi.MacUpdatedFlag ++;
1739 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1742 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1747 pAC->Pnmi.Port[PhysPortIndex].
1748 CounterOffset[CounterIndex] = GetPhysStatVal(
1749 pAC, IoC, PhysPortIndex, CounterIndex);
1750 pAC->Pnmi.Port[PhysPortIndex].
1751 CounterHigh[CounterIndex] = 0;
1754 pAC->Pnmi.MacUpdatedFlag --;
1757 case SK_PNMI_EVT_RLMT_PORT_UP:
1758 PhysPortIndex = (unsigned int)Param.Para32[0];
1760 if (PhysPortIndex >= SK_MAX_MACS) {
1762 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1763 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1764 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1770 * Store a trap message in the trap buffer and generate an event for
1771 * user space applications with the SK_DRIVER_SENDEVENT macro.
1773 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1774 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1776 /* Bugfix for XMAC errata (#10620)*/
1777 if (pAC->GIni.GIMacType == SK_MAC_XMAC){
1779 /* Add incremental difference to offset (#10620)*/
1780 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1781 XM_RXE_SHT_ERR, &Val32);
1783 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1784 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1785 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1786 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1789 /* Tell VctStatus() that a link was up meanwhile. */
1790 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1793 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1794 PhysPortIndex = (unsigned int)Param.Para32[0];
1797 if (PhysPortIndex >= SK_MAX_MACS) {
1799 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1800 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1801 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1807 * Store a trap message in the trap buffer and generate an event for
1808 * user space applications with the SK_DRIVER_SENDEVENT macro.
1810 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1811 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1813 /* Bugfix #10620 - get zero level for incremental difference */
1814 if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
1816 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1817 XM_RXE_SHT_ERR, &Val32);
1818 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1819 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1820 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1824 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1825 PhysPortIndex = (unsigned int)Param.Para32[0];
1826 NetIndex = (SK_U32)Param.Para32[1];
1829 if (PhysPortIndex >= SK_MAX_MACS) {
1831 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1832 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1836 if (NetIndex >= pAC->Rlmt.NumNets) {
1838 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1839 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1844 * For now, ignore event if NetIndex != 0.
1846 if (Param.Para32[1] != 0) {
1852 * Nothing to do if port is already inactive
1854 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1860 * Update statistic counters to calculate new offset for the virtual
1861 * port and increment semaphore to indicate that an update was already
1864 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1867 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1870 pAC->Pnmi.MacUpdatedFlag ++;
1873 * Calculate new counter offset for virtual port to grant continous
1874 * counting on port switches. The virtual port consists of all currently
1875 * active ports. The port down event indicates that a port is removed
1876 * from the virtual port. Therefore add the counter value of the removed
1877 * port to the CounterOffset for the virtual port to grant the same
1880 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1883 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1888 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1890 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1894 * Set port to inactive
1896 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1898 pAC->Pnmi.MacUpdatedFlag --;
1901 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1902 PhysPortIndex = (unsigned int)Param.Para32[0];
1903 NetIndex = (SK_U32)Param.Para32[1];
1906 if (PhysPortIndex >= SK_MAX_MACS) {
1908 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1909 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1913 if (NetIndex >= pAC->Rlmt.NumNets) {
1915 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1916 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1921 * For now, ignore event if NetIndex != 0.
1923 if (Param.Para32[1] != 0) {
1929 * Nothing to do if port is already active
1931 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1937 * Statistic maintenance
1939 pAC->Pnmi.RlmtChangeCts ++;
1940 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1943 * Store a trap message in the trap buffer and generate an event for
1944 * user space applications with the SK_DRIVER_SENDEVENT macro.
1946 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1947 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1950 * Update statistic counters to calculate new offset for the virtual
1951 * port and increment semaphore to indicate that an update was
1954 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1957 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1960 pAC->Pnmi.MacUpdatedFlag ++;
1963 * Calculate new counter offset for virtual port to grant continous
1964 * counting on port switches. A new port is added to the virtual port.
1965 * Therefore substract the counter value of the new port from the
1966 * CounterOffset for the virtual port to grant the same value.
1968 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1971 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1976 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1978 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1982 * Set port to active
1984 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1986 pAC->Pnmi.MacUpdatedFlag --;
1989 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1991 * Para.Para32[0] contains the NetIndex.
1995 * Store a trap message in the trap buffer and generate an event for
1996 * user space applications with the SK_DRIVER_SENDEVENT macro.
1998 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1999 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2002 case SK_PNMI_EVT_RLMT_SET_NETS:
2004 * Param.Para32[0] contains the number of Nets.
2005 * Param.Para32[1] is reserved, contains -1.
2008 * Check number of nets
2010 MaxNetNumber = pAC->GIni.GIMacsFound;
2011 if (((unsigned int)Param.Para32[0] < 1)
2012 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2013 return (SK_PNMI_ERR_UNKNOWN_NET);
2016 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2017 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2019 else { /* dual net mode */
2020 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2024 case SK_PNMI_EVT_VCT_RESET:
2025 PhysPortIndex = Param.Para32[0];
2026 pPrt = &pAC->GIni.GP[PhysPortIndex];
2027 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
2029 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2030 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2033 * VCT test is still running.
2034 * Start VCT timer counter again.
2036 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2037 Param.Para32[0] = PhysPortIndex;
2038 Param.Para32[1] = -1;
2039 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2040 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2043 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2044 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2045 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
2047 /* Copy results for later use to PNMI struct. */
2048 for (i = 0; i < 4; i++) {
2049 if (pPrt->PMdiPairLen[i] > 35) {
2050 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2055 pVctBackupData->PMdiPairLen[i] = CableLength;
2056 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2059 Param.Para32[0] = PhysPortIndex;
2060 Param.Para32[1] = -1;
2061 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2062 SkEventDispatcher(pAC, IoC);
2071 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2076 /******************************************************************************
2082 /*****************************************************************************
2084 * PnmiVar - Gets, presets, and sets single OIDs
2087 * Looks up the requested OID, calls the corresponding handler
2088 * function, and passes the parameters with the get, preset, or
2089 * set command. The function is called by SkGePnmiGetVar,
2090 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2093 * SK_PNMI_ERR_XXX. For details have a look to the description of the
2094 * calling functions.
2095 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2097 PNMI_STATIC int PnmiVar(
2098 SK_AC *pAC, /* Pointer to adapter context */
2099 SK_IOC IoC, /* IO context handle */
2100 int Action, /* Get/PreSet/Set action */
2101 SK_U32 Id, /* Object ID that is to be processed */
2102 char *pBuf, /* Buffer which stores the mgmt data to be set */
2103 unsigned int *pLen, /* Total length of mgmt data */
2104 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2105 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2107 unsigned int TableIndex;
2111 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2114 return (SK_PNMI_ERR_UNKNOWN_OID);
2120 if (NetIndex >= pAC->Rlmt.NumNets) {
2121 return (SK_PNMI_ERR_UNKNOWN_NET);
2124 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2126 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2127 Instance, TableIndex, NetIndex);
2129 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2134 /*****************************************************************************
2136 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2139 * The return value of the function will also be stored in
2140 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2141 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2142 * checks which OIDs are able to set, and calls the handler function of
2143 * the OID to perform the set. The return value of the function will
2144 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2145 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2146 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2149 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
2150 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2152 PNMI_STATIC int PnmiStruct(
2153 SK_AC *pAC, /* Pointer to adapter context */
2154 SK_IOC IoC, /* IO context handle */
2155 int Action, /* Set action to be performed */
2156 char *pBuf, /* Buffer which contains the data to be set */
2157 unsigned int *pLen, /* Length of buffer */
2158 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2161 unsigned int TableIndex;
2162 unsigned int DstOffset;
2164 unsigned int InstanceNo;
2165 unsigned int InstanceCnt;
2170 /* Check if the passed buffer has the right size */
2171 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2173 /* Check if we can return the error within the buffer */
2174 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2176 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2180 *pLen = SK_PNMI_STRUCT_SIZE;
2181 return (SK_PNMI_ERR_TOO_SHORT);
2187 if (NetIndex >= pAC->Rlmt.NumNets) {
2188 return (SK_PNMI_ERR_UNKNOWN_NET);
2191 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2194 * Update the values of RLMT and SIRQ and increment semaphores to
2195 * indicate that an update was already done.
2197 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2199 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2200 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2204 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2206 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2207 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2211 pAC->Pnmi.RlmtUpdatedFlag ++;
2212 pAC->Pnmi.SirqUpdatedFlag ++;
2214 /* Preset/Set values */
2215 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2217 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2218 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2223 InstanceNo = IdTable[TableIndex].InstanceNo;
2224 Id = IdTable[TableIndex].Id;
2226 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2229 DstOffset = IdTable[TableIndex].Offset +
2231 IdTable[TableIndex].StructSize;
2234 * Because VPD multiple instance variables are
2235 * not setable we do not need to evaluate VPD
2236 * instances. Have a look to VPD instance
2237 * calculation in SkPnmiGetStruct().
2239 Instance = (SK_U32)InstanceCnt;
2242 * Evaluate needed buffer length
2245 Ret = IdTable[TableIndex].Func(pAC, IoC,
2246 SK_PNMI_GET, IdTable[TableIndex].Id,
2247 NULL, &Len, Instance, TableIndex, NetIndex);
2249 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2253 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2255 pAC->Pnmi.RlmtUpdatedFlag --;
2256 pAC->Pnmi.SirqUpdatedFlag --;
2258 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2259 SK_PNMI_SET_STAT(pBuf,
2260 SK_PNMI_ERR_GENERAL, DstOffset);
2261 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2262 return (SK_PNMI_ERR_GENERAL);
2264 if (Id == OID_SKGE_VPD_ACTION) {
2266 switch (*(pBuf + DstOffset)) {
2268 case SK_PNMI_VPD_CREATE:
2269 Len = 3 + *(pBuf + DstOffset + 3);
2272 case SK_PNMI_VPD_DELETE:
2282 /* Call the OID handler function */
2283 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2284 IdTable[TableIndex].Id, pBuf + DstOffset,
2285 &Len, Instance, TableIndex, NetIndex);
2287 if (Ret != SK_PNMI_ERR_OK) {
2289 pAC->Pnmi.RlmtUpdatedFlag --;
2290 pAC->Pnmi.SirqUpdatedFlag --;
2292 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2293 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2295 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2296 return (SK_PNMI_ERR_BAD_VALUE);
2301 pAC->Pnmi.RlmtUpdatedFlag --;
2302 pAC->Pnmi.SirqUpdatedFlag --;
2304 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2305 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2306 return (SK_PNMI_ERR_OK);
2309 /*****************************************************************************
2311 * LookupId - Lookup an OID in the IdTable
2314 * Scans the IdTable to find the table entry of an OID.
2317 * The table index or -1 if not found.
2319 PNMI_STATIC int LookupId(
2320 SK_U32 Id) /* Object identifier to be searched */
2324 for (i = 0; i < ID_TABLE_SIZE; i++) {
2326 if (IdTable[i].Id == Id) {
2335 /*****************************************************************************
2337 * OidStruct - Handler of OID_SKGE_ALL_DATA
2340 * This OID performs a Get/Preset/SetStruct call and returns all data
2341 * in a SK_PNMI_STRUCT_DATA structure.
2344 * SK_PNMI_ERR_OK The request was successfully performed.
2345 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2346 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2347 * the correct data (e.g. a 32bit value is
2348 * needed, but a 16 bit value was passed).
2349 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2351 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2352 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2353 * exist (e.g. port instance 3 on a two port
2356 PNMI_STATIC int OidStruct(
2357 SK_AC *pAC, /* Pointer to adapter context */
2358 SK_IOC IoC, /* IO context handle */
2359 int Action, /* Get/PreSet/Set action */
2360 SK_U32 Id, /* Object ID that is to be processed */
2361 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2362 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2363 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2364 unsigned int TableIndex, /* Index to the Id table */
2365 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2367 if (Id != OID_SKGE_ALL_DATA) {
2369 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2373 return (SK_PNMI_ERR_GENERAL);
2377 * Check instance. We only handle single instance variables
2379 if (Instance != (SK_U32)(-1) && Instance != 1) {
2382 return (SK_PNMI_ERR_UNKNOWN_INST);
2388 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2390 case SK_PNMI_PRESET:
2391 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2394 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2397 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2400 return (SK_PNMI_ERR_GENERAL);
2403 /*****************************************************************************
2405 * Perform - OID handler of OID_SKGE_ACTION
2411 * SK_PNMI_ERR_OK The request was successfully performed.
2412 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2413 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2414 * the correct data (e.g. a 32bit value is
2415 * needed, but a 16 bit value was passed).
2416 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2418 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2419 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2420 * exist (e.g. port instance 3 on a two port
2423 PNMI_STATIC int Perform(
2424 SK_AC *pAC, /* Pointer to adapter context */
2425 SK_IOC IoC, /* IO context handle */
2426 int Action, /* Get/PreSet/Set action */
2427 SK_U32 Id, /* Object ID that is to be processed */
2428 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2429 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2430 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2431 unsigned int TableIndex, /* Index to the Id table */
2432 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2439 * Check instance. We only handle single instance variables
2441 if (Instance != (SK_U32)(-1) && Instance != 1) {
2444 return (SK_PNMI_ERR_UNKNOWN_INST);
2447 if (*pLen < sizeof(SK_U32)) {
2449 *pLen = sizeof(SK_U32);
2450 return (SK_PNMI_ERR_TOO_SHORT);
2453 /* Check if a get should be performed */
2454 if (Action == SK_PNMI_GET) {
2456 /* A get is easy. We always return the same value */
2457 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2458 SK_PNMI_STORE_U32(pBuf, ActionOp);
2459 *pLen = sizeof(SK_U32);
2461 return (SK_PNMI_ERR_OK);
2464 /* Continue with PRESET/SET action */
2465 if (*pLen > sizeof(SK_U32)) {
2467 return (SK_PNMI_ERR_BAD_VALUE);
2470 /* Check if the command is a known one */
2471 SK_PNMI_READ_U32(pBuf, ActionOp);
2472 if (*pLen > sizeof(SK_U32) ||
2473 (ActionOp != SK_PNMI_ACT_IDLE &&
2474 ActionOp != SK_PNMI_ACT_RESET &&
2475 ActionOp != SK_PNMI_ACT_SELFTEST &&
2476 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2479 return (SK_PNMI_ERR_BAD_VALUE);
2482 /* A preset ends here */
2483 if (Action == SK_PNMI_PRESET) {
2485 return (SK_PNMI_ERR_OK);
2490 case SK_PNMI_ACT_IDLE:
2494 case SK_PNMI_ACT_RESET:
2496 * Perform a driver reset or something that comes near
2499 Ret = SK_DRIVER_RESET(pAC, IoC);
2502 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2505 return (SK_PNMI_ERR_GENERAL);
2509 case SK_PNMI_ACT_SELFTEST:
2511 * Perform a driver selftest or something similar to this.
2512 * Currently this feature is not used and will probably
2513 * implemented in another way.
2515 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2516 pAC->Pnmi.TestResult = Ret;
2519 case SK_PNMI_ACT_RESETCNT:
2520 /* Set all counters and timestamps to zero */
2521 ResetCounter(pAC, IoC, NetIndex);
2525 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2528 return (SK_PNMI_ERR_GENERAL);
2531 return (SK_PNMI_ERR_OK);
2534 /*****************************************************************************
2536 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2539 * Retrieves the statistic values of the virtual port (logical
2540 * index 0). Only special OIDs of NDIS are handled which consist
2541 * of a 32 bit instead of a 64 bit value. The OIDs are public
2542 * because perhaps some other platform can use them too.
2545 * SK_PNMI_ERR_OK The request was successfully performed.
2546 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2547 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2548 * the correct data (e.g. a 32bit value is
2549 * needed, but a 16 bit value was passed).
2550 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2551 * exist (e.g. port instance 3 on a two port
2554 PNMI_STATIC int Mac8023Stat(
2555 SK_AC *pAC, /* Pointer to adapter context */
2556 SK_IOC IoC, /* IO context handle */
2557 int Action, /* Get/PreSet/Set action */
2558 SK_U32 Id, /* Object ID that is to be processed */
2559 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2560 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2561 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2562 unsigned int TableIndex, /* Index to the Id table */
2563 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2568 SK_BOOL Is64BitReq = SK_FALSE;
2571 * Only the active Mac is returned
2573 if (Instance != (SK_U32)(-1) && Instance != 1) {
2576 return (SK_PNMI_ERR_UNKNOWN_INST);
2582 if (Action != SK_PNMI_GET) {
2585 return (SK_PNMI_ERR_READ_ONLY);
2593 case OID_802_3_PERMANENT_ADDRESS:
2594 case OID_802_3_CURRENT_ADDRESS:
2595 if (*pLen < sizeof(SK_MAC_ADDR)) {
2597 *pLen = sizeof(SK_MAC_ADDR);
2598 return (SK_PNMI_ERR_TOO_SHORT);
2603 #ifndef SK_NDIS_64BIT_CTR
2604 if (*pLen < sizeof(SK_U32)) {
2605 *pLen = sizeof(SK_U32);
2606 return (SK_PNMI_ERR_TOO_SHORT);
2609 #else /* SK_NDIS_64BIT_CTR */
2612 * for compatibility, at least 32bit are required for oid
2614 if (*pLen < sizeof(SK_U32)) {
2616 * but indicate handling for 64bit values,
2617 * if insufficient space is provided
2619 *pLen = sizeof(SK_U64);
2620 return (SK_PNMI_ERR_TOO_SHORT);
2623 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2624 #endif /* SK_NDIS_64BIT_CTR */
2629 * Update all statistics, because we retrieve virtual MAC, which
2630 * consists of multiple physical statistics and increment semaphore
2631 * to indicate that an update was already done.
2633 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2634 if ( Ret != SK_PNMI_ERR_OK) {
2639 pAC->Pnmi.MacUpdatedFlag ++;
2642 * Get value (MAC Index 0 identifies the virtual MAC)
2646 case OID_802_3_PERMANENT_ADDRESS:
2647 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2648 *pLen = sizeof(SK_MAC_ADDR);
2651 case OID_802_3_CURRENT_ADDRESS:
2652 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2653 *pLen = sizeof(SK_MAC_ADDR);
2657 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2660 * by default 32bit values are evaluated
2663 StatVal32 = (SK_U32)StatVal;
2664 SK_PNMI_STORE_U32(pBuf, StatVal32);
2665 *pLen = sizeof(SK_U32);
2668 SK_PNMI_STORE_U64(pBuf, StatVal);
2669 *pLen = sizeof(SK_U64);
2674 pAC->Pnmi.MacUpdatedFlag --;
2676 return (SK_PNMI_ERR_OK);
2679 /*****************************************************************************
2681 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2684 * Retrieves the XMAC statistic data.
2687 * SK_PNMI_ERR_OK The request was successfully performed.
2688 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2689 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2690 * the correct data (e.g. a 32bit value is
2691 * needed, but a 16 bit value was passed).
2692 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2693 * exist (e.g. port instance 3 on a two port
2696 PNMI_STATIC int MacPrivateStat(
2697 SK_AC *pAC, /* Pointer to adapter context */
2698 SK_IOC IoC, /* IO context handle */
2699 int Action, /* Get/PreSet/Set action */
2700 SK_U32 Id, /* Object ID that is to be processed */
2701 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2702 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2703 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2704 unsigned int TableIndex, /* Index to the Id table */
2705 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2707 unsigned int LogPortMax;
2708 unsigned int LogPortIndex;
2709 unsigned int PhysPortMax;
2711 unsigned int Offset;
2717 * Calculate instance if wished. MAC index 0 is the virtual
2720 PhysPortMax = pAC->GIni.GIMacsFound;
2721 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2723 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2727 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2728 /* Check instance range */
2729 if ((Instance < 1) || (Instance > LogPortMax)) {
2732 return (SK_PNMI_ERR_UNKNOWN_INST);
2734 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2735 Limit = LogPortIndex + 1;
2738 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2748 if (Action != SK_PNMI_GET) {
2751 return (SK_PNMI_ERR_READ_ONLY);
2757 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2759 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2760 return (SK_PNMI_ERR_TOO_SHORT);
2764 * Update XMAC statistic and increment semaphore to indicate that
2765 * an update was already done.
2767 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2768 if (Ret != SK_PNMI_ERR_OK) {
2773 pAC->Pnmi.MacUpdatedFlag ++;
2779 for (; LogPortIndex < Limit; LogPortIndex ++) {
2783 /* XXX not yet implemented due to XMAC problems
2784 case OID_SKGE_STAT_TX_UTIL:
2785 return (SK_PNMI_ERR_GENERAL);
2787 /* XXX not yet implemented due to XMAC problems
2788 case OID_SKGE_STAT_RX_UTIL:
2789 return (SK_PNMI_ERR_GENERAL);
2791 case OID_SKGE_STAT_RX:
2792 case OID_SKGE_STAT_TX:
2793 switch (pAC->GIni.GIMacType) {
2795 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2796 IdTable[TableIndex].Param, NetIndex);
2800 if (Id == OID_SKGE_STAT_TX) {
2803 GetStatVal(pAC, IoC, LogPortIndex,
2804 SK_PNMI_HTX_BROADCAST, NetIndex) +
2805 GetStatVal(pAC, IoC, LogPortIndex,
2806 SK_PNMI_HTX_MULTICAST, NetIndex) +
2807 GetStatVal(pAC, IoC, LogPortIndex,
2808 SK_PNMI_HTX_UNICAST, NetIndex);
2812 GetStatVal(pAC, IoC, LogPortIndex,
2813 SK_PNMI_HRX_BROADCAST, NetIndex) +
2814 GetStatVal(pAC, IoC, LogPortIndex,
2815 SK_PNMI_HRX_MULTICAST, NetIndex) +
2816 GetStatVal(pAC, IoC, LogPortIndex,
2817 SK_PNMI_HRX_UNICAST, NetIndex) +
2818 GetStatVal(pAC, IoC, LogPortIndex,
2819 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2828 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2832 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2833 IdTable[TableIndex].Param, NetIndex);
2834 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2838 Offset += sizeof(SK_U64);
2842 pAC->Pnmi.MacUpdatedFlag --;
2844 return (SK_PNMI_ERR_OK);
2847 /*****************************************************************************
2849 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2852 * Get/Presets/Sets the current and factory MAC address. The MAC
2853 * address of the virtual port, which is reported to the OS, may
2854 * not be changed, but the physical ones. A set to the virtual port
2855 * will be ignored. No error should be reported because otherwise
2856 * a multiple instance set (-1) would always fail.
2859 * SK_PNMI_ERR_OK The request was successfully performed.
2860 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2861 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2862 * the correct data (e.g. a 32bit value is
2863 * needed, but a 16 bit value was passed).
2864 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2866 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2867 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2868 * exist (e.g. port instance 3 on a two port
2871 PNMI_STATIC int Addr(
2872 SK_AC *pAC, /* Pointer to adapter context */
2873 SK_IOC IoC, /* IO context handle */
2874 int Action, /* Get/PreSet/Set action */
2875 SK_U32 Id, /* Object ID that is to be processed */
2876 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2877 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2878 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2879 unsigned int TableIndex, /* Index to the Id table */
2880 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2883 unsigned int LogPortMax;
2884 unsigned int PhysPortMax;
2885 unsigned int LogPortIndex;
2886 unsigned int PhysPortIndex;
2888 unsigned int Offset = 0;
2891 * Calculate instance if wished. MAC index 0 is the virtual
2894 PhysPortMax = pAC->GIni.GIMacsFound;
2895 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2897 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2901 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2902 /* Check instance range */
2903 if ((Instance < 1) || (Instance > LogPortMax)) {
2906 return (SK_PNMI_ERR_UNKNOWN_INST);
2908 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2909 Limit = LogPortIndex + 1;
2912 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2921 if (Action == SK_PNMI_GET) {
2926 if (*pLen < (Limit - LogPortIndex) * 6) {
2928 *pLen = (Limit - LogPortIndex) * 6;
2929 return (SK_PNMI_ERR_TOO_SHORT);
2935 for (; LogPortIndex < Limit; LogPortIndex ++) {
2939 case OID_SKGE_PHYS_CUR_ADDR:
2940 if (LogPortIndex == 0) {
2941 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2944 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2946 CopyMac(pBuf + Offset,
2947 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2952 case OID_SKGE_PHYS_FAC_ADDR:
2953 if (LogPortIndex == 0) {
2954 CopyMac(pBuf + Offset,
2955 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2958 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2961 CopyMac(pBuf + Offset,
2962 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2968 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2972 return (SK_PNMI_ERR_GENERAL);
2980 * The logical MAC address may not be changed only
2983 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2986 return (SK_PNMI_ERR_READ_ONLY);
2990 * Only the current address may be changed
2992 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2994 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2998 return (SK_PNMI_ERR_GENERAL);
3004 if (*pLen < (Limit - LogPortIndex) * 6) {
3006 *pLen = (Limit - LogPortIndex) * 6;
3007 return (SK_PNMI_ERR_TOO_SHORT);
3009 if (*pLen > (Limit - LogPortIndex) * 6) {
3012 return (SK_PNMI_ERR_BAD_VALUE);
3018 if (Action == SK_PNMI_PRESET) {
3021 return (SK_PNMI_ERR_OK);
3025 * Set OID_SKGE_MAC_CUR_ADDR
3027 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3030 * A set to virtual port and set of broadcast
3031 * address will be ignored
3033 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3034 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3039 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3042 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3043 (SK_MAC_ADDR *)(pBuf + Offset),
3044 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3045 SK_ADDR_PHYSICAL_ADDRESS));
3046 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3048 return (SK_PNMI_ERR_GENERAL);
3054 return (SK_PNMI_ERR_OK);
3057 /*****************************************************************************
3059 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3062 * Retrieves the statistic values of the CSUM module. The CSUM data
3063 * structure must be available in the SK_AC even if the CSUM module
3064 * is not included, because PNMI reads the statistic data from the
3065 * CSUM part of SK_AC directly.
3068 * SK_PNMI_ERR_OK The request was successfully performed.
3069 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3070 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3071 * the correct data (e.g. a 32bit value is
3072 * needed, but a 16 bit value was passed).
3073 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3074 * exist (e.g. port instance 3 on a two port
3077 PNMI_STATIC int CsumStat(
3078 SK_AC *pAC, /* Pointer to adapter context */
3079 SK_IOC IoC, /* IO context handle */
3080 int Action, /* Get/PreSet/Set action */
3081 SK_U32 Id, /* Object ID that is to be processed */
3082 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3083 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3084 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3085 unsigned int TableIndex, /* Index to the Id table */
3086 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3090 unsigned int Offset = 0;
3095 * Calculate instance if wished
3097 if (Instance != (SK_U32)(-1)) {
3099 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3102 return (SK_PNMI_ERR_UNKNOWN_INST);
3104 Index = (unsigned int)Instance - 1;
3109 Limit = SKCS_NUM_PROTOCOLS;
3115 if (Action != SK_PNMI_GET) {
3118 return (SK_PNMI_ERR_READ_ONLY);
3124 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3126 *pLen = (Limit - Index) * sizeof(SK_U64);
3127 return (SK_PNMI_ERR_TOO_SHORT);
3133 for (; Index < Limit; Index ++) {
3137 case OID_SKGE_CHKSM_RX_OK_CTS:
3138 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3141 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3142 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3145 case OID_SKGE_CHKSM_RX_ERR_CTS:
3146 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3149 case OID_SKGE_CHKSM_TX_OK_CTS:
3150 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3153 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3154 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3158 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3162 return (SK_PNMI_ERR_GENERAL);
3165 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3166 Offset += sizeof(SK_U64);
3170 * Store used buffer space
3174 return (SK_PNMI_ERR_OK);
3177 /*****************************************************************************
3179 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3182 * Retrieves the statistic values of the I2C module, which handles
3183 * the temperature and voltage sensors.
3186 * SK_PNMI_ERR_OK The request was successfully performed.
3187 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3188 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3189 * the correct data (e.g. a 32bit value is
3190 * needed, but a 16 bit value was passed).
3191 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3192 * exist (e.g. port instance 3 on a two port
3195 PNMI_STATIC int SensorStat(
3196 SK_AC *pAC, /* Pointer to adapter context */
3197 SK_IOC IoC, /* IO context handle */
3198 int Action, /* Get/PreSet/Set action */
3199 SK_U32 Id, /* Object ID that is to be processed */
3200 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3201 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3202 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3203 unsigned int TableIndex, /* Index to the Id table */
3204 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3209 unsigned int Offset;
3216 * Calculate instance if wished
3218 if ((Instance != (SK_U32)(-1))) {
3220 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3223 return (SK_PNMI_ERR_UNKNOWN_INST);
3226 Index = (unsigned int)Instance -1;
3227 Limit = (unsigned int)Instance;
3231 Limit = (unsigned int) pAC->I2c.MaxSens;
3237 if (Action != SK_PNMI_GET) {
3240 return (SK_PNMI_ERR_READ_ONLY);
3248 case OID_SKGE_SENSOR_VALUE:
3249 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3250 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3251 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3252 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3253 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3255 *pLen = (Limit - Index) * sizeof(SK_U32);
3256 return (SK_PNMI_ERR_TOO_SHORT);
3260 case OID_SKGE_SENSOR_DESCR:
3261 for (Offset = 0, i = Index; i < Limit; i ++) {
3263 Len = (unsigned int)
3264 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3265 if (Len >= SK_PNMI_STRINGLEN2) {
3267 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3271 return (SK_PNMI_ERR_GENERAL);
3275 if (*pLen < Offset) {
3278 return (SK_PNMI_ERR_TOO_SHORT);
3282 case OID_SKGE_SENSOR_INDEX:
3283 case OID_SKGE_SENSOR_TYPE:
3284 case OID_SKGE_SENSOR_STATUS:
3285 if (*pLen < Limit - Index) {
3287 *pLen = Limit - Index;
3288 return (SK_PNMI_ERR_TOO_SHORT);
3292 case OID_SKGE_SENSOR_WAR_CTS:
3293 case OID_SKGE_SENSOR_WAR_TIME:
3294 case OID_SKGE_SENSOR_ERR_CTS:
3295 case OID_SKGE_SENSOR_ERR_TIME:
3296 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3298 *pLen = (Limit - Index) * sizeof(SK_U64);
3299 return (SK_PNMI_ERR_TOO_SHORT);
3304 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3308 return (SK_PNMI_ERR_GENERAL);
3315 for (Offset = 0; Index < Limit; Index ++) {
3319 case OID_SKGE_SENSOR_INDEX:
3320 *(pBuf + Offset) = (char)Index;
3321 Offset += sizeof(char);
3324 case OID_SKGE_SENSOR_DESCR:
3325 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3326 SK_MEMCPY(pBuf + Offset + 1,
3327 pAC->I2c.SenTable[Index].SenDesc, Len);
3328 *(pBuf + Offset) = (char)Len;
3332 case OID_SKGE_SENSOR_TYPE:
3334 (char)pAC->I2c.SenTable[Index].SenType;
3335 Offset += sizeof(char);
3338 case OID_SKGE_SENSOR_VALUE:
3339 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3340 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3341 Offset += sizeof(SK_U32);
3344 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3345 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3347 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3348 Offset += sizeof(SK_U32);
3351 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3352 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3354 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3355 Offset += sizeof(SK_U32);
3358 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3359 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3361 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3362 Offset += sizeof(SK_U32);
3365 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3366 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3367 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3368 Offset += sizeof(SK_U32);
3371 case OID_SKGE_SENSOR_STATUS:
3373 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3374 Offset += sizeof(char);
3377 case OID_SKGE_SENSOR_WAR_CTS:
3378 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3379 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3380 Offset += sizeof(SK_U64);
3383 case OID_SKGE_SENSOR_ERR_CTS:
3384 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3385 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3386 Offset += sizeof(SK_U64);
3389 case OID_SKGE_SENSOR_WAR_TIME:
3390 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3392 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3393 Offset += sizeof(SK_U64);
3396 case OID_SKGE_SENSOR_ERR_TIME:
3397 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3399 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3400 Offset += sizeof(SK_U64);
3404 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3405 ("SensorStat: Unknown OID should be handled before"));
3407 return (SK_PNMI_ERR_GENERAL);
3412 * Store used buffer space
3416 return (SK_PNMI_ERR_OK);
3419 /*****************************************************************************
3421 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3424 * Get/preset/set of VPD data. As instance the name of a VPD key
3425 * can be passed. The Instance parameter is a SK_U32 and can be
3426 * used as a string buffer for the VPD key, because their maximum
3430 * SK_PNMI_ERR_OK The request was successfully performed.
3431 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3432 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3433 * the correct data (e.g. a 32bit value is
3434 * needed, but a 16 bit value was passed).
3435 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3437 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3438 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3439 * exist (e.g. port instance 3 on a two port
3442 PNMI_STATIC int Vpd(
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 */
3453 SK_VPD_STATUS *pVpdStatus;
3454 unsigned int BufLen;
3456 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3457 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3459 unsigned int Offset;
3461 unsigned int FirstIndex;
3462 unsigned int LastIndex;
3468 * Get array of all currently stored VPD keys
3470 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
3472 if (Ret != SK_PNMI_ERR_OK) {
3478 * If instance is not -1, try to find the requested VPD key for
3479 * the multiple instance variables. The other OIDs as for example
3480 * OID VPD_ACTION are single instance variables and must be
3481 * handled separatly.
3486 if ((Instance != (SK_U32)(-1))) {
3488 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3489 Id == OID_SKGE_VPD_ACCESS) {
3491 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3494 for (Index = 0; Index < KeyNo; Index ++) {
3496 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3498 LastIndex = Index+1;
3502 if (Index == KeyNo) {
3505 return (SK_PNMI_ERR_UNKNOWN_INST);
3508 else if (Instance != 1) {
3511 return (SK_PNMI_ERR_UNKNOWN_INST);
3516 * Get value, if a query should be performed
3518 if (Action == SK_PNMI_GET) {
3522 case OID_SKGE_VPD_FREE_BYTES:
3523 /* Check length of buffer */
3524 if (*pLen < sizeof(SK_U32)) {
3526 *pLen = sizeof(SK_U32);
3527 return (SK_PNMI_ERR_TOO_SHORT);
3529 /* Get number of free bytes */
3530 pVpdStatus = VpdStat(pAC, IoC);
3531 if (pVpdStatus == NULL) {
3533 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3537 return (SK_PNMI_ERR_GENERAL);
3539 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3541 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3545 return (SK_PNMI_ERR_GENERAL);
3548 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3549 SK_PNMI_STORE_U32(pBuf, Val32);
3550 *pLen = sizeof(SK_U32);
3553 case OID_SKGE_VPD_ENTRIES_LIST:
3555 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3557 Len += SK_STRLEN(KeyArr[Index]) + 1;
3562 return (SK_PNMI_ERR_TOO_SHORT);
3566 *(pBuf) = (char)Len - 1;
3567 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3569 Len = SK_STRLEN(KeyArr[Index]);
3570 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3574 if (Index < KeyNo - 1) {
3576 *(pBuf + Offset) = ' ';
3583 case OID_SKGE_VPD_ENTRIES_NUMBER:
3585 if (*pLen < sizeof(SK_U32)) {
3587 *pLen = sizeof(SK_U32);
3588 return (SK_PNMI_ERR_TOO_SHORT);
3591 Val32 = (SK_U32)KeyNo;
3592 SK_PNMI_STORE_U32(pBuf, Val32);
3593 *pLen = sizeof(SK_U32);
3596 case OID_SKGE_VPD_KEY:
3597 /* Check buffer length, if it is large enough */
3598 for (Len = 0, Index = FirstIndex;
3599 Index < LastIndex; Index ++) {
3601 Len += SK_STRLEN(KeyArr[Index]) + 1;
3606 return (SK_PNMI_ERR_TOO_SHORT);
3610 * Get the key to an intermediate buffer, because
3611 * we have to prepend a length byte.
3613 for (Offset = 0, Index = FirstIndex;
3614 Index < LastIndex; Index ++) {
3616 Len = SK_STRLEN(KeyArr[Index]);
3618 *(pBuf + Offset) = (char)Len;
3619 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3626 case OID_SKGE_VPD_VALUE:
3627 /* Check the buffer length if it is large enough */
3628 for (Offset = 0, Index = FirstIndex;
3629 Index < LastIndex; Index ++) {
3632 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3633 (int *)&BufLen) > 0 ||
3634 BufLen >= SK_PNMI_VPD_DATALEN) {
3636 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3640 return (SK_PNMI_ERR_GENERAL);
3642 Offset += BufLen + 1;
3644 if (*pLen < Offset) {
3647 return (SK_PNMI_ERR_TOO_SHORT);
3651 * Get the value to an intermediate buffer, because
3652 * we have to prepend a length byte.
3654 for (Offset = 0, Index = FirstIndex;
3655 Index < LastIndex; Index ++) {
3658 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3659 (int *)&BufLen) > 0 ||
3660 BufLen >= SK_PNMI_VPD_DATALEN) {
3662 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3667 return (SK_PNMI_ERR_GENERAL);
3670 *(pBuf + Offset) = (char)BufLen;
3671 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3672 Offset += BufLen + 1;
3677 case OID_SKGE_VPD_ACCESS:
3678 if (*pLen < LastIndex - FirstIndex) {
3680 *pLen = LastIndex - FirstIndex;
3681 return (SK_PNMI_ERR_TOO_SHORT);
3684 for (Offset = 0, Index = FirstIndex;
3685 Index < LastIndex; Index ++) {
3687 if (VpdMayWrite(KeyArr[Index])) {
3689 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3692 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3699 case OID_SKGE_VPD_ACTION:
3700 Offset = LastIndex - FirstIndex;
3701 if (*pLen < Offset) {
3704 return (SK_PNMI_ERR_TOO_SHORT);
3706 SK_MEMSET(pBuf, 0, Offset);
3711 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3715 return (SK_PNMI_ERR_GENERAL);
3719 /* The only OID which can be set is VPD_ACTION */
3720 if (Id != OID_SKGE_VPD_ACTION) {
3722 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3723 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3724 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3725 Id == OID_SKGE_VPD_KEY ||
3726 Id == OID_SKGE_VPD_VALUE ||
3727 Id == OID_SKGE_VPD_ACCESS) {
3730 return (SK_PNMI_ERR_READ_ONLY);
3733 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3737 return (SK_PNMI_ERR_GENERAL);
3741 * From this point we handle VPD_ACTION. Check the buffer
3742 * length. It should at least have the size of one byte.
3747 return (SK_PNMI_ERR_TOO_SHORT);
3751 * The first byte contains the VPD action type we should
3756 case SK_PNMI_VPD_IGNORE:
3760 case SK_PNMI_VPD_CREATE:
3762 * We have to create a new VPD entry or we modify
3763 * an existing one. Check first the buffer length.
3768 return (SK_PNMI_ERR_TOO_SHORT);
3770 KeyStr[0] = pBuf[1];
3771 KeyStr[1] = pBuf[2];
3775 * Is the entry writable or does it belong to the
3778 if (!VpdMayWrite(KeyStr)) {
3781 return (SK_PNMI_ERR_BAD_VALUE);
3784 Offset = (int)pBuf[3] & 0xFF;
3786 SK_MEMCPY(Buf, pBuf + 4, Offset);
3789 /* A preset ends here */
3790 if (Action == SK_PNMI_PRESET) {
3792 return (SK_PNMI_ERR_OK);
3795 /* Write the new entry or modify an existing one */
3796 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3797 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3800 return (SK_PNMI_ERR_BAD_VALUE);
3802 else if (Ret != SK_PNMI_VPD_OK) {
3804 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3808 return (SK_PNMI_ERR_GENERAL);
3812 * Perform an update of the VPD data. This is
3813 * not mandantory, but just to be sure.
3815 Ret = VpdUpdate(pAC, IoC);
3816 if (Ret != SK_PNMI_VPD_OK) {
3818 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3822 return (SK_PNMI_ERR_GENERAL);
3826 case SK_PNMI_VPD_DELETE:
3827 /* Check if the buffer size is plausible */
3831 return (SK_PNMI_ERR_TOO_SHORT);
3836 return (SK_PNMI_ERR_BAD_VALUE);
3838 KeyStr[0] = pBuf[1];
3839 KeyStr[1] = pBuf[2];
3842 /* Find the passed key in the array */
3843 for (Index = 0; Index < KeyNo; Index ++) {
3845 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3851 * If we cannot find the key it is wrong, so we
3852 * return an appropriate error value.
3854 if (Index == KeyNo) {
3857 return (SK_PNMI_ERR_BAD_VALUE);
3860 if (Action == SK_PNMI_PRESET) {
3862 return (SK_PNMI_ERR_OK);
3865 /* Ok, you wanted it and you will get it */
3866 Ret = VpdDelete(pAC, IoC, KeyStr);
3867 if (Ret != SK_PNMI_VPD_OK) {
3869 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3873 return (SK_PNMI_ERR_GENERAL);
3877 * Perform an update of the VPD data. This is
3878 * not mandantory, but just to be sure.
3880 Ret = VpdUpdate(pAC, IoC);
3881 if (Ret != SK_PNMI_VPD_OK) {
3883 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3887 return (SK_PNMI_ERR_GENERAL);
3893 return (SK_PNMI_ERR_BAD_VALUE);
3897 return (SK_PNMI_ERR_OK);
3900 /*****************************************************************************
3902 * General - OID handler function of various single instance OIDs
3905 * The code is simple. No description necessary.
3908 * SK_PNMI_ERR_OK The request was successfully performed.
3909 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3910 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3911 * the correct data (e.g. a 32bit value is
3912 * needed, but a 16 bit value was passed).
3913 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3914 * exist (e.g. port instance 3 on a two port
3917 PNMI_STATIC int General(
3918 SK_AC *pAC, /* Pointer to adapter context */
3919 SK_IOC IoC, /* IO context handle */
3920 int Action, /* Get/PreSet/Set action */
3921 SK_U32 Id, /* Object ID that is to be processed */
3922 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3923 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3924 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3925 unsigned int TableIndex, /* Index to the Id table */
3926 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3931 unsigned int Offset;
3937 SK_U64 Val64RxHwErrs = 0;
3938 SK_U64 Val64TxHwErrs = 0;
3939 SK_BOOL Is64BitReq = SK_FALSE;
3944 * Check instance. We only handle single instance variables
3946 if (Instance != (SK_U32)(-1) && Instance != 1) {
3949 return (SK_PNMI_ERR_UNKNOWN_INST);
3953 * Check action. We only allow get requests.
3955 if (Action != SK_PNMI_GET) {
3958 return (SK_PNMI_ERR_READ_ONLY);
3961 MacType = pAC->GIni.GIMacType;
3964 * Check length for the various supported OIDs
3968 case OID_GEN_XMIT_ERROR:
3969 case OID_GEN_RCV_ERROR:
3970 case OID_GEN_RCV_NO_BUFFER:
3971 #ifndef SK_NDIS_64BIT_CTR
3972 if (*pLen < sizeof(SK_U32)) {
3973 *pLen = sizeof(SK_U32);
3974 return (SK_PNMI_ERR_TOO_SHORT);
3977 #else /* SK_NDIS_64BIT_CTR */
3980 * for compatibility, at least 32bit are required for oid
3982 if (*pLen < sizeof(SK_U32)) {
3984 * but indicate handling for 64bit values,
3985 * if insufficient space is provided
3987 *pLen = sizeof(SK_U64);
3988 return (SK_PNMI_ERR_TOO_SHORT);
3991 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3992 #endif /* SK_NDIS_64BIT_CTR */
3995 case OID_SKGE_PORT_NUMBER:
3996 case OID_SKGE_DEVICE_TYPE:
3997 case OID_SKGE_RESULT:
3998 case OID_SKGE_RLMT_MONITOR_NUMBER:
3999 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4000 case OID_SKGE_TRAP_NUMBER:
4001 case OID_SKGE_MDB_VERSION:
4002 if (*pLen < sizeof(SK_U32)) {
4004 *pLen = sizeof(SK_U32);
4005 return (SK_PNMI_ERR_TOO_SHORT);
4009 case OID_SKGE_CHIPSET:
4010 if (*pLen < sizeof(SK_U16)) {
4012 *pLen = sizeof(SK_U16);
4013 return (SK_PNMI_ERR_TOO_SHORT);
4017 case OID_SKGE_BUS_TYPE:
4018 case OID_SKGE_BUS_SPEED:
4019 case OID_SKGE_BUS_WIDTH:
4020 case OID_SKGE_SENSOR_NUMBER:
4021 case OID_SKGE_CHKSM_NUMBER:
4022 if (*pLen < sizeof(SK_U8)) {
4024 *pLen = sizeof(SK_U8);
4025 return (SK_PNMI_ERR_TOO_SHORT);
4029 case OID_SKGE_TX_SW_QUEUE_LEN:
4030 case OID_SKGE_TX_SW_QUEUE_MAX:
4031 case OID_SKGE_TX_RETRY:
4032 case OID_SKGE_RX_INTR_CTS:
4033 case OID_SKGE_TX_INTR_CTS:
4034 case OID_SKGE_RX_NO_BUF_CTS:
4035 case OID_SKGE_TX_NO_BUF_CTS:
4036 case OID_SKGE_TX_USED_DESCR_NO:
4037 case OID_SKGE_RX_DELIVERED_CTS:
4038 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4039 case OID_SKGE_RX_HW_ERROR_CTS:
4040 case OID_SKGE_TX_HW_ERROR_CTS:
4041 case OID_SKGE_IN_ERRORS_CTS:
4042 case OID_SKGE_OUT_ERROR_CTS:
4043 case OID_SKGE_ERR_RECOVERY_CTS:
4044 case OID_SKGE_SYSUPTIME:
4045 if (*pLen < sizeof(SK_U64)) {
4047 *pLen = sizeof(SK_U64);
4048 return (SK_PNMI_ERR_TOO_SHORT);
4057 /* Update statistic */
4058 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4059 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4060 Id == OID_SKGE_IN_ERRORS_CTS ||
4061 Id == OID_SKGE_OUT_ERROR_CTS ||
4062 Id == OID_GEN_XMIT_ERROR ||
4063 Id == OID_GEN_RCV_ERROR) {
4065 /* Force the XMAC to update its statistic counters and
4066 * Increment semaphore to indicate that an update was
4069 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4070 if (Ret != SK_PNMI_ERR_OK) {
4075 pAC->Pnmi.MacUpdatedFlag ++;
4078 * Some OIDs consist of multiple hardware counters. Those
4079 * values which are contained in all of them will be added
4084 case OID_SKGE_RX_HW_ERROR_CTS:
4085 case OID_SKGE_IN_ERRORS_CTS:
4086 case OID_GEN_RCV_ERROR:
4088 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4089 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4090 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
4091 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4092 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4093 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
4094 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4095 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4096 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4097 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4098 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4099 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
4102 case OID_SKGE_TX_HW_ERROR_CTS:
4103 case OID_SKGE_OUT_ERROR_CTS:
4104 case OID_GEN_XMIT_ERROR:
4106 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4107 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
4108 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
4109 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4119 case OID_SKGE_SUPPORTED_LIST:
4120 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4124 return (SK_PNMI_ERR_TOO_SHORT);
4126 for (Offset = 0, Index = 0; Offset < Len;
4127 Offset += sizeof(SK_U32), Index ++) {
4129 Val32 = (SK_U32)IdTable[Index].Id;
4130 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4135 case OID_SKGE_PORT_NUMBER:
4136 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4137 SK_PNMI_STORE_U32(pBuf, Val32);
4138 *pLen = sizeof(SK_U32);
4141 case OID_SKGE_DEVICE_TYPE:
4142 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4143 SK_PNMI_STORE_U32(pBuf, Val32);
4144 *pLen = sizeof(SK_U32);
4147 case OID_SKGE_DRIVER_DESCR:
4148 if (pAC->Pnmi.pDriverDescription == NULL) {
4150 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4154 return (SK_PNMI_ERR_GENERAL);
4157 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4158 if (Len > SK_PNMI_STRINGLEN1) {
4160 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4164 return (SK_PNMI_ERR_GENERAL);
4170 return (SK_PNMI_ERR_TOO_SHORT);
4172 *pBuf = (char)(Len - 1);
4173 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4177 case OID_SKGE_DRIVER_VERSION:
4178 if (pAC->Pnmi.pDriverVersion == NULL) {
4180 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4184 return (SK_PNMI_ERR_GENERAL);
4187 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4188 if (Len > SK_PNMI_STRINGLEN1) {
4190 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4194 return (SK_PNMI_ERR_GENERAL);
4200 return (SK_PNMI_ERR_TOO_SHORT);
4202 *pBuf = (char)(Len - 1);
4203 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4207 case OID_SKGE_HW_DESCR:
4209 * The hardware description is located in the VPD. This
4210 * query may move to the initialisation routine. But
4211 * the VPD data is cached and therefore a call here
4212 * will not make much difference.
4215 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4217 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4221 return (SK_PNMI_ERR_GENERAL);
4224 if (Len > SK_PNMI_STRINGLEN1) {
4226 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4230 return (SK_PNMI_ERR_GENERAL);
4235 return (SK_PNMI_ERR_TOO_SHORT);
4237 *pBuf = (char)(Len - 1);
4238 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4242 case OID_SKGE_HW_VERSION:
4243 /* Oh, I love to do some string manipulation */
4247 return (SK_PNMI_ERR_TOO_SHORT);
4249 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4252 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4254 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4258 case OID_SKGE_CHIPSET:
4259 Val16 = pAC->Pnmi.Chipset;
4260 SK_PNMI_STORE_U16(pBuf, Val16);
4261 *pLen = sizeof(SK_U16);
4264 case OID_SKGE_BUS_TYPE:
4265 *pBuf = (char)SK_PNMI_BUS_PCI;
4266 *pLen = sizeof(char);
4269 case OID_SKGE_BUS_SPEED:
4270 *pBuf = pAC->Pnmi.PciBusSpeed;
4271 *pLen = sizeof(char);
4274 case OID_SKGE_BUS_WIDTH:
4275 *pBuf = pAC->Pnmi.PciBusWidth;
4276 *pLen = sizeof(char);
4279 case OID_SKGE_RESULT:
4280 Val32 = pAC->Pnmi.TestResult;
4281 SK_PNMI_STORE_U32(pBuf, Val32);
4282 *pLen = sizeof(SK_U32);
4285 case OID_SKGE_SENSOR_NUMBER:
4286 *pBuf = (char)pAC->I2c.MaxSens;
4287 *pLen = sizeof(char);
4290 case OID_SKGE_CHKSM_NUMBER:
4291 *pBuf = SKCS_NUM_PROTOCOLS;
4292 *pLen = sizeof(char);
4295 case OID_SKGE_TRAP_NUMBER:
4296 GetTrapQueueLen(pAC, &Len, &Val);
4297 Val32 = (SK_U32)Val;
4298 SK_PNMI_STORE_U32(pBuf, Val32);
4299 *pLen = sizeof(SK_U32);
4303 GetTrapQueueLen(pAC, &Len, &Val);
4307 return (SK_PNMI_ERR_TOO_SHORT);
4309 CopyTrapQueue(pAC, pBuf);
4313 case OID_SKGE_RLMT_MONITOR_NUMBER:
4314 /* XXX Not yet implemented by RLMT therefore we return zero elements */
4316 SK_PNMI_STORE_U32(pBuf, Val32);
4317 *pLen = sizeof(SK_U32);
4320 case OID_SKGE_TX_SW_QUEUE_LEN:
4321 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4322 if (MacType == SK_MAC_XMAC) {
4324 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4325 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4327 /* Single net mode */
4329 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4330 pAC->Pnmi.BufPort[1].TxSwQueueLen;
4335 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4336 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4338 /* Single net mode */
4340 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4341 pAC->Pnmi.Port[1].TxSwQueueLen;
4344 SK_PNMI_STORE_U64(pBuf, Val64);
4345 *pLen = sizeof(SK_U64);
4349 case OID_SKGE_TX_SW_QUEUE_MAX:
4350 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4351 if (MacType == SK_MAC_XMAC) {
4353 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4354 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4356 /* Single net mode */
4358 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4359 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4364 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4365 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4367 /* Single net mode */
4369 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4370 pAC->Pnmi.Port[1].TxSwQueueMax;
4373 SK_PNMI_STORE_U64(pBuf, Val64);
4374 *pLen = sizeof(SK_U64);
4377 case OID_SKGE_TX_RETRY:
4378 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4379 if (MacType == SK_MAC_XMAC) {
4381 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4382 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4384 /* Single net mode */
4386 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4387 pAC->Pnmi.BufPort[1].TxRetryCts;
4392 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4393 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4395 /* Single net mode */
4397 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4398 pAC->Pnmi.Port[1].TxRetryCts;
4401 SK_PNMI_STORE_U64(pBuf, Val64);
4402 *pLen = sizeof(SK_U64);
4405 case OID_SKGE_RX_INTR_CTS:
4406 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4407 if (MacType == SK_MAC_XMAC) {
4409 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4410 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4412 /* Single net mode */
4414 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4415 pAC->Pnmi.BufPort[1].RxIntrCts;
4420 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4421 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4423 /* Single net mode */
4425 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4426 pAC->Pnmi.Port[1].RxIntrCts;
4429 SK_PNMI_STORE_U64(pBuf, Val64);
4430 *pLen = sizeof(SK_U64);
4433 case OID_SKGE_TX_INTR_CTS:
4434 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4435 if (MacType == SK_MAC_XMAC) {
4437 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4438 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4440 /* Single net mode */
4442 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4443 pAC->Pnmi.BufPort[1].TxIntrCts;
4448 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4449 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4451 /* Single net mode */
4453 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4454 pAC->Pnmi.Port[1].TxIntrCts;
4457 SK_PNMI_STORE_U64(pBuf, Val64);
4458 *pLen = sizeof(SK_U64);
4461 case OID_SKGE_RX_NO_BUF_CTS:
4462 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4463 if (MacType == SK_MAC_XMAC) {
4465 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4466 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4468 /* Single net mode */
4470 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4471 pAC->Pnmi.BufPort[1].RxNoBufCts;
4476 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4477 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4479 /* Single net mode */
4481 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4482 pAC->Pnmi.Port[1].RxNoBufCts;
4485 SK_PNMI_STORE_U64(pBuf, Val64);
4486 *pLen = sizeof(SK_U64);
4489 case OID_SKGE_TX_NO_BUF_CTS:
4490 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4491 if (MacType == SK_MAC_XMAC) {
4493 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4494 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4496 /* Single net mode */
4498 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4499 pAC->Pnmi.BufPort[1].TxNoBufCts;
4504 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4505 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4507 /* Single net mode */
4509 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4510 pAC->Pnmi.Port[1].TxNoBufCts;
4513 SK_PNMI_STORE_U64(pBuf, Val64);
4514 *pLen = sizeof(SK_U64);
4517 case OID_SKGE_TX_USED_DESCR_NO:
4518 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4519 if (MacType == SK_MAC_XMAC) {
4521 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4522 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4524 /* Single net mode */
4526 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4527 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4532 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4533 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4535 /* Single net mode */
4537 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4538 pAC->Pnmi.Port[1].TxUsedDescrNo;
4541 SK_PNMI_STORE_U64(pBuf, Val64);
4542 *pLen = sizeof(SK_U64);
4545 case OID_SKGE_RX_DELIVERED_CTS:
4546 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4547 if (MacType == SK_MAC_XMAC) {
4549 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4550 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4552 /* Single net mode */
4554 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4555 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4560 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4561 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4563 /* Single net mode */
4565 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4566 pAC->Pnmi.Port[1].RxDeliveredCts;
4569 SK_PNMI_STORE_U64(pBuf, Val64);
4570 *pLen = sizeof(SK_U64);
4573 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4574 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4575 if (MacType == SK_MAC_XMAC) {
4577 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4578 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4580 /* Single net mode */
4582 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4583 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4588 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4589 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4591 /* Single net mode */
4593 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4594 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4597 SK_PNMI_STORE_U64(pBuf, Val64);
4598 *pLen = sizeof(SK_U64);
4601 case OID_SKGE_RX_HW_ERROR_CTS:
4602 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4603 *pLen = sizeof(SK_U64);
4606 case OID_SKGE_TX_HW_ERROR_CTS:
4607 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4608 *pLen = sizeof(SK_U64);
4611 case OID_SKGE_IN_ERRORS_CTS:
4612 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4613 if (MacType == SK_MAC_XMAC) {
4615 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4616 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4618 /* Single net mode */
4620 Val64 = Val64RxHwErrs +
4621 pAC->Pnmi.BufPort[0].RxNoBufCts +
4622 pAC->Pnmi.BufPort[1].RxNoBufCts;
4627 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4628 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4630 /* Single net mode */
4632 Val64 = Val64RxHwErrs +
4633 pAC->Pnmi.Port[0].RxNoBufCts +
4634 pAC->Pnmi.Port[1].RxNoBufCts;
4637 SK_PNMI_STORE_U64(pBuf, Val64);
4638 *pLen = sizeof(SK_U64);
4641 case OID_SKGE_OUT_ERROR_CTS:
4642 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4643 if (MacType == SK_MAC_XMAC) {
4645 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4646 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4648 /* Single net mode */
4650 Val64 = Val64TxHwErrs +
4651 pAC->Pnmi.BufPort[0].TxNoBufCts +
4652 pAC->Pnmi.BufPort[1].TxNoBufCts;
4657 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4658 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4660 /* Single net mode */
4662 Val64 = Val64TxHwErrs +
4663 pAC->Pnmi.Port[0].TxNoBufCts +
4664 pAC->Pnmi.Port[1].TxNoBufCts;
4667 SK_PNMI_STORE_U64(pBuf, Val64);
4668 *pLen = sizeof(SK_U64);
4671 case OID_SKGE_ERR_RECOVERY_CTS:
4672 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4673 if (MacType == SK_MAC_XMAC) {
4675 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4676 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4678 /* Single net mode */
4680 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4681 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4686 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4687 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4689 /* Single net mode */
4691 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4692 pAC->Pnmi.Port[1].ErrRecoveryCts;
4695 SK_PNMI_STORE_U64(pBuf, Val64);
4696 *pLen = sizeof(SK_U64);
4699 case OID_SKGE_SYSUPTIME:
4700 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4701 Val64 -= pAC->Pnmi.StartUpTime;
4702 SK_PNMI_STORE_U64(pBuf, Val64);
4703 *pLen = sizeof(SK_U64);
4706 case OID_SKGE_MDB_VERSION:
4707 Val32 = SK_PNMI_MDB_VERSION;
4708 SK_PNMI_STORE_U32(pBuf, Val32);
4709 *pLen = sizeof(SK_U32);
4712 case OID_GEN_RCV_ERROR:
4713 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4714 if (MacType == SK_MAC_XMAC) {
4715 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4718 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4722 * by default 32bit values are evaluated
4725 Val32 = (SK_U32)Val64;
4726 SK_PNMI_STORE_U32(pBuf, Val32);
4727 *pLen = sizeof(SK_U32);
4730 SK_PNMI_STORE_U64(pBuf, Val64);
4731 *pLen = sizeof(SK_U64);
4735 case OID_GEN_XMIT_ERROR:
4736 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4737 if (MacType == SK_MAC_XMAC) {
4738 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4741 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4745 * by default 32bit values are evaluated
4748 Val32 = (SK_U32)Val64;
4749 SK_PNMI_STORE_U32(pBuf, Val32);
4750 *pLen = sizeof(SK_U32);
4753 SK_PNMI_STORE_U64(pBuf, Val64);
4754 *pLen = sizeof(SK_U64);
4758 case OID_GEN_RCV_NO_BUFFER:
4759 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4760 if (MacType == SK_MAC_XMAC) {
4761 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4764 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4768 * by default 32bit values are evaluated
4771 Val32 = (SK_U32)Val64;
4772 SK_PNMI_STORE_U32(pBuf, Val32);
4773 *pLen = sizeof(SK_U32);
4776 SK_PNMI_STORE_U64(pBuf, Val64);
4777 *pLen = sizeof(SK_U64);
4781 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4782 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4783 SK_PNMI_STORE_U32(pBuf, Val32);
4784 *pLen = sizeof(SK_U32);
4788 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4792 return (SK_PNMI_ERR_GENERAL);
4795 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4796 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4797 Id == OID_SKGE_IN_ERRORS_CTS ||
4798 Id == OID_SKGE_OUT_ERROR_CTS ||
4799 Id == OID_GEN_XMIT_ERROR ||
4800 Id == OID_GEN_RCV_ERROR) {
4802 pAC->Pnmi.MacUpdatedFlag --;
4805 return (SK_PNMI_ERR_OK);
4808 /*****************************************************************************
4810 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4813 * Get/Presets/Sets the RLMT OIDs.
4816 * SK_PNMI_ERR_OK The request was successfully performed.
4817 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4818 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4819 * the correct data (e.g. a 32bit value is
4820 * needed, but a 16 bit value was passed).
4821 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4823 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4824 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4825 * exist (e.g. port instance 3 on a two port
4828 PNMI_STATIC int Rlmt(
4829 SK_AC *pAC, /* Pointer to adapter context */
4830 SK_IOC IoC, /* IO context handle */
4831 int Action, /* Get/PreSet/Set action */
4832 SK_U32 Id, /* Object ID that is to be processed */
4833 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
4834 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
4835 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4836 unsigned int TableIndex, /* Index to the Id table */
4837 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
4840 unsigned int PhysPortIndex;
4841 unsigned int PhysPortMax;
4842 SK_EVPARA EventParam;
4848 * Check instance. Only single instance OIDs are allowed here.
4850 if (Instance != (SK_U32)(-1) && Instance != 1) {
4853 return (SK_PNMI_ERR_UNKNOWN_INST);
4857 * Perform the requested action
4859 if (Action == SK_PNMI_GET) {
4862 * Check if the buffer length is large enough.
4867 case OID_SKGE_RLMT_MODE:
4868 case OID_SKGE_RLMT_PORT_ACTIVE:
4869 case OID_SKGE_RLMT_PORT_PREFERRED:
4870 if (*pLen < sizeof(SK_U8)) {
4872 *pLen = sizeof(SK_U8);
4873 return (SK_PNMI_ERR_TOO_SHORT);
4877 case OID_SKGE_RLMT_PORT_NUMBER:
4878 if (*pLen < sizeof(SK_U32)) {
4880 *pLen = sizeof(SK_U32);
4881 return (SK_PNMI_ERR_TOO_SHORT);
4885 case OID_SKGE_RLMT_CHANGE_CTS:
4886 case OID_SKGE_RLMT_CHANGE_TIME:
4887 case OID_SKGE_RLMT_CHANGE_ESTIM:
4888 case OID_SKGE_RLMT_CHANGE_THRES:
4889 if (*pLen < sizeof(SK_U64)) {
4891 *pLen = sizeof(SK_U64);
4892 return (SK_PNMI_ERR_TOO_SHORT);
4897 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4901 return (SK_PNMI_ERR_GENERAL);
4905 * Update RLMT statistic and increment semaphores to indicate
4906 * that an update was already done. Maybe RLMT will hold its
4907 * statistic always up to date some time. Then we can
4908 * remove this type of call.
4910 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4915 pAC->Pnmi.RlmtUpdatedFlag ++;
4922 case OID_SKGE_RLMT_MODE:
4923 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4924 *pLen = sizeof(char);
4927 case OID_SKGE_RLMT_PORT_NUMBER:
4928 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4929 SK_PNMI_STORE_U32(pBuf, Val32);
4930 *pLen = sizeof(SK_U32);
4933 case OID_SKGE_RLMT_PORT_ACTIVE:
4936 * If multiple ports may become active this OID
4937 * doesn't make sense any more. A new variable in
4938 * the port structure should be created. However,
4939 * for this variable the first active port is
4942 PhysPortMax = pAC->GIni.GIMacsFound;
4944 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4947 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4949 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4953 *pLen = sizeof(char);
4956 case OID_SKGE_RLMT_PORT_PREFERRED:
4957 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4958 *pLen = sizeof(char);
4961 case OID_SKGE_RLMT_CHANGE_CTS:
4962 Val64 = pAC->Pnmi.RlmtChangeCts;
4963 SK_PNMI_STORE_U64(pBuf, Val64);
4964 *pLen = sizeof(SK_U64);
4967 case OID_SKGE_RLMT_CHANGE_TIME:
4968 Val64 = pAC->Pnmi.RlmtChangeTime;
4969 SK_PNMI_STORE_U64(pBuf, Val64);
4970 *pLen = sizeof(SK_U64);
4973 case OID_SKGE_RLMT_CHANGE_ESTIM:
4974 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4975 SK_PNMI_STORE_U64(pBuf, Val64);
4976 *pLen = sizeof(SK_U64);
4979 case OID_SKGE_RLMT_CHANGE_THRES:
4980 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4981 SK_PNMI_STORE_U64(pBuf, Val64);
4982 *pLen = sizeof(SK_U64);
4986 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4987 ("Rlmt: Unknown OID should be handled before"));
4989 pAC->Pnmi.RlmtUpdatedFlag --;
4991 return (SK_PNMI_ERR_GENERAL);
4994 pAC->Pnmi.RlmtUpdatedFlag --;
4997 /* Perform a preset or set */
5000 case OID_SKGE_RLMT_MODE:
5001 /* Check if the buffer length is plausible */
5002 if (*pLen < sizeof(char)) {
5004 *pLen = sizeof(char);
5005 return (SK_PNMI_ERR_TOO_SHORT);
5007 /* Check if the value range is correct */
5008 if (*pLen != sizeof(char) ||
5009 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5010 *(SK_U8 *)pBuf > 15) {
5013 return (SK_PNMI_ERR_BAD_VALUE);
5015 /* The preset ends here */
5016 if (Action == SK_PNMI_PRESET) {
5019 return (SK_PNMI_ERR_OK);
5021 /* Send an event to RLMT to change the mode */
5022 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5023 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5024 EventParam.Para32[1] = 0;
5025 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5028 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5032 return (SK_PNMI_ERR_GENERAL);
5036 case OID_SKGE_RLMT_PORT_PREFERRED:
5037 /* Check if the buffer length is plausible */
5038 if (*pLen < sizeof(char)) {
5040 *pLen = sizeof(char);
5041 return (SK_PNMI_ERR_TOO_SHORT);
5043 /* Check if the value range is correct */
5044 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5045 (SK_U8)pAC->GIni.GIMacsFound) {
5048 return (SK_PNMI_ERR_BAD_VALUE);
5050 /* The preset ends here */
5051 if (Action == SK_PNMI_PRESET) {
5054 return (SK_PNMI_ERR_OK);
5058 * Send an event to RLMT change the preferred port.
5059 * A param of -1 means automatic mode. RLMT will
5060 * make the decision which is the preferred port.
5062 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5063 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5064 EventParam.Para32[1] = NetIndex;
5065 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5068 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5072 return (SK_PNMI_ERR_GENERAL);
5076 case OID_SKGE_RLMT_CHANGE_THRES:
5077 /* Check if the buffer length is plausible */
5078 if (*pLen < sizeof(SK_U64)) {
5080 *pLen = sizeof(SK_U64);
5081 return (SK_PNMI_ERR_TOO_SHORT);
5084 * There are not many restrictions to the
5087 if (*pLen != sizeof(SK_U64)) {
5090 return (SK_PNMI_ERR_BAD_VALUE);
5092 /* A preset ends here */
5093 if (Action == SK_PNMI_PRESET) {
5096 return (SK_PNMI_ERR_OK);
5099 * Store the new threshold, which will be taken
5100 * on the next timer event.
5102 SK_PNMI_READ_U64(pBuf, Val64);
5103 pAC->Pnmi.RlmtChangeThreshold = Val64;
5107 /* The other OIDs are not be able for set */
5109 return (SK_PNMI_ERR_READ_ONLY);
5113 return (SK_PNMI_ERR_OK);
5116 /*****************************************************************************
5118 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5121 * Performs get requests on multiple instance variables.
5124 * SK_PNMI_ERR_OK The request was successfully performed.
5125 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5126 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5127 * the correct data (e.g. a 32bit value is
5128 * needed, but a 16 bit value was passed).
5129 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5130 * exist (e.g. port instance 3 on a two port
5133 PNMI_STATIC int RlmtStat(
5134 SK_AC *pAC, /* Pointer to adapter context */
5135 SK_IOC IoC, /* IO context handle */
5136 int Action, /* Get/PreSet/Set action */
5137 SK_U32 Id, /* Object ID that is to be processed */
5138 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5139 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5140 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5141 unsigned int TableIndex, /* Index to the Id table */
5142 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5144 unsigned int PhysPortMax;
5145 unsigned int PhysPortIndex;
5147 unsigned int Offset;
5153 * Calculate the port indexes from the instance
5155 PhysPortMax = pAC->GIni.GIMacsFound;
5157 if ((Instance != (SK_U32)(-1))) {
5158 /* Check instance range */
5159 if ((Instance < 1) || (Instance > PhysPortMax)) {
5162 return (SK_PNMI_ERR_UNKNOWN_INST);
5165 /* Single net mode */
5166 PhysPortIndex = Instance - 1;
5169 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5170 PhysPortIndex = NetIndex;
5173 /* Both net modes */
5174 Limit = PhysPortIndex + 1;
5177 /* Single net mode */
5179 Limit = PhysPortMax;
5182 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5183 PhysPortIndex = NetIndex;
5184 Limit = PhysPortIndex + 1;
5189 * Currently only get requests are allowed.
5191 if (Action != SK_PNMI_GET) {
5194 return (SK_PNMI_ERR_READ_ONLY);
5198 * Check if the buffer length is large enough.
5202 case OID_SKGE_RLMT_PORT_INDEX:
5203 case OID_SKGE_RLMT_STATUS:
5204 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5206 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5207 return (SK_PNMI_ERR_TOO_SHORT);
5211 case OID_SKGE_RLMT_TX_HELLO_CTS:
5212 case OID_SKGE_RLMT_RX_HELLO_CTS:
5213 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5214 case OID_SKGE_RLMT_RX_SP_CTS:
5215 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5217 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5218 return (SK_PNMI_ERR_TOO_SHORT);
5223 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5227 return (SK_PNMI_ERR_GENERAL);
5232 * Update statistic and increment semaphores to indicate that
5233 * an update was already done.
5235 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5240 pAC->Pnmi.RlmtUpdatedFlag ++;
5246 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5250 case OID_SKGE_RLMT_PORT_INDEX:
5251 Val32 = PhysPortIndex;
5252 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5253 Offset += sizeof(SK_U32);
5256 case OID_SKGE_RLMT_STATUS:
5257 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5259 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5262 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5264 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5266 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5269 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5271 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5272 Offset += sizeof(SK_U32);
5275 case OID_SKGE_RLMT_TX_HELLO_CTS:
5276 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5277 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5278 Offset += sizeof(SK_U64);
5281 case OID_SKGE_RLMT_RX_HELLO_CTS:
5282 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5283 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5284 Offset += sizeof(SK_U64);
5287 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5288 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5289 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5290 Offset += sizeof(SK_U64);
5293 case OID_SKGE_RLMT_RX_SP_CTS:
5294 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5295 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5296 Offset += sizeof(SK_U64);
5300 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5301 ("RlmtStat: Unknown OID should be errored before"));
5303 pAC->Pnmi.RlmtUpdatedFlag --;
5305 return (SK_PNMI_ERR_GENERAL);
5310 pAC->Pnmi.RlmtUpdatedFlag --;
5312 return (SK_PNMI_ERR_OK);
5315 /*****************************************************************************
5317 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5320 * Get/Presets/Sets the OIDs concerning the configuration.
5323 * SK_PNMI_ERR_OK The request was successfully performed.
5324 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5325 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5326 * the correct data (e.g. a 32bit value is
5327 * needed, but a 16 bit value was passed).
5328 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5330 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5331 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5332 * exist (e.g. port instance 3 on a two port
5335 PNMI_STATIC int MacPrivateConf(
5336 SK_AC *pAC, /* Pointer to adapter context */
5337 SK_IOC IoC, /* IO context handle */
5338 int Action, /* Get/PreSet/Set action */
5339 SK_U32 Id, /* Object ID that is to be processed */
5340 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5341 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5342 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5343 unsigned int TableIndex, /* Index to the Id table */
5344 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5346 unsigned int PhysPortMax;
5347 unsigned int PhysPortIndex;
5348 unsigned int LogPortMax;
5349 unsigned int LogPortIndex;
5351 unsigned int Offset;
5354 SK_EVPARA EventParam;
5359 * Calculate instance if wished. MAC index 0 is the virtual
5362 PhysPortMax = pAC->GIni.GIMacsFound;
5363 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5365 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5369 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5370 /* Check instance range */
5371 if ((Instance < 1) || (Instance > LogPortMax)) {
5374 return (SK_PNMI_ERR_UNKNOWN_INST);
5376 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5377 Limit = LogPortIndex + 1;
5380 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5389 if (Action == SK_PNMI_GET) {
5397 case OID_SKGE_CONNECTOR:
5398 case OID_SKGE_LINK_CAP:
5399 case OID_SKGE_LINK_MODE:
5400 case OID_SKGE_LINK_MODE_STATUS:
5401 case OID_SKGE_LINK_STATUS:
5402 case OID_SKGE_FLOWCTRL_CAP:
5403 case OID_SKGE_FLOWCTRL_MODE:
5404 case OID_SKGE_FLOWCTRL_STATUS:
5405 case OID_SKGE_PHY_OPERATION_CAP:
5406 case OID_SKGE_PHY_OPERATION_MODE:
5407 case OID_SKGE_PHY_OPERATION_STATUS:
5408 case OID_SKGE_SPEED_CAP:
5409 case OID_SKGE_SPEED_MODE:
5410 case OID_SKGE_SPEED_STATUS:
5411 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5413 *pLen = (Limit - LogPortIndex) *
5415 return (SK_PNMI_ERR_TOO_SHORT);
5420 if (*pLen < sizeof(SK_U32)) {
5422 *pLen = sizeof(SK_U32);
5423 return (SK_PNMI_ERR_TOO_SHORT);
5428 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5431 return (SK_PNMI_ERR_GENERAL);
5435 * Update statistic and increment semaphore to indicate
5436 * that an update was already done.
5438 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5443 pAC->Pnmi.SirqUpdatedFlag ++;
5449 for (; LogPortIndex < Limit; LogPortIndex ++) {
5454 *(pBuf + Offset) = pAC->Pnmi.PMD;
5455 Offset += sizeof(char);
5458 case OID_SKGE_CONNECTOR:
5459 *(pBuf + Offset) = pAC->Pnmi.Connector;
5460 Offset += sizeof(char);
5463 case OID_SKGE_LINK_CAP:
5464 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5465 if (LogPortIndex == 0) {
5467 /* Get value for virtual port */
5468 VirtualConf(pAC, IoC, Id, pBuf +
5472 /* Get value for physical ports */
5473 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5476 *(pBuf + Offset) = pAC->GIni.GP[
5477 PhysPortIndex].PLinkCap;
5479 Offset += sizeof(char);
5481 else { /* DualNetMode */
5483 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
5484 Offset += sizeof(char);
5488 case OID_SKGE_LINK_MODE:
5489 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5490 if (LogPortIndex == 0) {
5492 /* Get value for virtual port */
5493 VirtualConf(pAC, IoC, Id, pBuf +
5497 /* Get value for physical ports */
5498 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5501 *(pBuf + Offset) = pAC->GIni.GP[
5502 PhysPortIndex].PLinkModeConf;
5504 Offset += sizeof(char);
5506 else { /* DualNetMode */
5508 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
5509 Offset += sizeof(char);
5513 case OID_SKGE_LINK_MODE_STATUS:
5514 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5515 if (LogPortIndex == 0) {
5517 /* Get value for virtual port */
5518 VirtualConf(pAC, IoC, Id, pBuf +
5522 /* Get value for physical port */
5523 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5527 CalculateLinkModeStatus(pAC,
5528 IoC, PhysPortIndex);
5530 Offset += sizeof(char);
5532 else { /* DualNetMode */
5533 *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5534 Offset += sizeof(char);
5538 case OID_SKGE_LINK_STATUS:
5539 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5540 if (LogPortIndex == 0) {
5542 /* Get value for virtual port */
5543 VirtualConf(pAC, IoC, Id, pBuf +
5547 /* Get value for physical ports */
5548 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5552 CalculateLinkStatus(pAC,
5553 IoC, PhysPortIndex);
5555 Offset += sizeof(char);
5557 else { /* DualNetMode */
5559 *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
5560 Offset += sizeof(char);
5564 case OID_SKGE_FLOWCTRL_CAP:
5565 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5566 if (LogPortIndex == 0) {
5568 /* Get value for virtual port */
5569 VirtualConf(pAC, IoC, Id, pBuf +
5573 /* Get value for physical ports */
5574 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5577 *(pBuf + Offset) = pAC->GIni.GP[
5578 PhysPortIndex].PFlowCtrlCap;
5580 Offset += sizeof(char);
5582 else { /* DualNetMode */
5584 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5585 Offset += sizeof(char);
5589 case OID_SKGE_FLOWCTRL_MODE:
5590 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5591 if (LogPortIndex == 0) {
5593 /* Get value for virtual port */
5594 VirtualConf(pAC, IoC, Id, pBuf +
5598 /* Get value for physical port */
5599 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5602 *(pBuf + Offset) = pAC->GIni.GP[
5603 PhysPortIndex].PFlowCtrlMode;
5605 Offset += sizeof(char);
5607 else { /* DualNetMode */
5609 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5610 Offset += sizeof(char);
5614 case OID_SKGE_FLOWCTRL_STATUS:
5615 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5616 if (LogPortIndex == 0) {
5618 /* Get value for virtual port */
5619 VirtualConf(pAC, IoC, Id, pBuf +
5623 /* Get value for physical port */
5624 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5627 *(pBuf + Offset) = pAC->GIni.GP[
5628 PhysPortIndex].PFlowCtrlStatus;
5630 Offset += sizeof(char);
5632 else { /* DualNetMode */
5634 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5635 Offset += sizeof(char);
5639 case OID_SKGE_PHY_OPERATION_CAP:
5640 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5641 if (LogPortIndex == 0) {
5643 /* Get value for virtual port */
5644 VirtualConf(pAC, IoC, Id, pBuf +
5648 /* Get value for physical ports */
5649 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5652 *(pBuf + Offset) = pAC->GIni.GP[
5653 PhysPortIndex].PMSCap;
5655 Offset += sizeof(char);
5657 else { /* DualNetMode */
5659 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
5660 Offset += sizeof(char);
5664 case OID_SKGE_PHY_OPERATION_MODE:
5665 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5666 if (LogPortIndex == 0) {
5668 /* Get value for virtual port */
5669 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5672 /* Get value for physical port */
5673 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5676 *(pBuf + Offset) = pAC->GIni.GP[
5677 PhysPortIndex].PMSMode;
5679 Offset += sizeof(char);
5681 else { /* DualNetMode */
5683 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
5684 Offset += sizeof(char);
5688 case OID_SKGE_PHY_OPERATION_STATUS:
5689 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5690 if (LogPortIndex == 0) {
5692 /* Get value for virtual port */
5693 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5696 /* Get value for physical port */
5697 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5700 *(pBuf + Offset) = pAC->GIni.GP[
5701 PhysPortIndex].PMSStatus;
5703 Offset += sizeof(char);
5707 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
5708 Offset += sizeof(char);
5712 case OID_SKGE_SPEED_CAP:
5713 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5714 if (LogPortIndex == 0) {
5716 /* Get value for virtual port */
5717 VirtualConf(pAC, IoC, Id, pBuf +
5721 /* Get value for physical ports */
5722 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5725 *(pBuf + Offset) = pAC->GIni.GP[
5726 PhysPortIndex].PLinkSpeedCap;
5728 Offset += sizeof(char);
5730 else { /* DualNetMode */
5732 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5733 Offset += sizeof(char);
5737 case OID_SKGE_SPEED_MODE:
5738 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5739 if (LogPortIndex == 0) {
5741 /* Get value for virtual port */
5742 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5745 /* Get value for physical port */
5746 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5749 *(pBuf + Offset) = pAC->GIni.GP[
5750 PhysPortIndex].PLinkSpeed;
5752 Offset += sizeof(char);
5754 else { /* DualNetMode */
5756 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
5757 Offset += sizeof(char);
5761 case OID_SKGE_SPEED_STATUS:
5762 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5763 if (LogPortIndex == 0) {
5765 /* Get value for virtual port */
5766 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5769 /* Get value for physical port */
5770 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5773 *(pBuf + Offset) = pAC->GIni.GP[
5774 PhysPortIndex].PLinkSpeedUsed;
5776 Offset += sizeof(char);
5778 else { /* DualNetMode */
5780 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5781 Offset += sizeof(char);
5786 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5787 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5788 Offset += sizeof(SK_U32);
5792 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5793 ("MacPrivateConf: Unknown OID should be handled before"));
5795 pAC->Pnmi.SirqUpdatedFlag --;
5796 return (SK_PNMI_ERR_GENERAL);
5800 pAC->Pnmi.SirqUpdatedFlag --;
5802 return (SK_PNMI_ERR_OK);
5806 * From here SET or PRESET action. Check if the passed
5807 * buffer length is plausible.
5811 case OID_SKGE_LINK_MODE:
5812 case OID_SKGE_FLOWCTRL_MODE:
5813 case OID_SKGE_PHY_OPERATION_MODE:
5814 case OID_SKGE_SPEED_MODE:
5815 if (*pLen < Limit - LogPortIndex) {
5817 *pLen = Limit - LogPortIndex;
5818 return (SK_PNMI_ERR_TOO_SHORT);
5820 if (*pLen != Limit - LogPortIndex) {
5823 return (SK_PNMI_ERR_BAD_VALUE);
5828 if (*pLen < sizeof(SK_U32)) {
5830 *pLen = sizeof(SK_U32);
5831 return (SK_PNMI_ERR_TOO_SHORT);
5833 if (*pLen != sizeof(SK_U32)) {
5836 return (SK_PNMI_ERR_BAD_VALUE);
5842 return (SK_PNMI_ERR_READ_ONLY);
5846 * Perform preset or set
5849 for (; LogPortIndex < Limit; LogPortIndex ++) {
5853 case OID_SKGE_LINK_MODE:
5854 /* Check the value range */
5855 Val8 = *(pBuf + Offset);
5858 Offset += sizeof(char);
5861 if (Val8 < SK_LMODE_HALF ||
5862 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5863 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5866 return (SK_PNMI_ERR_BAD_VALUE);
5869 /* The preset ends here */
5870 if (Action == SK_PNMI_PRESET) {
5872 return (SK_PNMI_ERR_OK);
5875 if (LogPortIndex == 0) {
5878 * The virtual port consists of all currently
5879 * active ports. Find them and send an event
5880 * with the new link mode to SIRQ.
5882 for (PhysPortIndex = 0;
5883 PhysPortIndex < PhysPortMax;
5886 if (!pAC->Pnmi.Port[PhysPortIndex].
5892 EventParam.Para32[0] = PhysPortIndex;
5893 EventParam.Para32[1] = (SK_U32)Val8;
5894 if (SkGeSirqEvent(pAC, IoC,
5898 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5903 return (SK_PNMI_ERR_GENERAL);
5909 * Send an event with the new link mode to
5912 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5914 EventParam.Para32[1] = (SK_U32)Val8;
5915 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5918 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5923 return (SK_PNMI_ERR_GENERAL);
5926 Offset += sizeof(char);
5929 case OID_SKGE_FLOWCTRL_MODE:
5930 /* Check the value range */
5931 Val8 = *(pBuf + Offset);
5934 Offset += sizeof(char);
5937 if (Val8 < SK_FLOW_MODE_NONE ||
5938 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5939 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5942 return (SK_PNMI_ERR_BAD_VALUE);
5945 /* The preset ends here */
5946 if (Action == SK_PNMI_PRESET) {
5948 return (SK_PNMI_ERR_OK);
5951 if (LogPortIndex == 0) {
5954 * The virtual port consists of all currently
5955 * active ports. Find them and send an event
5956 * with the new flow control mode to SIRQ.
5958 for (PhysPortIndex = 0;
5959 PhysPortIndex < PhysPortMax;
5962 if (!pAC->Pnmi.Port[PhysPortIndex].
5968 EventParam.Para32[0] = PhysPortIndex;
5969 EventParam.Para32[1] = (SK_U32)Val8;
5970 if (SkGeSirqEvent(pAC, IoC,
5971 SK_HWEV_SET_FLOWMODE,
5974 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5979 return (SK_PNMI_ERR_GENERAL);
5985 * Send an event with the new flow control
5986 * mode to the SIRQ module.
5988 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5990 EventParam.Para32[1] = (SK_U32)Val8;
5991 if (SkGeSirqEvent(pAC, IoC,
5992 SK_HWEV_SET_FLOWMODE, EventParam)
5995 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6000 return (SK_PNMI_ERR_GENERAL);
6003 Offset += sizeof(char);
6006 case OID_SKGE_PHY_OPERATION_MODE :
6007 /* Check the value range */
6008 Val8 = *(pBuf + Offset);
6010 /* mode of this port remains unchanged */
6011 Offset += sizeof(char);
6014 if (Val8 < SK_MS_MODE_AUTO ||
6015 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
6016 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
6019 return (SK_PNMI_ERR_BAD_VALUE);
6022 /* The preset ends here */
6023 if (Action == SK_PNMI_PRESET) {
6025 return (SK_PNMI_ERR_OK);
6028 if (LogPortIndex == 0) {
6031 * The virtual port consists of all currently
6032 * active ports. Find them and send an event
6033 * with new master/slave (role) mode to SIRQ.
6035 for (PhysPortIndex = 0;
6036 PhysPortIndex < PhysPortMax;
6039 if (!pAC->Pnmi.Port[PhysPortIndex].
6045 EventParam.Para32[0] = PhysPortIndex;
6046 EventParam.Para32[1] = (SK_U32)Val8;
6047 if (SkGeSirqEvent(pAC, IoC,
6051 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6056 return (SK_PNMI_ERR_GENERAL);
6062 * Send an event with the new master/slave
6063 * (role) mode to the SIRQ module.
6065 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6067 EventParam.Para32[1] = (SK_U32)Val8;
6068 if (SkGeSirqEvent(pAC, IoC,
6069 SK_HWEV_SET_ROLE, EventParam) > 0) {
6071 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6076 return (SK_PNMI_ERR_GENERAL);
6080 Offset += sizeof(char);
6083 case OID_SKGE_SPEED_MODE:
6084 /* Check the value range */
6085 Val8 = *(pBuf + Offset);
6088 Offset += sizeof(char);
6091 if (Val8 < (SK_LSPEED_AUTO) ||
6092 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6093 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6096 return (SK_PNMI_ERR_BAD_VALUE);
6099 /* The preset ends here */
6100 if (Action == SK_PNMI_PRESET) {
6102 return (SK_PNMI_ERR_OK);
6105 if (LogPortIndex == 0) {
6108 * The virtual port consists of all currently
6109 * active ports. Find them and send an event
6110 * with the new flow control mode to SIRQ.
6112 for (PhysPortIndex = 0;
6113 PhysPortIndex < PhysPortMax;
6116 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6121 EventParam.Para32[0] = PhysPortIndex;
6122 EventParam.Para32[1] = (SK_U32)Val8;
6123 if (SkGeSirqEvent(pAC, IoC,
6127 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6132 return (SK_PNMI_ERR_GENERAL);
6138 * Send an event with the new flow control
6139 * mode to the SIRQ module.
6141 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6143 EventParam.Para32[1] = (SK_U32)Val8;
6144 if (SkGeSirqEvent(pAC, IoC,
6148 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6153 return (SK_PNMI_ERR_GENERAL);
6156 Offset += sizeof(char);
6160 /* Check the value range */
6161 Val32 = *(SK_U32*)(pBuf + Offset);
6163 /* mtu of this port remains unchanged */
6164 Offset += sizeof(SK_U32);
6167 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6169 return (SK_PNMI_ERR_BAD_VALUE);
6172 /* The preset ends here */
6173 if (Action == SK_PNMI_PRESET) {
6174 return (SK_PNMI_ERR_OK);
6177 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6178 return (SK_PNMI_ERR_GENERAL);
6181 Offset += sizeof(SK_U32);
6185 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6186 ("MacPrivateConf: Unknown OID should be handled before set"));
6189 return (SK_PNMI_ERR_GENERAL);
6193 return (SK_PNMI_ERR_OK);
6196 /*****************************************************************************
6198 * Monitor - OID handler function for RLMT_MONITOR_XXX
6201 * Because RLMT currently does not support the monitoring of
6202 * remote adapter cards, we return always an empty table.
6205 * SK_PNMI_ERR_OK The request was successfully performed.
6206 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6207 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6208 * the correct data (e.g. a 32bit value is
6209 * needed, but a 16 bit value was passed).
6210 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6212 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6213 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6214 * exist (e.g. port instance 3 on a two port
6217 PNMI_STATIC int Monitor(
6218 SK_AC *pAC, /* Pointer to adapter context */
6219 SK_IOC IoC, /* IO context handle */
6220 int Action, /* Get/PreSet/Set action */
6221 SK_U32 Id, /* Object ID that is to be processed */
6222 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
6223 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
6224 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6225 unsigned int TableIndex, /* Index to the Id table */
6226 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6230 unsigned int Offset;
6231 unsigned int Entries;
6235 * Calculate instance if wished.
6237 /* XXX Not yet implemented. Return always an empty table. */
6240 if ((Instance != (SK_U32)(-1))) {
6242 if ((Instance < 1) || (Instance > Entries)) {
6245 return (SK_PNMI_ERR_UNKNOWN_INST);
6248 Index = (unsigned int)Instance - 1;
6249 Limit = (unsigned int)Instance;
6259 if (Action == SK_PNMI_GET) {
6261 for (Offset=0; Index < Limit; Index ++) {
6265 case OID_SKGE_RLMT_MONITOR_INDEX:
6266 case OID_SKGE_RLMT_MONITOR_ADDR:
6267 case OID_SKGE_RLMT_MONITOR_ERRS:
6268 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6269 case OID_SKGE_RLMT_MONITOR_ADMIN:
6273 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6277 return (SK_PNMI_ERR_GENERAL);
6283 /* Only MONITOR_ADMIN can be set */
6284 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6287 return (SK_PNMI_ERR_READ_ONLY);
6290 /* Check if the length is plausible */
6291 if (*pLen < (Limit - Index)) {
6293 return (SK_PNMI_ERR_TOO_SHORT);
6295 /* Okay, we have a wide value range */
6296 if (*pLen != (Limit - Index)) {
6299 return (SK_PNMI_ERR_BAD_VALUE);
6302 for (Offset=0; Index < Limit; Index ++) {
6306 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6310 return (SK_PNMI_ERR_BAD_VALUE);
6313 return (SK_PNMI_ERR_OK);
6316 /*****************************************************************************
6318 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6321 * We handle here the get of the configuration group OIDs, which are
6322 * a little bit complicated. The virtual port consists of all currently
6323 * active physical ports. If multiple ports are active and configured
6324 * differently we get in some trouble to return a single value. So we
6325 * get the value of the first active port and compare it with that of
6326 * the other active ports. If they are not the same, we return a value
6327 * that indicates that the state is indeterminated.
6332 PNMI_STATIC void VirtualConf(
6333 SK_AC *pAC, /* Pointer to adapter context */
6334 SK_IOC IoC, /* IO context handle */
6335 SK_U32 Id, /* Object ID that is to be processed */
6336 char *pBuf) /* Buffer to which to mgmt data will be retrieved */
6338 unsigned int PhysPortMax;
6339 unsigned int PhysPortIndex;
6341 SK_BOOL PortActiveFlag;
6345 PortActiveFlag = SK_FALSE;
6346 PhysPortMax = pAC->GIni.GIMacsFound;
6348 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6351 /* Check if the physical port is active */
6352 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6357 PortActiveFlag = SK_TRUE;
6361 case OID_SKGE_LINK_CAP:
6364 * Different capabilities should not happen, but
6365 * in the case of the cases OR them all together.
6366 * From a curious point of view the virtual port
6367 * is capable of all found capabilities.
6369 *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
6372 case OID_SKGE_LINK_MODE:
6373 /* Check if it is the first active port */
6376 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
6381 * If we find an active port with a different link
6382 * mode than the first one we return a value that
6383 * indicates that the link mode is indeterminated.
6385 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
6388 *pBuf = SK_LMODE_INDETERMINATED;
6392 case OID_SKGE_LINK_MODE_STATUS:
6393 /* Get the link mode of the physical port */
6394 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6396 /* Check if it is the first active port */
6404 * If we find an active port with a different link
6405 * mode status than the first one we return a value
6406 * that indicates that the link mode status is
6409 if (*pBuf != Val8) {
6411 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6415 case OID_SKGE_LINK_STATUS:
6416 /* Get the link status of the physical port */
6417 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6419 /* Check if it is the first active port */
6427 * If we find an active port with a different link
6428 * status than the first one, we return a value
6429 * that indicates that the link status is
6432 if (*pBuf != Val8) {
6434 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6438 case OID_SKGE_FLOWCTRL_CAP:
6439 /* Check if it is the first active port */
6442 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6447 * From a curious point of view the virtual port
6448 * is capable of all found capabilities.
6450 *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6453 case OID_SKGE_FLOWCTRL_MODE:
6454 /* Check if it is the first active port */
6457 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
6462 * If we find an active port with a different flow
6463 * control mode than the first one, we return a value
6464 * that indicates that the mode is indeterminated.
6466 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
6468 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6472 case OID_SKGE_FLOWCTRL_STATUS:
6473 /* Check if it is the first active port */
6476 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
6481 * If we find an active port with a different flow
6482 * control status than the first one, we return a
6483 * value that indicates that the status is
6486 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
6488 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6492 case OID_SKGE_PHY_OPERATION_CAP:
6493 /* Check if it is the first active port */
6496 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
6501 * From a curious point of view the virtual port
6502 * is capable of all found capabilities.
6504 *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
6507 case OID_SKGE_PHY_OPERATION_MODE:
6508 /* Check if it is the first active port */
6511 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
6516 * If we find an active port with a different master/
6517 * slave mode than the first one, we return a value
6518 * that indicates that the mode is indeterminated.
6520 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
6522 *pBuf = SK_MS_MODE_INDETERMINATED;
6526 case OID_SKGE_PHY_OPERATION_STATUS:
6527 /* Check if it is the first active port */
6530 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
6535 * If we find an active port with a different master/
6536 * slave status than the first one, we return a
6537 * value that indicates that the status is
6540 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
6542 *pBuf = SK_MS_STAT_INDETERMINATED;
6546 case OID_SKGE_SPEED_MODE:
6547 /* Check if it is the first active port */
6550 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
6555 * If we find an active port with a different flow
6556 * control mode than the first one, we return a value
6557 * that indicates that the mode is indeterminated.
6559 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
6561 *pBuf = SK_LSPEED_INDETERMINATED;
6565 case OID_SKGE_SPEED_STATUS:
6566 /* Check if it is the first active port */
6569 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
6574 * If we find an active port with a different flow
6575 * control status than the first one, we return a
6576 * value that indicates that the status is
6579 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
6581 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6588 * If no port is active return an indeterminated answer
6590 if (!PortActiveFlag) {
6594 case OID_SKGE_LINK_CAP:
6595 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6598 case OID_SKGE_LINK_MODE:
6599 *pBuf = SK_LMODE_INDETERMINATED;
6602 case OID_SKGE_LINK_MODE_STATUS:
6603 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6606 case OID_SKGE_LINK_STATUS:
6607 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6610 case OID_SKGE_FLOWCTRL_CAP:
6611 case OID_SKGE_FLOWCTRL_MODE:
6612 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6615 case OID_SKGE_FLOWCTRL_STATUS:
6616 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6619 case OID_SKGE_PHY_OPERATION_CAP:
6620 *pBuf = SK_MS_CAP_INDETERMINATED;
6623 case OID_SKGE_PHY_OPERATION_MODE:
6624 *pBuf = SK_MS_MODE_INDETERMINATED;
6627 case OID_SKGE_PHY_OPERATION_STATUS:
6628 *pBuf = SK_MS_STAT_INDETERMINATED;
6630 case OID_SKGE_SPEED_CAP:
6631 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6634 case OID_SKGE_SPEED_MODE:
6635 *pBuf = SK_LSPEED_INDETERMINATED;
6638 case OID_SKGE_SPEED_STATUS:
6639 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6645 /*****************************************************************************
6647 * CalculateLinkStatus - Determins the link status of a physical port
6650 * Determins the link status the following way:
6651 * LSTAT_PHY_DOWN: Link is down
6652 * LSTAT_AUTONEG: Auto-negotiation failed
6653 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6655 * LSTAT_LOG_UP: RLMT marked the port as up
6658 * Link status of physical port
6660 PNMI_STATIC SK_U8 CalculateLinkStatus(
6661 SK_AC *pAC, /* Pointer to adapter context */
6662 SK_IOC IoC, /* IO context handle */
6663 unsigned int PhysPortIndex) /* Physical port index */
6668 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6670 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6672 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6674 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6676 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6678 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6681 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6687 /*****************************************************************************
6689 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6692 * The COMMON module only tells us if the mode is half or full duplex.
6693 * But in the decade of auto sensing it is usefull for the user to
6694 * know if the mode was negotiated or forced. Therefore we have a
6695 * look to the mode, which was last used by the negotiation process.
6698 * The link mode status
6700 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6701 SK_AC *pAC, /* Pointer to adapter context */
6702 SK_IOC IoC, /* IO context handle */
6703 unsigned int PhysPortIndex) /* Physical port index */
6708 /* Get the current mode, which can be full or half duplex */
6709 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6711 /* Check if no valid mode could be found (link is down) */
6712 if (Result < SK_LMODE_STAT_HALF) {
6714 Result = SK_LMODE_STAT_UNKNOWN;
6716 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6719 * Auto-negotiation was used to bring up the link. Change
6720 * the already found duplex status that it indicates
6721 * auto-negotiation was involved.
6723 if (Result == SK_LMODE_STAT_HALF) {
6725 Result = SK_LMODE_STAT_AUTOHALF;
6727 else if (Result == SK_LMODE_STAT_FULL) {
6729 Result = SK_LMODE_STAT_AUTOFULL;
6736 /*****************************************************************************
6738 * GetVpdKeyArr - Obtain an array of VPD keys
6741 * Read the VPD keys and build an array of VPD keys, which are
6745 * SK_PNMI_ERR_OK Task successfully performed.
6746 * SK_PNMI_ERR_GENERAL Something went wrong.
6748 PNMI_STATIC int GetVpdKeyArr(
6749 SK_AC *pAC, /* Pointer to adapter context */
6750 SK_IOC IoC, /* IO context handle */
6751 char *pKeyArr, /* Ptr KeyArray */
6752 unsigned int KeyArrLen, /* Length of array in bytes */
6753 unsigned int *pKeyNo) /* Number of keys */
6755 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6756 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6757 unsigned int StartOffset;
6758 unsigned int Offset;
6763 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6768 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6772 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6775 return (SK_PNMI_ERR_GENERAL);
6777 /* If no keys are available return now */
6778 if (*pKeyNo == 0 || BufKeysLen == 0) {
6780 return (SK_PNMI_ERR_OK);
6783 * If the key list is too long for us trunc it and give a
6784 * errorlog notification. This case should not happen because
6785 * the maximum number of keys is limited due to RAM limitations
6787 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6789 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6792 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6796 * Now build an array of fixed string length size and copy
6797 * the keys together.
6799 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6802 if (BufKeys[Offset] != 0) {
6807 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6809 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6811 return (SK_PNMI_ERR_GENERAL);
6814 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6815 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6818 StartOffset = Offset + 1;
6821 /* Last key not zero terminated? Get it anyway */
6822 if (StartOffset < Offset) {
6824 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6825 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6828 return (SK_PNMI_ERR_OK);
6831 /*****************************************************************************
6833 * SirqUpdate - Let the SIRQ update its internal values
6836 * Just to be sure that the SIRQ module holds its internal data
6837 * structures up to date, we send an update event before we make
6841 * SK_PNMI_ERR_OK Task successfully performed.
6842 * SK_PNMI_ERR_GENERAL Something went wrong.
6844 PNMI_STATIC int SirqUpdate(
6845 SK_AC *pAC, /* Pointer to adapter context */
6846 SK_IOC IoC) /* IO context handle */
6848 SK_EVPARA EventParam;
6851 /* Was the module already updated during the current PNMI call? */
6852 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6854 return (SK_PNMI_ERR_OK);
6857 /* Send an synchronuous update event to the module */
6858 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6859 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6861 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6864 return (SK_PNMI_ERR_GENERAL);
6867 return (SK_PNMI_ERR_OK);
6870 /*****************************************************************************
6872 * RlmtUpdate - Let the RLMT update its internal values
6875 * Just to be sure that the RLMT module holds its internal data
6876 * structures up to date, we send an update event before we make
6880 * SK_PNMI_ERR_OK Task successfully performed.
6881 * SK_PNMI_ERR_GENERAL Something went wrong.
6883 PNMI_STATIC int RlmtUpdate(
6884 SK_AC *pAC, /* Pointer to adapter context */
6885 SK_IOC IoC, /* IO context handle */
6886 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6888 SK_EVPARA EventParam;
6891 /* Was the module already updated during the current PNMI call? */
6892 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6894 return (SK_PNMI_ERR_OK);
6897 /* Send an synchronuous update event to the module */
6898 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6899 EventParam.Para32[0] = NetIndex;
6900 EventParam.Para32[1] = (SK_U32)-1;
6901 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6903 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6906 return (SK_PNMI_ERR_GENERAL);
6909 return (SK_PNMI_ERR_OK);
6912 /*****************************************************************************
6914 * MacUpdate - Force the XMAC to output the current statistic
6917 * The XMAC holds its statistic internally. To obtain the current
6918 * values we send a command so that the statistic data will
6919 * be written to apredefined memory area on the adapter.
6922 * SK_PNMI_ERR_OK Task successfully performed.
6923 * SK_PNMI_ERR_GENERAL Something went wrong.
6925 PNMI_STATIC int MacUpdate(
6926 SK_AC *pAC, /* Pointer to adapter context */
6927 SK_IOC IoC, /* IO context handle */
6928 unsigned int FirstMac, /* Index of the first Mac to be updated */
6929 unsigned int LastMac) /* Index of the last Mac to be updated */
6931 unsigned int MacIndex;
6934 * Were the statistics already updated during the
6935 * current PNMI call?
6937 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6939 return (SK_PNMI_ERR_OK);
6942 /* Send an update command to all MACs specified */
6943 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6946 * 2002-09-13 pweber: Freeze the current sw counters.
6947 * (That should be done as close as
6948 * possible to the update of the
6951 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6952 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6955 /* 2002-09-13 pweber: Update the hw counter */
6956 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6958 return (SK_PNMI_ERR_GENERAL);
6962 return (SK_PNMI_ERR_OK);
6965 /*****************************************************************************
6967 * GetStatVal - Retrieve an XMAC statistic counter
6970 * Retrieves the statistic counter of a virtual or physical port. The
6971 * virtual port is identified by the index 0. It consists of all
6972 * currently active ports. To obtain the counter value for this port
6973 * we must add the statistic counter of all active ports. To grant
6974 * continuous counter values for the virtual port even when port
6975 * switches occur we must additionally add a delta value, which was
6976 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6979 * Requested statistic value
6981 PNMI_STATIC SK_U64 GetStatVal(
6982 SK_AC *pAC, /* Pointer to adapter context */
6983 SK_IOC IoC, /* IO context handle */
6984 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6985 unsigned int StatIndex, /* Index to statistic value */
6986 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6988 unsigned int PhysPortIndex;
6989 unsigned int PhysPortMax;
6993 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6995 PhysPortIndex = NetIndex;
6996 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6998 else { /* Single Net mode */
7000 if (LogPortIndex == 0) {
7002 PhysPortMax = pAC->GIni.GIMacsFound;
7004 /* Add counter of all active ports */
7005 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
7008 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
7010 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
7015 /* Correct value because of port switches */
7016 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
7019 /* Get counter value of physical port */
7020 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7021 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7027 /*****************************************************************************
7029 * GetPhysStatVal - Get counter value for physical port
7032 * Builds a 64bit counter value. Except for the octet counters
7033 * the lower 32bit are counted in hardware and the upper 32bit
7034 * in software by monitoring counter overflow interrupts in the
7035 * event handler. To grant continous counter values during XMAC
7036 * resets (caused by a workaround) we must add a delta value.
7037 * The delta was calculated in the event handler when a
7038 * SK_PNMI_EVT_XMAC_RESET was received.
7043 PNMI_STATIC SK_U64 GetPhysStatVal(
7044 SK_AC *pAC, /* Pointer to adapter context */
7045 SK_IOC IoC, /* IO context handle */
7046 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7047 unsigned int StatIndex) /* Index to statistic value */
7055 SK_PNMI_PORT *pPnmiPrt;
7056 SK_GEMACFUNC *pFnMac;
7058 MacType = pAC->GIni.GIMacType;
7060 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
7061 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
7062 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7065 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7068 pFnMac = &pAC->GIni.GIFunc;
7070 switch (StatIndex) {
7073 /* Not supported by GMAC */
7074 if (MacType == SK_MAC_GMAC) {
7078 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7079 StatAddr[StatIndex][MacType].Reg,
7081 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7084 case SK_PNMI_HTX_OCTET:
7085 case SK_PNMI_HRX_OCTET:
7086 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7087 StatAddr[StatIndex][MacType].Reg,
7089 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7090 StatAddr[StatIndex + 1][MacType].Reg,
7094 case SK_PNMI_HTX_BURST:
7095 case SK_PNMI_HTX_EXCESS_DEF:
7096 case SK_PNMI_HTX_CARRIER:
7097 /* Not supported by GMAC */
7098 if (MacType == SK_MAC_GMAC) {
7102 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7103 StatAddr[StatIndex][MacType].Reg,
7105 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7108 case SK_PNMI_HTX_MACC:
7109 /* GMAC only supports PAUSE MAC control frames */
7110 if (MacType == SK_MAC_GMAC) {
7111 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
7116 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7117 StatAddr[StatIndex][MacType].Reg,
7119 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7122 case SK_PNMI_HTX_COL:
7123 case SK_PNMI_HRX_UNDERSIZE:
7124 /* Not supported by XMAC */
7125 if (MacType == SK_MAC_XMAC) {
7129 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7130 StatAddr[StatIndex][MacType].Reg,
7132 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7136 case SK_PNMI_HTX_DEFFERAL:
7137 /* Not supported by GMAC */
7138 if (MacType == SK_MAC_GMAC) {
7143 * XMAC counts frames with deferred transmission
7144 * even in full-duplex mode.
7146 * In full-duplex mode the counter remains constant!
7148 if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7149 (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7155 /* Otherwise get contents of hardware register. */
7156 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7157 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
7159 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7163 case SK_PNMI_HRX_BADOCTET:
7164 /* Not supported by XMAC */
7165 if (MacType == SK_MAC_XMAC) {
7169 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7170 StatAddr[StatIndex][MacType].Reg,
7172 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7173 StatAddr[StatIndex + 1][MacType].Reg,
7177 case SK_PNMI_HTX_OCTETLOW:
7178 case SK_PNMI_HRX_OCTETLOW:
7179 case SK_PNMI_HRX_BADOCTETLOW:
7182 case SK_PNMI_HRX_LONGFRAMES:
7183 /* For XMAC the SW counter is managed by PNMI */
7184 if (MacType == SK_MAC_XMAC) {
7185 return (pPnmiPrt->StatRxLongFrameCts);
7188 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7189 StatAddr[StatIndex][MacType].Reg,
7191 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7194 case SK_PNMI_HRX_TOO_LONG:
7195 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7196 StatAddr[StatIndex][MacType].Reg,
7198 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7200 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7204 /* For GMAC the SW counter is additionally managed by PNMI */
7205 Val += pPnmiPrt->StatRxFrameTooLongCts;
7210 * Frames longer than IEEE 802.3 frame max size are counted
7211 * by XMAC in frame_too_long counter even reception of long
7212 * frames was enabled and the frame was correct.
7213 * So correct the value by subtracting RxLongFrame counter.
7215 Val -= pPnmiPrt->StatRxLongFrameCts;
7222 LowVal = (SK_U32)Val;
7223 HighVal = (SK_U32)(Val >> 32);
7226 case SK_PNMI_HRX_SHORTS:
7227 /* Not supported by GMAC */
7228 if (MacType == SK_MAC_GMAC) {
7234 * XMAC counts short frame errors even if link down (#10620)
7236 * If link-down the counter remains constant
7238 if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7240 /* Otherwise get incremental difference */
7241 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7242 StatAddr[StatIndex][MacType].Reg,
7244 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7246 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7247 Val -= pPnmiPrt->RxShortZeroMark;
7249 LowVal = (SK_U32)Val;
7250 HighVal = (SK_U32)(Val >> 32);
7254 case SK_PNMI_HRX_MACC:
7255 case SK_PNMI_HRX_MACC_UNKWN:
7256 case SK_PNMI_HRX_BURST:
7257 case SK_PNMI_HRX_MISSED:
7258 case SK_PNMI_HRX_FRAMING:
7259 case SK_PNMI_HRX_CARRIER:
7260 case SK_PNMI_HRX_IRLENGTH:
7261 case SK_PNMI_HRX_SYMBOL:
7262 case SK_PNMI_HRX_CEXT:
7263 /* Not supported by GMAC */
7264 if (MacType == SK_MAC_GMAC) {
7269 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7270 StatAddr[StatIndex][MacType].Reg,
7272 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7275 case SK_PNMI_HRX_PMACC_ERR:
7276 /* For GMAC the SW counter is managed by PNMI */
7277 if (MacType == SK_MAC_GMAC) {
7278 return (pPnmiPrt->StatRxPMaccErr);
7281 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7282 StatAddr[StatIndex][MacType].Reg,
7284 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7287 /* SW counter managed by PNMI */
7288 case SK_PNMI_HTX_SYNC:
7289 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7290 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7293 /* SW counter managed by PNMI */
7294 case SK_PNMI_HTX_SYNC_OCTET:
7295 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7296 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7299 case SK_PNMI_HRX_FCS:
7301 * Broadcom filters fcs errors and counts it in
7302 * Receive Error Counter register
7304 if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
7305 /* do not read while not initialized (PHY_READ hangs!)*/
7306 if (pAC->GIni.GP[PhysPortIndex].PState) {
7307 PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
7308 PhysPortIndex, PHY_BCOM_RE_CTR,
7313 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7316 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7317 StatAddr[StatIndex][MacType].Reg,
7319 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7324 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7325 StatAddr[StatIndex][MacType].Reg,
7327 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7331 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7333 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7334 Val += pPnmiPrt->CounterOffset[StatIndex];
7339 /*****************************************************************************
7341 * ResetCounter - Set all counters and timestamps to zero
7344 * Notifies other common modules which store statistic data to
7345 * reset their counters and finally reset our own counters.
7350 PNMI_STATIC void ResetCounter(
7351 SK_AC *pAC, /* Pointer to adapter context */
7352 SK_IOC IoC, /* IO context handle */
7355 unsigned int PhysPortIndex;
7356 SK_EVPARA EventParam;
7359 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7361 /* Notify sensor module */
7362 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7364 /* Notify RLMT module */
7365 EventParam.Para32[0] = NetIndex;
7366 EventParam.Para32[1] = (SK_U32)-1;
7367 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7368 EventParam.Para32[1] = 0;
7370 /* Notify SIRQ module */
7371 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7373 /* Notify CSUM module */
7375 EventParam.Para32[0] = NetIndex;
7376 EventParam.Para32[1] = (SK_U32)-1;
7377 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7381 /* Clear XMAC statistic */
7382 for (PhysPortIndex = 0; PhysPortIndex <
7383 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7385 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7387 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7388 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7389 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7390 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7391 PhysPortIndex].CounterOffset));
7392 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7393 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7394 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7395 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7396 PhysPortIndex].StatSyncOctetsCts));
7397 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7398 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7399 PhysPortIndex].StatRxLongFrameCts));
7400 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7401 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7402 PhysPortIndex].StatRxFrameTooLongCts));
7403 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7404 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7405 PhysPortIndex].StatRxPMaccErr));
7409 * Clear local statistics
7411 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7412 sizeof(pAC->Pnmi.VirtualCounterOffset));
7413 pAC->Pnmi.RlmtChangeCts = 0;
7414 pAC->Pnmi.RlmtChangeTime = 0;
7415 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7416 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7417 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7418 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7419 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7420 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7421 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7422 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7423 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7424 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7425 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7426 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7427 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7428 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7431 /*****************************************************************************
7433 * GetTrapEntry - Get an entry in the trap buffer
7436 * The trap buffer stores various events. A user application somehow
7437 * gets notified that an event occured and retrieves the trap buffer
7438 * contens (or simply polls the buffer). The buffer is organized as
7439 * a ring which stores the newest traps at the beginning. The oldest
7440 * traps are overwritten by the newest ones. Each trap entry has a
7441 * unique number, so that applications may detect new trap entries.
7444 * A pointer to the trap entry
7446 PNMI_STATIC char* GetTrapEntry(
7447 SK_AC *pAC, /* Pointer to adapter context */
7448 SK_U32 TrapId, /* SNMP ID of the trap */
7449 unsigned int Size) /* Space needed for trap entry */
7451 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7452 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7453 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7454 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7455 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7457 unsigned int NeededSpace;
7458 unsigned int EntrySize;
7463 /* Last byte of entry will get a copy of the entry length */
7467 * Calculate needed buffer space */
7474 NeededSpace = Beg + Size;
7479 * Check if enough buffer space is provided. Otherwise
7480 * free some entries. Leave one byte space between begin
7481 * and end of buffer to make it possible to detect whether
7482 * the buffer is full or empty
7484 while (BufFree < NeededSpace + 1) {
7488 End = SK_PNMI_TRAP_QUEUE_LEN;
7491 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7492 BufFree += EntrySize;
7495 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7497 if (End == BufPad) {
7499 SK_MEMSET(pBuf, (char)(-1), End);
7508 * Insert new entry as first entry. Newest entries are
7509 * stored at the beginning of the queue.
7514 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7519 BufFree -= NeededSpace;
7521 /* Save the current offsets */
7522 pAC->Pnmi.TrapQueueBeg = Beg;
7523 pAC->Pnmi.TrapQueueEnd = End;
7524 pAC->Pnmi.TrapBufPad = BufPad;
7525 pAC->Pnmi.TrapBufFree = BufFree;
7527 /* Initialize the trap entry */
7528 *(pBuf + Beg + Size - 1) = (char)Size;
7529 *(pBuf + Beg) = (char)Size;
7530 Val32 = (pAC->Pnmi.TrapUnique) ++;
7531 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7532 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7533 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7534 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7536 return (pBuf + Beg);
7539 /*****************************************************************************
7541 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7544 * On a query of the TRAP OID the trap buffer contents will be
7545 * copied continuously to the request buffer, which must be large
7546 * enough. No length check is performed.
7551 PNMI_STATIC void CopyTrapQueue(
7552 SK_AC *pAC, /* Pointer to adapter context */
7553 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7555 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7556 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7557 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7558 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7560 unsigned int DstOff = 0;
7563 while (Trap != End) {
7565 Len = (unsigned int)*(pBuf + Trap);
7568 * Last byte containing a copy of the length will
7571 *(pDstBuf + DstOff) = (char)(Len - 1);
7572 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7576 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7583 /*****************************************************************************
7585 * GetTrapQueueLen - Get the length of the trap buffer
7588 * Evaluates the number of currently stored traps and the needed
7589 * buffer size to retrieve them.
7594 PNMI_STATIC void GetTrapQueueLen(
7595 SK_AC *pAC, /* Pointer to adapter context */
7596 unsigned int *pLen, /* Length in Bytes of all queued traps */
7597 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7599 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7600 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7601 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7602 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7604 unsigned int Entries = 0;
7605 unsigned int TotalLen = 0;
7608 while (Trap != End) {
7610 Len = (unsigned int)*(pBuf + Trap);
7611 TotalLen += Len - 1;
7615 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7621 *pEntries = Entries;
7625 /*****************************************************************************
7627 * QueueSimpleTrap - Store a simple trap to the trap buffer
7630 * A simple trap is a trap with now additional data. It consists
7631 * simply of a trap code.
7636 PNMI_STATIC void QueueSimpleTrap(
7637 SK_AC *pAC, /* Pointer to adapter context */
7638 SK_U32 TrapId) /* Type of sensor trap */
7640 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7643 /*****************************************************************************
7645 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7648 * Gets an entry in the trap buffer and fills it with sensor related
7654 PNMI_STATIC void QueueSensorTrap(
7655 SK_AC *pAC, /* Pointer to adapter context */
7656 SK_U32 TrapId, /* Type of sensor trap */
7657 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7660 unsigned int Offset;
7661 unsigned int DescrLen;
7665 /* Get trap buffer entry */
7666 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7667 pBuf = GetTrapEntry(pAC, TrapId,
7668 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7669 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7671 /* Store additionally sensor trap related data */
7672 Val32 = OID_SKGE_SENSOR_INDEX;
7673 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7674 *(pBuf + Offset + 4) = 4;
7675 Val32 = (SK_U32)SensorIndex;
7676 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7679 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7680 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7681 *(pBuf + Offset + 4) = (char)DescrLen;
7682 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7684 Offset += DescrLen + 5;
7686 Val32 = OID_SKGE_SENSOR_TYPE;
7687 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7688 *(pBuf + Offset + 4) = 1;
7689 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7692 Val32 = OID_SKGE_SENSOR_VALUE;
7693 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7694 *(pBuf + Offset + 4) = 4;
7695 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7696 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7699 /*****************************************************************************
7701 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7704 * Nothing further to explain.
7709 PNMI_STATIC void QueueRlmtNewMacTrap(
7710 SK_AC *pAC, /* Pointer to adapter context */
7711 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7717 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7718 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7720 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7721 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7722 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7723 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7726 /*****************************************************************************
7728 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7731 * Nothing further to explain.
7736 PNMI_STATIC void QueueRlmtPortTrap(
7737 SK_AC *pAC, /* Pointer to adapter context */
7738 SK_U32 TrapId, /* Type of RLMT port trap */
7739 unsigned int PortIndex) /* Index of the port, which changed its state */
7745 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7747 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7748 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7749 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7750 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7753 /*****************************************************************************
7755 * CopyMac - Copies a MAC address
7758 * Nothing further to explain.
7763 PNMI_STATIC void CopyMac(
7764 char *pDst, /* Pointer to destination buffer */
7765 SK_MAC_ADDR *pMac) /* Pointer of Source */
7770 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7772 *(pDst + i) = pMac->a[i];
7777 #ifdef SK_POWER_MGMT
7778 /*****************************************************************************
7780 * PowerManagement - OID handler function of PowerManagement OIDs
7783 * The code is simple. No description necessary.
7786 * SK_PNMI_ERR_OK The request was successfully performed.
7787 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7788 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7789 * the correct data (e.g. a 32bit value is
7790 * needed, but a 16 bit value was passed).
7791 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7792 * exist (e.g. port instance 3 on a two port
7796 PNMI_STATIC int PowerManagement(
7797 SK_AC *pAC, /* Pointer to adapter context */
7798 SK_IOC IoC, /* IO context handle */
7799 int Action, /* Get/PreSet/Set action */
7800 SK_U32 Id, /* Object ID that is to be processed */
7801 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7802 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7803 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7804 unsigned int TableIndex, /* Index to the Id table */
7805 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7808 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7811 * Check instance. We only handle single instance variables
7813 if (Instance != (SK_U32)(-1) && Instance != 1) {
7816 return (SK_PNMI_ERR_UNKNOWN_INST);
7822 if (Action == SK_PNMI_GET) {
7829 case OID_PNP_CAPABILITIES:
7830 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7832 *pLen = sizeof(SK_PNP_CAPABILITIES);
7833 return (SK_PNMI_ERR_TOO_SHORT);
7837 case OID_PNP_QUERY_POWER:
7838 case OID_PNP_ENABLE_WAKE_UP:
7839 if (*pLen < sizeof(SK_U32)) {
7841 *pLen = sizeof(SK_U32);
7842 return (SK_PNMI_ERR_TOO_SHORT);
7846 case OID_PNP_SET_POWER:
7847 case OID_PNP_ADD_WAKE_UP_PATTERN:
7848 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7852 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
7855 return (SK_PNMI_ERR_GENERAL);
7863 case OID_PNP_CAPABILITIES:
7864 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7867 case OID_PNP_QUERY_POWER:
7868 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7869 the miniport to indicate whether it can transition its NIC
7870 to the low-power state.
7871 A miniport driver must always return NDIS_STATUS_SUCCESS
7872 to a query of OID_PNP_QUERY_POWER. */
7873 RetCode = SK_PNMI_ERR_OK;
7876 /* NDIS handles these OIDs as write-only.
7877 * So in case of get action the buffer with written length = 0
7880 case OID_PNP_SET_POWER:
7881 case OID_PNP_ADD_WAKE_UP_PATTERN:
7882 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7884 RetCode = SK_PNMI_ERR_OK;
7887 case OID_PNP_ENABLE_WAKE_UP:
7888 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7892 RetCode = SK_PNMI_ERR_GENERAL;
7900 * From here SET or PRESET action. Check if the passed
7901 * buffer length is plausible.
7904 case OID_PNP_SET_POWER:
7905 case OID_PNP_ENABLE_WAKE_UP:
7906 if (*pLen < sizeof(SK_U32)) {
7908 *pLen = sizeof(SK_U32);
7909 return (SK_PNMI_ERR_TOO_SHORT);
7911 if (*pLen != sizeof(SK_U32)) {
7914 return (SK_PNMI_ERR_BAD_VALUE);
7918 case OID_PNP_ADD_WAKE_UP_PATTERN:
7919 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7920 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7923 return (SK_PNMI_ERR_BAD_VALUE);
7929 return (SK_PNMI_ERR_READ_ONLY);
7933 * Perform preset or set
7936 /* POWER module does not support PRESET action */
7937 if (Action == SK_PNMI_PRESET) {
7938 return (SK_PNMI_ERR_OK);
7942 case OID_PNP_SET_POWER:
7943 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7946 case OID_PNP_ADD_WAKE_UP_PATTERN:
7947 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7950 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7951 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7954 case OID_PNP_ENABLE_WAKE_UP:
7955 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7959 RetCode = SK_PNMI_ERR_GENERAL;
7964 #endif /* SK_POWER_MGMT */
7967 /*****************************************************************************
7969 * Vct - OID handler function of OIDs
7972 * The code is simple. No description necessary.
7975 * SK_PNMI_ERR_OK The request was performed successfully.
7976 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7977 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7978 * the correct data (e.g. a 32bit value is
7979 * needed, but a 16 bit value was passed).
7980 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7981 * exist (e.g. port instance 3 on a two port
7983 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7987 PNMI_STATIC int Vct(
7988 SK_AC *pAC, /* Pointer to adapter context */
7989 SK_IOC IoC, /* IO context handle */
7990 int Action, /* Get/PreSet/Set action */
7991 SK_U32 Id, /* Object ID that is to be processed */
7992 char *pBuf, /* Buffer to which the mgmt data will be copied */
7993 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7994 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7995 unsigned int TableIndex, /* Index to the Id table */
7996 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7999 SK_PNMI_VCT *pVctBackupData;
8002 SK_U32 PhysPortIndex;
8006 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8012 * Calculate the port indexes from the instance.
8014 PhysPortMax = pAC->GIni.GIMacsFound;
8015 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
8017 /* Dual net mode? */
8018 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8022 if ((Instance != (SK_U32) (-1))) {
8023 /* Check instance range. */
8024 if ((Instance < 2) || (Instance > LogPortMax)) {
8026 return (SK_PNMI_ERR_UNKNOWN_INST);
8029 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8030 PhysPortIndex = NetIndex;
8033 PhysPortIndex = Instance - 2;
8035 Limit = PhysPortIndex + 1;
8038 * Instance == (SK_U32) (-1), get all Instances of that OID.
8040 * Not implemented yet. May be used in future releases.
8043 Limit = PhysPortMax;
8046 pPrt = &pAC->GIni.GP[PhysPortIndex];
8047 if (pPrt->PHWLinkUp) {
8057 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8059 return (SK_PNMI_ERR_GENERAL);
8062 /* Initialize backup data pointer. */
8063 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8066 * Check action type.
8068 if (Action == SK_PNMI_GET) {
8074 case OID_SKGE_VCT_GET:
8075 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8076 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8077 return (SK_PNMI_ERR_TOO_SHORT);
8081 case OID_SKGE_VCT_STATUS:
8082 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8083 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8084 return (SK_PNMI_ERR_TOO_SHORT);
8090 return (SK_PNMI_ERR_GENERAL);
8097 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8100 case OID_SKGE_VCT_GET:
8101 if ((Link == SK_FALSE) &&
8102 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8103 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8105 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8106 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8107 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8109 /* Copy results for later use to PNMI struct. */
8110 for (i = 0; i < 4; i++) {
8111 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8112 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8113 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8116 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8117 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8122 pVctBackupData->PMdiPairLen[i] = CableLength;
8123 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8126 Para.Para32[0] = PhysPortIndex;
8127 Para.Para32[1] = -1;
8128 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8129 SkEventDispatcher(pAC, IoC);
8132 ; /* VCT test is running. */
8136 /* Get all results. */
8137 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8138 Offset += sizeof(SK_U8);
8139 *(pBuf + Offset) = pPrt->PCableLen;
8140 Offset += sizeof(SK_U8);
8141 for (i = 0; i < 4; i++) {
8142 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8143 Offset += sizeof(SK_U32);
8145 for (i = 0; i < 4; i++) {
8146 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8147 Offset += sizeof(SK_U8);
8150 RetCode = SK_PNMI_ERR_OK;
8153 case OID_SKGE_VCT_STATUS:
8154 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8155 Offset += sizeof(SK_U8);
8156 RetCode = SK_PNMI_ERR_OK;
8161 return (SK_PNMI_ERR_GENERAL);
8167 } /* if SK_PNMI_GET */
8170 * From here SET or PRESET action. Check if the passed
8171 * buffer length is plausible.
8178 case OID_SKGE_VCT_SET:
8179 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8180 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8181 return (SK_PNMI_ERR_TOO_SHORT);
8187 return (SK_PNMI_ERR_GENERAL);
8191 * Perform preset or set.
8194 /* VCT does not support PRESET action. */
8195 if (Action == SK_PNMI_PRESET) {
8196 return (SK_PNMI_ERR_OK);
8200 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8202 case OID_SKGE_VCT_SET: /* Start VCT test. */
8203 if (Link == SK_FALSE) {
8204 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8206 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8207 if (RetCode == 0) { /* RetCode: 0 => Start! */
8208 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8209 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8210 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8213 * Start VCT timer counter.
8215 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8216 Para.Para32[0] = PhysPortIndex;
8217 Para.Para32[1] = -1;
8218 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8219 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8220 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8221 RetCode = SK_PNMI_ERR_OK;
8223 else { /* RetCode: 2 => Running! */
8224 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8225 RetCode = SK_PNMI_ERR_OK;
8228 else { /* RetCode: 4 => Link! */
8230 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8231 RetCode = SK_PNMI_ERR_OK;
8233 Offset += sizeof(SK_U32);
8238 return (SK_PNMI_ERR_GENERAL);
8247 PNMI_STATIC void CheckVctStatus(
8252 SK_U32 PhysPortIndex)
8255 SK_PNMI_VCT *pVctData;
8257 SK_U8 LinkSpeedUsed;
8259 pPrt = &pAC->GIni.GP[PhysPortIndex];
8261 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8262 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8264 if (!pPrt->PHWLinkUp) {
8266 /* Was a VCT test ever made before? */
8267 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8268 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8269 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8272 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8276 /* Check VCT test status. */
8277 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8278 if (RetCode == 2) { /* VCT test is running. */
8279 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8281 else { /* VCT data was copied to pAC here. Check PENDING state. */
8282 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8283 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8287 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8288 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8293 /* Was a VCT test ever made before? */
8294 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8295 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8296 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8299 /* DSP only valid in 100/1000 modes. */
8300 LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
8301 if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
8302 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8306 } /* CheckVctStatus */