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 ****************************************************************************/
435 static const char SysKonnectFileId[] =
436 "@(#) $Id: skgepnmi.c,v 1.102 2002/12/16 14:03:24 tschilli Exp $"
439 #include "h/skdrv1st.h"
440 #include "h/sktypes.h"
441 #include "h/xmac_ii.h"
442 #include "h/skdebug.h"
443 #include "h/skqueue.h"
444 #include "h/skgepnmi.h"
445 #include "h/skgesirq.h"
446 #include "h/skcsum.h"
448 #include "h/skgehw.h"
449 #include "h/skgeinit.h"
450 #include "h/skdrv2nd.h"
451 #include "h/skgepnm2.h"
453 #include "h/skgepmgt.h"
455 /* defines *******************************************************************/
458 #define PNMI_STATIC static
464 * Public Function prototypes
466 int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level);
467 int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
468 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
469 int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
470 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
471 int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf,
472 unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
473 int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
474 unsigned int *pLen, SK_U32 NetIndex);
475 int SkPnmiPreSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
476 unsigned int *pLen, SK_U32 NetIndex);
477 int SkPnmiSetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf,
478 unsigned int *pLen, SK_U32 NetIndex);
479 int SkPnmiEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Param);
483 * Private Function prototypes
486 PNMI_STATIC SK_U8 CalculateLinkModeStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
488 PNMI_STATIC SK_U8 CalculateLinkStatus(SK_AC *pAC, SK_IOC IoC, unsigned int
490 PNMI_STATIC void CopyMac(char *pDst, SK_MAC_ADDR *pMac);
491 PNMI_STATIC void CopyTrapQueue(SK_AC *pAC, char *pDstBuf);
492 PNMI_STATIC SK_U64 GetPhysStatVal(SK_AC *pAC, SK_IOC IoC,
493 unsigned int PhysPortIndex, unsigned int StatIndex);
494 PNMI_STATIC SK_U64 GetStatVal(SK_AC *pAC, SK_IOC IoC, unsigned int LogPortIndex,
495 unsigned int StatIndex, SK_U32 NetIndex);
496 PNMI_STATIC char* GetTrapEntry(SK_AC *pAC, SK_U32 TrapId, unsigned int Size);
497 PNMI_STATIC void GetTrapQueueLen(SK_AC *pAC, unsigned int *pLen,
498 unsigned int *pEntries);
499 PNMI_STATIC int GetVpdKeyArr(SK_AC *pAC, SK_IOC IoC, char *pKeyArr,
500 unsigned int KeyArrLen, unsigned int *pKeyNo);
501 PNMI_STATIC int LookupId(SK_U32 Id);
502 PNMI_STATIC int MacUpdate(SK_AC *pAC, SK_IOC IoC, unsigned int FirstMac,
503 unsigned int LastMac);
504 PNMI_STATIC int PnmiStruct(SK_AC *pAC, SK_IOC IoC, int Action, char *pBuf,
505 unsigned int *pLen, SK_U32 NetIndex);
506 PNMI_STATIC int PnmiVar(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id,
507 char *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex);
508 PNMI_STATIC void QueueRlmtNewMacTrap(SK_AC *pAC, unsigned int ActiveMac);
509 PNMI_STATIC void QueueRlmtPortTrap(SK_AC *pAC, SK_U32 TrapId,
510 unsigned int PortIndex);
511 PNMI_STATIC void QueueSensorTrap(SK_AC *pAC, SK_U32 TrapId,
512 unsigned int SensorIndex);
513 PNMI_STATIC void QueueSimpleTrap(SK_AC *pAC, SK_U32 TrapId);
514 PNMI_STATIC void ResetCounter(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
515 PNMI_STATIC int RlmtUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 NetIndex);
516 PNMI_STATIC int SirqUpdate(SK_AC *pAC, SK_IOC IoC);
517 PNMI_STATIC void VirtualConf(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, char *pBuf);
518 PNMI_STATIC int Vct(SK_AC *pAC, SK_IOC IoC, int Action, SK_U32 Id, char *pBuf,
519 unsigned int *pLen, SK_U32 Instance, unsigned int TableIndex, SK_U32 NetIndex);
520 PNMI_STATIC void CheckVctStatus(SK_AC *, SK_IOC, char *, SK_U32, SK_U32);
523 * Table to correlate OID with handler function and index to
524 * hardware register stored in StatAddress if applicable.
528 /* global variables **********************************************************/
531 * Overflow status register bit table and corresponding counter
532 * dependent on MAC type - the number relates to the size of overflow
533 * mask returned by the pFnMacOverflow function
535 PNMI_STATIC const SK_U16 StatOvrflwBit[][SK_PNMI_MAC_TYPES] = {
536 /* Bit0 */ { SK_PNMI_HTX, SK_PNMI_HTX_UNICAST},
537 /* Bit1 */ { SK_PNMI_HTX_OCTETHIGH, SK_PNMI_HTX_BROADCAST},
538 /* Bit2 */ { SK_PNMI_HTX_OCTETLOW, SK_PNMI_HTX_PMACC},
539 /* Bit3 */ { SK_PNMI_HTX_BROADCAST, SK_PNMI_HTX_MULTICAST},
540 /* Bit4 */ { SK_PNMI_HTX_MULTICAST, SK_PNMI_HTX_OCTETLOW},
541 /* Bit5 */ { SK_PNMI_HTX_UNICAST, SK_PNMI_HTX_OCTETHIGH},
542 /* Bit6 */ { SK_PNMI_HTX_LONGFRAMES, SK_PNMI_HTX_64},
543 /* Bit7 */ { SK_PNMI_HTX_BURST, SK_PNMI_HTX_127},
544 /* Bit8 */ { SK_PNMI_HTX_PMACC, SK_PNMI_HTX_255},
545 /* Bit9 */ { SK_PNMI_HTX_MACC, SK_PNMI_HTX_511},
546 /* Bit10 */ { SK_PNMI_HTX_SINGLE_COL, SK_PNMI_HTX_1023},
547 /* Bit11 */ { SK_PNMI_HTX_MULTI_COL, SK_PNMI_HTX_MAX},
548 /* Bit12 */ { SK_PNMI_HTX_EXCESS_COL, SK_PNMI_HTX_LONGFRAMES},
549 /* Bit13 */ { SK_PNMI_HTX_LATE_COL, SK_PNMI_HTX_RESERVED},
550 /* Bit14 */ { SK_PNMI_HTX_DEFFERAL, SK_PNMI_HTX_COL},
551 /* Bit15 */ { SK_PNMI_HTX_EXCESS_DEF, SK_PNMI_HTX_LATE_COL},
552 /* Bit16 */ { SK_PNMI_HTX_UNDERRUN, SK_PNMI_HTX_EXCESS_COL},
553 /* Bit17 */ { SK_PNMI_HTX_CARRIER, SK_PNMI_HTX_MULTI_COL},
554 /* Bit18 */ { SK_PNMI_HTX_UTILUNDER, SK_PNMI_HTX_SINGLE_COL},
555 /* Bit19 */ { SK_PNMI_HTX_UTILOVER, SK_PNMI_HTX_UNDERRUN},
556 /* Bit20 */ { SK_PNMI_HTX_64, SK_PNMI_HTX_RESERVED},
557 /* Bit21 */ { SK_PNMI_HTX_127, SK_PNMI_HTX_RESERVED},
558 /* Bit22 */ { SK_PNMI_HTX_255, SK_PNMI_HTX_RESERVED},
559 /* Bit23 */ { SK_PNMI_HTX_511, SK_PNMI_HTX_RESERVED},
560 /* Bit24 */ { SK_PNMI_HTX_1023, SK_PNMI_HTX_RESERVED},
561 /* Bit25 */ { SK_PNMI_HTX_MAX, SK_PNMI_HTX_RESERVED},
562 /* Bit26 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
563 /* Bit27 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
564 /* Bit28 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
565 /* Bit29 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
566 /* Bit30 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
567 /* Bit31 */ { SK_PNMI_HTX_RESERVED, SK_PNMI_HTX_RESERVED},
568 /* Bit32 */ { SK_PNMI_HRX, SK_PNMI_HRX_UNICAST},
569 /* Bit33 */ { SK_PNMI_HRX_OCTETHIGH, SK_PNMI_HRX_BROADCAST},
570 /* Bit34 */ { SK_PNMI_HRX_OCTETLOW, SK_PNMI_HRX_PMACC},
571 /* Bit35 */ { SK_PNMI_HRX_BROADCAST, SK_PNMI_HRX_MULTICAST},
572 /* Bit36 */ { SK_PNMI_HRX_MULTICAST, SK_PNMI_HRX_FCS},
573 /* Bit37 */ { SK_PNMI_HRX_UNICAST, SK_PNMI_HRX_RESERVED},
574 /* Bit38 */ { SK_PNMI_HRX_PMACC, SK_PNMI_HRX_OCTETLOW},
575 /* Bit39 */ { SK_PNMI_HRX_MACC, SK_PNMI_HRX_OCTETHIGH},
576 /* Bit40 */ { SK_PNMI_HRX_PMACC_ERR, SK_PNMI_HRX_BADOCTETLOW},
577 /* Bit41 */ { SK_PNMI_HRX_MACC_UNKWN, SK_PNMI_HRX_BADOCTETHIGH},
578 /* Bit42 */ { SK_PNMI_HRX_BURST, SK_PNMI_HRX_UNDERSIZE},
579 /* Bit43 */ { SK_PNMI_HRX_MISSED, SK_PNMI_HRX_RUNT},
580 /* Bit44 */ { SK_PNMI_HRX_FRAMING, SK_PNMI_HRX_64},
581 /* Bit45 */ { SK_PNMI_HRX_OVERFLOW, SK_PNMI_HRX_127},
582 /* Bit46 */ { SK_PNMI_HRX_JABBER, SK_PNMI_HRX_255},
583 /* Bit47 */ { SK_PNMI_HRX_CARRIER, SK_PNMI_HRX_511},
584 /* Bit48 */ { SK_PNMI_HRX_IRLENGTH, SK_PNMI_HRX_1023},
585 /* Bit49 */ { SK_PNMI_HRX_SYMBOL, SK_PNMI_HRX_MAX},
586 /* Bit50 */ { SK_PNMI_HRX_SHORTS, SK_PNMI_HRX_LONGFRAMES},
587 /* Bit51 */ { SK_PNMI_HRX_RUNT, SK_PNMI_HRX_TOO_LONG},
588 /* Bit52 */ { SK_PNMI_HRX_TOO_LONG, SK_PNMI_HRX_JABBER},
589 /* Bit53 */ { SK_PNMI_HRX_FCS, SK_PNMI_HRX_RESERVED},
590 /* Bit54 */ { SK_PNMI_HRX_RESERVED, SK_PNMI_HRX_OVERFLOW},
591 /* Bit55 */ { SK_PNMI_HRX_CEXT, SK_PNMI_HRX_RESERVED},
592 /* Bit56 */ { SK_PNMI_HRX_UTILUNDER, SK_PNMI_HRX_RESERVED},
593 /* Bit57 */ { SK_PNMI_HRX_UTILOVER, SK_PNMI_HRX_RESERVED},
594 /* Bit58 */ { SK_PNMI_HRX_64, SK_PNMI_HRX_RESERVED},
595 /* Bit59 */ { SK_PNMI_HRX_127, SK_PNMI_HRX_RESERVED},
596 /* Bit60 */ { SK_PNMI_HRX_255, SK_PNMI_HRX_RESERVED},
597 /* Bit61 */ { SK_PNMI_HRX_511, SK_PNMI_HRX_RESERVED},
598 /* Bit62 */ { SK_PNMI_HRX_1023, SK_PNMI_HRX_RESERVED},
599 /* Bit63 */ { SK_PNMI_HRX_MAX, SK_PNMI_HRX_RESERVED}
603 * Table for hardware register saving on resets and port switches
605 PNMI_STATIC const SK_PNMI_STATADDR StatAddr[SK_PNMI_MAX_IDX][SK_PNMI_MAC_TYPES] = {
607 {{XM_TXF_OK, SK_TRUE}, {0, SK_FALSE}},
608 /* SK_PNMI_HTX_OCTETHIGH */
609 {{XM_TXO_OK_HI, SK_TRUE}, {GM_TXO_OK_HI, SK_TRUE}},
610 /* SK_PNMI_HTX_OCTETLOW */
611 {{XM_TXO_OK_LO, SK_FALSE}, {GM_TXO_OK_LO, SK_FALSE}},
612 /* SK_PNMI_HTX_BROADCAST */
613 {{XM_TXF_BC_OK, SK_TRUE}, {GM_TXF_BC_OK, SK_TRUE}},
614 /* SK_PNMI_HTX_MULTICAST */
615 {{XM_TXF_MC_OK, SK_TRUE}, {GM_TXF_MC_OK, SK_TRUE}},
616 /* SK_PNMI_HTX_UNICAST */
617 {{XM_TXF_UC_OK, SK_TRUE}, {GM_TXF_UC_OK, SK_TRUE}},
618 /* SK_PNMI_HTX_BURST */
619 {{XM_TXE_BURST, SK_TRUE}, {0, SK_FALSE}},
620 /* SK_PNMI_HTX_PMACC */
621 {{XM_TXF_MPAUSE, SK_TRUE}, {GM_TXF_MPAUSE, SK_TRUE}},
622 /* SK_PNMI_HTX_MACC */
623 {{XM_TXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
624 /* SK_PNMI_HTX_COL */
625 {{0, SK_FALSE}, {GM_TXF_COL, SK_TRUE}},
626 /* SK_PNMI_HTX_SINGLE_COL */
627 {{XM_TXF_SNG_COL, SK_TRUE}, {GM_TXF_SNG_COL, SK_TRUE}},
628 /* SK_PNMI_HTX_MULTI_COL */
629 {{XM_TXF_MUL_COL, SK_TRUE}, {GM_TXF_MUL_COL, SK_TRUE}},
630 /* SK_PNMI_HTX_EXCESS_COL */
631 {{XM_TXF_ABO_COL, SK_TRUE}, {GM_TXF_ABO_COL, SK_TRUE}},
632 /* SK_PNMI_HTX_LATE_COL */
633 {{XM_TXF_LAT_COL, SK_TRUE}, {GM_TXF_LAT_COL, SK_TRUE}},
634 /* SK_PNMI_HTX_DEFFERAL */
635 {{XM_TXF_DEF, SK_TRUE}, {0, SK_FALSE}},
636 /* SK_PNMI_HTX_EXCESS_DEF */
637 {{XM_TXF_EX_DEF, SK_TRUE}, {0, SK_FALSE}},
638 /* SK_PNMI_HTX_UNDERRUN */
639 {{XM_TXE_FIFO_UR, SK_TRUE}, {GM_TXE_FIFO_UR, SK_TRUE}},
640 /* SK_PNMI_HTX_CARRIER */
641 {{XM_TXE_CS_ERR, SK_TRUE}, {0, SK_FALSE}},
642 /* SK_PNMI_HTX_UTILUNDER */
643 {{0, SK_FALSE}, {0, SK_FALSE}},
644 /* SK_PNMI_HTX_UTILOVER */
645 {{0, SK_FALSE}, {0, SK_FALSE}},
647 {{XM_TXF_64B, SK_TRUE}, {GM_TXF_64B, SK_TRUE}},
648 /* SK_PNMI_HTX_127 */
649 {{XM_TXF_127B, SK_TRUE}, {GM_TXF_127B, SK_TRUE}},
650 /* SK_PNMI_HTX_255 */
651 {{XM_TXF_255B, SK_TRUE}, {GM_TXF_255B, SK_TRUE}},
652 /* SK_PNMI_HTX_511 */
653 {{XM_TXF_511B, SK_TRUE}, {GM_TXF_511B, SK_TRUE}},
654 /* SK_PNMI_HTX_1023 */
655 {{XM_TXF_1023B, SK_TRUE}, {GM_TXF_1023B, SK_TRUE}},
656 /* SK_PNMI_HTX_MAX */
657 {{XM_TXF_MAX_SZ, SK_TRUE}, {GM_TXF_1518B, SK_TRUE}},
658 /* SK_PNMI_HTX_LONGFRAMES */
659 {{XM_TXF_LONG, SK_TRUE}, {GM_TXF_MAX_SZ, SK_TRUE}},
660 /* SK_PNMI_HTX_SYNC */
661 {{0, SK_FALSE}, {0, SK_FALSE}},
662 /* SK_PNMI_HTX_SYNC_OCTET */
663 {{0, SK_FALSE}, {0, SK_FALSE}},
664 /* SK_PNMI_HTX_RESERVED */
665 {{0, SK_FALSE}, {0, SK_FALSE}},
667 {{XM_RXF_OK, SK_TRUE}, {0, SK_FALSE}},
668 /* SK_PNMI_HRX_OCTETHIGH */
669 {{XM_RXO_OK_HI, SK_TRUE}, {GM_RXO_OK_HI, SK_TRUE}},
670 /* SK_PNMI_HRX_OCTETLOW */
671 {{XM_RXO_OK_LO, SK_FALSE}, {GM_RXO_OK_LO, SK_FALSE}},
672 /* SK_PNMI_HRX_BADOCTETHIGH */
673 {{0, SK_FALSE}, {GM_RXO_ERR_HI, SK_TRUE}},
674 /* SK_PNMI_HRX_BADOCTETLOW */
675 {{0, SK_FALSE}, {GM_RXO_ERR_LO, SK_TRUE}},
676 /* SK_PNMI_HRX_BROADCAST */
677 {{XM_RXF_BC_OK, SK_TRUE}, {GM_RXF_BC_OK, SK_TRUE}},
678 /* SK_PNMI_HRX_MULTICAST */
679 {{XM_RXF_MC_OK, SK_TRUE}, {GM_RXF_MC_OK, SK_TRUE}},
680 /* SK_PNMI_HRX_UNICAST */
681 {{XM_RXF_UC_OK, SK_TRUE}, {GM_RXF_UC_OK, SK_TRUE}},
682 /* SK_PNMI_HRX_PMACC */
683 {{XM_RXF_MPAUSE, SK_TRUE}, {GM_RXF_MPAUSE, SK_TRUE}},
684 /* SK_PNMI_HRX_MACC */
685 {{XM_RXF_MCTRL, SK_TRUE}, {0, SK_FALSE}},
686 /* SK_PNMI_HRX_PMACC_ERR */
687 {{XM_RXF_INV_MP, SK_TRUE}, {0, SK_FALSE}},
688 /* SK_PNMI_HRX_MACC_UNKWN */
689 {{XM_RXF_INV_MOC, SK_TRUE}, {0, SK_FALSE}},
690 /* SK_PNMI_HRX_BURST */
691 {{XM_RXE_BURST, SK_TRUE}, {0, SK_FALSE}},
692 /* SK_PNMI_HRX_MISSED */
693 {{XM_RXE_FMISS, SK_TRUE}, {0, SK_FALSE}},
694 /* SK_PNMI_HRX_FRAMING */
695 {{XM_RXF_FRA_ERR, SK_TRUE}, {0, SK_FALSE}},
696 /* SK_PNMI_HRX_UNDERSIZE */
697 {{0, SK_FALSE},{GM_RXF_SHT, SK_TRUE}},
698 /* SK_PNMI_HRX_OVERFLOW */
699 {{XM_RXE_FIFO_OV, SK_TRUE}, {GM_RXE_FIFO_OV, SK_TRUE}},
700 /* SK_PNMI_HRX_JABBER */
701 {{XM_RXF_JAB_PKT, SK_TRUE}, {GM_RXF_JAB_PKT, SK_TRUE}},
702 /* SK_PNMI_HRX_CARRIER */
703 {{XM_RXE_CAR_ERR, SK_TRUE}, {0, SK_FALSE}},
704 /* SK_PNMI_HRX_IRLENGTH */
705 {{XM_RXF_LEN_ERR, SK_TRUE}, {0, SK_FALSE}},
706 /* SK_PNMI_HRX_SYMBOL */
707 {{XM_RXE_SYM_ERR, SK_TRUE}, {0, SK_FALSE}},
708 /* SK_PNMI_HRX_SHORTS */
709 {{XM_RXE_SHT_ERR, SK_TRUE}, {0, SK_FALSE}},
710 /* SK_PNMI_HRX_RUNT */
711 {{XM_RXE_RUNT, SK_TRUE}, {GM_RXE_FRAG, SK_TRUE}},
712 /* SK_PNMI_HRX_TOO_LONG */
713 {{XM_RXF_LNG_ERR, SK_TRUE}, {GM_RXF_LNG_ERR, SK_TRUE}},
714 /* SK_PNMI_HRX_FCS */
715 {{XM_RXF_FCS_ERR, SK_TRUE}, {GM_RXF_FCS_ERR, SK_TRUE}},
716 /* SK_PNMI_HRX_CEXT */
717 {{XM_RXF_CEX_ERR, SK_TRUE}, {0, SK_FALSE}},
718 /* SK_PNMI_HRX_UTILUNDER */
719 {{0, SK_FALSE}, {0, SK_FALSE}},
720 /* SK_PNMI_HRX_UTILOVER */
721 {{0, SK_FALSE}, {0, SK_FALSE}},
723 {{XM_RXF_64B, SK_TRUE}, {GM_RXF_64B, SK_TRUE}},
724 /* SK_PNMI_HRX_127 */
725 {{XM_RXF_127B, SK_TRUE}, {GM_RXF_127B, SK_TRUE}},
726 /* SK_PNMI_HRX_255 */
727 {{XM_RXF_255B, SK_TRUE}, {GM_RXF_255B, SK_TRUE}},
728 /* SK_PNMI_HRX_511 */
729 {{XM_RXF_511B, SK_TRUE}, {GM_RXF_511B, SK_TRUE}},
730 /* SK_PNMI_HRX_1023 */
731 {{XM_RXF_1023B, SK_TRUE}, {GM_RXF_1023B, SK_TRUE}},
732 /* SK_PNMI_HRX_MAX */
733 {{XM_RXF_MAX_SZ, SK_TRUE}, {GM_RXF_1518B, SK_TRUE}},
734 /* SK_PNMI_HRX_LONGFRAMES */
735 {{0, SK_FALSE}, {GM_RXF_MAX_SZ, SK_TRUE}},
736 /* SK_PNMI_HRX_RESERVED */
737 {{0, SK_FALSE}, {0, SK_FALSE}}
741 /*****************************************************************************
747 /*****************************************************************************
749 * SkPnmiInit - Init function of PNMI
752 * SK_INIT_DATA: Initialises the data structures
753 * SK_INIT_IO: Resets the XMAC statistics, determines the device and
755 * SK_INIT_RUN: Starts a timer event for port switch per hour
762 SK_AC *pAC, /* Pointer to adapter context */
763 SK_IOC IoC, /* IO context handle */
764 int Level) /* Initialization level */
766 unsigned int PortMax; /* Number of ports */
767 unsigned int PortIndex; /* Current port index in loop */
768 SK_U16 Val16; /* Multiple purpose 16 bit variable */
769 SK_U8 Val8; /* Mulitple purpose 8 bit variable */
770 SK_EVPARA EventParam; /* Event struct for timer event */
772 SK_PNMI_VCT *pVctBackupData;
775 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
776 ("PNMI: SkPnmiInit: Called, level=%d\n", Level));
781 SK_MEMSET((char *)&pAC->Pnmi, 0, sizeof(pAC->Pnmi));
782 pAC->Pnmi.TrapBufFree = SK_PNMI_TRAP_QUEUE_LEN;
783 pAC->Pnmi.StartUpTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
784 pAC->Pnmi.RlmtChangeThreshold = SK_PNMI_DEF_RLMT_CHG_THRES;
785 for (PortIndex = 0; PortIndex < SK_MAX_MACS; PortIndex ++) {
787 pAC->Pnmi.Port[PortIndex].ActiveFlag = SK_FALSE;
788 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
792 if (SK_PNMI_MAX_IDX != SK_PNMI_CNT_NO) {
794 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR049, SK_PNMI_ERR049MSG);
796 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
797 ("CounterOffset struct size (%d) differs from"
798 "SK_PNMI_MAX_IDX (%d)\n",
799 SK_PNMI_CNT_NO, SK_PNMI_MAX_IDX));
803 if (SK_PNMI_MAX_IDX !=
804 (sizeof(StatAddr) / (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES))) {
806 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR050, SK_PNMI_ERR050MSG);
808 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_INIT | SK_DBGCAT_FATAL,
809 ("StatAddr table size (%d) differs from "
810 "SK_PNMI_MAX_IDX (%d)\n",
812 (sizeof(SK_PNMI_STATADDR) * SK_PNMI_MAC_TYPES)),
816 #endif /* SK_PNMI_CHECK */
823 PortMax = pAC->GIni.GIMacsFound;
825 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
827 pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PortIndex);
830 /* Initialize DSP variables for Vct() to 0xff => Never written! */
831 for (PortIndex = 0; PortIndex < PortMax; PortIndex ++) {
832 pPrt = &pAC->GIni.GP[PortIndex];
833 pPrt->PCableLen =0xff;
834 pVctBackupData = &pAC->Pnmi.VctBackup[PortIndex];
835 pVctBackupData->PCableLen = 0xff;
841 SK_IN16(IoC, B0_CTST, &Val16);
842 if ((Val16 & CS_BUS_CLOCK) == 0) {
844 pAC->Pnmi.PciBusSpeed = 33;
847 pAC->Pnmi.PciBusSpeed = 66;
853 SK_IN16(IoC, B0_CTST, &Val16);
854 if ((Val16 & CS_BUS_SLOT_SZ) == 0) {
856 pAC->Pnmi.PciBusWidth = 32;
859 pAC->Pnmi.PciBusWidth = 64;
865 switch (pAC->GIni.GIChipId) {
866 case CHIP_ID_GENESIS:
867 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_XMAC;
871 pAC->Pnmi.Chipset = SK_PNMI_CHIPSET_YUKON;
879 * Get PMD and DeviceType
881 SK_IN8(IoC, B2_PMD_TYP, &Val8);
885 if (pAC->GIni.GIMacsFound > 1) {
887 pAC->Pnmi.DeviceType = 0x00020002;
890 pAC->Pnmi.DeviceType = 0x00020001;
896 if (pAC->GIni.GIMacsFound > 1) {
898 pAC->Pnmi.DeviceType = 0x00020004;
901 pAC->Pnmi.DeviceType = 0x00020003;
907 if (pAC->GIni.GIMacsFound > 1) {
909 pAC->Pnmi.DeviceType = 0x00020006;
912 pAC->Pnmi.DeviceType = 0x00020005;
918 if (pAC->GIni.GIMacsFound > 1) {
920 pAC->Pnmi.DeviceType = 0x00020008;
923 pAC->Pnmi.DeviceType = 0x00020007;
929 pAC->Pnmi.DeviceType = 0;
936 SK_IN8(IoC, B2_CONN_TYP, &Val8);
939 pAC->Pnmi.Connector = 2;
943 pAC->Pnmi.Connector = 3;
947 pAC->Pnmi.Connector = 4;
951 pAC->Pnmi.Connector = 5;
955 pAC->Pnmi.Connector = 6;
959 pAC->Pnmi.Connector = 1;
966 * Start timer for RLMT change counter
968 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
969 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
970 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
975 break; /* Nothing todo */
981 /*****************************************************************************
983 * SkPnmiGetVar - Retrieves the value of a single OID
986 * Calls a general sub-function for all this stuff. If the instance
987 * -1 is passed, the values of all instances are returned in an
991 * SK_PNMI_ERR_OK The request was successfully performed
992 * SK_PNMI_ERR_GENERAL A general severe internal error occured
993 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
995 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown
996 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
997 * exist (e.g. port instance 3 on a two port
1001 SK_AC *pAC, /* Pointer to adapter context */
1002 SK_IOC IoC, /* IO context handle */
1003 SK_U32 Id, /* Object ID that is to be processed */
1004 void *pBuf, /* Buffer to which to mgmt data will be retrieved */
1005 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
1006 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
1007 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1009 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1010 ("PNMI: SkPnmiGetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1011 Id, *pLen, Instance, NetIndex));
1013 return (PnmiVar(pAC, IoC, SK_PNMI_GET, Id, (char *)pBuf, pLen,
1014 Instance, NetIndex));
1017 /*****************************************************************************
1019 * SkPnmiPreSetVar - Presets the value of a single OID
1022 * Calls a general sub-function for all this stuff. The preset does
1023 * the same as a set, but returns just before finally setting the
1024 * new value. This is usefull to check if a set might be successfull.
1025 * If as instance a -1 is passed, an array of values is supposed and
1026 * all instance of the OID will be set.
1029 * SK_PNMI_ERR_OK The request was successfully performed.
1030 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1031 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1032 * the correct data (e.g. a 32bit value is
1033 * needed, but a 16 bit value was passed).
1034 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1036 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1037 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1038 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1039 * exist (e.g. port instance 3 on a two port
1042 int SkPnmiPreSetVar(
1043 SK_AC *pAC, /* Pointer to adapter context */
1044 SK_IOC IoC, /* IO context handle */
1045 SK_U32 Id, /* Object ID that is to be processed */
1046 void *pBuf, /* Buffer which stores the mgmt data to be set */
1047 unsigned int *pLen, /* Total length of mgmt data */
1048 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1049 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1051 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1052 ("PNMI: SkPnmiPreSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1053 Id, *pLen, Instance, NetIndex));
1056 return (PnmiVar(pAC, IoC, SK_PNMI_PRESET, Id, (char *)pBuf, pLen,
1057 Instance, NetIndex));
1060 /*****************************************************************************
1062 * SkPnmiSetVar - Sets the value of a single OID
1065 * Calls a general sub-function for all this stuff. The preset does
1066 * the same as a set, but returns just before finally setting the
1067 * new value. This is usefull to check if a set might be successfull.
1068 * If as instance a -1 is passed, an array of values is supposed and
1069 * all instance of the OID will be set.
1072 * SK_PNMI_ERR_OK The request was successfully performed.
1073 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1074 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1075 * the correct data (e.g. a 32bit value is
1076 * needed, but a 16 bit value was passed).
1077 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1079 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
1080 * SK_PNMI_ERR_UNKNOWN_OID The requested OID is unknown.
1081 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
1082 * exist (e.g. port instance 3 on a two port
1086 SK_AC *pAC, /* Pointer to adapter context */
1087 SK_IOC IoC, /* IO context handle */
1088 SK_U32 Id, /* Object ID that is to be processed */
1089 void *pBuf, /* Buffer which stores the mgmt data to be set */
1090 unsigned int *pLen, /* Total length of mgmt data */
1091 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
1092 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1094 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1095 ("PNMI: SkPnmiSetVar: Called, Id=0x%x, BufLen=%d, Instance=%d, NetIndex=%d\n",
1096 Id, *pLen, Instance, NetIndex));
1098 return (PnmiVar(pAC, IoC, SK_PNMI_SET, Id, (char *)pBuf, pLen,
1099 Instance, NetIndex));
1102 /*****************************************************************************
1104 * SkPnmiGetStruct - Retrieves the management database in SK_PNMI_STRUCT_DATA
1107 * Runs through the IdTable, queries the single OIDs and stores the
1108 * returned data into the management database structure
1109 * SK_PNMI_STRUCT_DATA. The offset of the OID in the structure
1110 * is stored in the IdTable. The return value of the function will also
1111 * be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
1112 * minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1115 * SK_PNMI_ERR_OK The request was successfully performed
1116 * SK_PNMI_ERR_GENERAL A general severe internal error occured
1117 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to take
1119 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
1121 int SkPnmiGetStruct(
1122 SK_AC *pAC, /* Pointer to adapter context */
1123 SK_IOC IoC, /* IO context handle */
1124 void *pBuf, /* Buffer which will store the retrieved data */
1125 unsigned int *pLen, /* Length of buffer */
1126 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1129 unsigned int TableIndex;
1130 unsigned int DstOffset;
1131 unsigned int InstanceNo;
1132 unsigned int InstanceCnt;
1134 unsigned int TmpLen;
1135 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
1138 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1139 ("PNMI: SkPnmiGetStruct: Called, BufLen=%d, NetIndex=%d\n",
1142 if (*pLen < SK_PNMI_STRUCT_SIZE) {
1144 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
1146 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
1150 *pLen = SK_PNMI_STRUCT_SIZE;
1151 return (SK_PNMI_ERR_TOO_SHORT);
1157 if (NetIndex >= pAC->Rlmt.NumNets) {
1158 return (SK_PNMI_ERR_UNKNOWN_NET);
1161 /* Update statistic */
1162 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On call");
1164 if ((Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1)) !=
1167 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1168 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1172 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
1174 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1175 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1179 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
1181 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1182 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1187 * Increment semaphores to indicate that an update was
1190 pAC->Pnmi.MacUpdatedFlag ++;
1191 pAC->Pnmi.RlmtUpdatedFlag ++;
1192 pAC->Pnmi.SirqUpdatedFlag ++;
1194 /* Get vpd keys for instance calculation */
1195 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr), &TmpLen);
1196 if (Ret != SK_PNMI_ERR_OK) {
1198 pAC->Pnmi.MacUpdatedFlag --;
1199 pAC->Pnmi.RlmtUpdatedFlag --;
1200 pAC->Pnmi.SirqUpdatedFlag --;
1202 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1203 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
1204 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1205 return (SK_PNMI_ERR_GENERAL);
1208 /* Retrieve values */
1209 SK_MEMSET((char *)pBuf, 0, SK_PNMI_STRUCT_SIZE);
1210 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
1212 InstanceNo = IdTable[TableIndex].InstanceNo;
1213 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
1216 DstOffset = IdTable[TableIndex].Offset +
1218 IdTable[TableIndex].StructSize;
1221 * For the VPD the instance is not an index number
1222 * but the key itself. Determin with the instance
1223 * counter the VPD key to be used.
1225 if (IdTable[TableIndex].Id == OID_SKGE_VPD_KEY ||
1226 IdTable[TableIndex].Id == OID_SKGE_VPD_VALUE ||
1227 IdTable[TableIndex].Id == OID_SKGE_VPD_ACCESS ||
1228 IdTable[TableIndex].Id == OID_SKGE_VPD_ACTION) {
1230 SK_STRNCPY((char *)&Instance, KeyArr[InstanceCnt - 1], 4);
1233 Instance = (SK_U32)InstanceCnt;
1236 TmpLen = *pLen - DstOffset;
1237 Ret = IdTable[TableIndex].Func(pAC, IoC, SK_PNMI_GET,
1238 IdTable[TableIndex].Id, (char *)pBuf +
1239 DstOffset, &TmpLen, Instance, TableIndex, NetIndex);
1242 * An unknown instance error means that we reached
1243 * the last instance of that variable. Proceed with
1244 * the next OID in the table and ignore the return
1247 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
1252 if (Ret != SK_PNMI_ERR_OK) {
1254 pAC->Pnmi.MacUpdatedFlag --;
1255 pAC->Pnmi.RlmtUpdatedFlag --;
1256 pAC->Pnmi.SirqUpdatedFlag --;
1258 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1259 SK_PNMI_SET_STAT(pBuf, Ret, DstOffset);
1260 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
1266 pAC->Pnmi.MacUpdatedFlag --;
1267 pAC->Pnmi.RlmtUpdatedFlag --;
1268 pAC->Pnmi.SirqUpdatedFlag --;
1270 *pLen = SK_PNMI_STRUCT_SIZE;
1271 SK_PNMI_CHECKFLAGS("SkPnmiGetStruct: On return");
1272 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
1273 return (SK_PNMI_ERR_OK);
1276 /*****************************************************************************
1278 * SkPnmiPreSetStruct - Presets the management database in SK_PNMI_STRUCT_DATA
1281 * Calls a general sub-function for all this set stuff. The preset does
1282 * the same as a set, but returns just before finally setting the
1283 * new value. This is usefull to check if a set might be successfull.
1284 * The sub-function runs through the IdTable, checks which OIDs are able
1285 * to set, and calls the handler function of the OID to perform the
1286 * preset. The return value of the function will also be stored in
1287 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1288 * SK_PNMI_MIN_STRUCT_SIZE.
1291 * SK_PNMI_ERR_OK The request was successfully performed.
1292 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1293 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1294 * the correct data (e.g. a 32bit value is
1295 * needed, but a 16 bit value was passed).
1296 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1299 int SkPnmiPreSetStruct(
1300 SK_AC *pAC, /* Pointer to adapter context */
1301 SK_IOC IoC, /* IO context handle */
1302 void *pBuf, /* Buffer which contains the data to be set */
1303 unsigned int *pLen, /* Length of buffer */
1304 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1306 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1307 ("PNMI: SkPnmiPreSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1310 return (PnmiStruct(pAC, IoC, SK_PNMI_PRESET, (char *)pBuf,
1314 /*****************************************************************************
1316 * SkPnmiSetStruct - Sets the management database in SK_PNMI_STRUCT_DATA
1319 * Calls a general sub-function for all this set stuff. The return value
1320 * of the function will also be stored in SK_PNMI_STRUCT_DATA if the
1321 * passed buffer has the minimum size of SK_PNMI_MIN_STRUCT_SIZE.
1322 * The sub-function runs through the IdTable, checks which OIDs are able
1323 * to set, and calls the handler function of the OID to perform the
1324 * set. The return value of the function will also be stored in
1325 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
1326 * SK_PNMI_MIN_STRUCT_SIZE.
1329 * SK_PNMI_ERR_OK The request was successfully performed.
1330 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
1331 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
1332 * the correct data (e.g. a 32bit value is
1333 * needed, but a 16 bit value was passed).
1334 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
1337 int SkPnmiSetStruct(
1338 SK_AC *pAC, /* Pointer to adapter context */
1339 SK_IOC IoC, /* IO context handle */
1340 void *pBuf, /* Buffer which contains the data to be set */
1341 unsigned int *pLen, /* Length of buffer */
1342 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
1344 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1345 ("PNMI: SkPnmiSetStruct: Called, BufLen=%d, NetIndex=%d\n",
1348 return (PnmiStruct(pAC, IoC, SK_PNMI_SET, (char *)pBuf,
1352 /*****************************************************************************
1354 * SkPnmiEvent - Event handler
1357 * Handles the following events:
1358 * SK_PNMI_EVT_SIRQ_OVERFLOW When a hardware counter overflows an
1359 * interrupt will be generated which is
1360 * first handled by SIRQ which generates a
1361 * this event. The event increments the
1362 * upper 32 bit of the 64 bit counter.
1363 * SK_PNMI_EVT_SEN_XXX The event is generated by the I2C module
1364 * when a sensor reports a warning or
1365 * error. The event will store a trap
1366 * message in the trap buffer.
1367 * SK_PNMI_EVT_CHG_EST_TIMER The timer event was initiated by this
1368 * module and is used to calculate the
1369 * port switches per hour.
1370 * SK_PNMI_EVT_CLEAR_COUNTER The event clears all counters and
1372 * SK_PNMI_EVT_XMAC_RESET The event is generated by the driver
1373 * before a hard reset of the XMAC is
1374 * performed. All counters will be saved
1375 * and added to the hardware counter
1376 * values after reset to grant continuous
1378 * SK_PNMI_EVT_RLMT_PORT_UP Generated by RLMT to notify that a port
1379 * went logically up. A trap message will
1380 * be stored to the trap buffer.
1381 * SK_PNMI_EVT_RLMT_PORT_DOWN Generated by RLMT to notify that a port
1382 * went logically down. A trap message will
1383 * be stored to the trap buffer.
1384 * SK_PNMI_EVT_RLMT_SEGMENTATION Generated by RLMT to notify that two
1385 * spanning tree root bridges were
1386 * detected. A trap message will be stored
1387 * to the trap buffer.
1388 * SK_PNMI_EVT_RLMT_ACTIVE_DOWN Notifies PNMI that an active port went
1389 * down. PNMI will not further add the
1390 * statistic values to the virtual port.
1391 * SK_PNMI_EVT_RLMT_ACTIVE_UP Notifies PNMI that a port went up and
1392 * is now an active port. PNMI will now
1393 * add the statistic data of this port to
1395 * SK_PNMI_EVT_RLMT_SET_NETS Notifies PNMI about the net mode. The first Parameter
1396 * contains the number of nets. 1 means single net, 2 means
1397 * dual net. The second Parameter is -1
1403 SK_AC *pAC, /* Pointer to adapter context */
1404 SK_IOC IoC, /* IO context handle */
1405 SK_U32 Event, /* Event-Id */
1406 SK_EVPARA Param) /* Event dependent parameter */
1408 unsigned int PhysPortIndex;
1409 unsigned int MaxNetNumber;
1413 SK_U64 OverflowStatus;
1419 SK_EVPARA EventParam;
1423 SK_PNMI_ESTIMATE *pEst;
1426 SK_PNMI_VCT *pVctBackupData;
1433 if (Event != SK_PNMI_EVT_XMAC_RESET) {
1435 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1436 ("PNMI: SkPnmiEvent: Called, Event=0x%x, Param=0x%x\n",
1437 (unsigned int)Event, (unsigned int)Param.Para64));
1440 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On call");
1442 MacType = pAC->GIni.GIMacType;
1446 case SK_PNMI_EVT_SIRQ_OVERFLOW:
1447 PhysPortIndex = (int)Param.Para32[0];
1448 MacStatus = (SK_U16)Param.Para32[1];
1450 if (PhysPortIndex >= SK_MAX_MACS) {
1452 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1453 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SIRQ_OVERFLOW parameter"
1454 " wrong, PhysPortIndex=0x%x\n",
1462 * Check which source caused an overflow interrupt.
1464 if ((pAC->GIni.GIFunc.pFnMacOverflow(
1465 pAC, IoC, PhysPortIndex, MacStatus, &OverflowStatus) != 0) ||
1466 (OverflowStatus == 0)) {
1468 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1473 * Check the overflow status register and increment
1474 * the upper dword of corresponding counter.
1476 for (CounterIndex = 0; CounterIndex < sizeof(Mask) * 8;
1479 Mask = (SK_U64)1 << CounterIndex;
1480 if ((OverflowStatus & Mask) == 0) {
1485 switch (StatOvrflwBit[CounterIndex][MacType]) {
1487 case SK_PNMI_HTX_UTILUNDER:
1488 case SK_PNMI_HTX_UTILOVER:
1489 XM_IN16(IoC, PhysPortIndex, XM_TX_CMD,
1491 Register |= XM_TX_SAM_LINE;
1492 XM_OUT16(IoC, PhysPortIndex, XM_TX_CMD,
1496 case SK_PNMI_HRX_UTILUNDER:
1497 case SK_PNMI_HRX_UTILOVER:
1498 XM_IN16(IoC, PhysPortIndex, XM_RX_CMD,
1500 Register |= XM_RX_SAM_LINE;
1501 XM_OUT16(IoC, PhysPortIndex, XM_RX_CMD,
1505 case SK_PNMI_HTX_OCTETHIGH:
1506 case SK_PNMI_HTX_OCTETLOW:
1507 case SK_PNMI_HTX_RESERVED:
1508 case SK_PNMI_HRX_OCTETHIGH:
1509 case SK_PNMI_HRX_OCTETLOW:
1510 case SK_PNMI_HRX_IRLENGTH:
1511 case SK_PNMI_HRX_RESERVED:
1514 * the following counters aren't be handled (id > 63)
1516 case SK_PNMI_HTX_SYNC:
1517 case SK_PNMI_HTX_SYNC_OCTET:
1520 case SK_PNMI_HRX_LONGFRAMES:
1521 if (MacType == SK_MAC_GMAC) {
1522 pAC->Pnmi.Port[PhysPortIndex].
1523 CounterHigh[CounterIndex] ++;
1528 pAC->Pnmi.Port[PhysPortIndex].
1529 CounterHigh[CounterIndex] ++;
1534 case SK_PNMI_EVT_SEN_WAR_LOW:
1536 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1538 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1539 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_LOW parameter wrong, SensorIndex=%d\n",
1540 (unsigned int)Param.Para64));
1545 * Store a trap message in the trap buffer and generate
1546 * an event for user space applications with the
1547 * SK_DRIVER_SENDEVENT macro.
1549 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_LOW,
1550 (unsigned int)Param.Para64);
1551 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1554 case SK_PNMI_EVT_SEN_WAR_UPP:
1556 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1558 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1559 ("PNMI: ERR:SkPnmiEvent: SK_PNMI_EVT_SEN_WAR_UPP parameter wrong, SensorIndex=%d\n",
1560 (unsigned int)Param.Para64));
1565 * Store a trap message in the trap buffer and generate
1566 * an event for user space applications with the
1567 * SK_DRIVER_SENDEVENT macro.
1569 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_WAR_UPP,
1570 (unsigned int)Param.Para64);
1571 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1574 case SK_PNMI_EVT_SEN_ERR_LOW:
1576 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1578 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1579 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_LOW parameter wrong, SensorIndex=%d\n",
1580 (unsigned int)Param.Para64));
1585 * Store a trap message in the trap buffer and generate
1586 * an event for user space applications with the
1587 * SK_DRIVER_SENDEVENT macro.
1589 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_LOW,
1590 (unsigned int)Param.Para64);
1591 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1594 case SK_PNMI_EVT_SEN_ERR_UPP:
1596 if ((unsigned int)Param.Para64 >= (unsigned int)pAC->I2c.MaxSens) {
1598 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1599 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_SEN_ERR_UPP parameter wrong, SensorIndex=%d\n",
1600 (unsigned int)Param.Para64));
1605 * Store a trap message in the trap buffer and generate
1606 * an event for user space applications with the
1607 * SK_DRIVER_SENDEVENT macro.
1609 QueueSensorTrap(pAC, OID_SKGE_TRAP_SEN_ERR_UPP,
1610 (unsigned int)Param.Para64);
1611 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1614 case SK_PNMI_EVT_CHG_EST_TIMER:
1616 * Calculate port switch average on a per hour basis
1617 * Time interval for check : 28125 ms
1618 * Number of values for average : 8
1620 * Be careful in changing these values, on change check
1621 * - typedef of SK_PNMI_ESTIMATE (Size of EstValue
1622 * array one less than value number)
1623 * - Timer initilization SkTimerStart() in SkPnmiInit
1624 * - Delta value below must be multiplicated with
1628 pEst = &pAC->Pnmi.RlmtChangeEstimate;
1629 CounterIndex = pEst->EstValueIndex + 1;
1630 if (CounterIndex == 7) {
1634 pEst->EstValueIndex = CounterIndex;
1636 NewestValue = pAC->Pnmi.RlmtChangeCts;
1637 OldestValue = pEst->EstValue[CounterIndex];
1638 pEst->EstValue[CounterIndex] = NewestValue;
1641 * Calculate average. Delta stores the number of
1642 * port switches per 28125 * 8 = 225000 ms
1644 if (NewestValue >= OldestValue) {
1646 Delta = NewestValue - OldestValue;
1649 /* Overflow situation */
1650 Delta = (SK_U64)(0 - OldestValue) + NewestValue;
1654 * Extrapolate delta to port switches per hour.
1655 * Estimate = Delta * (3600000 / 225000)
1659 pAC->Pnmi.RlmtChangeEstimate.Estimate = Delta << 4;
1662 * Check if threshold is exceeded. If the threshold is
1663 * permanently exceeded every 28125 ms an event will be
1664 * generated to remind the user of this condition.
1666 if ((pAC->Pnmi.RlmtChangeThreshold != 0) &&
1667 (pAC->Pnmi.RlmtChangeEstimate.Estimate >=
1668 pAC->Pnmi.RlmtChangeThreshold)) {
1670 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_CHANGE_THRES);
1671 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1674 SK_MEMSET((char *) &EventParam, 0, sizeof(EventParam));
1675 SkTimerStart(pAC, IoC, &pAC->Pnmi.RlmtChangeEstimate.EstTimer,
1676 28125000, SKGE_PNMI, SK_PNMI_EVT_CHG_EST_TIMER,
1680 case SK_PNMI_EVT_CLEAR_COUNTER:
1682 * Param.Para32[0] contains the NetIndex (0 ..1).
1683 * Param.Para32[1] is reserved, contains -1.
1685 NetIndex = (SK_U32)Param.Para32[0];
1688 if (NetIndex >= pAC->Rlmt.NumNets) {
1690 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1691 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_CLEAR_COUNTER parameter wrong, NetIndex=%d\n",
1699 * Set all counters and timestamps to zero
1701 ResetCounter(pAC, IoC, NetIndex); /* the according NetIndex is required
1702 as a Parameter of the Event */
1705 case SK_PNMI_EVT_XMAC_RESET:
1707 * To grant continuous counter values store the current
1708 * XMAC statistic values to the entries 1..n of the
1709 * CounterOffset array. XMAC Errata #2
1712 if ((unsigned int)Param.Para64 >= SK_MAX_MACS) {
1714 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1715 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_XMAC_RESET parameter wrong, PhysPortIndex=%d\n",
1716 (unsigned int)Param.Para64));
1720 PhysPortIndex = (unsigned int)Param.Para64;
1723 * Update XMAC statistic to get fresh values
1725 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
1726 if (Ret != SK_PNMI_ERR_OK) {
1728 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1732 * Increment semaphore to indicate that an update was
1735 pAC->Pnmi.MacUpdatedFlag ++;
1737 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1740 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1745 pAC->Pnmi.Port[PhysPortIndex].
1746 CounterOffset[CounterIndex] = GetPhysStatVal(
1747 pAC, IoC, PhysPortIndex, CounterIndex);
1748 pAC->Pnmi.Port[PhysPortIndex].
1749 CounterHigh[CounterIndex] = 0;
1752 pAC->Pnmi.MacUpdatedFlag --;
1755 case SK_PNMI_EVT_RLMT_PORT_UP:
1756 PhysPortIndex = (unsigned int)Param.Para32[0];
1758 if (PhysPortIndex >= SK_MAX_MACS) {
1760 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1761 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_UP parameter"
1762 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1768 * Store a trap message in the trap buffer and generate an event for
1769 * user space applications with the SK_DRIVER_SENDEVENT macro.
1771 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_UP, PhysPortIndex);
1772 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1774 /* Bugfix for XMAC errata (#10620)*/
1775 if (pAC->GIni.GIMacType == SK_MAC_XMAC){
1777 /* Add incremental difference to offset (#10620)*/
1778 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1779 XM_RXE_SHT_ERR, &Val32);
1781 Value = (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1782 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1783 pAC->Pnmi.Port[PhysPortIndex].CounterOffset[SK_PNMI_HRX_SHORTS] +=
1784 Value - pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark;
1787 /* Tell VctStatus() that a link was up meanwhile. */
1788 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_LINK;
1791 case SK_PNMI_EVT_RLMT_PORT_DOWN:
1792 PhysPortIndex = (unsigned int)Param.Para32[0];
1795 if (PhysPortIndex >= SK_MAX_MACS) {
1797 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1798 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_PORT_DOWN parameter"
1799 " wrong, PhysPortIndex=%d\n", PhysPortIndex));
1805 * Store a trap message in the trap buffer and generate an event for
1806 * user space applications with the SK_DRIVER_SENDEVENT macro.
1808 QueueRlmtPortTrap(pAC, OID_SKGE_TRAP_RLMT_PORT_DOWN, PhysPortIndex);
1809 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1811 /* Bugfix #10620 - get zero level for incremental difference */
1812 if ((pAC->GIni.GIMacType == SK_MAC_XMAC)) {
1814 (void)pAC->GIni.GIFunc.pFnMacStatistic(pAC, IoC, PhysPortIndex,
1815 XM_RXE_SHT_ERR, &Val32);
1816 pAC->Pnmi.Port[PhysPortIndex].RxShortZeroMark =
1817 (((SK_U64)pAC->Pnmi.Port[PhysPortIndex].
1818 CounterHigh[SK_PNMI_HRX_SHORTS] << 32) | (SK_U64)Val32);
1822 case SK_PNMI_EVT_RLMT_ACTIVE_DOWN:
1823 PhysPortIndex = (unsigned int)Param.Para32[0];
1824 NetIndex = (SK_U32)Param.Para32[1];
1827 if (PhysPortIndex >= SK_MAX_MACS) {
1829 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1830 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, PhysPort=%d\n",
1834 if (NetIndex >= pAC->Rlmt.NumNets) {
1836 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1837 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_DOWN parameter too high, NetIndex=%d\n",
1842 * For now, ignore event if NetIndex != 0.
1844 if (Param.Para32[1] != 0) {
1850 * Nothing to do if port is already inactive
1852 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1858 * Update statistic counters to calculate new offset for the virtual
1859 * port and increment semaphore to indicate that an update was already
1862 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1865 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1868 pAC->Pnmi.MacUpdatedFlag ++;
1871 * Calculate new counter offset for virtual port to grant continous
1872 * counting on port switches. The virtual port consists of all currently
1873 * active ports. The port down event indicates that a port is removed
1874 * from the virtual port. Therefore add the counter value of the removed
1875 * port to the CounterOffset for the virtual port to grant the same
1878 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1881 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1886 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1888 pAC->Pnmi.VirtualCounterOffset[CounterIndex] += Value;
1892 * Set port to inactive
1894 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_FALSE;
1896 pAC->Pnmi.MacUpdatedFlag --;
1899 case SK_PNMI_EVT_RLMT_ACTIVE_UP:
1900 PhysPortIndex = (unsigned int)Param.Para32[0];
1901 NetIndex = (SK_U32)Param.Para32[1];
1904 if (PhysPortIndex >= SK_MAX_MACS) {
1906 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1907 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, PhysPort=%d\n",
1911 if (NetIndex >= pAC->Rlmt.NumNets) {
1913 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_CTRL,
1914 ("PNMI: ERR: SkPnmiEvent: SK_PNMI_EVT_RLMT_ACTIVE_UP parameter too high, NetIndex=%d\n",
1919 * For now, ignore event if NetIndex != 0.
1921 if (Param.Para32[1] != 0) {
1927 * Nothing to do if port is already active
1929 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
1935 * Statistic maintenance
1937 pAC->Pnmi.RlmtChangeCts ++;
1938 pAC->Pnmi.RlmtChangeTime = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
1941 * Store a trap message in the trap buffer and generate an event for
1942 * user space applications with the SK_DRIVER_SENDEVENT macro.
1944 QueueRlmtNewMacTrap(pAC, PhysPortIndex);
1945 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
1948 * Update statistic counters to calculate new offset for the virtual
1949 * port and increment semaphore to indicate that an update was
1952 if (MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1) !=
1955 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
1958 pAC->Pnmi.MacUpdatedFlag ++;
1961 * Calculate new counter offset for virtual port to grant continous
1962 * counting on port switches. A new port is added to the virtual port.
1963 * Therefore substract the counter value of the new port from the
1964 * CounterOffset for the virtual port to grant the same value.
1966 for (CounterIndex = 0; CounterIndex < SK_PNMI_MAX_IDX;
1969 if (!StatAddr[CounterIndex][MacType].GetOffset) {
1974 Value = GetPhysStatVal(pAC, IoC, PhysPortIndex, CounterIndex);
1976 pAC->Pnmi.VirtualCounterOffset[CounterIndex] -= Value;
1980 * Set port to active
1982 pAC->Pnmi.Port[PhysPortIndex].ActiveFlag = SK_TRUE;
1984 pAC->Pnmi.MacUpdatedFlag --;
1987 case SK_PNMI_EVT_RLMT_SEGMENTATION:
1989 * Para.Para32[0] contains the NetIndex.
1993 * Store a trap message in the trap buffer and generate an event for
1994 * user space applications with the SK_DRIVER_SENDEVENT macro.
1996 QueueSimpleTrap(pAC, OID_SKGE_TRAP_RLMT_SEGMENTATION);
1997 (void)SK_DRIVER_SENDEVENT(pAC, IoC);
2000 case SK_PNMI_EVT_RLMT_SET_NETS:
2002 * Param.Para32[0] contains the number of Nets.
2003 * Param.Para32[1] is reserved, contains -1.
2006 * Check number of nets
2008 MaxNetNumber = pAC->GIni.GIMacsFound;
2009 if (((unsigned int)Param.Para32[0] < 1)
2010 || ((unsigned int)Param.Para32[0] > MaxNetNumber)) {
2011 return (SK_PNMI_ERR_UNKNOWN_NET);
2014 if ((unsigned int)Param.Para32[0] == 1) { /* single net mode */
2015 pAC->Pnmi.DualNetActiveFlag = SK_FALSE;
2017 else { /* dual net mode */
2018 pAC->Pnmi.DualNetActiveFlag = SK_TRUE;
2022 case SK_PNMI_EVT_VCT_RESET:
2023 PhysPortIndex = Param.Para32[0];
2024 pPrt = &pAC->GIni.GP[PhysPortIndex];
2025 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
2027 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
2028 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
2031 * VCT test is still running.
2032 * Start VCT timer counter again.
2034 SK_MEMSET((char *) &Param, 0, sizeof(Param));
2035 Param.Para32[0] = PhysPortIndex;
2036 Param.Para32[1] = -1;
2037 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
2038 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Param);
2041 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
2042 pAC->Pnmi.VctStatus[PhysPortIndex] |=
2043 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
2045 /* Copy results for later use to PNMI struct. */
2046 for (i = 0; i < 4; i++) {
2047 if (pPrt->PMdiPairLen[i] > 35) {
2048 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
2053 pVctBackupData->PMdiPairLen[i] = CableLength;
2054 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
2057 Param.Para32[0] = PhysPortIndex;
2058 Param.Para32[1] = -1;
2059 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Param);
2060 SkEventDispatcher(pAC, IoC);
2069 SK_PNMI_CHECKFLAGS("SkPnmiEvent: On return");
2074 /******************************************************************************
2080 /*****************************************************************************
2082 * PnmiVar - Gets, presets, and sets single OIDs
2085 * Looks up the requested OID, calls the corresponding handler
2086 * function, and passes the parameters with the get, preset, or
2087 * set command. The function is called by SkGePnmiGetVar,
2088 * SkGePnmiPreSetVar, or SkGePnmiSetVar.
2091 * SK_PNMI_ERR_XXX. For details have a look to the description of the
2092 * calling functions.
2093 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2095 PNMI_STATIC int PnmiVar(
2096 SK_AC *pAC, /* Pointer to adapter context */
2097 SK_IOC IoC, /* IO context handle */
2098 int Action, /* Get/PreSet/Set action */
2099 SK_U32 Id, /* Object ID that is to be processed */
2100 char *pBuf, /* Buffer which stores the mgmt data to be set */
2101 unsigned int *pLen, /* Total length of mgmt data */
2102 SK_U32 Instance, /* Instance (1..n) that is to be set or -1 */
2103 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2105 unsigned int TableIndex;
2109 if ((TableIndex = LookupId(Id)) == (unsigned int)(-1)) {
2112 return (SK_PNMI_ERR_UNKNOWN_OID);
2118 if (NetIndex >= pAC->Rlmt.NumNets) {
2119 return (SK_PNMI_ERR_UNKNOWN_NET);
2122 SK_PNMI_CHECKFLAGS("PnmiVar: On call");
2124 Ret = IdTable[TableIndex].Func(pAC, IoC, Action, Id, pBuf, pLen,
2125 Instance, TableIndex, NetIndex);
2127 SK_PNMI_CHECKFLAGS("PnmiVar: On return");
2132 /*****************************************************************************
2134 * PnmiStruct - Presets and Sets data in structure SK_PNMI_STRUCT_DATA
2137 * The return value of the function will also be stored in
2138 * SK_PNMI_STRUCT_DATA if the passed buffer has the minimum size of
2139 * SK_PNMI_MIN_STRUCT_SIZE. The sub-function runs through the IdTable,
2140 * checks which OIDs are able to set, and calls the handler function of
2141 * the OID to perform the set. The return value of the function will
2142 * also be stored in SK_PNMI_STRUCT_DATA if the passed buffer has the
2143 * minimum size of SK_PNMI_MIN_STRUCT_SIZE. The function is called
2144 * by SkGePnmiPreSetStruct and SkGePnmiSetStruct.
2147 * SK_PNMI_ERR_XXX. The codes are described in the calling functions.
2148 * SK_PNMI_ERR_UNKNOWN_NET The requested NetIndex doesn't exist
2150 PNMI_STATIC int PnmiStruct(
2151 SK_AC *pAC, /* Pointer to adapter context */
2152 SK_IOC IoC, /* IO context handle */
2153 int Action, /* Set action to be performed */
2154 char *pBuf, /* Buffer which contains the data to be set */
2155 unsigned int *pLen, /* Length of buffer */
2156 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2159 unsigned int TableIndex;
2160 unsigned int DstOffset;
2162 unsigned int InstanceNo;
2163 unsigned int InstanceCnt;
2168 /* Check if the passed buffer has the right size */
2169 if (*pLen < SK_PNMI_STRUCT_SIZE) {
2171 /* Check if we can return the error within the buffer */
2172 if (*pLen >= SK_PNMI_MIN_STRUCT_SIZE) {
2174 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_TOO_SHORT,
2178 *pLen = SK_PNMI_STRUCT_SIZE;
2179 return (SK_PNMI_ERR_TOO_SHORT);
2185 if (NetIndex >= pAC->Rlmt.NumNets) {
2186 return (SK_PNMI_ERR_UNKNOWN_NET);
2189 SK_PNMI_CHECKFLAGS("PnmiStruct: On call");
2192 * Update the values of RLMT and SIRQ and increment semaphores to
2193 * indicate that an update was already done.
2195 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
2197 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2198 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2202 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
2204 SK_PNMI_SET_STAT(pBuf, Ret, (SK_U32)(-1));
2205 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2209 pAC->Pnmi.RlmtUpdatedFlag ++;
2210 pAC->Pnmi.SirqUpdatedFlag ++;
2212 /* Preset/Set values */
2213 for (TableIndex = 0; TableIndex < ID_TABLE_SIZE; TableIndex ++) {
2215 if ((IdTable[TableIndex].Access != SK_PNMI_RW) &&
2216 (IdTable[TableIndex].Access != SK_PNMI_WO)) {
2221 InstanceNo = IdTable[TableIndex].InstanceNo;
2222 Id = IdTable[TableIndex].Id;
2224 for (InstanceCnt = 1; InstanceCnt <= InstanceNo;
2227 DstOffset = IdTable[TableIndex].Offset +
2229 IdTable[TableIndex].StructSize;
2232 * Because VPD multiple instance variables are
2233 * not setable we do not need to evaluate VPD
2234 * instances. Have a look to VPD instance
2235 * calculation in SkPnmiGetStruct().
2237 Instance = (SK_U32)InstanceCnt;
2240 * Evaluate needed buffer length
2243 Ret = IdTable[TableIndex].Func(pAC, IoC,
2244 SK_PNMI_GET, IdTable[TableIndex].Id,
2245 NULL, &Len, Instance, TableIndex, NetIndex);
2247 if (Ret == SK_PNMI_ERR_UNKNOWN_INST) {
2251 if (Ret != SK_PNMI_ERR_TOO_SHORT) {
2253 pAC->Pnmi.RlmtUpdatedFlag --;
2254 pAC->Pnmi.SirqUpdatedFlag --;
2256 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2257 SK_PNMI_SET_STAT(pBuf,
2258 SK_PNMI_ERR_GENERAL, DstOffset);
2259 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2260 return (SK_PNMI_ERR_GENERAL);
2262 if (Id == OID_SKGE_VPD_ACTION) {
2264 switch (*(pBuf + DstOffset)) {
2266 case SK_PNMI_VPD_CREATE:
2267 Len = 3 + *(pBuf + DstOffset + 3);
2270 case SK_PNMI_VPD_DELETE:
2280 /* Call the OID handler function */
2281 Ret = IdTable[TableIndex].Func(pAC, IoC, Action,
2282 IdTable[TableIndex].Id, pBuf + DstOffset,
2283 &Len, Instance, TableIndex, NetIndex);
2285 if (Ret != SK_PNMI_ERR_OK) {
2287 pAC->Pnmi.RlmtUpdatedFlag --;
2288 pAC->Pnmi.SirqUpdatedFlag --;
2290 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2291 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_BAD_VALUE,
2293 *pLen = SK_PNMI_MIN_STRUCT_SIZE;
2294 return (SK_PNMI_ERR_BAD_VALUE);
2299 pAC->Pnmi.RlmtUpdatedFlag --;
2300 pAC->Pnmi.SirqUpdatedFlag --;
2302 SK_PNMI_CHECKFLAGS("PnmiStruct: On return");
2303 SK_PNMI_SET_STAT(pBuf, SK_PNMI_ERR_OK, (SK_U32)(-1));
2304 return (SK_PNMI_ERR_OK);
2307 /*****************************************************************************
2309 * LookupId - Lookup an OID in the IdTable
2312 * Scans the IdTable to find the table entry of an OID.
2315 * The table index or -1 if not found.
2317 PNMI_STATIC int LookupId(
2318 SK_U32 Id) /* Object identifier to be searched */
2322 for (i = 0; i < ID_TABLE_SIZE; i++) {
2324 if (IdTable[i].Id == Id) {
2333 /*****************************************************************************
2335 * OidStruct - Handler of OID_SKGE_ALL_DATA
2338 * This OID performs a Get/Preset/SetStruct call and returns all data
2339 * in a SK_PNMI_STRUCT_DATA structure.
2342 * SK_PNMI_ERR_OK The request was successfully performed.
2343 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2344 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2345 * the correct data (e.g. a 32bit value is
2346 * needed, but a 16 bit value was passed).
2347 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2349 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2350 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2351 * exist (e.g. port instance 3 on a two port
2354 PNMI_STATIC int OidStruct(
2355 SK_AC *pAC, /* Pointer to adapter context */
2356 SK_IOC IoC, /* IO context handle */
2357 int Action, /* Get/PreSet/Set action */
2358 SK_U32 Id, /* Object ID that is to be processed */
2359 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2360 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2361 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2362 unsigned int TableIndex, /* Index to the Id table */
2363 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2365 if (Id != OID_SKGE_ALL_DATA) {
2367 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR003,
2371 return (SK_PNMI_ERR_GENERAL);
2375 * Check instance. We only handle single instance variables
2377 if (Instance != (SK_U32)(-1) && Instance != 1) {
2380 return (SK_PNMI_ERR_UNKNOWN_INST);
2386 return (SkPnmiGetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2388 case SK_PNMI_PRESET:
2389 return (SkPnmiPreSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2392 return (SkPnmiSetStruct(pAC, IoC, pBuf, pLen, NetIndex));
2395 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR004, SK_PNMI_ERR004MSG);
2398 return (SK_PNMI_ERR_GENERAL);
2401 /*****************************************************************************
2403 * Perform - OID handler of OID_SKGE_ACTION
2409 * SK_PNMI_ERR_OK The request was successfully performed.
2410 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2411 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2412 * the correct data (e.g. a 32bit value is
2413 * needed, but a 16 bit value was passed).
2414 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2416 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2417 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2418 * exist (e.g. port instance 3 on a two port
2421 PNMI_STATIC int Perform(
2422 SK_AC *pAC, /* Pointer to adapter context */
2423 SK_IOC IoC, /* IO context handle */
2424 int Action, /* Get/PreSet/Set action */
2425 SK_U32 Id, /* Object ID that is to be processed */
2426 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2427 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2428 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2429 unsigned int TableIndex, /* Index to the Id table */
2430 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2437 * Check instance. We only handle single instance variables
2439 if (Instance != (SK_U32)(-1) && Instance != 1) {
2442 return (SK_PNMI_ERR_UNKNOWN_INST);
2445 if (*pLen < sizeof(SK_U32)) {
2447 *pLen = sizeof(SK_U32);
2448 return (SK_PNMI_ERR_TOO_SHORT);
2451 /* Check if a get should be performed */
2452 if (Action == SK_PNMI_GET) {
2454 /* A get is easy. We always return the same value */
2455 ActionOp = (SK_U32)SK_PNMI_ACT_IDLE;
2456 SK_PNMI_STORE_U32(pBuf, ActionOp);
2457 *pLen = sizeof(SK_U32);
2459 return (SK_PNMI_ERR_OK);
2462 /* Continue with PRESET/SET action */
2463 if (*pLen > sizeof(SK_U32)) {
2465 return (SK_PNMI_ERR_BAD_VALUE);
2468 /* Check if the command is a known one */
2469 SK_PNMI_READ_U32(pBuf, ActionOp);
2470 if (*pLen > sizeof(SK_U32) ||
2471 (ActionOp != SK_PNMI_ACT_IDLE &&
2472 ActionOp != SK_PNMI_ACT_RESET &&
2473 ActionOp != SK_PNMI_ACT_SELFTEST &&
2474 ActionOp != SK_PNMI_ACT_RESETCNT)) {
2477 return (SK_PNMI_ERR_BAD_VALUE);
2480 /* A preset ends here */
2481 if (Action == SK_PNMI_PRESET) {
2483 return (SK_PNMI_ERR_OK);
2488 case SK_PNMI_ACT_IDLE:
2492 case SK_PNMI_ACT_RESET:
2494 * Perform a driver reset or something that comes near
2497 Ret = SK_DRIVER_RESET(pAC, IoC);
2500 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR005,
2503 return (SK_PNMI_ERR_GENERAL);
2507 case SK_PNMI_ACT_SELFTEST:
2509 * Perform a driver selftest or something similar to this.
2510 * Currently this feature is not used and will probably
2511 * implemented in another way.
2513 Ret = SK_DRIVER_SELFTEST(pAC, IoC);
2514 pAC->Pnmi.TestResult = Ret;
2517 case SK_PNMI_ACT_RESETCNT:
2518 /* Set all counters and timestamps to zero */
2519 ResetCounter(pAC, IoC, NetIndex);
2523 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR006,
2526 return (SK_PNMI_ERR_GENERAL);
2529 return (SK_PNMI_ERR_OK);
2532 /*****************************************************************************
2534 * Mac8023Stat - OID handler of OID_GEN_XXX and OID_802_3_XXX
2537 * Retrieves the statistic values of the virtual port (logical
2538 * index 0). Only special OIDs of NDIS are handled which consist
2539 * of a 32 bit instead of a 64 bit value. The OIDs are public
2540 * because perhaps some other platform can use them too.
2543 * SK_PNMI_ERR_OK The request was successfully performed.
2544 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2545 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2546 * the correct data (e.g. a 32bit value is
2547 * needed, but a 16 bit value was passed).
2548 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2549 * exist (e.g. port instance 3 on a two port
2552 PNMI_STATIC int Mac8023Stat(
2553 SK_AC *pAC, /* Pointer to adapter context */
2554 SK_IOC IoC, /* IO context handle */
2555 int Action, /* Get/PreSet/Set action */
2556 SK_U32 Id, /* Object ID that is to be processed */
2557 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2558 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2559 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2560 unsigned int TableIndex, /* Index to the Id table */
2561 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2566 SK_BOOL Is64BitReq = SK_FALSE;
2569 * Only the active Mac is returned
2571 if (Instance != (SK_U32)(-1) && Instance != 1) {
2574 return (SK_PNMI_ERR_UNKNOWN_INST);
2580 if (Action != SK_PNMI_GET) {
2583 return (SK_PNMI_ERR_READ_ONLY);
2591 case OID_802_3_PERMANENT_ADDRESS:
2592 case OID_802_3_CURRENT_ADDRESS:
2593 if (*pLen < sizeof(SK_MAC_ADDR)) {
2595 *pLen = sizeof(SK_MAC_ADDR);
2596 return (SK_PNMI_ERR_TOO_SHORT);
2601 #ifndef SK_NDIS_64BIT_CTR
2602 if (*pLen < sizeof(SK_U32)) {
2603 *pLen = sizeof(SK_U32);
2604 return (SK_PNMI_ERR_TOO_SHORT);
2607 #else /* SK_NDIS_64BIT_CTR */
2610 * for compatibility, at least 32bit are required for oid
2612 if (*pLen < sizeof(SK_U32)) {
2614 * but indicate handling for 64bit values,
2615 * if insufficient space is provided
2617 *pLen = sizeof(SK_U64);
2618 return (SK_PNMI_ERR_TOO_SHORT);
2621 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
2622 #endif /* SK_NDIS_64BIT_CTR */
2627 * Update all statistics, because we retrieve virtual MAC, which
2628 * consists of multiple physical statistics and increment semaphore
2629 * to indicate that an update was already done.
2631 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2632 if ( Ret != SK_PNMI_ERR_OK) {
2637 pAC->Pnmi.MacUpdatedFlag ++;
2640 * Get value (MAC Index 0 identifies the virtual MAC)
2644 case OID_802_3_PERMANENT_ADDRESS:
2645 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2646 *pLen = sizeof(SK_MAC_ADDR);
2649 case OID_802_3_CURRENT_ADDRESS:
2650 CopyMac(pBuf, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2651 *pLen = sizeof(SK_MAC_ADDR);
2655 StatVal = GetStatVal(pAC, IoC, 0, IdTable[TableIndex].Param, NetIndex);
2658 * by default 32bit values are evaluated
2661 StatVal32 = (SK_U32)StatVal;
2662 SK_PNMI_STORE_U32(pBuf, StatVal32);
2663 *pLen = sizeof(SK_U32);
2666 SK_PNMI_STORE_U64(pBuf, StatVal);
2667 *pLen = sizeof(SK_U64);
2672 pAC->Pnmi.MacUpdatedFlag --;
2674 return (SK_PNMI_ERR_OK);
2677 /*****************************************************************************
2679 * MacPrivateStat - OID handler function of OID_SKGE_STAT_XXX
2682 * Retrieves the XMAC statistic data.
2685 * SK_PNMI_ERR_OK The request was successfully performed.
2686 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2687 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2688 * the correct data (e.g. a 32bit value is
2689 * needed, but a 16 bit value was passed).
2690 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2691 * exist (e.g. port instance 3 on a two port
2694 PNMI_STATIC int MacPrivateStat(
2695 SK_AC *pAC, /* Pointer to adapter context */
2696 SK_IOC IoC, /* IO context handle */
2697 int Action, /* Get/PreSet/Set action */
2698 SK_U32 Id, /* Object ID that is to be processed */
2699 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2700 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2701 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2702 unsigned int TableIndex, /* Index to the Id table */
2703 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2705 unsigned int LogPortMax;
2706 unsigned int LogPortIndex;
2707 unsigned int PhysPortMax;
2709 unsigned int Offset;
2715 * Calculate instance if wished. MAC index 0 is the virtual
2718 PhysPortMax = pAC->GIni.GIMacsFound;
2719 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2721 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2725 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2726 /* Check instance range */
2727 if ((Instance < 1) || (Instance > LogPortMax)) {
2730 return (SK_PNMI_ERR_UNKNOWN_INST);
2732 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2733 Limit = LogPortIndex + 1;
2736 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2746 if (Action != SK_PNMI_GET) {
2749 return (SK_PNMI_ERR_READ_ONLY);
2755 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U64)) {
2757 *pLen = (Limit - LogPortIndex) * sizeof(SK_U64);
2758 return (SK_PNMI_ERR_TOO_SHORT);
2762 * Update XMAC statistic and increment semaphore to indicate that
2763 * an update was already done.
2765 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
2766 if (Ret != SK_PNMI_ERR_OK) {
2771 pAC->Pnmi.MacUpdatedFlag ++;
2777 for (; LogPortIndex < Limit; LogPortIndex ++) {
2781 /* XXX not yet implemented due to XMAC problems
2782 case OID_SKGE_STAT_TX_UTIL:
2783 return (SK_PNMI_ERR_GENERAL);
2785 /* XXX not yet implemented due to XMAC problems
2786 case OID_SKGE_STAT_RX_UTIL:
2787 return (SK_PNMI_ERR_GENERAL);
2789 case OID_SKGE_STAT_RX:
2790 case OID_SKGE_STAT_TX:
2791 switch (pAC->GIni.GIMacType) {
2793 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2794 IdTable[TableIndex].Param, NetIndex);
2798 if (Id == OID_SKGE_STAT_TX) {
2801 GetStatVal(pAC, IoC, LogPortIndex,
2802 SK_PNMI_HTX_BROADCAST, NetIndex) +
2803 GetStatVal(pAC, IoC, LogPortIndex,
2804 SK_PNMI_HTX_MULTICAST, NetIndex) +
2805 GetStatVal(pAC, IoC, LogPortIndex,
2806 SK_PNMI_HTX_UNICAST, NetIndex);
2810 GetStatVal(pAC, IoC, LogPortIndex,
2811 SK_PNMI_HRX_BROADCAST, NetIndex) +
2812 GetStatVal(pAC, IoC, LogPortIndex,
2813 SK_PNMI_HRX_MULTICAST, NetIndex) +
2814 GetStatVal(pAC, IoC, LogPortIndex,
2815 SK_PNMI_HRX_UNICAST, NetIndex) +
2816 GetStatVal(pAC, IoC, LogPortIndex,
2817 SK_PNMI_HRX_UNDERSIZE, NetIndex);
2826 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2830 StatVal = GetStatVal(pAC, IoC, LogPortIndex,
2831 IdTable[TableIndex].Param, NetIndex);
2832 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
2836 Offset += sizeof(SK_U64);
2840 pAC->Pnmi.MacUpdatedFlag --;
2842 return (SK_PNMI_ERR_OK);
2845 /*****************************************************************************
2847 * Addr - OID handler function of OID_SKGE_PHYS_CUR_ADDR and _FAC_ADDR
2850 * Get/Presets/Sets the current and factory MAC address. The MAC
2851 * address of the virtual port, which is reported to the OS, may
2852 * not be changed, but the physical ones. A set to the virtual port
2853 * will be ignored. No error should be reported because otherwise
2854 * a multiple instance set (-1) would always fail.
2857 * SK_PNMI_ERR_OK The request was successfully performed.
2858 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
2859 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
2860 * the correct data (e.g. a 32bit value is
2861 * needed, but a 16 bit value was passed).
2862 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
2864 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
2865 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
2866 * exist (e.g. port instance 3 on a two port
2869 PNMI_STATIC int Addr(
2870 SK_AC *pAC, /* Pointer to adapter context */
2871 SK_IOC IoC, /* IO context handle */
2872 int Action, /* Get/PreSet/Set action */
2873 SK_U32 Id, /* Object ID that is to be processed */
2874 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
2875 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
2876 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
2877 unsigned int TableIndex, /* Index to the Id table */
2878 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
2881 unsigned int LogPortMax;
2882 unsigned int PhysPortMax;
2883 unsigned int LogPortIndex;
2884 unsigned int PhysPortIndex;
2886 unsigned int Offset = 0;
2889 * Calculate instance if wished. MAC index 0 is the virtual
2892 PhysPortMax = pAC->GIni.GIMacsFound;
2893 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
2895 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
2899 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
2900 /* Check instance range */
2901 if ((Instance < 1) || (Instance > LogPortMax)) {
2904 return (SK_PNMI_ERR_UNKNOWN_INST);
2906 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
2907 Limit = LogPortIndex + 1;
2910 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
2919 if (Action == SK_PNMI_GET) {
2924 if (*pLen < (Limit - LogPortIndex) * 6) {
2926 *pLen = (Limit - LogPortIndex) * 6;
2927 return (SK_PNMI_ERR_TOO_SHORT);
2933 for (; LogPortIndex < Limit; LogPortIndex ++) {
2937 case OID_SKGE_PHYS_CUR_ADDR:
2938 if (LogPortIndex == 0) {
2939 CopyMac(pBuf + Offset, &pAC->Addr.Net[NetIndex].CurrentMacAddress);
2942 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
2944 CopyMac(pBuf + Offset,
2945 &pAC->Addr.Port[PhysPortIndex].CurrentMacAddress);
2950 case OID_SKGE_PHYS_FAC_ADDR:
2951 if (LogPortIndex == 0) {
2952 CopyMac(pBuf + Offset,
2953 &pAC->Addr.Net[NetIndex].PermanentMacAddress);
2956 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
2959 CopyMac(pBuf + Offset,
2960 &pAC->Addr.Port[PhysPortIndex].PermanentMacAddress);
2966 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR008,
2970 return (SK_PNMI_ERR_GENERAL);
2978 * The logical MAC address may not be changed only
2981 if (Id == OID_SKGE_PHYS_FAC_ADDR) {
2984 return (SK_PNMI_ERR_READ_ONLY);
2988 * Only the current address may be changed
2990 if (Id != OID_SKGE_PHYS_CUR_ADDR) {
2992 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR009,
2996 return (SK_PNMI_ERR_GENERAL);
3002 if (*pLen < (Limit - LogPortIndex) * 6) {
3004 *pLen = (Limit - LogPortIndex) * 6;
3005 return (SK_PNMI_ERR_TOO_SHORT);
3007 if (*pLen > (Limit - LogPortIndex) * 6) {
3010 return (SK_PNMI_ERR_BAD_VALUE);
3016 if (Action == SK_PNMI_PRESET) {
3019 return (SK_PNMI_ERR_OK);
3023 * Set OID_SKGE_MAC_CUR_ADDR
3025 for (; LogPortIndex < Limit; LogPortIndex ++, Offset += 6) {
3028 * A set to virtual port and set of broadcast
3029 * address will be ignored
3031 if (LogPortIndex == 0 || SK_MEMCMP(pBuf + Offset,
3032 "\xff\xff\xff\xff\xff\xff", 6) == 0) {
3037 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC,
3040 Ret = SkAddrOverride(pAC, IoC, PhysPortIndex,
3041 (SK_MAC_ADDR *)(pBuf + Offset),
3042 (LogPortIndex == 0 ? SK_ADDR_VIRTUAL_ADDRESS :
3043 SK_ADDR_PHYSICAL_ADDRESS));
3044 if (Ret != SK_ADDR_OVERRIDE_SUCCESS) {
3046 return (SK_PNMI_ERR_GENERAL);
3052 return (SK_PNMI_ERR_OK);
3055 /*****************************************************************************
3057 * CsumStat - OID handler function of OID_SKGE_CHKSM_XXX
3060 * Retrieves the statistic values of the CSUM module. The CSUM data
3061 * structure must be available in the SK_AC even if the CSUM module
3062 * is not included, because PNMI reads the statistic data from the
3063 * CSUM part of SK_AC directly.
3066 * SK_PNMI_ERR_OK The request was successfully performed.
3067 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3068 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3069 * the correct data (e.g. a 32bit value is
3070 * needed, but a 16 bit value was passed).
3071 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3072 * exist (e.g. port instance 3 on a two port
3075 PNMI_STATIC int CsumStat(
3076 SK_AC *pAC, /* Pointer to adapter context */
3077 SK_IOC IoC, /* IO context handle */
3078 int Action, /* Get/PreSet/Set action */
3079 SK_U32 Id, /* Object ID that is to be processed */
3080 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3081 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3082 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3083 unsigned int TableIndex, /* Index to the Id table */
3084 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3088 unsigned int Offset = 0;
3093 * Calculate instance if wished
3095 if (Instance != (SK_U32)(-1)) {
3097 if ((Instance < 1) || (Instance > SKCS_NUM_PROTOCOLS)) {
3100 return (SK_PNMI_ERR_UNKNOWN_INST);
3102 Index = (unsigned int)Instance - 1;
3107 Limit = SKCS_NUM_PROTOCOLS;
3113 if (Action != SK_PNMI_GET) {
3116 return (SK_PNMI_ERR_READ_ONLY);
3122 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3124 *pLen = (Limit - Index) * sizeof(SK_U64);
3125 return (SK_PNMI_ERR_TOO_SHORT);
3131 for (; Index < Limit; Index ++) {
3135 case OID_SKGE_CHKSM_RX_OK_CTS:
3136 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxOkCts;
3139 case OID_SKGE_CHKSM_RX_UNABLE_CTS:
3140 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxUnableCts;
3143 case OID_SKGE_CHKSM_RX_ERR_CTS:
3144 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].RxErrCts;
3147 case OID_SKGE_CHKSM_TX_OK_CTS:
3148 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxOkCts;
3151 case OID_SKGE_CHKSM_TX_UNABLE_CTS:
3152 StatVal = pAC->Csum.ProtoStats[NetIndex][Index].TxUnableCts;
3156 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR010,
3160 return (SK_PNMI_ERR_GENERAL);
3163 SK_PNMI_STORE_U64(pBuf + Offset, StatVal);
3164 Offset += sizeof(SK_U64);
3168 * Store used buffer space
3172 return (SK_PNMI_ERR_OK);
3175 /*****************************************************************************
3177 * SensorStat - OID handler function of OID_SKGE_SENSOR_XXX
3180 * Retrieves the statistic values of the I2C module, which handles
3181 * the temperature and voltage sensors.
3184 * SK_PNMI_ERR_OK The request was successfully performed.
3185 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3186 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3187 * the correct data (e.g. a 32bit value is
3188 * needed, but a 16 bit value was passed).
3189 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3190 * exist (e.g. port instance 3 on a two port
3193 PNMI_STATIC int SensorStat(
3194 SK_AC *pAC, /* Pointer to adapter context */
3195 SK_IOC IoC, /* IO context handle */
3196 int Action, /* Get/PreSet/Set action */
3197 SK_U32 Id, /* Object ID that is to be processed */
3198 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3199 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3200 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3201 unsigned int TableIndex, /* Index to the Id table */
3202 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3207 unsigned int Offset;
3214 * Calculate instance if wished
3216 if ((Instance != (SK_U32)(-1))) {
3218 if ((Instance < 1) || (Instance > (SK_U32)pAC->I2c.MaxSens)) {
3221 return (SK_PNMI_ERR_UNKNOWN_INST);
3224 Index = (unsigned int)Instance -1;
3225 Limit = (unsigned int)Instance;
3229 Limit = (unsigned int) pAC->I2c.MaxSens;
3235 if (Action != SK_PNMI_GET) {
3238 return (SK_PNMI_ERR_READ_ONLY);
3246 case OID_SKGE_SENSOR_VALUE:
3247 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3248 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3249 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3250 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3251 if (*pLen < (Limit - Index) * sizeof(SK_U32)) {
3253 *pLen = (Limit - Index) * sizeof(SK_U32);
3254 return (SK_PNMI_ERR_TOO_SHORT);
3258 case OID_SKGE_SENSOR_DESCR:
3259 for (Offset = 0, i = Index; i < Limit; i ++) {
3261 Len = (unsigned int)
3262 SK_STRLEN(pAC->I2c.SenTable[i].SenDesc) + 1;
3263 if (Len >= SK_PNMI_STRINGLEN2) {
3265 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR011,
3269 return (SK_PNMI_ERR_GENERAL);
3273 if (*pLen < Offset) {
3276 return (SK_PNMI_ERR_TOO_SHORT);
3280 case OID_SKGE_SENSOR_INDEX:
3281 case OID_SKGE_SENSOR_TYPE:
3282 case OID_SKGE_SENSOR_STATUS:
3283 if (*pLen < Limit - Index) {
3285 *pLen = Limit - Index;
3286 return (SK_PNMI_ERR_TOO_SHORT);
3290 case OID_SKGE_SENSOR_WAR_CTS:
3291 case OID_SKGE_SENSOR_WAR_TIME:
3292 case OID_SKGE_SENSOR_ERR_CTS:
3293 case OID_SKGE_SENSOR_ERR_TIME:
3294 if (*pLen < (Limit - Index) * sizeof(SK_U64)) {
3296 *pLen = (Limit - Index) * sizeof(SK_U64);
3297 return (SK_PNMI_ERR_TOO_SHORT);
3302 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR012,
3306 return (SK_PNMI_ERR_GENERAL);
3313 for (Offset = 0; Index < Limit; Index ++) {
3317 case OID_SKGE_SENSOR_INDEX:
3318 *(pBuf + Offset) = (char)Index;
3319 Offset += sizeof(char);
3322 case OID_SKGE_SENSOR_DESCR:
3323 Len = SK_STRLEN(pAC->I2c.SenTable[Index].SenDesc);
3324 SK_MEMCPY(pBuf + Offset + 1,
3325 pAC->I2c.SenTable[Index].SenDesc, Len);
3326 *(pBuf + Offset) = (char)Len;
3330 case OID_SKGE_SENSOR_TYPE:
3332 (char)pAC->I2c.SenTable[Index].SenType;
3333 Offset += sizeof(char);
3336 case OID_SKGE_SENSOR_VALUE:
3337 Val32 = (SK_U32)pAC->I2c.SenTable[Index].SenValue;
3338 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3339 Offset += sizeof(SK_U32);
3342 case OID_SKGE_SENSOR_WAR_THRES_LOW:
3343 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3345 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3346 Offset += sizeof(SK_U32);
3349 case OID_SKGE_SENSOR_WAR_THRES_UPP:
3350 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3352 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3353 Offset += sizeof(SK_U32);
3356 case OID_SKGE_SENSOR_ERR_THRES_LOW:
3357 Val32 = (SK_U32)pAC->I2c.SenTable[Index].
3359 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3360 Offset += sizeof(SK_U32);
3363 case OID_SKGE_SENSOR_ERR_THRES_UPP:
3364 Val32 = pAC->I2c.SenTable[Index].SenThreErrHigh;
3365 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
3366 Offset += sizeof(SK_U32);
3369 case OID_SKGE_SENSOR_STATUS:
3371 (char)pAC->I2c.SenTable[Index].SenErrFlag;
3372 Offset += sizeof(char);
3375 case OID_SKGE_SENSOR_WAR_CTS:
3376 Val64 = pAC->I2c.SenTable[Index].SenWarnCts;
3377 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3378 Offset += sizeof(SK_U64);
3381 case OID_SKGE_SENSOR_ERR_CTS:
3382 Val64 = pAC->I2c.SenTable[Index].SenErrCts;
3383 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3384 Offset += sizeof(SK_U64);
3387 case OID_SKGE_SENSOR_WAR_TIME:
3388 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3390 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3391 Offset += sizeof(SK_U64);
3394 case OID_SKGE_SENSOR_ERR_TIME:
3395 Val64 = SK_PNMI_HUNDREDS_SEC(pAC->I2c.SenTable[Index].
3397 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
3398 Offset += sizeof(SK_U64);
3402 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
3403 ("SensorStat: Unknown OID should be handled before"));
3405 return (SK_PNMI_ERR_GENERAL);
3410 * Store used buffer space
3414 return (SK_PNMI_ERR_OK);
3417 /*****************************************************************************
3419 * Vpd - OID handler function of OID_SKGE_VPD_XXX
3422 * Get/preset/set of VPD data. As instance the name of a VPD key
3423 * can be passed. The Instance parameter is a SK_U32 and can be
3424 * used as a string buffer for the VPD key, because their maximum
3428 * SK_PNMI_ERR_OK The request was successfully performed.
3429 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3430 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3431 * the correct data (e.g. a 32bit value is
3432 * needed, but a 16 bit value was passed).
3433 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
3435 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
3436 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3437 * exist (e.g. port instance 3 on a two port
3440 PNMI_STATIC int Vpd(
3441 SK_AC *pAC, /* Pointer to adapter context */
3442 SK_IOC IoC, /* IO context handle */
3443 int Action, /* Get/PreSet/Set action */
3444 SK_U32 Id, /* Object ID that is to be processed */
3445 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3446 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3447 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3448 unsigned int TableIndex, /* Index to the Id table */
3449 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3451 SK_VPD_STATUS *pVpdStatus;
3452 unsigned int BufLen;
3454 char KeyArr[SK_PNMI_VPD_ENTRIES][SK_PNMI_VPD_KEY_SIZE];
3455 char KeyStr[SK_PNMI_VPD_KEY_SIZE];
3457 unsigned int Offset;
3459 unsigned int FirstIndex;
3460 unsigned int LastIndex;
3466 * Get array of all currently stored VPD keys
3468 Ret = GetVpdKeyArr(pAC, IoC, &KeyArr[0][0], sizeof(KeyArr),
3470 if (Ret != SK_PNMI_ERR_OK) {
3476 * If instance is not -1, try to find the requested VPD key for
3477 * the multiple instance variables. The other OIDs as for example
3478 * OID VPD_ACTION are single instance variables and must be
3479 * handled separatly.
3484 if ((Instance != (SK_U32)(-1))) {
3486 if (Id == OID_SKGE_VPD_KEY || Id == OID_SKGE_VPD_VALUE ||
3487 Id == OID_SKGE_VPD_ACCESS) {
3489 SK_STRNCPY(KeyStr, (char *)&Instance, 4);
3492 for (Index = 0; Index < KeyNo; Index ++) {
3494 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3496 LastIndex = Index+1;
3500 if (Index == KeyNo) {
3503 return (SK_PNMI_ERR_UNKNOWN_INST);
3506 else if (Instance != 1) {
3509 return (SK_PNMI_ERR_UNKNOWN_INST);
3514 * Get value, if a query should be performed
3516 if (Action == SK_PNMI_GET) {
3520 case OID_SKGE_VPD_FREE_BYTES:
3521 /* Check length of buffer */
3522 if (*pLen < sizeof(SK_U32)) {
3524 *pLen = sizeof(SK_U32);
3525 return (SK_PNMI_ERR_TOO_SHORT);
3527 /* Get number of free bytes */
3528 pVpdStatus = VpdStat(pAC, IoC);
3529 if (pVpdStatus == NULL) {
3531 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR017,
3535 return (SK_PNMI_ERR_GENERAL);
3537 if ((pVpdStatus->vpd_status & VPD_VALID) == 0) {
3539 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR018,
3543 return (SK_PNMI_ERR_GENERAL);
3546 Val32 = (SK_U32)pVpdStatus->vpd_free_rw;
3547 SK_PNMI_STORE_U32(pBuf, Val32);
3548 *pLen = sizeof(SK_U32);
3551 case OID_SKGE_VPD_ENTRIES_LIST:
3553 for (Len = 0, Index = 0; Index < KeyNo; Index ++) {
3555 Len += SK_STRLEN(KeyArr[Index]) + 1;
3560 return (SK_PNMI_ERR_TOO_SHORT);
3564 *(pBuf) = (char)Len - 1;
3565 for (Offset = 1, Index = 0; Index < KeyNo; Index ++) {
3567 Len = SK_STRLEN(KeyArr[Index]);
3568 SK_MEMCPY(pBuf + Offset, KeyArr[Index], Len);
3572 if (Index < KeyNo - 1) {
3574 *(pBuf + Offset) = ' ';
3581 case OID_SKGE_VPD_ENTRIES_NUMBER:
3583 if (*pLen < sizeof(SK_U32)) {
3585 *pLen = sizeof(SK_U32);
3586 return (SK_PNMI_ERR_TOO_SHORT);
3589 Val32 = (SK_U32)KeyNo;
3590 SK_PNMI_STORE_U32(pBuf, Val32);
3591 *pLen = sizeof(SK_U32);
3594 case OID_SKGE_VPD_KEY:
3595 /* Check buffer length, if it is large enough */
3596 for (Len = 0, Index = FirstIndex;
3597 Index < LastIndex; Index ++) {
3599 Len += SK_STRLEN(KeyArr[Index]) + 1;
3604 return (SK_PNMI_ERR_TOO_SHORT);
3608 * Get the key to an intermediate buffer, because
3609 * we have to prepend a length byte.
3611 for (Offset = 0, Index = FirstIndex;
3612 Index < LastIndex; Index ++) {
3614 Len = SK_STRLEN(KeyArr[Index]);
3616 *(pBuf + Offset) = (char)Len;
3617 SK_MEMCPY(pBuf + Offset + 1, KeyArr[Index],
3624 case OID_SKGE_VPD_VALUE:
3625 /* Check the buffer length if it is large enough */
3626 for (Offset = 0, Index = FirstIndex;
3627 Index < LastIndex; Index ++) {
3630 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3631 (int *)&BufLen) > 0 ||
3632 BufLen >= SK_PNMI_VPD_DATALEN) {
3634 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3638 return (SK_PNMI_ERR_GENERAL);
3640 Offset += BufLen + 1;
3642 if (*pLen < Offset) {
3645 return (SK_PNMI_ERR_TOO_SHORT);
3649 * Get the value to an intermediate buffer, because
3650 * we have to prepend a length byte.
3652 for (Offset = 0, Index = FirstIndex;
3653 Index < LastIndex; Index ++) {
3656 if (VpdRead(pAC, IoC, KeyArr[Index], Buf,
3657 (int *)&BufLen) > 0 ||
3658 BufLen >= SK_PNMI_VPD_DATALEN) {
3660 SK_ERR_LOG(pAC, SK_ERRCL_SW,
3665 return (SK_PNMI_ERR_GENERAL);
3668 *(pBuf + Offset) = (char)BufLen;
3669 SK_MEMCPY(pBuf + Offset + 1, Buf, BufLen);
3670 Offset += BufLen + 1;
3675 case OID_SKGE_VPD_ACCESS:
3676 if (*pLen < LastIndex - FirstIndex) {
3678 *pLen = LastIndex - FirstIndex;
3679 return (SK_PNMI_ERR_TOO_SHORT);
3682 for (Offset = 0, Index = FirstIndex;
3683 Index < LastIndex; Index ++) {
3685 if (VpdMayWrite(KeyArr[Index])) {
3687 *(pBuf + Offset) = SK_PNMI_VPD_RW;
3690 *(pBuf + Offset) = SK_PNMI_VPD_RO;
3697 case OID_SKGE_VPD_ACTION:
3698 Offset = LastIndex - FirstIndex;
3699 if (*pLen < Offset) {
3702 return (SK_PNMI_ERR_TOO_SHORT);
3704 SK_MEMSET(pBuf, 0, Offset);
3709 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR023,
3713 return (SK_PNMI_ERR_GENERAL);
3717 /* The only OID which can be set is VPD_ACTION */
3718 if (Id != OID_SKGE_VPD_ACTION) {
3720 if (Id == OID_SKGE_VPD_FREE_BYTES ||
3721 Id == OID_SKGE_VPD_ENTRIES_LIST ||
3722 Id == OID_SKGE_VPD_ENTRIES_NUMBER ||
3723 Id == OID_SKGE_VPD_KEY ||
3724 Id == OID_SKGE_VPD_VALUE ||
3725 Id == OID_SKGE_VPD_ACCESS) {
3728 return (SK_PNMI_ERR_READ_ONLY);
3731 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR024,
3735 return (SK_PNMI_ERR_GENERAL);
3739 * From this point we handle VPD_ACTION. Check the buffer
3740 * length. It should at least have the size of one byte.
3745 return (SK_PNMI_ERR_TOO_SHORT);
3749 * The first byte contains the VPD action type we should
3754 case SK_PNMI_VPD_IGNORE:
3758 case SK_PNMI_VPD_CREATE:
3760 * We have to create a new VPD entry or we modify
3761 * an existing one. Check first the buffer length.
3766 return (SK_PNMI_ERR_TOO_SHORT);
3768 KeyStr[0] = pBuf[1];
3769 KeyStr[1] = pBuf[2];
3773 * Is the entry writable or does it belong to the
3776 if (!VpdMayWrite(KeyStr)) {
3779 return (SK_PNMI_ERR_BAD_VALUE);
3782 Offset = (int)pBuf[3] & 0xFF;
3784 SK_MEMCPY(Buf, pBuf + 4, Offset);
3787 /* A preset ends here */
3788 if (Action == SK_PNMI_PRESET) {
3790 return (SK_PNMI_ERR_OK);
3793 /* Write the new entry or modify an existing one */
3794 Ret = VpdWrite(pAC, IoC, KeyStr, Buf);
3795 if (Ret == SK_PNMI_VPD_NOWRITE ) {
3798 return (SK_PNMI_ERR_BAD_VALUE);
3800 else if (Ret != SK_PNMI_VPD_OK) {
3802 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR025,
3806 return (SK_PNMI_ERR_GENERAL);
3810 * Perform an update of the VPD data. This is
3811 * not mandantory, but just to be sure.
3813 Ret = VpdUpdate(pAC, IoC);
3814 if (Ret != SK_PNMI_VPD_OK) {
3816 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR026,
3820 return (SK_PNMI_ERR_GENERAL);
3824 case SK_PNMI_VPD_DELETE:
3825 /* Check if the buffer size is plausible */
3829 return (SK_PNMI_ERR_TOO_SHORT);
3834 return (SK_PNMI_ERR_BAD_VALUE);
3836 KeyStr[0] = pBuf[1];
3837 KeyStr[1] = pBuf[2];
3840 /* Find the passed key in the array */
3841 for (Index = 0; Index < KeyNo; Index ++) {
3843 if (SK_STRCMP(KeyStr, KeyArr[Index]) == 0) {
3849 * If we cannot find the key it is wrong, so we
3850 * return an appropriate error value.
3852 if (Index == KeyNo) {
3855 return (SK_PNMI_ERR_BAD_VALUE);
3858 if (Action == SK_PNMI_PRESET) {
3860 return (SK_PNMI_ERR_OK);
3863 /* Ok, you wanted it and you will get it */
3864 Ret = VpdDelete(pAC, IoC, KeyStr);
3865 if (Ret != SK_PNMI_VPD_OK) {
3867 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR027,
3871 return (SK_PNMI_ERR_GENERAL);
3875 * Perform an update of the VPD data. This is
3876 * not mandantory, but just to be sure.
3878 Ret = VpdUpdate(pAC, IoC);
3879 if (Ret != SK_PNMI_VPD_OK) {
3881 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR028,
3885 return (SK_PNMI_ERR_GENERAL);
3891 return (SK_PNMI_ERR_BAD_VALUE);
3895 return (SK_PNMI_ERR_OK);
3898 /*****************************************************************************
3900 * General - OID handler function of various single instance OIDs
3903 * The code is simple. No description necessary.
3906 * SK_PNMI_ERR_OK The request was successfully performed.
3907 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
3908 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
3909 * the correct data (e.g. a 32bit value is
3910 * needed, but a 16 bit value was passed).
3911 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
3912 * exist (e.g. port instance 3 on a two port
3915 PNMI_STATIC int General(
3916 SK_AC *pAC, /* Pointer to adapter context */
3917 SK_IOC IoC, /* IO context handle */
3918 int Action, /* Get/PreSet/Set action */
3919 SK_U32 Id, /* Object ID that is to be processed */
3920 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
3921 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
3922 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
3923 unsigned int TableIndex, /* Index to the Id table */
3924 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
3929 unsigned int Offset;
3935 SK_U64 Val64RxHwErrs = 0;
3936 SK_U64 Val64TxHwErrs = 0;
3937 SK_BOOL Is64BitReq = SK_FALSE;
3942 * Check instance. We only handle single instance variables
3944 if (Instance != (SK_U32)(-1) && Instance != 1) {
3947 return (SK_PNMI_ERR_UNKNOWN_INST);
3951 * Check action. We only allow get requests.
3953 if (Action != SK_PNMI_GET) {
3956 return (SK_PNMI_ERR_READ_ONLY);
3959 MacType = pAC->GIni.GIMacType;
3962 * Check length for the various supported OIDs
3966 case OID_GEN_XMIT_ERROR:
3967 case OID_GEN_RCV_ERROR:
3968 case OID_GEN_RCV_NO_BUFFER:
3969 #ifndef SK_NDIS_64BIT_CTR
3970 if (*pLen < sizeof(SK_U32)) {
3971 *pLen = sizeof(SK_U32);
3972 return (SK_PNMI_ERR_TOO_SHORT);
3975 #else /* SK_NDIS_64BIT_CTR */
3978 * for compatibility, at least 32bit are required for oid
3980 if (*pLen < sizeof(SK_U32)) {
3982 * but indicate handling for 64bit values,
3983 * if insufficient space is provided
3985 *pLen = sizeof(SK_U64);
3986 return (SK_PNMI_ERR_TOO_SHORT);
3989 Is64BitReq = (*pLen < sizeof(SK_U64)) ? SK_FALSE : SK_TRUE;
3990 #endif /* SK_NDIS_64BIT_CTR */
3993 case OID_SKGE_PORT_NUMBER:
3994 case OID_SKGE_DEVICE_TYPE:
3995 case OID_SKGE_RESULT:
3996 case OID_SKGE_RLMT_MONITOR_NUMBER:
3997 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
3998 case OID_SKGE_TRAP_NUMBER:
3999 case OID_SKGE_MDB_VERSION:
4000 if (*pLen < sizeof(SK_U32)) {
4002 *pLen = sizeof(SK_U32);
4003 return (SK_PNMI_ERR_TOO_SHORT);
4007 case OID_SKGE_CHIPSET:
4008 if (*pLen < sizeof(SK_U16)) {
4010 *pLen = sizeof(SK_U16);
4011 return (SK_PNMI_ERR_TOO_SHORT);
4015 case OID_SKGE_BUS_TYPE:
4016 case OID_SKGE_BUS_SPEED:
4017 case OID_SKGE_BUS_WIDTH:
4018 case OID_SKGE_SENSOR_NUMBER:
4019 case OID_SKGE_CHKSM_NUMBER:
4020 if (*pLen < sizeof(SK_U8)) {
4022 *pLen = sizeof(SK_U8);
4023 return (SK_PNMI_ERR_TOO_SHORT);
4027 case OID_SKGE_TX_SW_QUEUE_LEN:
4028 case OID_SKGE_TX_SW_QUEUE_MAX:
4029 case OID_SKGE_TX_RETRY:
4030 case OID_SKGE_RX_INTR_CTS:
4031 case OID_SKGE_TX_INTR_CTS:
4032 case OID_SKGE_RX_NO_BUF_CTS:
4033 case OID_SKGE_TX_NO_BUF_CTS:
4034 case OID_SKGE_TX_USED_DESCR_NO:
4035 case OID_SKGE_RX_DELIVERED_CTS:
4036 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4037 case OID_SKGE_RX_HW_ERROR_CTS:
4038 case OID_SKGE_TX_HW_ERROR_CTS:
4039 case OID_SKGE_IN_ERRORS_CTS:
4040 case OID_SKGE_OUT_ERROR_CTS:
4041 case OID_SKGE_ERR_RECOVERY_CTS:
4042 case OID_SKGE_SYSUPTIME:
4043 if (*pLen < sizeof(SK_U64)) {
4045 *pLen = sizeof(SK_U64);
4046 return (SK_PNMI_ERR_TOO_SHORT);
4055 /* Update statistic */
4056 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4057 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4058 Id == OID_SKGE_IN_ERRORS_CTS ||
4059 Id == OID_SKGE_OUT_ERROR_CTS ||
4060 Id == OID_GEN_XMIT_ERROR ||
4061 Id == OID_GEN_RCV_ERROR) {
4063 /* Force the XMAC to update its statistic counters and
4064 * Increment semaphore to indicate that an update was
4067 Ret = MacUpdate(pAC, IoC, 0, pAC->GIni.GIMacsFound - 1);
4068 if (Ret != SK_PNMI_ERR_OK) {
4073 pAC->Pnmi.MacUpdatedFlag ++;
4076 * Some OIDs consist of multiple hardware counters. Those
4077 * values which are contained in all of them will be added
4082 case OID_SKGE_RX_HW_ERROR_CTS:
4083 case OID_SKGE_IN_ERRORS_CTS:
4084 case OID_GEN_RCV_ERROR:
4086 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_MISSED, NetIndex) +
4087 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FRAMING, NetIndex) +
4088 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_OVERFLOW, NetIndex)+
4089 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_JABBER, NetIndex) +
4090 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CARRIER, NetIndex) +
4091 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_IRLENGTH, NetIndex)+
4092 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SYMBOL, NetIndex) +
4093 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_SHORTS, NetIndex) +
4094 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_RUNT, NetIndex) +
4095 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_TOO_LONG, NetIndex) +
4096 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_FCS, NetIndex) +
4097 GetStatVal(pAC, IoC, 0, SK_PNMI_HRX_CEXT, NetIndex);
4100 case OID_SKGE_TX_HW_ERROR_CTS:
4101 case OID_SKGE_OUT_ERROR_CTS:
4102 case OID_GEN_XMIT_ERROR:
4104 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_EXCESS_COL, NetIndex) +
4105 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_LATE_COL, NetIndex)+
4106 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_UNDERRUN, NetIndex)+
4107 GetStatVal(pAC, IoC, 0, SK_PNMI_HTX_CARRIER, NetIndex);
4117 case OID_SKGE_SUPPORTED_LIST:
4118 Len = ID_TABLE_SIZE * sizeof(SK_U32);
4122 return (SK_PNMI_ERR_TOO_SHORT);
4124 for (Offset = 0, Index = 0; Offset < Len;
4125 Offset += sizeof(SK_U32), Index ++) {
4127 Val32 = (SK_U32)IdTable[Index].Id;
4128 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
4133 case OID_SKGE_PORT_NUMBER:
4134 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4135 SK_PNMI_STORE_U32(pBuf, Val32);
4136 *pLen = sizeof(SK_U32);
4139 case OID_SKGE_DEVICE_TYPE:
4140 Val32 = (SK_U32)pAC->Pnmi.DeviceType;
4141 SK_PNMI_STORE_U32(pBuf, Val32);
4142 *pLen = sizeof(SK_U32);
4145 case OID_SKGE_DRIVER_DESCR:
4146 if (pAC->Pnmi.pDriverDescription == NULL) {
4148 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR007,
4152 return (SK_PNMI_ERR_GENERAL);
4155 Len = SK_STRLEN(pAC->Pnmi.pDriverDescription) + 1;
4156 if (Len > SK_PNMI_STRINGLEN1) {
4158 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR029,
4162 return (SK_PNMI_ERR_GENERAL);
4168 return (SK_PNMI_ERR_TOO_SHORT);
4170 *pBuf = (char)(Len - 1);
4171 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverDescription, Len - 1);
4175 case OID_SKGE_DRIVER_VERSION:
4176 if (pAC->Pnmi.pDriverVersion == NULL) {
4178 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR030,
4182 return (SK_PNMI_ERR_GENERAL);
4185 Len = SK_STRLEN(pAC->Pnmi.pDriverVersion) + 1;
4186 if (Len > SK_PNMI_STRINGLEN1) {
4188 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR031,
4192 return (SK_PNMI_ERR_GENERAL);
4198 return (SK_PNMI_ERR_TOO_SHORT);
4200 *pBuf = (char)(Len - 1);
4201 SK_MEMCPY(pBuf + 1, pAC->Pnmi.pDriverVersion, Len - 1);
4205 case OID_SKGE_HW_DESCR:
4207 * The hardware description is located in the VPD. This
4208 * query may move to the initialisation routine. But
4209 * the VPD data is cached and therefore a call here
4210 * will not make much difference.
4213 if (VpdRead(pAC, IoC, VPD_NAME, Buf, (int *)&Len) > 0) {
4215 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR032,
4219 return (SK_PNMI_ERR_GENERAL);
4222 if (Len > SK_PNMI_STRINGLEN1) {
4224 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR033,
4228 return (SK_PNMI_ERR_GENERAL);
4233 return (SK_PNMI_ERR_TOO_SHORT);
4235 *pBuf = (char)(Len - 1);
4236 SK_MEMCPY(pBuf + 1, Buf, Len - 1);
4240 case OID_SKGE_HW_VERSION:
4241 /* Oh, I love to do some string manipulation */
4245 return (SK_PNMI_ERR_TOO_SHORT);
4247 Val8 = (SK_U8)pAC->GIni.GIPciHwRev;
4250 pBuf[2] = (char)(0x30 | ((Val8 >> 4) & 0x0F));
4252 pBuf[4] = (char)(0x30 | (Val8 & 0x0F));
4256 case OID_SKGE_CHIPSET:
4257 Val16 = pAC->Pnmi.Chipset;
4258 SK_PNMI_STORE_U16(pBuf, Val16);
4259 *pLen = sizeof(SK_U16);
4262 case OID_SKGE_BUS_TYPE:
4263 *pBuf = (char)SK_PNMI_BUS_PCI;
4264 *pLen = sizeof(char);
4267 case OID_SKGE_BUS_SPEED:
4268 *pBuf = pAC->Pnmi.PciBusSpeed;
4269 *pLen = sizeof(char);
4272 case OID_SKGE_BUS_WIDTH:
4273 *pBuf = pAC->Pnmi.PciBusWidth;
4274 *pLen = sizeof(char);
4277 case OID_SKGE_RESULT:
4278 Val32 = pAC->Pnmi.TestResult;
4279 SK_PNMI_STORE_U32(pBuf, Val32);
4280 *pLen = sizeof(SK_U32);
4283 case OID_SKGE_SENSOR_NUMBER:
4284 *pBuf = (char)pAC->I2c.MaxSens;
4285 *pLen = sizeof(char);
4288 case OID_SKGE_CHKSM_NUMBER:
4289 *pBuf = SKCS_NUM_PROTOCOLS;
4290 *pLen = sizeof(char);
4293 case OID_SKGE_TRAP_NUMBER:
4294 GetTrapQueueLen(pAC, &Len, &Val);
4295 Val32 = (SK_U32)Val;
4296 SK_PNMI_STORE_U32(pBuf, Val32);
4297 *pLen = sizeof(SK_U32);
4301 GetTrapQueueLen(pAC, &Len, &Val);
4305 return (SK_PNMI_ERR_TOO_SHORT);
4307 CopyTrapQueue(pAC, pBuf);
4311 case OID_SKGE_RLMT_MONITOR_NUMBER:
4312 /* XXX Not yet implemented by RLMT therefore we return zero elements */
4314 SK_PNMI_STORE_U32(pBuf, Val32);
4315 *pLen = sizeof(SK_U32);
4318 case OID_SKGE_TX_SW_QUEUE_LEN:
4319 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4320 if (MacType == SK_MAC_XMAC) {
4322 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4323 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueLen;
4325 /* Single net mode */
4327 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueLen +
4328 pAC->Pnmi.BufPort[1].TxSwQueueLen;
4333 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4334 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4336 /* Single net mode */
4338 Val64 = pAC->Pnmi.Port[0].TxSwQueueLen +
4339 pAC->Pnmi.Port[1].TxSwQueueLen;
4342 SK_PNMI_STORE_U64(pBuf, Val64);
4343 *pLen = sizeof(SK_U64);
4347 case OID_SKGE_TX_SW_QUEUE_MAX:
4348 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4349 if (MacType == SK_MAC_XMAC) {
4351 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4352 Val64 = pAC->Pnmi.BufPort[NetIndex].TxSwQueueMax;
4354 /* Single net mode */
4356 Val64 = pAC->Pnmi.BufPort[0].TxSwQueueMax +
4357 pAC->Pnmi.BufPort[1].TxSwQueueMax;
4362 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4363 Val64 = pAC->Pnmi.Port[NetIndex].TxSwQueueMax;
4365 /* Single net mode */
4367 Val64 = pAC->Pnmi.Port[0].TxSwQueueMax +
4368 pAC->Pnmi.Port[1].TxSwQueueMax;
4371 SK_PNMI_STORE_U64(pBuf, Val64);
4372 *pLen = sizeof(SK_U64);
4375 case OID_SKGE_TX_RETRY:
4376 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4377 if (MacType == SK_MAC_XMAC) {
4379 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4380 Val64 = pAC->Pnmi.BufPort[NetIndex].TxRetryCts;
4382 /* Single net mode */
4384 Val64 = pAC->Pnmi.BufPort[0].TxRetryCts +
4385 pAC->Pnmi.BufPort[1].TxRetryCts;
4390 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4391 Val64 = pAC->Pnmi.Port[NetIndex].TxRetryCts;
4393 /* Single net mode */
4395 Val64 = pAC->Pnmi.Port[0].TxRetryCts +
4396 pAC->Pnmi.Port[1].TxRetryCts;
4399 SK_PNMI_STORE_U64(pBuf, Val64);
4400 *pLen = sizeof(SK_U64);
4403 case OID_SKGE_RX_INTR_CTS:
4404 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4405 if (MacType == SK_MAC_XMAC) {
4407 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4408 Val64 = pAC->Pnmi.BufPort[NetIndex].RxIntrCts;
4410 /* Single net mode */
4412 Val64 = pAC->Pnmi.BufPort[0].RxIntrCts +
4413 pAC->Pnmi.BufPort[1].RxIntrCts;
4418 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4419 Val64 = pAC->Pnmi.Port[NetIndex].RxIntrCts;
4421 /* Single net mode */
4423 Val64 = pAC->Pnmi.Port[0].RxIntrCts +
4424 pAC->Pnmi.Port[1].RxIntrCts;
4427 SK_PNMI_STORE_U64(pBuf, Val64);
4428 *pLen = sizeof(SK_U64);
4431 case OID_SKGE_TX_INTR_CTS:
4432 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4433 if (MacType == SK_MAC_XMAC) {
4435 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4436 Val64 = pAC->Pnmi.BufPort[NetIndex].TxIntrCts;
4438 /* Single net mode */
4440 Val64 = pAC->Pnmi.BufPort[0].TxIntrCts +
4441 pAC->Pnmi.BufPort[1].TxIntrCts;
4446 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4447 Val64 = pAC->Pnmi.Port[NetIndex].TxIntrCts;
4449 /* Single net mode */
4451 Val64 = pAC->Pnmi.Port[0].TxIntrCts +
4452 pAC->Pnmi.Port[1].TxIntrCts;
4455 SK_PNMI_STORE_U64(pBuf, Val64);
4456 *pLen = sizeof(SK_U64);
4459 case OID_SKGE_RX_NO_BUF_CTS:
4460 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4461 if (MacType == SK_MAC_XMAC) {
4463 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4464 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4466 /* Single net mode */
4468 Val64 = pAC->Pnmi.BufPort[0].RxNoBufCts +
4469 pAC->Pnmi.BufPort[1].RxNoBufCts;
4474 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4475 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4477 /* Single net mode */
4479 Val64 = pAC->Pnmi.Port[0].RxNoBufCts +
4480 pAC->Pnmi.Port[1].RxNoBufCts;
4483 SK_PNMI_STORE_U64(pBuf, Val64);
4484 *pLen = sizeof(SK_U64);
4487 case OID_SKGE_TX_NO_BUF_CTS:
4488 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4489 if (MacType == SK_MAC_XMAC) {
4491 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4492 Val64 = pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4494 /* Single net mode */
4496 Val64 = pAC->Pnmi.BufPort[0].TxNoBufCts +
4497 pAC->Pnmi.BufPort[1].TxNoBufCts;
4502 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4503 Val64 = pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4505 /* Single net mode */
4507 Val64 = pAC->Pnmi.Port[0].TxNoBufCts +
4508 pAC->Pnmi.Port[1].TxNoBufCts;
4511 SK_PNMI_STORE_U64(pBuf, Val64);
4512 *pLen = sizeof(SK_U64);
4515 case OID_SKGE_TX_USED_DESCR_NO:
4516 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4517 if (MacType == SK_MAC_XMAC) {
4519 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4520 Val64 = pAC->Pnmi.BufPort[NetIndex].TxUsedDescrNo;
4522 /* Single net mode */
4524 Val64 = pAC->Pnmi.BufPort[0].TxUsedDescrNo +
4525 pAC->Pnmi.BufPort[1].TxUsedDescrNo;
4530 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4531 Val64 = pAC->Pnmi.Port[NetIndex].TxUsedDescrNo;
4533 /* Single net mode */
4535 Val64 = pAC->Pnmi.Port[0].TxUsedDescrNo +
4536 pAC->Pnmi.Port[1].TxUsedDescrNo;
4539 SK_PNMI_STORE_U64(pBuf, Val64);
4540 *pLen = sizeof(SK_U64);
4543 case OID_SKGE_RX_DELIVERED_CTS:
4544 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4545 if (MacType == SK_MAC_XMAC) {
4547 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4548 Val64 = pAC->Pnmi.BufPort[NetIndex].RxDeliveredCts;
4550 /* Single net mode */
4552 Val64 = pAC->Pnmi.BufPort[0].RxDeliveredCts +
4553 pAC->Pnmi.BufPort[1].RxDeliveredCts;
4558 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4559 Val64 = pAC->Pnmi.Port[NetIndex].RxDeliveredCts;
4561 /* Single net mode */
4563 Val64 = pAC->Pnmi.Port[0].RxDeliveredCts +
4564 pAC->Pnmi.Port[1].RxDeliveredCts;
4567 SK_PNMI_STORE_U64(pBuf, Val64);
4568 *pLen = sizeof(SK_U64);
4571 case OID_SKGE_RX_OCTETS_DELIV_CTS:
4572 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4573 if (MacType == SK_MAC_XMAC) {
4575 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4576 Val64 = pAC->Pnmi.BufPort[NetIndex].RxOctetsDeliveredCts;
4578 /* Single net mode */
4580 Val64 = pAC->Pnmi.BufPort[0].RxOctetsDeliveredCts +
4581 pAC->Pnmi.BufPort[1].RxOctetsDeliveredCts;
4586 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4587 Val64 = pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts;
4589 /* Single net mode */
4591 Val64 = pAC->Pnmi.Port[0].RxOctetsDeliveredCts +
4592 pAC->Pnmi.Port[1].RxOctetsDeliveredCts;
4595 SK_PNMI_STORE_U64(pBuf, Val64);
4596 *pLen = sizeof(SK_U64);
4599 case OID_SKGE_RX_HW_ERROR_CTS:
4600 SK_PNMI_STORE_U64(pBuf, Val64RxHwErrs);
4601 *pLen = sizeof(SK_U64);
4604 case OID_SKGE_TX_HW_ERROR_CTS:
4605 SK_PNMI_STORE_U64(pBuf, Val64TxHwErrs);
4606 *pLen = sizeof(SK_U64);
4609 case OID_SKGE_IN_ERRORS_CTS:
4610 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4611 if (MacType == SK_MAC_XMAC) {
4613 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4614 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4616 /* Single net mode */
4618 Val64 = Val64RxHwErrs +
4619 pAC->Pnmi.BufPort[0].RxNoBufCts +
4620 pAC->Pnmi.BufPort[1].RxNoBufCts;
4625 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4626 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4628 /* Single net mode */
4630 Val64 = Val64RxHwErrs +
4631 pAC->Pnmi.Port[0].RxNoBufCts +
4632 pAC->Pnmi.Port[1].RxNoBufCts;
4635 SK_PNMI_STORE_U64(pBuf, Val64);
4636 *pLen = sizeof(SK_U64);
4639 case OID_SKGE_OUT_ERROR_CTS:
4640 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4641 if (MacType == SK_MAC_XMAC) {
4643 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4644 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4646 /* Single net mode */
4648 Val64 = Val64TxHwErrs +
4649 pAC->Pnmi.BufPort[0].TxNoBufCts +
4650 pAC->Pnmi.BufPort[1].TxNoBufCts;
4655 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4656 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4658 /* Single net mode */
4660 Val64 = Val64TxHwErrs +
4661 pAC->Pnmi.Port[0].TxNoBufCts +
4662 pAC->Pnmi.Port[1].TxNoBufCts;
4665 SK_PNMI_STORE_U64(pBuf, Val64);
4666 *pLen = sizeof(SK_U64);
4669 case OID_SKGE_ERR_RECOVERY_CTS:
4670 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4671 if (MacType == SK_MAC_XMAC) {
4673 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4674 Val64 = pAC->Pnmi.BufPort[NetIndex].ErrRecoveryCts;
4676 /* Single net mode */
4678 Val64 = pAC->Pnmi.BufPort[0].ErrRecoveryCts +
4679 pAC->Pnmi.BufPort[1].ErrRecoveryCts;
4684 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
4685 Val64 = pAC->Pnmi.Port[NetIndex].ErrRecoveryCts;
4687 /* Single net mode */
4689 Val64 = pAC->Pnmi.Port[0].ErrRecoveryCts +
4690 pAC->Pnmi.Port[1].ErrRecoveryCts;
4693 SK_PNMI_STORE_U64(pBuf, Val64);
4694 *pLen = sizeof(SK_U64);
4697 case OID_SKGE_SYSUPTIME:
4698 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
4699 Val64 -= pAC->Pnmi.StartUpTime;
4700 SK_PNMI_STORE_U64(pBuf, Val64);
4701 *pLen = sizeof(SK_U64);
4704 case OID_SKGE_MDB_VERSION:
4705 Val32 = SK_PNMI_MDB_VERSION;
4706 SK_PNMI_STORE_U32(pBuf, Val32);
4707 *pLen = sizeof(SK_U32);
4710 case OID_GEN_RCV_ERROR:
4711 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4712 if (MacType == SK_MAC_XMAC) {
4713 Val64 = Val64RxHwErrs + pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4716 Val64 = Val64RxHwErrs + pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4720 * by default 32bit values are evaluated
4723 Val32 = (SK_U32)Val64;
4724 SK_PNMI_STORE_U32(pBuf, Val32);
4725 *pLen = sizeof(SK_U32);
4728 SK_PNMI_STORE_U64(pBuf, Val64);
4729 *pLen = sizeof(SK_U64);
4733 case OID_GEN_XMIT_ERROR:
4734 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4735 if (MacType == SK_MAC_XMAC) {
4736 Val64 = Val64TxHwErrs + pAC->Pnmi.BufPort[NetIndex].TxNoBufCts;
4739 Val64 = Val64TxHwErrs + pAC->Pnmi.Port[NetIndex].TxNoBufCts;
4743 * by default 32bit values are evaluated
4746 Val32 = (SK_U32)Val64;
4747 SK_PNMI_STORE_U32(pBuf, Val32);
4748 *pLen = sizeof(SK_U32);
4751 SK_PNMI_STORE_U64(pBuf, Val64);
4752 *pLen = sizeof(SK_U64);
4756 case OID_GEN_RCV_NO_BUFFER:
4757 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
4758 if (MacType == SK_MAC_XMAC) {
4759 Val64 = pAC->Pnmi.BufPort[NetIndex].RxNoBufCts;
4762 Val64 = pAC->Pnmi.Port[NetIndex].RxNoBufCts;
4766 * by default 32bit values are evaluated
4769 Val32 = (SK_U32)Val64;
4770 SK_PNMI_STORE_U32(pBuf, Val32);
4771 *pLen = sizeof(SK_U32);
4774 SK_PNMI_STORE_U64(pBuf, Val64);
4775 *pLen = sizeof(SK_U64);
4779 case OID_GEN_TRANSMIT_QUEUE_LENGTH:
4780 Val32 = (SK_U32)pAC->Pnmi.Port[NetIndex].TxSwQueueLen;
4781 SK_PNMI_STORE_U32(pBuf, Val32);
4782 *pLen = sizeof(SK_U32);
4786 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR034,
4790 return (SK_PNMI_ERR_GENERAL);
4793 if (Id == OID_SKGE_RX_HW_ERROR_CTS ||
4794 Id == OID_SKGE_TX_HW_ERROR_CTS ||
4795 Id == OID_SKGE_IN_ERRORS_CTS ||
4796 Id == OID_SKGE_OUT_ERROR_CTS ||
4797 Id == OID_GEN_XMIT_ERROR ||
4798 Id == OID_GEN_RCV_ERROR) {
4800 pAC->Pnmi.MacUpdatedFlag --;
4803 return (SK_PNMI_ERR_OK);
4806 /*****************************************************************************
4808 * Rlmt - OID handler function of OID_SKGE_RLMT_XXX single instance.
4811 * Get/Presets/Sets the RLMT OIDs.
4814 * SK_PNMI_ERR_OK The request was successfully performed.
4815 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
4816 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
4817 * the correct data (e.g. a 32bit value is
4818 * needed, but a 16 bit value was passed).
4819 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
4821 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
4822 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
4823 * exist (e.g. port instance 3 on a two port
4826 PNMI_STATIC int Rlmt(
4827 SK_AC *pAC, /* Pointer to adapter context */
4828 SK_IOC IoC, /* IO context handle */
4829 int Action, /* Get/PreSet/Set action */
4830 SK_U32 Id, /* Object ID that is to be processed */
4831 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
4832 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
4833 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
4834 unsigned int TableIndex, /* Index to the Id table */
4835 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
4838 unsigned int PhysPortIndex;
4839 unsigned int PhysPortMax;
4840 SK_EVPARA EventParam;
4846 * Check instance. Only single instance OIDs are allowed here.
4848 if (Instance != (SK_U32)(-1) && Instance != 1) {
4851 return (SK_PNMI_ERR_UNKNOWN_INST);
4855 * Perform the requested action
4857 if (Action == SK_PNMI_GET) {
4860 * Check if the buffer length is large enough.
4865 case OID_SKGE_RLMT_MODE:
4866 case OID_SKGE_RLMT_PORT_ACTIVE:
4867 case OID_SKGE_RLMT_PORT_PREFERRED:
4868 if (*pLen < sizeof(SK_U8)) {
4870 *pLen = sizeof(SK_U8);
4871 return (SK_PNMI_ERR_TOO_SHORT);
4875 case OID_SKGE_RLMT_PORT_NUMBER:
4876 if (*pLen < sizeof(SK_U32)) {
4878 *pLen = sizeof(SK_U32);
4879 return (SK_PNMI_ERR_TOO_SHORT);
4883 case OID_SKGE_RLMT_CHANGE_CTS:
4884 case OID_SKGE_RLMT_CHANGE_TIME:
4885 case OID_SKGE_RLMT_CHANGE_ESTIM:
4886 case OID_SKGE_RLMT_CHANGE_THRES:
4887 if (*pLen < sizeof(SK_U64)) {
4889 *pLen = sizeof(SK_U64);
4890 return (SK_PNMI_ERR_TOO_SHORT);
4895 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR035,
4899 return (SK_PNMI_ERR_GENERAL);
4903 * Update RLMT statistic and increment semaphores to indicate
4904 * that an update was already done. Maybe RLMT will hold its
4905 * statistic always up to date some time. Then we can
4906 * remove this type of call.
4908 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
4913 pAC->Pnmi.RlmtUpdatedFlag ++;
4920 case OID_SKGE_RLMT_MODE:
4921 *pBuf = (char)pAC->Rlmt.Net[0].RlmtMode;
4922 *pLen = sizeof(char);
4925 case OID_SKGE_RLMT_PORT_NUMBER:
4926 Val32 = (SK_U32)pAC->GIni.GIMacsFound;
4927 SK_PNMI_STORE_U32(pBuf, Val32);
4928 *pLen = sizeof(SK_U32);
4931 case OID_SKGE_RLMT_PORT_ACTIVE:
4934 * If multiple ports may become active this OID
4935 * doesn't make sense any more. A new variable in
4936 * the port structure should be created. However,
4937 * for this variable the first active port is
4940 PhysPortMax = pAC->GIni.GIMacsFound;
4942 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
4945 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
4947 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(PhysPortIndex);
4951 *pLen = sizeof(char);
4954 case OID_SKGE_RLMT_PORT_PREFERRED:
4955 *pBuf = (char)SK_PNMI_PORT_PHYS2LOG(pAC->Rlmt.Net[NetIndex].Preference);
4956 *pLen = sizeof(char);
4959 case OID_SKGE_RLMT_CHANGE_CTS:
4960 Val64 = pAC->Pnmi.RlmtChangeCts;
4961 SK_PNMI_STORE_U64(pBuf, Val64);
4962 *pLen = sizeof(SK_U64);
4965 case OID_SKGE_RLMT_CHANGE_TIME:
4966 Val64 = pAC->Pnmi.RlmtChangeTime;
4967 SK_PNMI_STORE_U64(pBuf, Val64);
4968 *pLen = sizeof(SK_U64);
4971 case OID_SKGE_RLMT_CHANGE_ESTIM:
4972 Val64 = pAC->Pnmi.RlmtChangeEstimate.Estimate;
4973 SK_PNMI_STORE_U64(pBuf, Val64);
4974 *pLen = sizeof(SK_U64);
4977 case OID_SKGE_RLMT_CHANGE_THRES:
4978 Val64 = pAC->Pnmi.RlmtChangeThreshold;
4979 SK_PNMI_STORE_U64(pBuf, Val64);
4980 *pLen = sizeof(SK_U64);
4984 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
4985 ("Rlmt: Unknown OID should be handled before"));
4987 pAC->Pnmi.RlmtUpdatedFlag --;
4989 return (SK_PNMI_ERR_GENERAL);
4992 pAC->Pnmi.RlmtUpdatedFlag --;
4995 /* Perform a preset or set */
4998 case OID_SKGE_RLMT_MODE:
4999 /* Check if the buffer length is plausible */
5000 if (*pLen < sizeof(char)) {
5002 *pLen = sizeof(char);
5003 return (SK_PNMI_ERR_TOO_SHORT);
5005 /* Check if the value range is correct */
5006 if (*pLen != sizeof(char) ||
5007 (*pBuf & SK_PNMI_RLMT_MODE_CHK_LINK) == 0 ||
5008 *(SK_U8 *)pBuf > 15) {
5011 return (SK_PNMI_ERR_BAD_VALUE);
5013 /* The preset ends here */
5014 if (Action == SK_PNMI_PRESET) {
5017 return (SK_PNMI_ERR_OK);
5019 /* Send an event to RLMT to change the mode */
5020 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5021 EventParam.Para32[0] |= (SK_U32)(*pBuf);
5022 EventParam.Para32[1] = 0;
5023 if (SkRlmtEvent(pAC, IoC, SK_RLMT_MODE_CHANGE,
5026 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR037,
5030 return (SK_PNMI_ERR_GENERAL);
5034 case OID_SKGE_RLMT_PORT_PREFERRED:
5035 /* Check if the buffer length is plausible */
5036 if (*pLen < sizeof(char)) {
5038 *pLen = sizeof(char);
5039 return (SK_PNMI_ERR_TOO_SHORT);
5041 /* Check if the value range is correct */
5042 if (*pLen != sizeof(char) || *(SK_U8 *)pBuf >
5043 (SK_U8)pAC->GIni.GIMacsFound) {
5046 return (SK_PNMI_ERR_BAD_VALUE);
5048 /* The preset ends here */
5049 if (Action == SK_PNMI_PRESET) {
5052 return (SK_PNMI_ERR_OK);
5056 * Send an event to RLMT change the preferred port.
5057 * A param of -1 means automatic mode. RLMT will
5058 * make the decision which is the preferred port.
5060 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
5061 EventParam.Para32[0] = (SK_U32)(*pBuf) - 1;
5062 EventParam.Para32[1] = NetIndex;
5063 if (SkRlmtEvent(pAC, IoC, SK_RLMT_PREFPORT_CHANGE,
5066 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR038,
5070 return (SK_PNMI_ERR_GENERAL);
5074 case OID_SKGE_RLMT_CHANGE_THRES:
5075 /* Check if the buffer length is plausible */
5076 if (*pLen < sizeof(SK_U64)) {
5078 *pLen = sizeof(SK_U64);
5079 return (SK_PNMI_ERR_TOO_SHORT);
5082 * There are not many restrictions to the
5085 if (*pLen != sizeof(SK_U64)) {
5088 return (SK_PNMI_ERR_BAD_VALUE);
5090 /* A preset ends here */
5091 if (Action == SK_PNMI_PRESET) {
5094 return (SK_PNMI_ERR_OK);
5097 * Store the new threshold, which will be taken
5098 * on the next timer event.
5100 SK_PNMI_READ_U64(pBuf, Val64);
5101 pAC->Pnmi.RlmtChangeThreshold = Val64;
5105 /* The other OIDs are not be able for set */
5107 return (SK_PNMI_ERR_READ_ONLY);
5111 return (SK_PNMI_ERR_OK);
5114 /*****************************************************************************
5116 * RlmtStat - OID handler function of OID_SKGE_RLMT_XXX multiple instance.
5119 * Performs get requests on multiple instance variables.
5122 * SK_PNMI_ERR_OK The request was successfully performed.
5123 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5124 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5125 * the correct data (e.g. a 32bit value is
5126 * needed, but a 16 bit value was passed).
5127 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5128 * exist (e.g. port instance 3 on a two port
5131 PNMI_STATIC int RlmtStat(
5132 SK_AC *pAC, /* Pointer to adapter context */
5133 SK_IOC IoC, /* IO context handle */
5134 int Action, /* Get/PreSet/Set action */
5135 SK_U32 Id, /* Object ID that is to be processed */
5136 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5137 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5138 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5139 unsigned int TableIndex, /* Index to the Id table */
5140 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5142 unsigned int PhysPortMax;
5143 unsigned int PhysPortIndex;
5145 unsigned int Offset;
5151 * Calculate the port indexes from the instance
5153 PhysPortMax = pAC->GIni.GIMacsFound;
5155 if ((Instance != (SK_U32)(-1))) {
5156 /* Check instance range */
5157 if ((Instance < 1) || (Instance > PhysPortMax)) {
5160 return (SK_PNMI_ERR_UNKNOWN_INST);
5163 /* Single net mode */
5164 PhysPortIndex = Instance - 1;
5167 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5168 PhysPortIndex = NetIndex;
5171 /* Both net modes */
5172 Limit = PhysPortIndex + 1;
5175 /* Single net mode */
5177 Limit = PhysPortMax;
5180 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
5181 PhysPortIndex = NetIndex;
5182 Limit = PhysPortIndex + 1;
5187 * Currently only get requests are allowed.
5189 if (Action != SK_PNMI_GET) {
5192 return (SK_PNMI_ERR_READ_ONLY);
5196 * Check if the buffer length is large enough.
5200 case OID_SKGE_RLMT_PORT_INDEX:
5201 case OID_SKGE_RLMT_STATUS:
5202 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
5204 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
5205 return (SK_PNMI_ERR_TOO_SHORT);
5209 case OID_SKGE_RLMT_TX_HELLO_CTS:
5210 case OID_SKGE_RLMT_RX_HELLO_CTS:
5211 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5212 case OID_SKGE_RLMT_RX_SP_CTS:
5213 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U64)) {
5215 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U64);
5216 return (SK_PNMI_ERR_TOO_SHORT);
5221 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR039,
5225 return (SK_PNMI_ERR_GENERAL);
5230 * Update statistic and increment semaphores to indicate that
5231 * an update was already done.
5233 if ((Ret = RlmtUpdate(pAC, IoC, NetIndex)) != SK_PNMI_ERR_OK) {
5238 pAC->Pnmi.RlmtUpdatedFlag ++;
5244 for (; PhysPortIndex < Limit; PhysPortIndex ++) {
5248 case OID_SKGE_RLMT_PORT_INDEX:
5249 Val32 = PhysPortIndex;
5250 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5251 Offset += sizeof(SK_U32);
5254 case OID_SKGE_RLMT_STATUS:
5255 if (pAC->Rlmt.Port[PhysPortIndex].PortState ==
5257 pAC->Rlmt.Port[PhysPortIndex].PortState ==
5260 Val32 = SK_PNMI_RLMT_STATUS_ERROR;
5262 else if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
5264 Val32 = SK_PNMI_RLMT_STATUS_ACTIVE;
5267 Val32 = SK_PNMI_RLMT_STATUS_STANDBY;
5269 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5270 Offset += sizeof(SK_U32);
5273 case OID_SKGE_RLMT_TX_HELLO_CTS:
5274 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxHelloCts;
5275 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5276 Offset += sizeof(SK_U64);
5279 case OID_SKGE_RLMT_RX_HELLO_CTS:
5280 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxHelloCts;
5281 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5282 Offset += sizeof(SK_U64);
5285 case OID_SKGE_RLMT_TX_SP_REQ_CTS:
5286 Val64 = pAC->Rlmt.Port[PhysPortIndex].TxSpHelloReqCts;
5287 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5288 Offset += sizeof(SK_U64);
5291 case OID_SKGE_RLMT_RX_SP_CTS:
5292 Val64 = pAC->Rlmt.Port[PhysPortIndex].RxSpHelloCts;
5293 SK_PNMI_STORE_U64(pBuf + Offset, Val64);
5294 Offset += sizeof(SK_U64);
5298 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5299 ("RlmtStat: Unknown OID should be errored before"));
5301 pAC->Pnmi.RlmtUpdatedFlag --;
5303 return (SK_PNMI_ERR_GENERAL);
5308 pAC->Pnmi.RlmtUpdatedFlag --;
5310 return (SK_PNMI_ERR_OK);
5313 /*****************************************************************************
5315 * MacPrivateConf - OID handler function of OIDs concerning the configuration
5318 * Get/Presets/Sets the OIDs concerning the configuration.
5321 * SK_PNMI_ERR_OK The request was successfully performed.
5322 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
5323 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
5324 * the correct data (e.g. a 32bit value is
5325 * needed, but a 16 bit value was passed).
5326 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
5328 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
5329 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
5330 * exist (e.g. port instance 3 on a two port
5333 PNMI_STATIC int MacPrivateConf(
5334 SK_AC *pAC, /* Pointer to adapter context */
5335 SK_IOC IoC, /* IO context handle */
5336 int Action, /* Get/PreSet/Set action */
5337 SK_U32 Id, /* Object ID that is to be processed */
5338 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
5339 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
5340 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
5341 unsigned int TableIndex, /* Index to the Id table */
5342 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
5344 unsigned int PhysPortMax;
5345 unsigned int PhysPortIndex;
5346 unsigned int LogPortMax;
5347 unsigned int LogPortIndex;
5349 unsigned int Offset;
5352 SK_EVPARA EventParam;
5357 * Calculate instance if wished. MAC index 0 is the virtual
5360 PhysPortMax = pAC->GIni.GIMacsFound;
5361 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
5363 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
5367 if ((Instance != (SK_U32)(-1))) { /* Only one specific instance is queried */
5368 /* Check instance range */
5369 if ((Instance < 1) || (Instance > LogPortMax)) {
5372 return (SK_PNMI_ERR_UNKNOWN_INST);
5374 LogPortIndex = SK_PNMI_PORT_INST2LOG(Instance);
5375 Limit = LogPortIndex + 1;
5378 else { /* Instance == (SK_U32)(-1), get all Instances of that OID */
5387 if (Action == SK_PNMI_GET) {
5395 case OID_SKGE_CONNECTOR:
5396 case OID_SKGE_LINK_CAP:
5397 case OID_SKGE_LINK_MODE:
5398 case OID_SKGE_LINK_MODE_STATUS:
5399 case OID_SKGE_LINK_STATUS:
5400 case OID_SKGE_FLOWCTRL_CAP:
5401 case OID_SKGE_FLOWCTRL_MODE:
5402 case OID_SKGE_FLOWCTRL_STATUS:
5403 case OID_SKGE_PHY_OPERATION_CAP:
5404 case OID_SKGE_PHY_OPERATION_MODE:
5405 case OID_SKGE_PHY_OPERATION_STATUS:
5406 case OID_SKGE_SPEED_CAP:
5407 case OID_SKGE_SPEED_MODE:
5408 case OID_SKGE_SPEED_STATUS:
5409 if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) {
5411 *pLen = (Limit - LogPortIndex) *
5413 return (SK_PNMI_ERR_TOO_SHORT);
5418 if (*pLen < sizeof(SK_U32)) {
5420 *pLen = sizeof(SK_U32);
5421 return (SK_PNMI_ERR_TOO_SHORT);
5426 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR041,
5429 return (SK_PNMI_ERR_GENERAL);
5433 * Update statistic and increment semaphore to indicate
5434 * that an update was already done.
5436 if ((Ret = SirqUpdate(pAC, IoC)) != SK_PNMI_ERR_OK) {
5441 pAC->Pnmi.SirqUpdatedFlag ++;
5447 for (; LogPortIndex < Limit; LogPortIndex ++) {
5452 *(pBuf + Offset) = pAC->Pnmi.PMD;
5453 Offset += sizeof(char);
5456 case OID_SKGE_CONNECTOR:
5457 *(pBuf + Offset) = pAC->Pnmi.Connector;
5458 Offset += sizeof(char);
5461 case OID_SKGE_LINK_CAP:
5462 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5463 if (LogPortIndex == 0) {
5465 /* Get value for virtual port */
5466 VirtualConf(pAC, IoC, Id, pBuf +
5470 /* Get value for physical ports */
5471 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5474 *(pBuf + Offset) = pAC->GIni.GP[
5475 PhysPortIndex].PLinkCap;
5477 Offset += sizeof(char);
5479 else { /* DualNetMode */
5481 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkCap;
5482 Offset += sizeof(char);
5486 case OID_SKGE_LINK_MODE:
5487 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5488 if (LogPortIndex == 0) {
5490 /* Get value for virtual port */
5491 VirtualConf(pAC, IoC, Id, pBuf +
5495 /* Get value for physical ports */
5496 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5499 *(pBuf + Offset) = pAC->GIni.GP[
5500 PhysPortIndex].PLinkModeConf;
5502 Offset += sizeof(char);
5504 else { /* DualNetMode */
5506 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkModeConf;
5507 Offset += sizeof(char);
5511 case OID_SKGE_LINK_MODE_STATUS:
5512 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5513 if (LogPortIndex == 0) {
5515 /* Get value for virtual port */
5516 VirtualConf(pAC, IoC, Id, pBuf +
5520 /* Get value for physical port */
5521 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5525 CalculateLinkModeStatus(pAC,
5526 IoC, PhysPortIndex);
5528 Offset += sizeof(char);
5530 else { /* DualNetMode */
5531 *(pBuf + Offset) = CalculateLinkModeStatus(pAC, IoC, NetIndex);
5532 Offset += sizeof(char);
5536 case OID_SKGE_LINK_STATUS:
5537 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5538 if (LogPortIndex == 0) {
5540 /* Get value for virtual port */
5541 VirtualConf(pAC, IoC, Id, pBuf +
5545 /* Get value for physical ports */
5546 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5550 CalculateLinkStatus(pAC,
5551 IoC, PhysPortIndex);
5553 Offset += sizeof(char);
5555 else { /* DualNetMode */
5557 *(pBuf + Offset) = CalculateLinkStatus(pAC, IoC, NetIndex);
5558 Offset += sizeof(char);
5562 case OID_SKGE_FLOWCTRL_CAP:
5563 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5564 if (LogPortIndex == 0) {
5566 /* Get value for virtual port */
5567 VirtualConf(pAC, IoC, Id, pBuf +
5571 /* Get value for physical ports */
5572 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5575 *(pBuf + Offset) = pAC->GIni.GP[
5576 PhysPortIndex].PFlowCtrlCap;
5578 Offset += sizeof(char);
5580 else { /* DualNetMode */
5582 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlCap;
5583 Offset += sizeof(char);
5587 case OID_SKGE_FLOWCTRL_MODE:
5588 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5589 if (LogPortIndex == 0) {
5591 /* Get value for virtual port */
5592 VirtualConf(pAC, IoC, Id, pBuf +
5596 /* Get value for physical port */
5597 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5600 *(pBuf + Offset) = pAC->GIni.GP[
5601 PhysPortIndex].PFlowCtrlMode;
5603 Offset += sizeof(char);
5605 else { /* DualNetMode */
5607 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlMode;
5608 Offset += sizeof(char);
5612 case OID_SKGE_FLOWCTRL_STATUS:
5613 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5614 if (LogPortIndex == 0) {
5616 /* Get value for virtual port */
5617 VirtualConf(pAC, IoC, Id, pBuf +
5621 /* Get value for physical port */
5622 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5625 *(pBuf + Offset) = pAC->GIni.GP[
5626 PhysPortIndex].PFlowCtrlStatus;
5628 Offset += sizeof(char);
5630 else { /* DualNetMode */
5632 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PFlowCtrlStatus;
5633 Offset += sizeof(char);
5637 case OID_SKGE_PHY_OPERATION_CAP:
5638 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5639 if (LogPortIndex == 0) {
5641 /* Get value for virtual port */
5642 VirtualConf(pAC, IoC, Id, pBuf +
5646 /* Get value for physical ports */
5647 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5650 *(pBuf + Offset) = pAC->GIni.GP[
5651 PhysPortIndex].PMSCap;
5653 Offset += sizeof(char);
5655 else { /* DualNetMode */
5657 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSCap;
5658 Offset += sizeof(char);
5662 case OID_SKGE_PHY_OPERATION_MODE:
5663 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5664 if (LogPortIndex == 0) {
5666 /* Get value for virtual port */
5667 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5670 /* Get value for physical port */
5671 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5674 *(pBuf + Offset) = pAC->GIni.GP[
5675 PhysPortIndex].PMSMode;
5677 Offset += sizeof(char);
5679 else { /* DualNetMode */
5681 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSMode;
5682 Offset += sizeof(char);
5686 case OID_SKGE_PHY_OPERATION_STATUS:
5687 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5688 if (LogPortIndex == 0) {
5690 /* Get value for virtual port */
5691 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5694 /* Get value for physical port */
5695 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5698 *(pBuf + Offset) = pAC->GIni.GP[
5699 PhysPortIndex].PMSStatus;
5701 Offset += sizeof(char);
5705 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PMSStatus;
5706 Offset += sizeof(char);
5710 case OID_SKGE_SPEED_CAP:
5711 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5712 if (LogPortIndex == 0) {
5714 /* Get value for virtual port */
5715 VirtualConf(pAC, IoC, Id, pBuf +
5719 /* Get value for physical ports */
5720 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5723 *(pBuf + Offset) = pAC->GIni.GP[
5724 PhysPortIndex].PLinkSpeedCap;
5726 Offset += sizeof(char);
5728 else { /* DualNetMode */
5730 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedCap;
5731 Offset += sizeof(char);
5735 case OID_SKGE_SPEED_MODE:
5736 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5737 if (LogPortIndex == 0) {
5739 /* Get value for virtual port */
5740 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5743 /* Get value for physical port */
5744 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5747 *(pBuf + Offset) = pAC->GIni.GP[
5748 PhysPortIndex].PLinkSpeed;
5750 Offset += sizeof(char);
5752 else { /* DualNetMode */
5754 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeed;
5755 Offset += sizeof(char);
5759 case OID_SKGE_SPEED_STATUS:
5760 if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */
5761 if (LogPortIndex == 0) {
5763 /* Get value for virtual port */
5764 VirtualConf(pAC, IoC, Id, pBuf + Offset);
5767 /* Get value for physical port */
5768 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(
5771 *(pBuf + Offset) = pAC->GIni.GP[
5772 PhysPortIndex].PLinkSpeedUsed;
5774 Offset += sizeof(char);
5776 else { /* DualNetMode */
5778 *(pBuf + Offset) = pAC->GIni.GP[NetIndex].PLinkSpeedUsed;
5779 Offset += sizeof(char);
5784 Val32 = SK_DRIVER_GET_MTU(pAC, IoC, NetIndex);
5785 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
5786 Offset += sizeof(SK_U32);
5790 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
5791 ("MacPrivateConf: Unknown OID should be handled before"));
5793 pAC->Pnmi.SirqUpdatedFlag --;
5794 return (SK_PNMI_ERR_GENERAL);
5798 pAC->Pnmi.SirqUpdatedFlag --;
5800 return (SK_PNMI_ERR_OK);
5804 * From here SET or PRESET action. Check if the passed
5805 * buffer length is plausible.
5809 case OID_SKGE_LINK_MODE:
5810 case OID_SKGE_FLOWCTRL_MODE:
5811 case OID_SKGE_PHY_OPERATION_MODE:
5812 case OID_SKGE_SPEED_MODE:
5813 if (*pLen < Limit - LogPortIndex) {
5815 *pLen = Limit - LogPortIndex;
5816 return (SK_PNMI_ERR_TOO_SHORT);
5818 if (*pLen != Limit - LogPortIndex) {
5821 return (SK_PNMI_ERR_BAD_VALUE);
5826 if (*pLen < sizeof(SK_U32)) {
5828 *pLen = sizeof(SK_U32);
5829 return (SK_PNMI_ERR_TOO_SHORT);
5831 if (*pLen != sizeof(SK_U32)) {
5834 return (SK_PNMI_ERR_BAD_VALUE);
5840 return (SK_PNMI_ERR_READ_ONLY);
5844 * Perform preset or set
5847 for (; LogPortIndex < Limit; LogPortIndex ++) {
5851 case OID_SKGE_LINK_MODE:
5852 /* Check the value range */
5853 Val8 = *(pBuf + Offset);
5856 Offset += sizeof(char);
5859 if (Val8 < SK_LMODE_HALF ||
5860 (LogPortIndex != 0 && Val8 > SK_LMODE_AUTOSENSE) ||
5861 (LogPortIndex == 0 && Val8 > SK_LMODE_INDETERMINATED)) {
5864 return (SK_PNMI_ERR_BAD_VALUE);
5867 /* The preset ends here */
5868 if (Action == SK_PNMI_PRESET) {
5870 return (SK_PNMI_ERR_OK);
5873 if (LogPortIndex == 0) {
5876 * The virtual port consists of all currently
5877 * active ports. Find them and send an event
5878 * with the new link mode to SIRQ.
5880 for (PhysPortIndex = 0;
5881 PhysPortIndex < PhysPortMax;
5884 if (!pAC->Pnmi.Port[PhysPortIndex].
5890 EventParam.Para32[0] = PhysPortIndex;
5891 EventParam.Para32[1] = (SK_U32)Val8;
5892 if (SkGeSirqEvent(pAC, IoC,
5896 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5901 return (SK_PNMI_ERR_GENERAL);
5907 * Send an event with the new link mode to
5910 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5912 EventParam.Para32[1] = (SK_U32)Val8;
5913 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_SET_LMODE,
5916 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5921 return (SK_PNMI_ERR_GENERAL);
5924 Offset += sizeof(char);
5927 case OID_SKGE_FLOWCTRL_MODE:
5928 /* Check the value range */
5929 Val8 = *(pBuf + Offset);
5932 Offset += sizeof(char);
5935 if (Val8 < SK_FLOW_MODE_NONE ||
5936 (LogPortIndex != 0 && Val8 > SK_FLOW_MODE_SYM_OR_REM) ||
5937 (LogPortIndex == 0 && Val8 > SK_FLOW_MODE_INDETERMINATED)) {
5940 return (SK_PNMI_ERR_BAD_VALUE);
5943 /* The preset ends here */
5944 if (Action == SK_PNMI_PRESET) {
5946 return (SK_PNMI_ERR_OK);
5949 if (LogPortIndex == 0) {
5952 * The virtual port consists of all currently
5953 * active ports. Find them and send an event
5954 * with the new flow control mode to SIRQ.
5956 for (PhysPortIndex = 0;
5957 PhysPortIndex < PhysPortMax;
5960 if (!pAC->Pnmi.Port[PhysPortIndex].
5966 EventParam.Para32[0] = PhysPortIndex;
5967 EventParam.Para32[1] = (SK_U32)Val8;
5968 if (SkGeSirqEvent(pAC, IoC,
5969 SK_HWEV_SET_FLOWMODE,
5972 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5977 return (SK_PNMI_ERR_GENERAL);
5983 * Send an event with the new flow control
5984 * mode to the SIRQ module.
5986 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
5988 EventParam.Para32[1] = (SK_U32)Val8;
5989 if (SkGeSirqEvent(pAC, IoC,
5990 SK_HWEV_SET_FLOWMODE, EventParam)
5993 SK_ERR_LOG(pAC, SK_ERRCL_SW,
5998 return (SK_PNMI_ERR_GENERAL);
6001 Offset += sizeof(char);
6004 case OID_SKGE_PHY_OPERATION_MODE :
6005 /* Check the value range */
6006 Val8 = *(pBuf + Offset);
6008 /* mode of this port remains unchanged */
6009 Offset += sizeof(char);
6012 if (Val8 < SK_MS_MODE_AUTO ||
6013 (LogPortIndex != 0 && Val8 > SK_MS_MODE_SLAVE) ||
6014 (LogPortIndex == 0 && Val8 > SK_MS_MODE_INDETERMINATED)) {
6017 return (SK_PNMI_ERR_BAD_VALUE);
6020 /* The preset ends here */
6021 if (Action == SK_PNMI_PRESET) {
6023 return (SK_PNMI_ERR_OK);
6026 if (LogPortIndex == 0) {
6029 * The virtual port consists of all currently
6030 * active ports. Find them and send an event
6031 * with new master/slave (role) mode to SIRQ.
6033 for (PhysPortIndex = 0;
6034 PhysPortIndex < PhysPortMax;
6037 if (!pAC->Pnmi.Port[PhysPortIndex].
6043 EventParam.Para32[0] = PhysPortIndex;
6044 EventParam.Para32[1] = (SK_U32)Val8;
6045 if (SkGeSirqEvent(pAC, IoC,
6049 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6054 return (SK_PNMI_ERR_GENERAL);
6060 * Send an event with the new master/slave
6061 * (role) mode to the SIRQ module.
6063 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6065 EventParam.Para32[1] = (SK_U32)Val8;
6066 if (SkGeSirqEvent(pAC, IoC,
6067 SK_HWEV_SET_ROLE, EventParam) > 0) {
6069 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6074 return (SK_PNMI_ERR_GENERAL);
6078 Offset += sizeof(char);
6081 case OID_SKGE_SPEED_MODE:
6082 /* Check the value range */
6083 Val8 = *(pBuf + Offset);
6086 Offset += sizeof(char);
6089 if (Val8 < (SK_LSPEED_AUTO) ||
6090 (LogPortIndex != 0 && Val8 > (SK_LSPEED_1000MBPS)) ||
6091 (LogPortIndex == 0 && Val8 > (SK_LSPEED_INDETERMINATED))) {
6094 return (SK_PNMI_ERR_BAD_VALUE);
6097 /* The preset ends here */
6098 if (Action == SK_PNMI_PRESET) {
6100 return (SK_PNMI_ERR_OK);
6103 if (LogPortIndex == 0) {
6106 * The virtual port consists of all currently
6107 * active ports. Find them and send an event
6108 * with the new flow control mode to SIRQ.
6110 for (PhysPortIndex = 0;
6111 PhysPortIndex < PhysPortMax;
6114 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6119 EventParam.Para32[0] = PhysPortIndex;
6120 EventParam.Para32[1] = (SK_U32)Val8;
6121 if (SkGeSirqEvent(pAC, IoC,
6125 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6130 return (SK_PNMI_ERR_GENERAL);
6136 * Send an event with the new flow control
6137 * mode to the SIRQ module.
6139 EventParam.Para32[0] = SK_PNMI_PORT_LOG2PHYS(
6141 EventParam.Para32[1] = (SK_U32)Val8;
6142 if (SkGeSirqEvent(pAC, IoC,
6146 SK_ERR_LOG(pAC, SK_ERRCL_SW,
6151 return (SK_PNMI_ERR_GENERAL);
6154 Offset += sizeof(char);
6158 /* Check the value range */
6159 Val32 = *(SK_U32*)(pBuf + Offset);
6161 /* mtu of this port remains unchanged */
6162 Offset += sizeof(SK_U32);
6165 if (SK_DRIVER_PRESET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6167 return (SK_PNMI_ERR_BAD_VALUE);
6170 /* The preset ends here */
6171 if (Action == SK_PNMI_PRESET) {
6172 return (SK_PNMI_ERR_OK);
6175 if (SK_DRIVER_SET_MTU(pAC, IoC, NetIndex, Val32) != 0) {
6176 return (SK_PNMI_ERR_GENERAL);
6179 Offset += sizeof(SK_U32);
6183 SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR,
6184 ("MacPrivateConf: Unknown OID should be handled before set"));
6187 return (SK_PNMI_ERR_GENERAL);
6191 return (SK_PNMI_ERR_OK);
6194 /*****************************************************************************
6196 * Monitor - OID handler function for RLMT_MONITOR_XXX
6199 * Because RLMT currently does not support the monitoring of
6200 * remote adapter cards, we return always an empty table.
6203 * SK_PNMI_ERR_OK The request was successfully performed.
6204 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
6205 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
6206 * the correct data (e.g. a 32bit value is
6207 * needed, but a 16 bit value was passed).
6208 * SK_PNMI_ERR_BAD_VALUE The passed value is not in the valid
6210 * SK_PNMI_ERR_READ_ONLY The OID is read-only and cannot be set.
6211 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
6212 * exist (e.g. port instance 3 on a two port
6215 PNMI_STATIC int Monitor(
6216 SK_AC *pAC, /* Pointer to adapter context */
6217 SK_IOC IoC, /* IO context handle */
6218 int Action, /* Get/PreSet/Set action */
6219 SK_U32 Id, /* Object ID that is to be processed */
6220 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
6221 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
6222 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
6223 unsigned int TableIndex, /* Index to the Id table */
6224 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6228 unsigned int Offset;
6229 unsigned int Entries;
6233 * Calculate instance if wished.
6235 /* XXX Not yet implemented. Return always an empty table. */
6238 if ((Instance != (SK_U32)(-1))) {
6240 if ((Instance < 1) || (Instance > Entries)) {
6243 return (SK_PNMI_ERR_UNKNOWN_INST);
6246 Index = (unsigned int)Instance - 1;
6247 Limit = (unsigned int)Instance;
6257 if (Action == SK_PNMI_GET) {
6259 for (Offset=0; Index < Limit; Index ++) {
6263 case OID_SKGE_RLMT_MONITOR_INDEX:
6264 case OID_SKGE_RLMT_MONITOR_ADDR:
6265 case OID_SKGE_RLMT_MONITOR_ERRS:
6266 case OID_SKGE_RLMT_MONITOR_TIMESTAMP:
6267 case OID_SKGE_RLMT_MONITOR_ADMIN:
6271 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR046,
6275 return (SK_PNMI_ERR_GENERAL);
6281 /* Only MONITOR_ADMIN can be set */
6282 if (Id != OID_SKGE_RLMT_MONITOR_ADMIN) {
6285 return (SK_PNMI_ERR_READ_ONLY);
6288 /* Check if the length is plausible */
6289 if (*pLen < (Limit - Index)) {
6291 return (SK_PNMI_ERR_TOO_SHORT);
6293 /* Okay, we have a wide value range */
6294 if (*pLen != (Limit - Index)) {
6297 return (SK_PNMI_ERR_BAD_VALUE);
6300 for (Offset=0; Index < Limit; Index ++) {
6304 * XXX Not yet implemented. Return always BAD_VALUE, because the table
6308 return (SK_PNMI_ERR_BAD_VALUE);
6311 return (SK_PNMI_ERR_OK);
6314 /*****************************************************************************
6316 * VirtualConf - Calculates the values of configuration OIDs for virtual port
6319 * We handle here the get of the configuration group OIDs, which are
6320 * a little bit complicated. The virtual port consists of all currently
6321 * active physical ports. If multiple ports are active and configured
6322 * differently we get in some trouble to return a single value. So we
6323 * get the value of the first active port and compare it with that of
6324 * the other active ports. If they are not the same, we return a value
6325 * that indicates that the state is indeterminated.
6330 PNMI_STATIC void VirtualConf(
6331 SK_AC *pAC, /* Pointer to adapter context */
6332 SK_IOC IoC, /* IO context handle */
6333 SK_U32 Id, /* Object ID that is to be processed */
6334 char *pBuf) /* Buffer to which to mgmt data will be retrieved */
6336 unsigned int PhysPortMax;
6337 unsigned int PhysPortIndex;
6339 SK_BOOL PortActiveFlag;
6343 PortActiveFlag = SK_FALSE;
6344 PhysPortMax = pAC->GIni.GIMacsFound;
6346 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
6349 /* Check if the physical port is active */
6350 if (!pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
6355 PortActiveFlag = SK_TRUE;
6359 case OID_SKGE_LINK_CAP:
6362 * Different capabilities should not happen, but
6363 * in the case of the cases OR them all together.
6364 * From a curious point of view the virtual port
6365 * is capable of all found capabilities.
6367 *pBuf |= pAC->GIni.GP[PhysPortIndex].PLinkCap;
6370 case OID_SKGE_LINK_MODE:
6371 /* Check if it is the first active port */
6374 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkModeConf;
6379 * If we find an active port with a different link
6380 * mode than the first one we return a value that
6381 * indicates that the link mode is indeterminated.
6383 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkModeConf
6386 *pBuf = SK_LMODE_INDETERMINATED;
6390 case OID_SKGE_LINK_MODE_STATUS:
6391 /* Get the link mode of the physical port */
6392 Val8 = CalculateLinkModeStatus(pAC, IoC, PhysPortIndex);
6394 /* Check if it is the first active port */
6402 * If we find an active port with a different link
6403 * mode status than the first one we return a value
6404 * that indicates that the link mode status is
6407 if (*pBuf != Val8) {
6409 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6413 case OID_SKGE_LINK_STATUS:
6414 /* Get the link status of the physical port */
6415 Val8 = CalculateLinkStatus(pAC, IoC, PhysPortIndex);
6417 /* Check if it is the first active port */
6425 * If we find an active port with a different link
6426 * status than the first one, we return a value
6427 * that indicates that the link status is
6430 if (*pBuf != Val8) {
6432 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6436 case OID_SKGE_FLOWCTRL_CAP:
6437 /* Check if it is the first active port */
6440 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6445 * From a curious point of view the virtual port
6446 * is capable of all found capabilities.
6448 *pBuf |= pAC->GIni.GP[PhysPortIndex].PFlowCtrlCap;
6451 case OID_SKGE_FLOWCTRL_MODE:
6452 /* Check if it is the first active port */
6455 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode;
6460 * If we find an active port with a different flow
6461 * control mode than the first one, we return a value
6462 * that indicates that the mode is indeterminated.
6464 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlMode) {
6466 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6470 case OID_SKGE_FLOWCTRL_STATUS:
6471 /* Check if it is the first active port */
6474 *pBuf = pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus;
6479 * If we find an active port with a different flow
6480 * control status than the first one, we return a
6481 * value that indicates that the status is
6484 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PFlowCtrlStatus) {
6486 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6490 case OID_SKGE_PHY_OPERATION_CAP:
6491 /* Check if it is the first active port */
6494 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSCap;
6499 * From a curious point of view the virtual port
6500 * is capable of all found capabilities.
6502 *pBuf |= pAC->GIni.GP[PhysPortIndex].PMSCap;
6505 case OID_SKGE_PHY_OPERATION_MODE:
6506 /* Check if it is the first active port */
6509 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSMode;
6514 * If we find an active port with a different master/
6515 * slave mode than the first one, we return a value
6516 * that indicates that the mode is indeterminated.
6518 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSMode) {
6520 *pBuf = SK_MS_MODE_INDETERMINATED;
6524 case OID_SKGE_PHY_OPERATION_STATUS:
6525 /* Check if it is the first active port */
6528 *pBuf = pAC->GIni.GP[PhysPortIndex].PMSStatus;
6533 * If we find an active port with a different master/
6534 * slave status than the first one, we return a
6535 * value that indicates that the status is
6538 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PMSStatus) {
6540 *pBuf = SK_MS_STAT_INDETERMINATED;
6544 case OID_SKGE_SPEED_MODE:
6545 /* Check if it is the first active port */
6548 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeed;
6553 * If we find an active port with a different flow
6554 * control mode than the first one, we return a value
6555 * that indicates that the mode is indeterminated.
6557 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeed) {
6559 *pBuf = SK_LSPEED_INDETERMINATED;
6563 case OID_SKGE_SPEED_STATUS:
6564 /* Check if it is the first active port */
6567 *pBuf = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
6572 * If we find an active port with a different flow
6573 * control status than the first one, we return a
6574 * value that indicates that the status is
6577 if (*pBuf != pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed) {
6579 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6586 * If no port is active return an indeterminated answer
6588 if (!PortActiveFlag) {
6592 case OID_SKGE_LINK_CAP:
6593 *pBuf = SK_LMODE_CAP_INDETERMINATED;
6596 case OID_SKGE_LINK_MODE:
6597 *pBuf = SK_LMODE_INDETERMINATED;
6600 case OID_SKGE_LINK_MODE_STATUS:
6601 *pBuf = SK_LMODE_STAT_INDETERMINATED;
6604 case OID_SKGE_LINK_STATUS:
6605 *pBuf = SK_PNMI_RLMT_LSTAT_INDETERMINATED;
6608 case OID_SKGE_FLOWCTRL_CAP:
6609 case OID_SKGE_FLOWCTRL_MODE:
6610 *pBuf = SK_FLOW_MODE_INDETERMINATED;
6613 case OID_SKGE_FLOWCTRL_STATUS:
6614 *pBuf = SK_FLOW_STAT_INDETERMINATED;
6617 case OID_SKGE_PHY_OPERATION_CAP:
6618 *pBuf = SK_MS_CAP_INDETERMINATED;
6621 case OID_SKGE_PHY_OPERATION_MODE:
6622 *pBuf = SK_MS_MODE_INDETERMINATED;
6625 case OID_SKGE_PHY_OPERATION_STATUS:
6626 *pBuf = SK_MS_STAT_INDETERMINATED;
6628 case OID_SKGE_SPEED_CAP:
6629 *pBuf = SK_LSPEED_CAP_INDETERMINATED;
6632 case OID_SKGE_SPEED_MODE:
6633 *pBuf = SK_LSPEED_INDETERMINATED;
6636 case OID_SKGE_SPEED_STATUS:
6637 *pBuf = SK_LSPEED_STAT_INDETERMINATED;
6643 /*****************************************************************************
6645 * CalculateLinkStatus - Determins the link status of a physical port
6648 * Determins the link status the following way:
6649 * LSTAT_PHY_DOWN: Link is down
6650 * LSTAT_AUTONEG: Auto-negotiation failed
6651 * LSTAT_LOG_DOWN: Link is up but RLMT did not yet put the port
6653 * LSTAT_LOG_UP: RLMT marked the port as up
6656 * Link status of physical port
6658 PNMI_STATIC SK_U8 CalculateLinkStatus(
6659 SK_AC *pAC, /* Pointer to adapter context */
6660 SK_IOC IoC, /* IO context handle */
6661 unsigned int PhysPortIndex) /* Physical port index */
6666 if (!pAC->GIni.GP[PhysPortIndex].PHWLinkUp) {
6668 Result = SK_PNMI_RLMT_LSTAT_PHY_DOWN;
6670 else if (pAC->GIni.GP[PhysPortIndex].PAutoNegFail > 0) {
6672 Result = SK_PNMI_RLMT_LSTAT_AUTONEG;
6674 else if (!pAC->Rlmt.Port[PhysPortIndex].PortDown) {
6676 Result = SK_PNMI_RLMT_LSTAT_LOG_UP;
6679 Result = SK_PNMI_RLMT_LSTAT_LOG_DOWN;
6685 /*****************************************************************************
6687 * CalculateLinkModeStatus - Determins the link mode status of a phys. port
6690 * The COMMON module only tells us if the mode is half or full duplex.
6691 * But in the decade of auto sensing it is usefull for the user to
6692 * know if the mode was negotiated or forced. Therefore we have a
6693 * look to the mode, which was last used by the negotiation process.
6696 * The link mode status
6698 PNMI_STATIC SK_U8 CalculateLinkModeStatus(
6699 SK_AC *pAC, /* Pointer to adapter context */
6700 SK_IOC IoC, /* IO context handle */
6701 unsigned int PhysPortIndex) /* Physical port index */
6706 /* Get the current mode, which can be full or half duplex */
6707 Result = pAC->GIni.GP[PhysPortIndex].PLinkModeStatus;
6709 /* Check if no valid mode could be found (link is down) */
6710 if (Result < SK_LMODE_STAT_HALF) {
6712 Result = SK_LMODE_STAT_UNKNOWN;
6714 else if (pAC->GIni.GP[PhysPortIndex].PLinkMode >= SK_LMODE_AUTOHALF) {
6717 * Auto-negotiation was used to bring up the link. Change
6718 * the already found duplex status that it indicates
6719 * auto-negotiation was involved.
6721 if (Result == SK_LMODE_STAT_HALF) {
6723 Result = SK_LMODE_STAT_AUTOHALF;
6725 else if (Result == SK_LMODE_STAT_FULL) {
6727 Result = SK_LMODE_STAT_AUTOFULL;
6734 /*****************************************************************************
6736 * GetVpdKeyArr - Obtain an array of VPD keys
6739 * Read the VPD keys and build an array of VPD keys, which are
6743 * SK_PNMI_ERR_OK Task successfully performed.
6744 * SK_PNMI_ERR_GENERAL Something went wrong.
6746 PNMI_STATIC int GetVpdKeyArr(
6747 SK_AC *pAC, /* Pointer to adapter context */
6748 SK_IOC IoC, /* IO context handle */
6749 char *pKeyArr, /* Ptr KeyArray */
6750 unsigned int KeyArrLen, /* Length of array in bytes */
6751 unsigned int *pKeyNo) /* Number of keys */
6753 unsigned int BufKeysLen = SK_PNMI_VPD_BUFSIZE;
6754 char BufKeys[SK_PNMI_VPD_BUFSIZE];
6755 unsigned int StartOffset;
6756 unsigned int Offset;
6761 SK_MEMSET(pKeyArr, 0, KeyArrLen);
6766 Ret = VpdKeys(pAC, IoC, (char *)&BufKeys, (int *)&BufKeysLen,
6770 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR014,
6773 return (SK_PNMI_ERR_GENERAL);
6775 /* If no keys are available return now */
6776 if (*pKeyNo == 0 || BufKeysLen == 0) {
6778 return (SK_PNMI_ERR_OK);
6781 * If the key list is too long for us trunc it and give a
6782 * errorlog notification. This case should not happen because
6783 * the maximum number of keys is limited due to RAM limitations
6785 if (*pKeyNo > SK_PNMI_VPD_ENTRIES) {
6787 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR015,
6790 *pKeyNo = SK_PNMI_VPD_ENTRIES;
6794 * Now build an array of fixed string length size and copy
6795 * the keys together.
6797 for (Index = 0, StartOffset = 0, Offset = 0; Offset < BufKeysLen;
6800 if (BufKeys[Offset] != 0) {
6805 if (Offset - StartOffset > SK_PNMI_VPD_KEY_SIZE) {
6807 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR016,
6809 return (SK_PNMI_ERR_GENERAL);
6812 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6813 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6816 StartOffset = Offset + 1;
6819 /* Last key not zero terminated? Get it anyway */
6820 if (StartOffset < Offset) {
6822 SK_STRNCPY(pKeyArr + Index * SK_PNMI_VPD_KEY_SIZE,
6823 &BufKeys[StartOffset], SK_PNMI_VPD_KEY_SIZE);
6826 return (SK_PNMI_ERR_OK);
6829 /*****************************************************************************
6831 * SirqUpdate - Let the SIRQ update its internal values
6834 * Just to be sure that the SIRQ module holds its internal data
6835 * structures up to date, we send an update event before we make
6839 * SK_PNMI_ERR_OK Task successfully performed.
6840 * SK_PNMI_ERR_GENERAL Something went wrong.
6842 PNMI_STATIC int SirqUpdate(
6843 SK_AC *pAC, /* Pointer to adapter context */
6844 SK_IOC IoC) /* IO context handle */
6846 SK_EVPARA EventParam;
6849 /* Was the module already updated during the current PNMI call? */
6850 if (pAC->Pnmi.SirqUpdatedFlag > 0) {
6852 return (SK_PNMI_ERR_OK);
6855 /* Send an synchronuous update event to the module */
6856 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6857 if (SkGeSirqEvent(pAC, IoC, SK_HWEV_UPDATE_STAT, EventParam) > 0) {
6859 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR047,
6862 return (SK_PNMI_ERR_GENERAL);
6865 return (SK_PNMI_ERR_OK);
6868 /*****************************************************************************
6870 * RlmtUpdate - Let the RLMT update its internal values
6873 * Just to be sure that the RLMT module holds its internal data
6874 * structures up to date, we send an update event before we make
6878 * SK_PNMI_ERR_OK Task successfully performed.
6879 * SK_PNMI_ERR_GENERAL Something went wrong.
6881 PNMI_STATIC int RlmtUpdate(
6882 SK_AC *pAC, /* Pointer to adapter context */
6883 SK_IOC IoC, /* IO context handle */
6884 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6886 SK_EVPARA EventParam;
6889 /* Was the module already updated during the current PNMI call? */
6890 if (pAC->Pnmi.RlmtUpdatedFlag > 0) {
6892 return (SK_PNMI_ERR_OK);
6895 /* Send an synchronuous update event to the module */
6896 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
6897 EventParam.Para32[0] = NetIndex;
6898 EventParam.Para32[1] = (SK_U32)-1;
6899 if (SkRlmtEvent(pAC, IoC, SK_RLMT_STATS_UPDATE, EventParam) > 0) {
6901 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR048,
6904 return (SK_PNMI_ERR_GENERAL);
6907 return (SK_PNMI_ERR_OK);
6910 /*****************************************************************************
6912 * MacUpdate - Force the XMAC to output the current statistic
6915 * The XMAC holds its statistic internally. To obtain the current
6916 * values we send a command so that the statistic data will
6917 * be written to apredefined memory area on the adapter.
6920 * SK_PNMI_ERR_OK Task successfully performed.
6921 * SK_PNMI_ERR_GENERAL Something went wrong.
6923 PNMI_STATIC int MacUpdate(
6924 SK_AC *pAC, /* Pointer to adapter context */
6925 SK_IOC IoC, /* IO context handle */
6926 unsigned int FirstMac, /* Index of the first Mac to be updated */
6927 unsigned int LastMac) /* Index of the last Mac to be updated */
6929 unsigned int MacIndex;
6932 * Were the statistics already updated during the
6933 * current PNMI call?
6935 if (pAC->Pnmi.MacUpdatedFlag > 0) {
6937 return (SK_PNMI_ERR_OK);
6940 /* Send an update command to all MACs specified */
6941 for (MacIndex = FirstMac; MacIndex <= LastMac; MacIndex ++) {
6944 * 2002-09-13 pweber: Freeze the current sw counters.
6945 * (That should be done as close as
6946 * possible to the update of the
6949 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
6950 pAC->Pnmi.BufPort[MacIndex] = pAC->Pnmi.Port[MacIndex];
6953 /* 2002-09-13 pweber: Update the hw counter */
6954 if (pAC->GIni.GIFunc.pFnMacUpdateStats(pAC, IoC, MacIndex) != 0) {
6956 return (SK_PNMI_ERR_GENERAL);
6960 return (SK_PNMI_ERR_OK);
6963 /*****************************************************************************
6965 * GetStatVal - Retrieve an XMAC statistic counter
6968 * Retrieves the statistic counter of a virtual or physical port. The
6969 * virtual port is identified by the index 0. It consists of all
6970 * currently active ports. To obtain the counter value for this port
6971 * we must add the statistic counter of all active ports. To grant
6972 * continuous counter values for the virtual port even when port
6973 * switches occur we must additionally add a delta value, which was
6974 * calculated during a SK_PNMI_EVT_RLMT_ACTIVE_UP event.
6977 * Requested statistic value
6979 PNMI_STATIC SK_U64 GetStatVal(
6980 SK_AC *pAC, /* Pointer to adapter context */
6981 SK_IOC IoC, /* IO context handle */
6982 unsigned int LogPortIndex, /* Index of the logical Port to be processed */
6983 unsigned int StatIndex, /* Index to statistic value */
6984 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
6986 unsigned int PhysPortIndex;
6987 unsigned int PhysPortMax;
6991 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) { /* Dual net mode */
6993 PhysPortIndex = NetIndex;
6994 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
6996 else { /* Single Net mode */
6998 if (LogPortIndex == 0) {
7000 PhysPortMax = pAC->GIni.GIMacsFound;
7002 /* Add counter of all active ports */
7003 for (PhysPortIndex = 0; PhysPortIndex < PhysPortMax;
7006 if (pAC->Pnmi.Port[PhysPortIndex].ActiveFlag) {
7008 Val += GetPhysStatVal(pAC, IoC, PhysPortIndex,
7013 /* Correct value because of port switches */
7014 Val += pAC->Pnmi.VirtualCounterOffset[StatIndex];
7017 /* Get counter value of physical port */
7018 PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex);
7019 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, StatIndex);
7025 /*****************************************************************************
7027 * GetPhysStatVal - Get counter value for physical port
7030 * Builds a 64bit counter value. Except for the octet counters
7031 * the lower 32bit are counted in hardware and the upper 32bit
7032 * in software by monitoring counter overflow interrupts in the
7033 * event handler. To grant continous counter values during XMAC
7034 * resets (caused by a workaround) we must add a delta value.
7035 * The delta was calculated in the event handler when a
7036 * SK_PNMI_EVT_XMAC_RESET was received.
7041 PNMI_STATIC SK_U64 GetPhysStatVal(
7042 SK_AC *pAC, /* Pointer to adapter context */
7043 SK_IOC IoC, /* IO context handle */
7044 unsigned int PhysPortIndex, /* Index of the logical Port to be processed */
7045 unsigned int StatIndex) /* Index to statistic value */
7053 SK_PNMI_PORT *pPnmiPrt;
7054 SK_GEMACFUNC *pFnMac;
7056 MacType = pAC->GIni.GIMacType;
7058 /* 2002-09-17 pweber: For XMAC, use the frozen sw counters (BufPort) */
7059 if (pAC->GIni.GIMacType == SK_MAC_XMAC) {
7060 pPnmiPrt = &pAC->Pnmi.BufPort[PhysPortIndex];
7063 pPnmiPrt = &pAC->Pnmi.Port[PhysPortIndex];
7066 pFnMac = &pAC->GIni.GIFunc;
7068 switch (StatIndex) {
7071 /* Not supported by GMAC */
7072 if (MacType == SK_MAC_GMAC) {
7076 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7077 StatAddr[StatIndex][MacType].Reg,
7079 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7082 case SK_PNMI_HTX_OCTET:
7083 case SK_PNMI_HRX_OCTET:
7084 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7085 StatAddr[StatIndex][MacType].Reg,
7087 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7088 StatAddr[StatIndex + 1][MacType].Reg,
7092 case SK_PNMI_HTX_BURST:
7093 case SK_PNMI_HTX_EXCESS_DEF:
7094 case SK_PNMI_HTX_CARRIER:
7095 /* Not supported by GMAC */
7096 if (MacType == SK_MAC_GMAC) {
7100 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7101 StatAddr[StatIndex][MacType].Reg,
7103 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7106 case SK_PNMI_HTX_MACC:
7107 /* GMAC only supports PAUSE MAC control frames */
7108 if (MacType == SK_MAC_GMAC) {
7109 Val = GetPhysStatVal(pAC, IoC, PhysPortIndex, SK_PNMI_HTX_PMACC);
7114 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7115 StatAddr[StatIndex][MacType].Reg,
7117 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7120 case SK_PNMI_HTX_COL:
7121 case SK_PNMI_HRX_UNDERSIZE:
7122 /* Not supported by XMAC */
7123 if (MacType == SK_MAC_XMAC) {
7127 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7128 StatAddr[StatIndex][MacType].Reg,
7130 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7135 case SK_PNMI_HTX_DEFFERAL:
7136 /* Not supported by GMAC */
7137 if (MacType == SK_MAC_GMAC) {
7142 * XMAC counts frames with deferred transmission
7143 * even in full-duplex mode.
7145 * In full-duplex mode the counter remains constant!
7147 if ((pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_AUTOFULL) ||
7148 (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus == SK_LMODE_STAT_FULL)) {
7154 /* Otherwise get contents of hardware register. */
7155 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7156 StatAddr[SK_PNMI_HTX_DEFFERAL][MacType].Reg,
7158 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7162 case SK_PNMI_HRX_BADOCTET:
7163 /* Not supported by XMAC */
7164 if (MacType == SK_MAC_XMAC) {
7168 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7169 StatAddr[StatIndex][MacType].Reg,
7171 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7172 StatAddr[StatIndex + 1][MacType].Reg,
7176 case SK_PNMI_HTX_OCTETLOW:
7177 case SK_PNMI_HRX_OCTETLOW:
7178 case SK_PNMI_HRX_BADOCTETLOW:
7181 case SK_PNMI_HRX_LONGFRAMES:
7182 /* For XMAC the SW counter is managed by PNMI */
7183 if (MacType == SK_MAC_XMAC) {
7184 return (pPnmiPrt->StatRxLongFrameCts);
7187 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7188 StatAddr[StatIndex][MacType].Reg,
7190 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7193 case SK_PNMI_HRX_TOO_LONG:
7194 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7195 StatAddr[StatIndex][MacType].Reg,
7197 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7199 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7203 /* For GMAC the SW counter is additionally managed by PNMI */
7204 Val += pPnmiPrt->StatRxFrameTooLongCts;
7209 * Frames longer than IEEE 802.3 frame max size are counted
7210 * by XMAC in frame_too_long counter even reception of long
7211 * frames was enabled and the frame was correct.
7212 * So correct the value by subtracting RxLongFrame counter.
7214 Val -= pPnmiPrt->StatRxLongFrameCts;
7221 LowVal = (SK_U32)Val;
7222 HighVal = (SK_U32)(Val >> 32);
7225 case SK_PNMI_HRX_SHORTS:
7226 /* Not supported by GMAC */
7227 if (MacType == SK_MAC_GMAC) {
7233 * XMAC counts short frame errors even if link down (#10620)
7235 * If link-down the counter remains constant
7237 if (pAC->GIni.GP[PhysPortIndex].PLinkModeStatus != SK_LMODE_STAT_UNKNOWN) {
7239 /* Otherwise get incremental difference */
7240 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7241 StatAddr[StatIndex][MacType].Reg,
7243 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7245 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7246 Val -= pPnmiPrt->RxShortZeroMark;
7248 LowVal = (SK_U32)Val;
7249 HighVal = (SK_U32)(Val >> 32);
7253 case SK_PNMI_HRX_MACC:
7254 case SK_PNMI_HRX_MACC_UNKWN:
7255 case SK_PNMI_HRX_BURST:
7256 case SK_PNMI_HRX_MISSED:
7257 case SK_PNMI_HRX_FRAMING:
7258 case SK_PNMI_HRX_CARRIER:
7259 case SK_PNMI_HRX_IRLENGTH:
7260 case SK_PNMI_HRX_SYMBOL:
7261 case SK_PNMI_HRX_CEXT:
7262 /* Not supported by GMAC */
7263 if (MacType == SK_MAC_GMAC) {
7268 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7269 StatAddr[StatIndex][MacType].Reg,
7271 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7274 case SK_PNMI_HRX_PMACC_ERR:
7275 /* For GMAC the SW counter is managed by PNMI */
7276 if (MacType == SK_MAC_GMAC) {
7277 return (pPnmiPrt->StatRxPMaccErr);
7280 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7281 StatAddr[StatIndex][MacType].Reg,
7283 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7286 /* SW counter managed by PNMI */
7287 case SK_PNMI_HTX_SYNC:
7288 LowVal = (SK_U32)pPnmiPrt->StatSyncCts;
7289 HighVal = (SK_U32)(pPnmiPrt->StatSyncCts >> 32);
7292 /* SW counter managed by PNMI */
7293 case SK_PNMI_HTX_SYNC_OCTET:
7294 LowVal = (SK_U32)pPnmiPrt->StatSyncOctetsCts;
7295 HighVal = (SK_U32)(pPnmiPrt->StatSyncOctetsCts >> 32);
7298 case SK_PNMI_HRX_FCS:
7300 * Broadcom filters fcs errors and counts it in
7301 * Receive Error Counter register
7303 if (pAC->GIni.GP[PhysPortIndex].PhyType == SK_PHY_BCOM) {
7304 /* do not read while not initialized (PHY_READ hangs!)*/
7305 if (pAC->GIni.GP[PhysPortIndex].PState) {
7306 PHY_READ(IoC, &pAC->GIni.GP[PhysPortIndex],
7307 PhysPortIndex, PHY_BCOM_RE_CTR,
7312 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7315 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7316 StatAddr[StatIndex][MacType].Reg,
7318 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7323 (void)pFnMac->pFnMacStatistic(pAC, IoC, PhysPortIndex,
7324 StatAddr[StatIndex][MacType].Reg,
7326 HighVal = pPnmiPrt->CounterHigh[StatIndex];
7330 Val = (((SK_U64)HighVal << 32) | (SK_U64)LowVal);
7332 /* Correct value because of possible XMAC reset. XMAC Errata #2 */
7333 Val += pPnmiPrt->CounterOffset[StatIndex];
7338 /*****************************************************************************
7340 * ResetCounter - Set all counters and timestamps to zero
7343 * Notifies other common modules which store statistic data to
7344 * reset their counters and finally reset our own counters.
7349 PNMI_STATIC void ResetCounter(
7350 SK_AC *pAC, /* Pointer to adapter context */
7351 SK_IOC IoC, /* IO context handle */
7354 unsigned int PhysPortIndex;
7355 SK_EVPARA EventParam;
7358 SK_MEMSET((char *)&EventParam, 0, sizeof(EventParam));
7360 /* Notify sensor module */
7361 SkEventQueue(pAC, SKGE_I2C, SK_I2CEV_CLEAR, EventParam);
7363 /* Notify RLMT module */
7364 EventParam.Para32[0] = NetIndex;
7365 EventParam.Para32[1] = (SK_U32)-1;
7366 SkEventQueue(pAC, SKGE_RLMT, SK_RLMT_STATS_CLEAR, EventParam);
7367 EventParam.Para32[1] = 0;
7369 /* Notify SIRQ module */
7370 SkEventQueue(pAC, SKGE_HWAC, SK_HWEV_CLEAR_STAT, EventParam);
7372 /* Notify CSUM module */
7374 EventParam.Para32[0] = NetIndex;
7375 EventParam.Para32[1] = (SK_U32)-1;
7376 SkEventQueue(pAC, SKGE_CSUM, SK_CSUM_EVENT_CLEAR_PROTO_STATS,
7380 /* Clear XMAC statistic */
7381 for (PhysPortIndex = 0; PhysPortIndex <
7382 (unsigned int)pAC->GIni.GIMacsFound; PhysPortIndex ++) {
7384 (void)pAC->GIni.GIFunc.pFnMacResetCounter(pAC, IoC, PhysPortIndex);
7386 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].CounterHigh,
7387 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].CounterHigh));
7388 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7389 CounterOffset, 0, sizeof(pAC->Pnmi.Port[
7390 PhysPortIndex].CounterOffset));
7391 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].StatSyncCts,
7392 0, sizeof(pAC->Pnmi.Port[PhysPortIndex].StatSyncCts));
7393 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7394 StatSyncOctetsCts, 0, sizeof(pAC->Pnmi.Port[
7395 PhysPortIndex].StatSyncOctetsCts));
7396 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7397 StatRxLongFrameCts, 0, sizeof(pAC->Pnmi.Port[
7398 PhysPortIndex].StatRxLongFrameCts));
7399 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7400 StatRxFrameTooLongCts, 0, sizeof(pAC->Pnmi.Port[
7401 PhysPortIndex].StatRxFrameTooLongCts));
7402 SK_MEMSET((char *)&pAC->Pnmi.Port[PhysPortIndex].
7403 StatRxPMaccErr, 0, sizeof(pAC->Pnmi.Port[
7404 PhysPortIndex].StatRxPMaccErr));
7408 * Clear local statistics
7410 SK_MEMSET((char *)&pAC->Pnmi.VirtualCounterOffset, 0,
7411 sizeof(pAC->Pnmi.VirtualCounterOffset));
7412 pAC->Pnmi.RlmtChangeCts = 0;
7413 pAC->Pnmi.RlmtChangeTime = 0;
7414 SK_MEMSET((char *)&pAC->Pnmi.RlmtChangeEstimate.EstValue[0], 0,
7415 sizeof(pAC->Pnmi.RlmtChangeEstimate.EstValue));
7416 pAC->Pnmi.RlmtChangeEstimate.EstValueIndex = 0;
7417 pAC->Pnmi.RlmtChangeEstimate.Estimate = 0;
7418 pAC->Pnmi.Port[NetIndex].TxSwQueueMax = 0;
7419 pAC->Pnmi.Port[NetIndex].TxRetryCts = 0;
7420 pAC->Pnmi.Port[NetIndex].RxIntrCts = 0;
7421 pAC->Pnmi.Port[NetIndex].TxIntrCts = 0;
7422 pAC->Pnmi.Port[NetIndex].RxNoBufCts = 0;
7423 pAC->Pnmi.Port[NetIndex].TxNoBufCts = 0;
7424 pAC->Pnmi.Port[NetIndex].TxUsedDescrNo = 0;
7425 pAC->Pnmi.Port[NetIndex].RxDeliveredCts = 0;
7426 pAC->Pnmi.Port[NetIndex].RxOctetsDeliveredCts = 0;
7427 pAC->Pnmi.Port[NetIndex].ErrRecoveryCts = 0;
7430 /*****************************************************************************
7432 * GetTrapEntry - Get an entry in the trap buffer
7435 * The trap buffer stores various events. A user application somehow
7436 * gets notified that an event occured and retrieves the trap buffer
7437 * contens (or simply polls the buffer). The buffer is organized as
7438 * a ring which stores the newest traps at the beginning. The oldest
7439 * traps are overwritten by the newest ones. Each trap entry has a
7440 * unique number, so that applications may detect new trap entries.
7443 * A pointer to the trap entry
7445 PNMI_STATIC char* GetTrapEntry(
7446 SK_AC *pAC, /* Pointer to adapter context */
7447 SK_U32 TrapId, /* SNMP ID of the trap */
7448 unsigned int Size) /* Space needed for trap entry */
7450 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7451 unsigned int BufFree = pAC->Pnmi.TrapBufFree;
7452 unsigned int Beg = pAC->Pnmi.TrapQueueBeg;
7453 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7454 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7456 unsigned int NeededSpace;
7457 unsigned int EntrySize;
7462 /* Last byte of entry will get a copy of the entry length */
7466 * Calculate needed buffer space */
7473 NeededSpace = Beg + Size;
7478 * Check if enough buffer space is provided. Otherwise
7479 * free some entries. Leave one byte space between begin
7480 * and end of buffer to make it possible to detect whether
7481 * the buffer is full or empty
7483 while (BufFree < NeededSpace + 1) {
7487 End = SK_PNMI_TRAP_QUEUE_LEN;
7490 EntrySize = (unsigned int)*((unsigned char *)pBuf + End - 1);
7491 BufFree += EntrySize;
7494 SK_MEMSET(pBuf + End, (char)(-1), EntrySize);
7496 if (End == BufPad) {
7498 SK_MEMSET(pBuf, (char)(-1), End);
7507 * Insert new entry as first entry. Newest entries are
7508 * stored at the beginning of the queue.
7513 Beg = SK_PNMI_TRAP_QUEUE_LEN - Size;
7518 BufFree -= NeededSpace;
7520 /* Save the current offsets */
7521 pAC->Pnmi.TrapQueueBeg = Beg;
7522 pAC->Pnmi.TrapQueueEnd = End;
7523 pAC->Pnmi.TrapBufPad = BufPad;
7524 pAC->Pnmi.TrapBufFree = BufFree;
7526 /* Initialize the trap entry */
7527 *(pBuf + Beg + Size - 1) = (char)Size;
7528 *(pBuf + Beg) = (char)Size;
7529 Val32 = (pAC->Pnmi.TrapUnique) ++;
7530 SK_PNMI_STORE_U32(pBuf + Beg + 1, Val32);
7531 SK_PNMI_STORE_U32(pBuf + Beg + 1 + sizeof(SK_U32), TrapId);
7532 Val64 = SK_PNMI_HUNDREDS_SEC(SkOsGetTime(pAC));
7533 SK_PNMI_STORE_U64(pBuf + Beg + 1 + 2 * sizeof(SK_U32), Val64);
7535 return (pBuf + Beg);
7538 /*****************************************************************************
7540 * CopyTrapQueue - Copies the trap buffer for the TRAP OID
7543 * On a query of the TRAP OID the trap buffer contents will be
7544 * copied continuously to the request buffer, which must be large
7545 * enough. No length check is performed.
7550 PNMI_STATIC void CopyTrapQueue(
7551 SK_AC *pAC, /* Pointer to adapter context */
7552 char *pDstBuf) /* Buffer to which the queued traps will be copied */
7554 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7555 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7556 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7557 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7559 unsigned int DstOff = 0;
7562 while (Trap != End) {
7564 Len = (unsigned int)*(pBuf + Trap);
7567 * Last byte containing a copy of the length will
7570 *(pDstBuf + DstOff) = (char)(Len - 1);
7571 SK_MEMCPY(pDstBuf + DstOff + 1, pBuf + Trap + 1, Len - 2);
7575 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7582 /*****************************************************************************
7584 * GetTrapQueueLen - Get the length of the trap buffer
7587 * Evaluates the number of currently stored traps and the needed
7588 * buffer size to retrieve them.
7593 PNMI_STATIC void GetTrapQueueLen(
7594 SK_AC *pAC, /* Pointer to adapter context */
7595 unsigned int *pLen, /* Length in Bytes of all queued traps */
7596 unsigned int *pEntries) /* Returns number of trapes stored in queue */
7598 unsigned int BufPad = pAC->Pnmi.TrapBufPad;
7599 unsigned int Trap = pAC->Pnmi.TrapQueueBeg;
7600 unsigned int End = pAC->Pnmi.TrapQueueEnd;
7601 char *pBuf = &pAC->Pnmi.TrapBuf[0];
7603 unsigned int Entries = 0;
7604 unsigned int TotalLen = 0;
7607 while (Trap != End) {
7609 Len = (unsigned int)*(pBuf + Trap);
7610 TotalLen += Len - 1;
7614 if (Trap == SK_PNMI_TRAP_QUEUE_LEN) {
7620 *pEntries = Entries;
7624 /*****************************************************************************
7626 * QueueSimpleTrap - Store a simple trap to the trap buffer
7629 * A simple trap is a trap with now additional data. It consists
7630 * simply of a trap code.
7635 PNMI_STATIC void QueueSimpleTrap(
7636 SK_AC *pAC, /* Pointer to adapter context */
7637 SK_U32 TrapId) /* Type of sensor trap */
7639 GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_SIMPLE_LEN);
7642 /*****************************************************************************
7644 * QueueSensorTrap - Stores a sensor trap in the trap buffer
7647 * Gets an entry in the trap buffer and fills it with sensor related
7653 PNMI_STATIC void QueueSensorTrap(
7654 SK_AC *pAC, /* Pointer to adapter context */
7655 SK_U32 TrapId, /* Type of sensor trap */
7656 unsigned int SensorIndex) /* Index of sensor which caused the trap */
7659 unsigned int Offset;
7660 unsigned int DescrLen;
7664 /* Get trap buffer entry */
7665 DescrLen = SK_STRLEN(pAC->I2c.SenTable[SensorIndex].SenDesc);
7666 pBuf = GetTrapEntry(pAC, TrapId,
7667 SK_PNMI_TRAP_SENSOR_LEN_BASE + DescrLen);
7668 Offset = SK_PNMI_TRAP_SIMPLE_LEN;
7670 /* Store additionally sensor trap related data */
7671 Val32 = OID_SKGE_SENSOR_INDEX;
7672 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7673 *(pBuf + Offset + 4) = 4;
7674 Val32 = (SK_U32)SensorIndex;
7675 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7678 Val32 = (SK_U32)OID_SKGE_SENSOR_DESCR;
7679 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7680 *(pBuf + Offset + 4) = (char)DescrLen;
7681 SK_MEMCPY(pBuf + Offset + 5, pAC->I2c.SenTable[SensorIndex].SenDesc,
7683 Offset += DescrLen + 5;
7685 Val32 = OID_SKGE_SENSOR_TYPE;
7686 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7687 *(pBuf + Offset + 4) = 1;
7688 *(pBuf + Offset + 5) = (char)pAC->I2c.SenTable[SensorIndex].SenType;
7691 Val32 = OID_SKGE_SENSOR_VALUE;
7692 SK_PNMI_STORE_U32(pBuf + Offset, Val32);
7693 *(pBuf + Offset + 4) = 4;
7694 Val32 = (SK_U32)pAC->I2c.SenTable[SensorIndex].SenValue;
7695 SK_PNMI_STORE_U32(pBuf + Offset + 5, Val32);
7698 /*****************************************************************************
7700 * QueueRlmtNewMacTrap - Store a port switch trap in the trap buffer
7703 * Nothing further to explain.
7708 PNMI_STATIC void QueueRlmtNewMacTrap(
7709 SK_AC *pAC, /* Pointer to adapter context */
7710 unsigned int ActiveMac) /* Index (0..n) of the currently active port */
7716 pBuf = GetTrapEntry(pAC, OID_SKGE_TRAP_RLMT_CHANGE_PORT,
7717 SK_PNMI_TRAP_RLMT_CHANGE_LEN);
7719 Val32 = OID_SKGE_RLMT_PORT_ACTIVE;
7720 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7721 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7722 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)ActiveMac;
7725 /*****************************************************************************
7727 * QueueRlmtPortTrap - Store port related RLMT trap to trap buffer
7730 * Nothing further to explain.
7735 PNMI_STATIC void QueueRlmtPortTrap(
7736 SK_AC *pAC, /* Pointer to adapter context */
7737 SK_U32 TrapId, /* Type of RLMT port trap */
7738 unsigned int PortIndex) /* Index of the port, which changed its state */
7744 pBuf = GetTrapEntry(pAC, TrapId, SK_PNMI_TRAP_RLMT_PORT_LEN);
7746 Val32 = OID_SKGE_RLMT_PORT_INDEX;
7747 SK_PNMI_STORE_U32(pBuf + SK_PNMI_TRAP_SIMPLE_LEN, Val32);
7748 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 4) = 1;
7749 *(pBuf + SK_PNMI_TRAP_SIMPLE_LEN + 5) = (char)PortIndex;
7752 /*****************************************************************************
7754 * CopyMac - Copies a MAC address
7757 * Nothing further to explain.
7762 PNMI_STATIC void CopyMac(
7763 char *pDst, /* Pointer to destination buffer */
7764 SK_MAC_ADDR *pMac) /* Pointer of Source */
7769 for (i = 0; i < sizeof(SK_MAC_ADDR); i ++) {
7771 *(pDst + i) = pMac->a[i];
7776 #ifdef SK_POWER_MGMT
7777 /*****************************************************************************
7779 * PowerManagement - OID handler function of PowerManagement OIDs
7782 * The code is simple. No description necessary.
7785 * SK_PNMI_ERR_OK The request was successfully performed.
7786 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7787 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7788 * the correct data (e.g. a 32bit value is
7789 * needed, but a 16 bit value was passed).
7790 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7791 * exist (e.g. port instance 3 on a two port
7795 PNMI_STATIC int PowerManagement(
7796 SK_AC *pAC, /* Pointer to adapter context */
7797 SK_IOC IoC, /* IO context handle */
7798 int Action, /* Get/PreSet/Set action */
7799 SK_U32 Id, /* Object ID that is to be processed */
7800 char *pBuf, /* Buffer to which to mgmt data will be retrieved */
7801 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7802 SK_U32 Instance, /* Instance (1..n) that is to be queried or -1 */
7803 unsigned int TableIndex, /* Index to the Id table */
7804 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode allways zero */
7807 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
7810 * Check instance. We only handle single instance variables
7812 if (Instance != (SK_U32)(-1) && Instance != 1) {
7815 return (SK_PNMI_ERR_UNKNOWN_INST);
7821 if (Action == SK_PNMI_GET) {
7828 case OID_PNP_CAPABILITIES:
7829 if (*pLen < sizeof(SK_PNP_CAPABILITIES)) {
7831 *pLen = sizeof(SK_PNP_CAPABILITIES);
7832 return (SK_PNMI_ERR_TOO_SHORT);
7836 case OID_PNP_QUERY_POWER:
7837 case OID_PNP_ENABLE_WAKE_UP:
7838 if (*pLen < sizeof(SK_U32)) {
7840 *pLen = sizeof(SK_U32);
7841 return (SK_PNMI_ERR_TOO_SHORT);
7845 case OID_PNP_SET_POWER:
7846 case OID_PNP_ADD_WAKE_UP_PATTERN:
7847 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7851 SK_ERR_LOG(pAC, SK_ERRCL_SW, SK_PNMI_ERR040,
7854 return (SK_PNMI_ERR_GENERAL);
7862 case OID_PNP_CAPABILITIES:
7863 RetCode = SkPowerQueryPnPCapabilities(pAC, IoC, pBuf, pLen);
7866 case OID_PNP_QUERY_POWER:
7867 /* The Windows DDK describes: An OID_PNP_QUERY_POWER requests
7868 the miniport to indicate whether it can transition its NIC
7869 to the low-power state.
7870 A miniport driver must always return NDIS_STATUS_SUCCESS
7871 to a query of OID_PNP_QUERY_POWER. */
7872 RetCode = SK_PNMI_ERR_OK;
7875 /* NDIS handles these OIDs as write-only.
7876 * So in case of get action the buffer with written length = 0
7879 case OID_PNP_SET_POWER:
7880 case OID_PNP_ADD_WAKE_UP_PATTERN:
7881 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7883 RetCode = SK_PNMI_ERR_OK;
7886 case OID_PNP_ENABLE_WAKE_UP:
7887 RetCode = SkPowerGetEnableWakeUp(pAC, IoC, pBuf, pLen);
7891 RetCode = SK_PNMI_ERR_GENERAL;
7899 * From here SET or PRESET action. Check if the passed
7900 * buffer length is plausible.
7903 case OID_PNP_SET_POWER:
7904 case OID_PNP_ENABLE_WAKE_UP:
7905 if (*pLen < sizeof(SK_U32)) {
7907 *pLen = sizeof(SK_U32);
7908 return (SK_PNMI_ERR_TOO_SHORT);
7910 if (*pLen != sizeof(SK_U32)) {
7913 return (SK_PNMI_ERR_BAD_VALUE);
7917 case OID_PNP_ADD_WAKE_UP_PATTERN:
7918 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7919 if (*pLen < sizeof(SK_PM_PACKET_PATTERN)) {
7922 return (SK_PNMI_ERR_BAD_VALUE);
7928 return (SK_PNMI_ERR_READ_ONLY);
7932 * Perform preset or set
7935 /* POWER module does not support PRESET action */
7936 if (Action == SK_PNMI_PRESET) {
7937 return (SK_PNMI_ERR_OK);
7941 case OID_PNP_SET_POWER:
7942 RetCode = SkPowerSetPower(pAC, IoC, pBuf, pLen);
7945 case OID_PNP_ADD_WAKE_UP_PATTERN:
7946 RetCode = SkPowerAddWakeUpPattern(pAC, IoC, pBuf, pLen);
7949 case OID_PNP_REMOVE_WAKE_UP_PATTERN:
7950 RetCode = SkPowerRemoveWakeUpPattern(pAC, IoC, pBuf, pLen);
7953 case OID_PNP_ENABLE_WAKE_UP:
7954 RetCode = SkPowerSetEnableWakeUp(pAC, IoC, pBuf, pLen);
7958 RetCode = SK_PNMI_ERR_GENERAL;
7963 #endif /* SK_POWER_MGMT */
7966 /*****************************************************************************
7968 * Vct - OID handler function of OIDs
7971 * The code is simple. No description necessary.
7974 * SK_PNMI_ERR_OK The request was performed successfully.
7975 * SK_PNMI_ERR_GENERAL A general severe internal error occured.
7976 * SK_PNMI_ERR_TOO_SHORT The passed buffer is too short to contain
7977 * the correct data (e.g. a 32bit value is
7978 * needed, but a 16 bit value was passed).
7979 * SK_PNMI_ERR_UNKNOWN_INST The requested instance of the OID doesn't
7980 * exist (e.g. port instance 3 on a two port
7982 * SK_PNMI_ERR_READ_ONLY Only the Get action is allowed.
7986 PNMI_STATIC int Vct(
7987 SK_AC *pAC, /* Pointer to adapter context */
7988 SK_IOC IoC, /* IO context handle */
7989 int Action, /* Get/PreSet/Set action */
7990 SK_U32 Id, /* Object ID that is to be processed */
7991 char *pBuf, /* Buffer to which the mgmt data will be copied */
7992 unsigned int *pLen, /* On call: buffer length. On return: used buffer */
7993 SK_U32 Instance, /* Instance (-1,2..n) that is to be queried */
7994 unsigned int TableIndex, /* Index to the Id table */
7995 SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */
7998 SK_PNMI_VCT *pVctBackupData;
8001 SK_U32 PhysPortIndex;
8005 SK_U32 RetCode = SK_PNMI_ERR_GENERAL;
8011 * Calculate the port indexes from the instance.
8013 PhysPortMax = pAC->GIni.GIMacsFound;
8014 LogPortMax = SK_PNMI_PORT_PHYS2LOG(PhysPortMax);
8016 /* Dual net mode? */
8017 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8021 if ((Instance != (SK_U32) (-1))) {
8022 /* Check instance range. */
8023 if ((Instance < 2) || (Instance > LogPortMax)) {
8025 return (SK_PNMI_ERR_UNKNOWN_INST);
8028 if (pAC->Pnmi.DualNetActiveFlag == SK_TRUE) {
8029 PhysPortIndex = NetIndex;
8032 PhysPortIndex = Instance - 2;
8034 Limit = PhysPortIndex + 1;
8037 * Instance == (SK_U32) (-1), get all Instances of that OID.
8039 * Not implemented yet. May be used in future releases.
8042 Limit = PhysPortMax;
8045 pPrt = &pAC->GIni.GP[PhysPortIndex];
8046 if (pPrt->PHWLinkUp) {
8056 if (pPrt->PhyType != SK_PHY_MARV_COPPER) {
8058 return (SK_PNMI_ERR_GENERAL);
8061 /* Initialize backup data pointer. */
8062 pVctBackupData = &pAC->Pnmi.VctBackup[PhysPortIndex];
8065 * Check action type.
8067 if (Action == SK_PNMI_GET) {
8073 case OID_SKGE_VCT_GET:
8074 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT)) {
8075 *pLen = (Limit - PhysPortIndex) * sizeof(SK_PNMI_VCT);
8076 return (SK_PNMI_ERR_TOO_SHORT);
8080 case OID_SKGE_VCT_STATUS:
8081 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U8)) {
8082 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U8);
8083 return (SK_PNMI_ERR_TOO_SHORT);
8089 return (SK_PNMI_ERR_GENERAL);
8096 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8099 case OID_SKGE_VCT_GET:
8100 if ((Link == SK_FALSE) &&
8101 (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING)) {
8102 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_FALSE);
8104 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_PENDING;
8105 pAC->Pnmi.VctStatus[PhysPortIndex] |=
8106 (SK_PNMI_VCT_NEW_VCT_DATA | SK_PNMI_VCT_TEST_DONE);
8108 /* Copy results for later use to PNMI struct. */
8109 for (i = 0; i < 4; i++) {
8110 if (pPrt->PMdiPairSts[i] == SK_PNMI_VCT_NORMAL_CABLE) {
8111 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] < 0xff)) {
8112 pPrt->PMdiPairSts[i] = SK_PNMI_VCT_IMPEDANCE_MISMATCH;
8115 if ((pPrt->PMdiPairLen[i] > 35) && (pPrt->PMdiPairLen[i] != 0xff)) {
8116 CableLength = 1000 * (((175 * pPrt->PMdiPairLen[i]) / 210) - 28);
8121 pVctBackupData->PMdiPairLen[i] = CableLength;
8122 pVctBackupData->PMdiPairSts[i] = pPrt->PMdiPairSts[i];
8125 Para.Para32[0] = PhysPortIndex;
8126 Para.Para32[1] = -1;
8127 SkEventQueue(pAC, SKGE_DRV, SK_DRV_PORT_RESET, Para);
8128 SkEventDispatcher(pAC, IoC);
8131 ; /* VCT test is running. */
8135 /* Get all results. */
8136 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8137 Offset += sizeof(SK_U8);
8138 *(pBuf + Offset) = pPrt->PCableLen;
8139 Offset += sizeof(SK_U8);
8140 for (i = 0; i < 4; i++) {
8141 SK_PNMI_STORE_U32((pBuf + Offset), pVctBackupData->PMdiPairLen[i]);
8142 Offset += sizeof(SK_U32);
8144 for (i = 0; i < 4; i++) {
8145 *(pBuf + Offset) = pVctBackupData->PMdiPairSts[i];
8146 Offset += sizeof(SK_U8);
8149 RetCode = SK_PNMI_ERR_OK;
8152 case OID_SKGE_VCT_STATUS:
8153 CheckVctStatus(pAC, IoC, pBuf, Offset, PhysPortIndex);
8154 Offset += sizeof(SK_U8);
8155 RetCode = SK_PNMI_ERR_OK;
8160 return (SK_PNMI_ERR_GENERAL);
8166 } /* if SK_PNMI_GET */
8169 * From here SET or PRESET action. Check if the passed
8170 * buffer length is plausible.
8177 case OID_SKGE_VCT_SET:
8178 if (*pLen < (Limit - PhysPortIndex) * sizeof(SK_U32)) {
8179 *pLen = (Limit - PhysPortIndex) * sizeof(SK_U32);
8180 return (SK_PNMI_ERR_TOO_SHORT);
8186 return (SK_PNMI_ERR_GENERAL);
8190 * Perform preset or set.
8193 /* VCT does not support PRESET action. */
8194 if (Action == SK_PNMI_PRESET) {
8195 return (SK_PNMI_ERR_OK);
8199 for (; PhysPortIndex < Limit; PhysPortIndex++) {
8201 case OID_SKGE_VCT_SET: /* Start VCT test. */
8202 if (Link == SK_FALSE) {
8203 SkGeStopPort(pAC, IoC, PhysPortIndex, SK_STOP_ALL, SK_SOFT_RST);
8205 RetCode = SkGmCableDiagStatus(pAC, IoC, PhysPortIndex, SK_TRUE);
8206 if (RetCode == 0) { /* RetCode: 0 => Start! */
8207 pAC->Pnmi.VctStatus[PhysPortIndex] |= SK_PNMI_VCT_PENDING;
8208 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8209 pAC->Pnmi.VctStatus[PhysPortIndex] &= ~SK_PNMI_VCT_LINK;
8212 * Start VCT timer counter.
8214 SK_MEMSET((char *) &Para, 0, sizeof(Para));
8215 Para.Para32[0] = PhysPortIndex;
8216 Para.Para32[1] = -1;
8217 SkTimerStart(pAC, IoC, &pAC->Pnmi.VctTimeout[PhysPortIndex].VctTimer,
8218 4000000, SKGE_PNMI, SK_PNMI_EVT_VCT_RESET, Para);
8219 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8220 RetCode = SK_PNMI_ERR_OK;
8222 else { /* RetCode: 2 => Running! */
8223 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8224 RetCode = SK_PNMI_ERR_OK;
8227 else { /* RetCode: 4 => Link! */
8229 SK_PNMI_STORE_U32((pBuf + Offset), RetCode);
8230 RetCode = SK_PNMI_ERR_OK;
8232 Offset += sizeof(SK_U32);
8237 return (SK_PNMI_ERR_GENERAL);
8246 PNMI_STATIC void CheckVctStatus(
8251 SK_U32 PhysPortIndex)
8254 SK_PNMI_VCT *pVctData;
8256 SK_U8 LinkSpeedUsed;
8258 pPrt = &pAC->GIni.GP[PhysPortIndex];
8260 pVctData = (SK_PNMI_VCT *) (pBuf + Offset);
8261 pVctData->VctStatus = SK_PNMI_VCT_NONE;
8263 if (!pPrt->PHWLinkUp) {
8265 /* Was a VCT test ever made before? */
8266 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8267 if ((pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_LINK)) {
8268 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8271 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8275 /* Check VCT test status. */
8276 RetCode = SkGmCableDiagStatus(pAC,IoC, PhysPortIndex, SK_FALSE);
8277 if (RetCode == 2) { /* VCT test is running. */
8278 pVctData->VctStatus |= SK_PNMI_VCT_RUNNING;
8280 else { /* VCT data was copied to pAC here. Check PENDING state. */
8281 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_PENDING) {
8282 pVctData->VctStatus |= SK_PNMI_VCT_NEW_VCT_DATA;
8286 if (pPrt->PCableLen != 0xff) { /* Old DSP value. */
8287 pVctData->VctStatus |= SK_PNMI_VCT_OLD_DSP_DATA;
8292 /* Was a VCT test ever made before? */
8293 if (pAC->Pnmi.VctStatus[PhysPortIndex] & SK_PNMI_VCT_TEST_DONE) {
8294 pVctData->VctStatus &= ~SK_PNMI_VCT_NEW_VCT_DATA;
8295 pVctData->VctStatus |= SK_PNMI_VCT_OLD_VCT_DATA;
8298 /* DSP only valid in 100/1000 modes. */
8299 LinkSpeedUsed = pAC->GIni.GP[PhysPortIndex].PLinkSpeedUsed;
8300 if (LinkSpeedUsed != SK_LSPEED_STAT_10MBPS) {
8301 pVctData->VctStatus |= SK_PNMI_VCT_NEW_DSP_DATA;
8305 } /* CheckVctStatus */